/* ================================================================
   platform-home.jsx — Capital Economics research platform, signed-in
   home page, TRIAL state layered on the client page.

   The client page and the trial page are the SAME page. Every trial
   difference is state, never a structural change: a persistent chip
   in the secondary nav, a "Your trial" sidebar panel, locked cards
   in the same grid, and a single spend confirmation. Remove the
   trial state and you are looking at the client home.

   Brand purple carries all trial status (system chrome). Teal is
   reserved for content actions so trial messaging never competes
   with "Explore our analysis". Amber for warning, red only at expiry.

   States: healthy · low · exhausted · expired · client.
   Built at 1440px, terminal-dense, no illustration.
================================================================ */
const DSNS = window.CapitalEconomicsDesignSystem_f2a5b2 || {};

/* ---------- tokens local to this page ---------- */
const PURPLE = "#164194", PURPLE_D = "#123573", PURPLE_BG = "#eef2fb", PURPLE_BD = "#c5d2ef";
const TEAL = "#0b8a80", TEAL_D = "#097368";
const AMBER = "#c0392b", AMBER_BG = "#fbe4e1", AMBER_BD = "#eeb3ac";
const REDX = "#c0392b";

/* ---------- icons (Lucide subset) ---------- */
const P_ICONS = {
  search: <><circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3" /></>,
  user: <><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" /><circle cx="12" cy="7" r="4" /></>,
  bell: <><path d="M10.268 21a2 2 0 0 0 3.464 0" /><path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" /></>,
  "chevron-down": <path d="m6 9 6 6 6-6" />,
  "arrow-right": <><path d="M5 12h14" /><path d="m12 5 7 7-7 7" /></>,
  lock: <><rect width="18" height="11" x="3" y="11" rx="2" /><path d="M7 11V7a5 5 0 0 1 10 0v4" /></>,
  plus: <><path d="M5 12h14" /><path d="M12 5v14" /></>,
  check: <path d="M20 6 9 17l-5-5" />,
  clock: <><circle cx="12" cy="12" r="10" /><path d="M12 6v6l4 2" /></>,
  x: <><path d="M18 6 6 18" /><path d="M6 6l12 12" /></>,
  mail: <><rect width="20" height="16" x="2" y="4" rx="2" /><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" /></>,
  download: <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><path d="M7 10l5 5 5-5" /><path d="M12 15V3" /></>,
  message: <path d="M21 11.5a8.38 8.38 0 0 1-9 8.4 8.5 8.5 0 0 1-3.9-.9L3 21l1.9-4.1A8.38 8.38 0 0 1 4 12.5a8.5 8.5 0 0 1 8.5-8.5A8.38 8.38 0 0 1 21 11.5Z" />,
  layers: <><path d="m12 2 9 5-9 5-9-5 9-5z" /><path d="m3 12 9 5 9-5" /><path d="m3 17 9 5 9-5" /></>,
  info: <><circle cx="12" cy="12" r="10" /><path d="M12 16v-4M12 8h.01" /></>,
  "alert-triangle": <><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" /><path d="M12 9v4M12 17h.01" /></>,
  sun: <><circle cx="12" cy="12" r="4" /><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4" /></>,
  moon: <path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" />,
};
function PIcon({ name, size = 18, stroke = 2, style }) {
  return <svg style={style} width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">{P_ICONS[name]}</svg>;
}

/* ---------- mini chart motif for thumbnails ---------- */
function Motif({ kind, seed = 1, muted }) {
  const rnd = (n) => { let x = Math.sin(seed * 9301 + n * 49297) * 233280; return x - Math.floor(x); };
  const stroke = muted ? "var(--pg-chart-muted, #9aa3b2)" : "var(--pg-chart, #164194)";
  const fill = stroke;
  const W = 300, H = 150;
  if (kind === "bars") {
    return (
      <svg viewBox={`0 0 ${W} ${H}`} width="100%" height="100%" preserveAspectRatio="none" aria-hidden="true">
        {Array.from({ length: 9 }).map((_, i) => { const h = 30 + rnd(i) * 95; return <rect key={i} x={22 + i * 30} y={H - 14 - h} width={17} height={h} rx={2} fill={fill} opacity={muted ? 0.4 : 0.35 + i * 0.06} />; })}
      </svg>
    );
  }
  const pts = Array.from({ length: 8 }).map((_, i) => [22 + i * (W - 44) / 7, 24 + rnd(i) * 100]);
  const line = pts.map((p, i) => (i ? "L" : "M") + p[0].toFixed(1) + " " + p[1].toFixed(1)).join(" ");
  const area = line + ` L${W - 22} ${H - 14} L22 ${H - 14} Z`;
  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" height="100%" preserveAspectRatio="none" aria-hidden="true">
      <defs><linearGradient id={"pg" + seed + (muted ? "m" : "")} x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stopColor={fill} stopOpacity={muted ? 0.14 : 0.18} /><stop offset="100%" stopColor={fill} stopOpacity="0" /></linearGradient></defs>
      <path d={area} fill={`url(#pg${seed}${muted ? "m" : ""})`} />
      <path d={line} fill="none" stroke={stroke} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" opacity={muted ? 0.7 : 1} />
    </svg>
  );
}

/* ---------- data ---------- */
const TOP_NAV = ["Topic Alerts", "Data Explorer", "Economist Q&A", "Consultancy", "All Analysis"];
const SUB_NAV = ["Key Issues", "Global Macro", "Financial Markets", "DM Macro", "EM Macro", "Real Estate", "Commodities"];

const CARDS = [
  { id: "c1", cat: "Monetary policy", title: "The Fed's December cut still looks likely despite sticky services", stand: "Core services printed above consensus, but the trend still points to one more cut this year.", date: "26 Jun", read: 6, kind: "line" },
  { id: "c2", cat: "FX & rates", title: "Sterling's rally has further to run into the autumn", stand: "Rate differentials and improving terms of trade support a firmer pound near term.", date: "26 Jun", read: 5, kind: "line", locked: true },
  { id: "c3", cat: "Commodities", title: "Why the oil market is underpricing spare capacity", stand: "OPEC's buffer is larger than the curve implies, capping the upside from here.", date: "25 Jun", read: 8, kind: "bars" },
  { id: "c4", cat: "China", title: "Beijing's stimulus is targeted, not a bazooka", stand: "The latest measures steady growth without reflating the property sector.", date: "25 Jun", read: 7, kind: "line", locked: true },
  { id: "c5", cat: "Global macro", title: "Our mid-year forecast set across the economies we cover", stand: "Where we see growth, inflation and policy rates through 2027.", date: "24 Jun", read: 18, kind: "bars" },
  { id: "c6", cat: "Financial markets", title: "Equity valuations can hold if earnings deliver", stand: "The multiple looks stretched, but the profit path does most of the work.", date: "24 Jun", read: 6, kind: "line", locked: true },
];
const LATEST = [
  { id: "l1", cat: "EM macro", title: "India's disinflation opens the door to earlier cuts", stand: "Food prices are normalising faster than the RBI expected.", date: "23 Jun", read: 5, kind: "line" },
  { id: "l2", cat: "Real estate", title: "The office repricing has further to go in Europe", stand: "Cap rates have moved, but rents have not finished adjusting.", date: "23 Jun", read: 9, kind: "bars" },
  { id: "l3", cat: "DM macro", title: "The euro-zone recovery is real but shallow", stand: "A consumer-led pickup, not an investment boom.", date: "22 Jun", read: 7, kind: "line" },
  { id: "l4", cat: "Central banks", title: "What quieter guidance means for rate volatility", stand: "Fewer voices, clearer signal, calmer decision days.", date: "22 Jun", read: 6, kind: "line" },
  { id: "l5", cat: "Commodities", title: "Copper's structural story survives the cyclical wobble", stand: "Electrification demand outlasts the near-term destocking.", date: "21 Jun", read: 8, kind: "bars" },
  { id: "l6", cat: "US", title: "The labour market is loosening, gently", stand: "Hiring is cooling without the layoffs that mark a downturn.", date: "21 Jun", read: 5, kind: "line" },
];

const UNLOCKS = [
  { icon: "layers", label: "Unlimited analysis across every region" },
  { icon: "mail", label: "Topic alerts delivered by email" },
  { icon: "download", label: "Data downloads and the Excel add-in" },
  { icon: "message", label: "Direct economist Q&A" },
];

const STATE_CFG = {
  healthy: { trial: true, credits: 6, used: 4, days: 5, tone: "purple" },
  low: { trial: true, credits: 2, used: 8, days: 2, tone: "amber" },
  exhausted: { trial: true, credits: 0, used: 10, days: 5, tone: "amber", banner: true },
  expired: { trial: true, credits: 0, used: 10, days: 0, tone: "red", expired: true },
  client: { trial: false },
};

let pgCSS = false;
function injectPgCSS() {
  if (pgCSS || typeof document === "undefined") return; pgCSS = true;
  const css = `
  .pg { font-family: var(--font-ui); color: var(--text-primary); background: var(--surface-page); min-height: 100%; position: relative; --pg-chart: #164194; --pg-chart-muted: #9aa3b2; }
  .pg-tp { --tp: ${PURPLE}; --tpd: ${PURPLE_D}; --tpbg: ${PURPLE_BG}; --tpbd: ${PURPLE_BD}; }

  /* ---------- DARK MODE (the signed-in platform runs dark) ---------- */
  .pg.dark {
    --surface-page: #131120; --surface-card: #1e1b2c; --surface-sunken: #272338; --surface-subtle: #241f36;
    --text-primary: #eef0f7; --text-secondary: #b6b9cc; --text-muted: #8388a0;
    --border-subtle: #2c2940; --border-default: #3a3654; --border-strong: #4a4668;
    --brand: #8ea6e0; --brand-subtle: rgba(142,166,224,0.14); --brand-hover: #a7bce9;
    --text-link: #8ea6e0; --ce-navy: #1b1928; --shadow-sm: 0 1px 3px rgba(0,0,0,0.5);
    --pg-chart: #8ea6e0; --pg-chart-muted: #6b6f88;
    --tpbg: rgba(120,150,220,0.18); --tpbd: rgba(120,150,220,0.45); --tpd: #b6c8ef;
  }
  .pg.dark .pg-thumb { background: #272338; }
  .pg.dark .pg-chip { color: #c2d2f2; }
  .pg.dark .pg-chip.amber { --tpbg: rgba(224,79,78,0.2); --tpbd: rgba(224,79,78,0.5); --tpd: #f0928c; color: #f0928c; }
  .pg.dark .pg-meter-blocks .off { box-shadow: inset 0 0 0 1.4px var(--tpbd); }
  .pg.dark .pg-trialpanel { --tpbg: rgba(120,150,220,0.18); --tpbd: rgba(120,150,220,0.42); }
  .pg.dark .pg-trialpanel h3 { color: #fff; }
  .pg.dark .pg-btn-outline { color: #b6c8ef; border-color: var(--tpbd); }
  .pg.dark .pg-lockchip { background: rgba(0,0,0,0.72); }
  .pg.dark .pg-card.locked .pg-thumb { filter: saturate(0.4) brightness(0.9); }
  .pg.dark .pg-drawer-eyebrow, .pg.dark .pg-card.locked .pg-card-foot { color: #b6c8ef; }
  .pg.dark .pg-exbanner { background: rgba(224,79,78,0.16); border-color: rgba(224,79,78,0.4); }
  .pg.dark .pg-exb-icon { color: #f0928c; }
  .pg.dark .pg-exbanner h4 { color: #f0928c; } .pg.dark .pg-exbanner p { color: #e7a9a3; }
  .pg.dark .pg-tp-warn { color: #f0928c; }
  .pg.dark .pg-toast { background: #2a2740; border: 1px solid var(--border-default); }
  .pg.dark .pg-modal-check input { accent-color: ${TEAL}; }

  /* top nav */
  .pg-top { background: var(--ce-navy); color: #fff; height: 58px; display: flex; align-items: center; gap: 26px; padding: 0 26px; }
  .pg-logo { font-family: var(--font-serif); font-weight: 700; font-size: 19px; letter-spacing: 0.02em; color: #fff; display: inline-flex; align-items: center; gap: 9px; white-space: nowrap; }
  .pg-logo .pg-mark { width: 26px; height: 26px; border-radius: 5px; background: var(--ce-blue); display: inline-flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 800; }
  .pg-topnav { display: flex; align-items: center; gap: 4px; margin: 0 auto; }
  .pg-topnav a { font-size: 13.5px; font-weight: 600; color: rgba(255,255,255,0.82); text-decoration: none; padding: 8px 12px; border-radius: 6px; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
  .pg-topnav a:hover { background: rgba(255,255,255,0.08); color: #fff; }
  .pg-topicons { display: flex; align-items: center; gap: 4px; }
  .pg-iconbtn { width: 36px; height: 36px; border-radius: 7px; border: 0; background: transparent; color: rgba(255,255,255,0.82); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
  .pg-iconbtn:hover { background: rgba(255,255,255,0.1); color: #fff; }

  /* secondary nav */
  .pg-sub { background: var(--surface-card); border-bottom: 1px solid var(--border-subtle); height: 50px; display: flex; align-items: center; padding: 0 26px; gap: 2px; position: relative; }
  .pg-sub a { font-size: 13.5px; font-weight: 600; color: var(--text-secondary); text-decoration: none; padding: 7px 12px; border-radius: 6px; white-space: nowrap; }
  .pg-sub a:hover { color: var(--brand); background: var(--brand-subtle); }
  .pg-sub a.on { color: var(--brand); }
  .pg-sub a.on::after { content: ""; }

  /* trial chip */
  .pg-chipwrap { margin-left: auto; position: relative; }
  .pg-chip { display: inline-flex; align-items: center; gap: 9px; height: 34px; padding: 0 14px; border-radius: 999px; border: 1px solid var(--tpbd); background: var(--tpbg); color: var(--tpd); font-size: 13px; font-weight: 700; cursor: pointer; white-space: nowrap; }
  .pg-chip .pg-chip-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--tp); }
  .pg-chip .pg-chip-sep { color: var(--tpbd); font-weight: 400; }
  .pg-chip:hover { border-color: var(--tp); }
  .pg-chip.amber { --tp:${AMBER}; --tpd:#a12a1d; --tpbg:${AMBER_BG}; --tpbd:${AMBER_BD}; }

  /* popover */
  .pg-pop { position: absolute; top: calc(100% + 10px); right: 0; width: 320px; background: var(--surface-card); border: 1px solid var(--border-default); border-radius: 12px; box-shadow: 0 18px 44px rgba(20,24,46,0.22); padding: 18px; z-index: 60; }
  .pg-pop h4 { font-size: 15px; font-weight: 700; margin: 0 0 12px; color: var(--text-primary); }
  .pg-pop .pg-meter { margin: 0 0 12px; }
  .pg-pop-list { list-style: none; margin: 12px 0 16px; padding: 12px 0 0; border-top: 1px solid var(--border-subtle); display: flex; flex-direction: column; gap: 7px; }
  .pg-pop-list li { font-size: 12.5px; line-height: 1.4; color: var(--text-secondary); display: flex; gap: 8px; align-items: flex-start; }
  .pg-pop-list li svg { flex: 0 0 auto; margin-top: 1px; }
  .pg-pop-exp { font-size: 12.5px; color: var(--text-muted); margin: 0 0 2px; }

  /* meter */
  .pg-meter-blocks { display: flex; gap: 4px; }
  .pg-meter-blocks span { flex: 1; height: 10px; border-radius: 2px; box-sizing: border-box; }
  .pg-meter-blocks .on { background: var(--tp); }
  .pg-meter-blocks .off { background: transparent; box-shadow: inset 0 0 0 1.4px var(--tpbd); }
  .pg-meter-label { font-size: 12.5px; font-weight: 700; color: var(--text-primary); margin: 9px 0 0; }
  .pg-meter.amber { --tp:${AMBER}; --tpbd:${AMBER_BD}; }

  /* layout */
  .pg-body { display: grid; grid-template-columns: 260px minmax(0,1fr); gap: 26px; max-width: 1440px; margin: 0 auto; padding: 24px 26px 40px; align-items: start; }
  .pg-side { display: flex; flex-direction: column; gap: 14px; position: sticky; top: 16px; }
  .pg-panel { background: var(--surface-card); border: 1px solid var(--border-subtle); border-radius: 10px; padding: 15px 16px; }
  .pg-panel h3 { font-size: 13px; font-weight: 800; letter-spacing: 0.01em; color: var(--text-primary); margin: 0 0 4px; text-transform: none; }
  .pg-panel .pg-panel-sub { font-size: 12px; color: var(--text-muted); margin: 0 0 10px; line-height: 1.45; }
  .pg-panel ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
  .pg-panel ul a { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 13px; color: var(--text-secondary); text-decoration: none; padding: 6px 0; border-bottom: 1px solid var(--border-subtle); }
  .pg-panel ul li:last-child a { border-bottom: 0; }
  .pg-panel ul a:hover { color: var(--brand); }
  .pg-panel ul a .pg-cnt { font-size: 11px; color: var(--text-muted); font-weight: 700; }

  /* your-trial panel */
  .pg-trialpanel { border: 0; background: var(--tp); border-radius: 10px; padding: 18px 16px; }
  .pg-trialpanel.amber { --tp:${AMBER}; --tpd:#a12a1d; --tpbg:${AMBER_BG}; --tpbd:${AMBER_BD}; }
  .pg-trialpanel h3 { font-size: 13px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: #fff; margin: 0 0 12px; }
  .pg-trialpanel .pg-meter-blocks .on { background: #fff; }
  .pg-trialpanel .pg-meter-blocks .off { box-shadow: inset 0 0 0 1.4px rgba(255,255,255,0.5); }
  .pg-trialpanel .pg-meter-label { color: #fff; }
  .pg-trialpanel .pg-tp-line { color: rgba(255,255,255,0.82); }
  .pg-trialpanel .pg-tp-line strong { color: #fff; }
  .pg-trialpanel .pg-tp-warn { color: #ffd9d4; }
  .pg-trialpanel .pg-tp-unlocks-h { color: rgba(255,255,255,0.68); }
  .pg-trialpanel .pg-tp-unlocks { border-top-color: rgba(255,255,255,0.22); }
  .pg-trialpanel .pg-tp-unlocks li { color: rgba(255,255,255,0.9); }
  .pg-trialpanel .pg-tp-unlocks li .pg-uglyph { background: rgba(255,255,255,0.16); color: #fff; }
  .pg-trialpanel .pg-tp-cta { background: #fff; color: var(--tp); }
  .pg-trialpanel .pg-tp-cta:hover { background: rgba(255,255,255,0.9); }
  .pg-tp-line { font-size: 12.5px; color: var(--text-secondary); margin: 0; }
  .pg-tp-line strong { color: var(--text-primary); font-weight: 700; }
  .pg-tp-warn { font-size: 12.5px; color: #a12a1d; font-weight: 600; margin: 10px 0 0; line-height: 1.4; }
  .pg-tp-unlocks { list-style: none; margin: 14px 0 14px; padding: 13px 0 0; border-top: 1px solid var(--border-subtle); display: flex; flex-direction: column; gap: 9px; }
  .pg-tp-unlocks li { display: flex; gap: 9px; align-items: flex-start; font-size: 12.5px; line-height: 1.35; color: var(--text-secondary); }
  .pg-tp-unlocks li .pg-uglyph { width: 18px; height: 18px; border-radius: 5px; background: var(--tpbg); color: var(--tp); display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; }
  .pg-tp-unlocks-h { font-size: 11px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); margin: 14px 0 0; }

  /* buttons */
  .pg-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; font-family: var(--font-ui); font-weight: 700; font-size: 13.5px; border-radius: 7px; border: 1px solid transparent; cursor: pointer; padding: 0 16px; height: 40px; white-space: nowrap; text-decoration: none; }
  .pg-btn-block { width: 100%; }
  .pg-btn-purple { background: var(--tp, ${PURPLE}); color: #fff; }
  .pg-btn-purple:hover { background: ${PURPLE_D}; }
  .pg-btn-teal { background: ${TEAL}; color: #fff; }
  .pg-btn-teal:hover { background: ${TEAL_D}; }
  .pg-btn-outline { background: transparent; color: var(--tp, ${PURPLE}); border-color: var(--tpbd, ${PURPLE_BD}); }
  .pg-btn-outline:hover { background: var(--tpbg, ${PURPLE_BG}); }
  .pg-btn-quiet { background: transparent; color: var(--text-secondary); border-color: var(--border-default); }
  .pg-btn-quiet:hover { background: var(--surface-sunken); }
  .pg-btn-sm { height: 34px; font-size: 12.5px; padding: 0 13px; }
  .pg-btn-lg { height: 46px; font-size: 15px; padding: 0 22px; }
  .pg-textlink { background: 0; border: 0; font-family: var(--font-ui); font-size: 12.5px; font-weight: 700; color: var(--text-secondary); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; padding: 0; }
  .pg-textlink:hover { color: var(--brand); }

  /* main column */
  .pg-main { min-width: 0; }
  .pg-h1 { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; color: var(--text-primary); margin: 2px 0 18px; }
  .pg-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }

  /* content card */
  .pg-card { display: flex; flex-direction: column; background: var(--surface-card); border: 1px solid var(--border-subtle); border-radius: 10px; overflow: hidden; text-decoration: none; color: inherit; cursor: pointer; transition: border-color 150ms, box-shadow 150ms, transform 150ms; }
  .pg-card:hover { border-color: var(--border-default); box-shadow: var(--shadow-sm); transform: translateY(-2px); }
  .pg-thumb { position: relative; aspect-ratio: 16/9; background: #eef2fb; overflow: hidden; }
  .pg-card-body { padding: 14px 15px 15px; display: flex; flex-direction: column; flex: 1; }
  .pg-cat { font-size: 10.5px; font-weight: 800; letter-spacing: 0.09em; text-transform: uppercase; color: var(--brand); margin-bottom: 7px; }
  .pg-card-title { font-family: var(--font-serif); font-weight: 600; font-size: 16.5px; line-height: 1.26; letter-spacing: -0.01em; color: var(--text-primary); margin: 0 0 7px; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
  .pg-card-stand { font-size: 12.5px; line-height: 1.45; color: var(--text-secondary); margin: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .pg-card-foot { display: flex; align-items: center; gap: 7px; margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--border-subtle); font-size: 11.5px; color: var(--text-muted); }
  .pg-card-foot .pg-dot { opacity: 0.6; }

  /* locked card */
  .pg-card.locked .pg-thumb { filter: saturate(0.32) brightness(1.03); }
  .pg-lockchip { position: absolute; top: 10px; left: 10px; display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 9px; border-radius: 999px; background: rgba(36,33,58,0.86); color: #fff; font-size: 10.5px; font-weight: 700; letter-spacing: 0.02em; }
  .pg-card.locked .pg-card-foot { color: var(--tp, ${PURPLE}); font-weight: 700; }
  .pg-card.locked .pg-card-foot .pg-fullsub { display: inline-flex; align-items: center; gap: 6px; }

  /* dark promo banner */
  .pg-promo { grid-column: 1 / -1; background: var(--ce-navy); border-radius: 12px; padding: 26px 30px; display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
  .pg-promo-h { font-family: var(--font-serif); font-weight: 600; font-size: 22px; line-height: 1.2; letter-spacing: -0.01em; color: #fff; margin: 0 0 6px; max-width: 44ch; }
  .pg-promo-p { font-size: 13.5px; color: rgba(255,255,255,0.76); margin: 0; max-width: 56ch; }

  /* exhausted banner */
  .pg-exbanner { background: ${AMBER_BG}; border: 1px solid ${AMBER_BD}; border-radius: 10px; padding: 16px 20px; display: flex; align-items: flex-start; gap: 14px; margin-bottom: 20px; }
  .pg-exbanner .pg-exb-icon { flex: 0 0 auto; color: ${AMBER}; align-self: stretch; display: inline-flex; align-items: center; }
  .pg-exbanner .pg-exb-icon svg { width: auto; height: 100%; }
  .pg-exbanner .pg-exb-txt { flex: 1; }
  .pg-exbanner h4 { font-size: 15px; font-weight: 800; color: #96271b; margin: 0 0 3px; }
  .pg-exbanner p { font-size: 13px; color: #a12a1d; margin: 0; }

  /* latest section */
  .pg-latest { margin-top: 30px; text-align: center; }
  .pg-latest h2 { font-family: var(--font-serif); font-weight: 600; font-size: 24px; letter-spacing: -0.015em; color: var(--text-primary); margin: 0 0 20px; }
  .pg-latest .pg-grid { text-align: left; }
  .pg-latest-cta { margin-top: 26px; display: flex; justify-content: center; }

  /* footer */
  .pg-footer { border-top: 1px solid var(--border-subtle); background: var(--surface-card); }
  .pg-footer-in { max-width: 1440px; margin: 0 auto; padding: 34px 26px 40px; display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 30px; }
  .pg-footer h5 { font-size: 11px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted); margin: 0 0 12px; }
  .pg-footer a, .pg-footer p { display: block; font-size: 13px; color: var(--text-secondary); text-decoration: none; margin: 0 0 8px; }
  .pg-footer a:hover { color: var(--brand); }

  /* overlays */
  .pg-scrim { position: fixed; inset: 0; background: rgba(20,24,46,0.5); z-index: 80; display: flex; align-items: center; justify-content: center; padding: 24px; }
  .pg-modal { background: var(--surface-card); border-radius: 14px; width: 420px; max-width: 100%; padding: 26px; box-shadow: 0 24px 60px rgba(20,24,46,0.35); }
  .pg-modal h3 { font-family: var(--font-serif); font-weight: 600; font-size: 22px; letter-spacing: -0.015em; margin: 0 0 10px; color: var(--text-primary); }
  .pg-modal p { font-size: 14px; line-height: 1.55; color: var(--text-secondary); margin: 0 0 18px; }
  .pg-modal-check { display: flex; align-items: center; gap: 9px; font-size: 12.5px; color: var(--text-secondary); margin: 0 0 18px; cursor: pointer; }
  .pg-modal-check input { width: 15px; height: 15px; accent-color: ${TEAL}; }
  .pg-modal-actions { display: flex; gap: 10px; justify-content: flex-end; }

  /* upgrade drawer */
  .pg-drawer-scrim { position: fixed; inset: 0; background: rgba(20,24,46,0.5); z-index: 80; }
  .pg-drawer { position: fixed; top: 0; right: 0; bottom: 0; width: 400px; max-width: 92vw; background: var(--surface-card); z-index: 81; box-shadow: -18px 0 50px rgba(20,24,46,0.24); display: flex; flex-direction: column; }
  .pg-drawer-head { padding: 20px 22px; border-bottom: 1px solid var(--border-subtle); display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
  .pg-drawer-eyebrow { display: inline-flex; align-items: center; gap: 6px; font-size: 10.5px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: ${PURPLE}; margin-bottom: 8px; }
  .pg-drawer h3 { font-family: var(--font-serif); font-weight: 600; font-size: 21px; letter-spacing: -0.015em; margin: 0; color: var(--text-primary); line-height: 1.2; }
  .pg-drawer-body { padding: 22px; overflow-y: auto; flex: 1; }
  .pg-drawer-body p { font-size: 14px; line-height: 1.6; color: var(--text-secondary); margin: 0 0 18px; }
  .pg-drawer-foot { padding: 18px 22px; border-top: 1px solid var(--border-subtle); display: flex; flex-direction: column; gap: 10px; }

  /* toast */
  .pg-toast { position: fixed; right: 22px; bottom: 22px; z-index: 90; background: var(--ce-navy); color: #fff; border-radius: 10px; padding: 13px 16px; font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 10px; box-shadow: 0 16px 40px rgba(20,24,46,0.3); animation: pgtoast 200ms cubic-bezier(0.2,0,0,1); }
  .pg-toast svg { color: #7ec150; }
  @keyframes pgtoast { from { opacity: 0; transform: translateY(8px); } }

  /* expired takeover */
  .pg-blur { filter: blur(5px); pointer-events: none; user-select: none; }
  .pg-takeover { position: fixed; inset: 0; z-index: 95; display: flex; align-items: center; justify-content: center; padding: 24px; background: rgba(36,33,58,0.32); }
  .pg-takeover-card { background: var(--surface-card); border-radius: 16px; width: 460px; max-width: 100%; padding: 34px; text-align: center; box-shadow: 0 30px 80px rgba(20,24,46,0.4); border-top: 4px solid ${REDX}; }
  .pg-takeover-card h2 { font-family: var(--font-serif); font-weight: 600; font-size: 27px; letter-spacing: -0.02em; margin: 0 0 12px; color: var(--text-primary); }
  .pg-takeover-card p { font-size: 14.5px; line-height: 1.6; color: var(--text-secondary); margin: 0 0 10px; }
  .pg-takeover-sum { background: var(--surface-sunken); border-radius: 10px; padding: 14px 16px; margin: 18px 0 22px; font-size: 13px; color: var(--text-secondary); text-align: left; }
  .pg-takeover-sum strong { color: var(--text-primary); }

  /* ---------- MOBILE ---------- */
  @media (max-width: 860px) {
    .pg-top { gap: 12px; padding: 0 16px; height: 54px; }
    .pg-topnav { display: none; }
    .pg-logo-img { height: 24px !important; }
    .pg-sub { padding: 0 16px; gap: 2px; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
    .pg-sub::-webkit-scrollbar { display: none; }
    .pg-sub a { flex: 0 0 auto; }
    .pg-chipwrap { position: static; margin-left: 8px; flex: 0 0 auto; }
    .pg-chip { height: 30px; font-size: 12px; padding: 0 11px; }
    .pg-pop { position: fixed; top: auto; bottom: 12px; left: 12px; right: 12px; width: auto; }
    .pg-body { grid-template-columns: 1fr; gap: 18px; padding: 16px 16px 32px; }
    .pg-side { position: static; }
    .pg-grid { grid-template-columns: 1fr; gap: 14px; }
    .pg-h1 { font-size: 22px; }
    .pg-promo { flex-direction: column; align-items: flex-start; padding: 22px; }
    .pg-promo .pg-btn { width: 100%; }
    .pg-latest .pg-latest-cta .pg-btn { width: 100%; }
    .pg-footer-in { grid-template-columns: 1fr 1fr; gap: 24px 20px; padding: 28px 16px 32px; }
    .pg-drawer { width: 100%; max-width: 100%; }
    .pg-toast { left: 12px; right: 12px; bottom: 12px; }
  }
  @media (max-width: 480px) {
    .pg-footer-in { grid-template-columns: 1fr; }
  }
  `;
  const el = document.createElement("style"); el.setAttribute("data-ce", "platform-home"); el.textContent = css;
  document.head.appendChild(el);
}

/* ---------- segmented credit meter ---------- */
function Meter({ used, total = 10, amber, label }) {
  return (
    <div className={"pg-meter" + (amber ? " amber" : "")}>
      <div className="pg-meter-blocks">
        {Array.from({ length: total }).map((_, i) => <span key={i} className={i < used ? "on" : "off"} />)}
      </div>
      {label && <p className="pg-meter-label">{label}</p>}
    </div>
  );
}

/* ---------- trial chip + popover ---------- */
function TrialChip({ cfg, live }) {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef();
  React.useEffect(() => {
    if (!open) return;
    const h = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", h); return () => document.removeEventListener("mousedown", h);
  }, [open]);
  if (!cfg.trial) return null;
  const amber = cfg.tone !== "purple";
  return (
    <div className="pg-chipwrap" ref={ref} onMouseEnter={() => live && setOpen(true)}>
      <button className={"pg-chip" + (amber ? " amber" : "")} onClick={() => setOpen((o) => !o)} aria-expanded={open}>
        <span className="pg-chip-dot" />Free trial<span className="pg-chip-sep">·</span>{cfg.credits} credits<span className="pg-chip-sep">·</span>{cfg.days} days left
      </button>
      {open && (
        <div className="pg-pop" onMouseLeave={() => setOpen(false)}>
          <h4>Your free trial</h4>
          <Meter used={cfg.used} amber={amber} label={cfg.credits + " of 10 items remaining"} />
          <p className="pg-pop-exp" style={{ marginTop: 10 }}>{cfg.days} days left · ends 20 August</p>
          <ul className="pg-pop-list">
            <li><PIcon name="check" size={14} style={{ color: TEAL }} />Read any {cfg.credits} more publications you choose</li>
            <li><PIcon name="check" size={14} style={{ color: TEAL }} />Re-read anything you have already opened, free</li>
            <li><PIcon name="lock" size={13} style={{ color: "var(--text-muted)" }} />No alerts, data downloads or economist Q&A</li>
          </ul>
          <button className="pg-btn pg-btn-purple pg-btn-block" style={amber ? { background: AMBER } : null}>Talk to us about full access</button>
          <div style={{ textAlign: "center", marginTop: 10 }}><button className="pg-textlink">See what full access includes</button></div>
        </div>
      )}
    </div>
  );
}

/* ---------- your-trial sidebar panel ---------- */
function TrialPanel({ cfg, onTalk }) {
  if (!cfg.trial) return null;
  const amber = cfg.tone !== "purple";
  if (cfg.expired || cfg.credits === 0) {
    // exhausted / expired: panel converts to conversion content
    return (
      <div className={"pg-trialpanel" + (amber ? " amber" : "")}>
        <h3>Your trial</h3>
        <Meter used={10} amber={amber} label="0 of 10 items remaining" />
        <p className="pg-tp-line" style={{ marginTop: 8 }}>{cfg.expired ? "Trial ended 20 August" : cfg.days + " days left, ends 20 August"}</p>
        <p className="pg-tp-warn">You have opened everything your trial allows. Full access removes the cap and turns on alerts, data and Q&A.</p>
        <p className="pg-tp-unlocks-h">Full access also unlocks</p>
        <ul className="pg-tp-unlocks">
          {UNLOCKS.map((u) => <li key={u.label}><span className="pg-uglyph"><PIcon name={u.icon} size={11} /></span>{u.label}</li>)}
        </ul>
        <button className="pg-btn pg-tp-cta pg-btn-block" onClick={onTalk}>Talk to us about full access</button>
      </div>
    );
  }
  return (
    <div className={"pg-trialpanel" + (amber ? " amber" : "")}>
      <h3>Your trial</h3>
      <Meter used={cfg.used} amber={amber} label={cfg.credits + " of 10 items remaining"} />
      <p className="pg-tp-line" style={{ marginTop: 8 }}><strong>{cfg.days} days left</strong>, ends 20 August</p>
      {amber && <p className="pg-tp-warn">Running low. Talk to us before your trial ends.</p>}
      <p className="pg-tp-unlocks-h">Full access also unlocks</p>
      <ul className="pg-tp-unlocks">
        {UNLOCKS.map((u) => <li key={u.label}><span className="pg-uglyph"><PIcon name={u.icon} size={11} /></span>{u.label}</li>)}
      </ul>
      <button className="pg-btn pg-tp-cta pg-btn-block" onClick={onTalk}>Talk to us about full access</button>
    </div>
  );
}

/* ---------- content card ---------- */
function ContentCard({ c, cfg, onOpen, onLocked }) {
  const seed = parseInt(c.id.replace(/\D/g, ""), 10) || 1;
  // In exhausted/expired, every unopened card is locked. Otherwise use the card's own flag.
  const forcedLock = cfg.trial && (cfg.credits === 0);
  const locked = cfg.trial && (c.locked || forcedLock);
  return (
    <a className={"pg-card" + (locked ? " locked" : "")} onClick={(e) => { e.preventDefault(); locked ? onLocked(c) : onOpen(c); }}>
      <div className="pg-thumb">
        <Motif kind={c.kind} seed={seed} muted={locked} />
        {locked && <span className="pg-lockchip"><PIcon name="lock" size={11} stroke={2.4} />Locked</span>}
      </div>
      <div className="pg-card-body">
        <div className="pg-cat">{c.cat}</div>
        <h3 className="pg-card-title">{c.title}</h3>
        <p className="pg-card-stand">{c.stand}</p>
        <div className="pg-card-foot">
          {locked
            ? <span className="pg-fullsub"><PIcon name="lock" size={12} />Full subscription</span>
            : <><span>{c.date}</span><span className="pg-dot">·</span><span>{c.read} min read</span></>}
        </div>
      </div>
    </a>
  );
}

/* ---------- left sidebar ---------- */
function SidePanel({ title, sub, items }) {
  return (
    <div className="pg-panel">
      <h3>{title}</h3>
      {sub && <p className="pg-panel-sub">{sub}</p>}
      {items && <ul>{items.map((it) => <li key={it[0]}><a href="#">{it[0]}{it[1] && <span className="pg-cnt">{it[1]}</span>}</a></li>)}</ul>}
    </div>
  );
}

function TopicAlertsPanel({ cfg, onSeeAccess }) {
  // Dead-end fix: on a read-only trial, alerts are locked, not an invitation into a wall.
  if (cfg.trial) {
    return (
      <div className="pg-panel">
        <h3>My topic alerts</h3>
        <p className="pg-panel-sub">Topic alerts are part of a full subscription. We will email you when your topics move.</p>
        <button className="pg-btn pg-btn-outline pg-btn-sm pg-btn-block" onClick={onSeeAccess}>See what full access includes</button>
      </div>
    );
  }
  return (
    <div className="pg-panel">
      <h3>My topic alerts</h3>
      <p className="pg-panel-sub">Get an email the moment your topics move.</p>
      <button className="pg-btn pg-btn-purple pg-btn-sm pg-btn-block" style={{ background: PURPLE }}>Create new topic alert</button>
    </div>
  );
}

/* ================================================================ */
function PlatformHome({ state = "healthy", live = false }) {
  const baseCfg = STATE_CFG[state];
  const [modalCard, setModalCard] = React.useState(null);
  const [drawer, setDrawer] = React.useState(null);
  const [toast, setToast] = React.useState(null);
  const [dontAsk, setDontAsk] = React.useState(false);
  const dontAskRef = React.useRef(false);
  const [credits, setCredits] = React.useState(baseCfg.credits);
  const [theme, setTheme] = React.useState(() => {
    try { return localStorage.getItem("ce-platform-theme") || "light"; } catch (e) { return "light"; }
  });
  const toggleTheme = () => setTheme((t) => { const n = t === "dark" ? "light" : "dark"; try { localStorage.setItem("ce-platform-theme", n); } catch (e) {} return n; });
  // Live view reflects spends in the chip, sidebar meter and card locks.
  const cfg = baseCfg.trial ? { ...baseCfg, credits, used: 10 - credits } : baseCfg;

  React.useEffect(() => { if (!toast) return; const t = setTimeout(() => setToast(null), 3600); return () => clearTimeout(t); }, [toast]);

  const doOpen = (c) => {
    const next = Math.max(0, credits - 1);
    setCredits(next);
    setToast(`Report opened. ${next} credits and ${baseCfg.days} days remaining.`);
  };
  const onOpenCard = (c) => {
    if (!live || !cfg.trial) return;
    if (dontAskRef.current) { doOpen(c); return; }
    setModalCard(c);
  };
  const onLocked = (c) => { if (live) setDrawer({ kind: "content", c }); };
  const onTalk = () => { if (live) setDrawer({ kind: "talk" }); };
  const onQA = (e) => { if (live) { e.preventDefault(); setDrawer({ kind: "qa" }); } };

  const sidebar = (
    <aside className="pg-side">
      <TrialPanel cfg={cfg} onTalk={onTalk} />
      <SidePanel title="Recommended for me" sub="Chosen from the topics and regions you follow." items={[["US monetary policy"], ["China growth"], ["Global commodities"]]} />
      <SidePanel title="Latest" items={[["Today's research", "12"], ["This week", "68"]]} />
      <TopicAlertsPanel cfg={cfg} onSeeAccess={onTalk} />
      <SidePanel title="Popular across Capital Economics" items={[["The rate-cut path"], ["China property"], ["Dollar outlook"]]} />
      <SidePanel title="Key Issues" items={[["Inflation"], ["Recession risk"], ["Elections"]]} />
      <SidePanel title="Resources" items={[["Chart books"], ["Forecast tables"], ["Webinars"]]} />
    </aside>
  );

  const grid1 = CARDS.slice(0, 3), grid2 = CARDS.slice(3, 6);

  return (
    <div className={"pg pg-tp" + (theme === "dark" ? " dark" : "")}>
      <div className={cfg.expired ? "pg-blur" : ""}>
        {/* TOP NAV */}
        <div className="pg-top">
          <img className="pg-logo-img" src="assets/ce-logo-header.svg" alt="Capital Economics" style={{ height: 30, width: "auto", flex: "none" }} />
          <nav className="pg-topnav">
            {TOP_NAV.map((n) => <a key={n} href="#" onClick={n === "Economist Q&A" ? onQA : undefined}>{n}</a>)}
            <a href="#">Resources<PIcon name="chevron-down" size={15} /></a>
          </nav>
          <div className="pg-topicons">
            <button className="pg-iconbtn" aria-label={theme === "dark" ? "Switch to light mode" : "Switch to dark mode"} onClick={toggleTheme}><PIcon name={theme === "dark" ? "sun" : "moon"} size={18} /></button>
            <button className="pg-iconbtn" aria-label="Search"><PIcon name="search" size={18} /></button>
            <button className="pg-iconbtn" aria-label="Account"><PIcon name="user" size={18} /></button>
            <button className="pg-iconbtn" aria-label="Notifications"><PIcon name="bell" size={18} /></button>
          </div>
        </div>

        {/* SECONDARY NAV + trial chip */}
        <div className="pg-sub">
          {SUB_NAV.map((n, i) => <a key={n} href="#" className={i === 0 ? "on" : ""}>{n}</a>)}
          <TrialChip cfg={cfg} live={live} />
        </div>

        {/* BODY */}
        <div className="pg-body">
          {sidebar}
          <main className="pg-main">
            {cfg.banner && (
              <div className="pg-exbanner">
                <span className="pg-exb-icon"><PIcon name="alert-triangle" size={38} /></span>
                <div className="pg-exb-txt">
                  <h4>You have used all 10 trial items.</h4>
                  <p>Everything you opened stays available until 20 August.</p>
                </div>
                <button className="pg-btn pg-btn-purple" style={{ background: PURPLE }} onClick={onTalk}>Talk to us about full access</button>
              </div>
            )}
            <h1 className="pg-h1">Recommended for me</h1>
            <div className="pg-grid">
              {grid1.map((c) => <ContentCard key={c.id} c={c} cfg={cfg} onOpen={onOpenCard} onLocked={onLocked} />)}
              <div className="pg-promo">
                <div>
                  <h3 className="pg-promo-h">The mid-year forecast set is live across every economy we cover</h3>
                  <p className="pg-promo-p">Growth, inflation and policy rates through 2027, with the charts and data behind each call.</p>
                </div>
                <a className="pg-btn pg-btn-teal pg-btn-lg" href="#">Explore the forecasts<PIcon name="arrow-right" size={17} /></a>
              </div>
              {grid2.map((c) => <ContentCard key={c.id} c={c} cfg={cfg} onOpen={onOpenCard} onLocked={onLocked} />)}
            </div>

            <section className="pg-latest">
              <h2>Latest from Capital Economics</h2>
              <div className="pg-grid">
                {LATEST.map((c) => <ContentCard key={c.id} c={c} cfg={cfg} onOpen={onOpenCard} onLocked={onLocked} />)}
              </div>
              <div className="pg-latest-cta"><a className="pg-btn pg-btn-teal pg-btn-lg" href="#">Explore all our latest analysis<PIcon name="arrow-right" size={17} /></a></div>
            </section>
          </main>
        </div>

        {/* FOOTER */}
        <footer className="pg-footer">
          <div className="pg-footer-in">
            <div>
              <img src={theme === "dark" ? "assets/ce-logo-header.svg" : "assets/ce-logo-footer-light.svg"} alt="Capital Economics" style={{ height: 30, width: "auto" }} />
              <p style={{ marginTop: 12 }}>5th Floor, 100 Victoria Street<br />London SW1E 5JL</p>
              <p>+44 (0)20 7808 4000</p>
              <p>subscriptions@capitaleconomics.com</p>
            </div>
            <div><h5>What we do</h5><a href="#">Research</a><a href="#">Data</a><a href="#">Consultancy</a><a href="#">Events</a></div>
            <div><h5>Solutions</h5><a href="#">Asset management</a><a href="#">Banking</a><a href="#">Corporates</a><a href="#">Public sector</a></div>
            <div><h5>Policies</h5><a href="#">Terms of use</a><a href="#">Privacy</a><a href="#">Cookies</a><a href="#">Accessibility</a></div>
          </div>
        </footer>
      </div>

      {/* SPEND MODAL */}
      {modalCard && (
        <div className="pg-scrim" onClick={() => setModalCard(null)}>
          <div className="pg-modal" onClick={(e) => e.stopPropagation()}>
            <h3>Open this report?</h3>
            <p>This uses 1 of your {credits} remaining trial items. You can re-read anything you have already opened at no cost.</p>
            <label className="pg-modal-check"><input type="checkbox" checked={dontAsk} onChange={(e) => setDontAsk(e.target.checked)} />Do not ask again</label>
            <div className="pg-modal-actions">
              <button className="pg-btn pg-btn-quiet" onClick={() => setModalCard(null)}>Cancel</button>
              <button className="pg-btn pg-btn-teal" onClick={() => { dontAskRef.current = dontAsk; doOpen(modalCard); setModalCard(null); }}>Open report</button>
            </div>
          </div>
        </div>
      )}

      {/* UPGRADE DRAWER */}
      {drawer && (
        <>
          <div className="pg-drawer-scrim" onClick={() => setDrawer(null)} />
          <div className="pg-drawer">
            <div className="pg-drawer-head">
              <div>
                <span className="pg-drawer-eyebrow"><PIcon name="lock" size={11} stroke={2.4} />{drawer.kind === "qa" ? "Economist Q&A" : drawer.kind === "talk" ? "Full access" : "Subscriber content"}</span>
                <h3>{drawer.kind === "qa" ? "Economist Q&A is part of full access" : drawer.kind === "talk" ? "Full access to Capital Economics" : "This report is part of full access"}</h3>
              </div>
              <button className="pg-iconbtn" style={{ color: "var(--text-muted)" }} onClick={() => setDrawer(null)} aria-label="Close"><PIcon name="x" size={20} /></button>
            </div>
            <div className="pg-drawer-body">
              {drawer.kind === "content" && <p style={{ fontFamily: "var(--font-serif)", fontSize: 16, color: "var(--text-primary)" }}>{drawer.c.title}</p>}
              <p>{drawer.kind === "qa"
                ? "Put questions directly to the economists who cover your markets and get a considered answer, usually within a day. It is included with a full subscription."
                : "A full subscription removes the trial cap and turns on everything below. Talk to us and we will set you up with the coverage your desk needs."}</p>
              <p className="pg-tp-unlocks-h" style={{ marginTop: 0 }}>Full access includes</p>
              <ul className="pg-tp-unlocks" style={{ borderTop: 0, paddingTop: 8 }}>
                {UNLOCKS.map((u) => <li key={u.label}><span className="pg-uglyph" style={{ background: PURPLE_BG, color: PURPLE }}><PIcon name={u.icon} size={11} /></span>{u.label}</li>)}
              </ul>
            </div>
            <div className="pg-drawer-foot">
              <button className="pg-btn pg-btn-purple pg-btn-block" style={{ background: PURPLE }}>Talk to us about full access</button>
              <button className="pg-btn pg-btn-quiet pg-btn-block" onClick={() => setDrawer(null)}>Not now</button>
            </div>
          </div>
        </>
      )}

      {/* TOAST */}
      {toast && <div className="pg-toast"><PIcon name="check" size={16} stroke={2.6} />{toast}</div>}

      {/* EXPIRED TAKEOVER */}
      {cfg.expired && (
        <div className="pg-takeover">
          <div className="pg-takeover-card">
            <h2>Your trial ended on 20 August</h2>
            <p>Thanks for trying Capital Economics. Your trial has now closed.</p>
            <div className="pg-takeover-sum">
              Over your trial you opened <strong>10 publications</strong> across <strong>monetary policy, commodities and China</strong>. Talk to us to keep reading and to turn on alerts, data and economist Q&A.
            </div>
            <button className="pg-btn pg-btn-purple pg-btn-lg pg-btn-block" style={{ background: PURPLE }}>Talk to us about full access</button>
          </div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { PlatformHome, injectPgCSS });

/* ---------- canvas ---------- */
function PgCanvas() {
  injectPgCSS();
  const { DesignCanvas, DCSection, DCArtboard } = window;
  const F = [
    ["healthy", "Healthy — 6 of 10 credits, 5 days (primary)"],
    ["low", "Low warning — 2 credits / 2 days (amber)"],
    ["exhausted", "Exhausted — 0 credits, days remaining"],
    ["expired", "Expired — takeover over blurred page"],
    ["client", "Client (no trial) — same page, chip slot empty"],
  ];
  return (
    <DesignCanvas>
      <DCSection id="states" title="Platform home — trial states" subtitle="One page. Every difference is state, not structure. Purple carries trial chrome, teal stays on content actions.">
        {F.map(([s, label]) => (
          <DCArtboard key={s} id={s} label={label} width={1440} height={1760}>
            <PlatformHome state={s} />
          </DCArtboard>
        ))}
      </DCSection>
    </DesignCanvas>
  );
}

if (window.__PG_MODE === "canvas") {
  ReactDOM.createRoot(document.getElementById("root")).render(<PgCanvas />);
}
