// GuestMaker CRM B2B · proposals, integrations, agenda, status, rollout, footer.

// ── proposals ─────────────────────────────────────────────
const PROP_LANGS = {
  EN: { h: "Negotiated corporate rate agreement 2027", greet: "Dear Lennart,", lead: "Thank you for the time your team gave us in Hannover. Below is the rate structure for the five properties we discussed, valid for stays between 1 January and 31 December 2027.", inv: "Investment", terms: "Terms & conditions", accept: "Accept and sign", sign: "Signature of the authorised representative" },
  ES: { h: "Acuerdo de tarifa corporativa negociada 2027", greet: "Estimado Lennart:", lead: "Gracias por el tiempo que nos dedicó su equipo en Hannover. A continuación, la estructura de tarifas para los cinco hoteles comentados, válida para estancias entre el 1 de enero y el 31 de diciembre de 2027.", inv: "Inversión", terms: "Condiciones", accept: "Aceptar y firmar", sign: "Firma del representante autorizado" },
  DE: { h: "Verhandelte Firmenratenvereinbarung 2027", greet: "Sehr geehrter Herr Brauwe,", lead: "Vielen Dank für die Zeit, die Ihr Team uns in Hannover gewidmet hat. Nachstehend die Ratenstruktur für die fünf besprochenen Häuser, gültig für Aufenthalte vom 1. Januar bis 31. Dezember 2027.", inv: "Investition", terms: "Bedingungen", accept: "Annehmen und unterschreiben", sign: "Unterschrift des Bevollmächtigten" },
  SV: { h: "Förhandlat företagsavtal 2027", greet: "Hej Lennart,", lead: "Tack för tiden ert team gav oss i Hannover. Nedan följer prisstrukturen för de fem hotell vi diskuterade, giltig för vistelser mellan 1 januari och 31 december 2027.", inv: "Investering", terms: "Villkor", accept: "Godkänn och signera", sign: "Behörig representants signatur" },
};
const PROP_SECTIONS = ["Cover", "Summary", "Rooms & rates", "Inclusions", "Investment", "Terms"];

/* B2BFooter was removed here on 2026-08-12. The page uses the site's own
   SectionFooter, so it was dead code — and it carried help@hotelinking.com,
   a phone number and a Hotelinking helpdesk link, which is a third party's
   support desk sitting one accidental render away from a GuestMaker page. */
function ProposalShowcase({ noEditor }) {
  const [mode, setMode] = useState(noEditor ? "client" : "editor");
  const [lang, setLang] = useState("EN");
  const [sections, setSections] = useState(PROP_SECTIONS);
  const [signed, setSigned] = useState(false);
  const t = PROP_LANGS[lang];
  const move = (i, dir) => setSections(s => {
    const j = i + dir; if (j < 0 || j >= s.length) return s;
    const c = [...s]; [c[i], c[j]] = [c[j], c[i]]; return c;
  });

  return (
    <div style={{ background: SURFACE, border: `1px solid ${RULE}`, borderRadius: 12, overflow: "hidden", boxShadow: "0 40px 90px -55px rgba(26,20,26,0.4)" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "10px 14px", borderBottom: `1px solid ${RULE}`, background: PAPER, flexWrap: "wrap" }}>
        {[["editor", "Editor", "pen"], ["client", "What the client opens", "eye"], ["accept", "Acceptance", "sign"]].filter(([k]) => !(noEditor && k === "editor")).map(([k, l, ic]) => (
          <button key={k} onClick={() => setMode(k)} style={{
            display: "inline-flex", alignItems: "center", gap: 6, height: 28, padding: "0 11px", borderRadius: 999, cursor: "pointer",
            border: `1px solid ${mode === k ? INK : RULE}`, background: mode === k ? INK : SURFACE, color: mode === k ? "#fff" : DIM,
            fontFamily: SANS, fontSize: 11.5, fontWeight: 600,
          }}><Icon name={ic} size={11} color={mode === k ? "#fff" : FAINT} />{l}</button>
        ))}
        <div style={{ flex: 1 }} />
        <Mono size={9.5} color={FAINT}>PR-2026-0184 · VALID UNTIL 30 SEP 2026</Mono>
        <span style={{ display: "flex", gap: 3 }}>
          {Object.keys(PROP_LANGS).map(l => (
            <button key={l} onClick={() => setLang(l)} style={{
              width: 30, height: 26, borderRadius: 6, cursor: "pointer", fontFamily: MONO, fontSize: 10, fontWeight: 700,
              border: `1px solid ${lang === l ? FUCHSIA : RULE}`, background: lang === l ? FUCHSIA : SURFACE, color: lang === l ? "#fff" : DIM,
            }}>{l}</button>
          ))}
        </span>
      </div>

      {mode === "editor" && (
        <div style={{ display: "grid", gridTemplateColumns: "212px 1fr", minHeight: 430 }}>
          <div style={{ borderRight: `1px solid ${RULE}`, background: PAPER, padding: "13px 12px" }}>
            <Mono size={9} color={FAINT} style={{ letterSpacing: "0.16em", fontWeight: 700 }}>SECTIONS · DRAG TO REORDER</Mono>
            <div style={{ display: "grid", gap: 6, marginTop: 9 }}>
              {sections.map((s, i) => (
                <div key={s} style={{ display: "flex", alignItems: "center", gap: 6, background: SURFACE, border: `1px solid ${RULE}`, borderRadius: 6, padding: "6px 8px" }}>
                  <Icon name="grip" size={11} color={FAINT} />
                  <span style={{ fontSize: 11.5, fontWeight: 500, flex: 1 }}>{s}</span>
                  <button onClick={() => move(i, -1)} style={{ background: "none", border: "none", cursor: "pointer", padding: 1 }}><Icon name="arrow-u" size={10} color={DIM} /></button>
                  <button onClick={() => move(i, 1)} style={{ background: "none", border: "none", cursor: "pointer", padding: 1 }}><Icon name="arrow-d" size={10} color={DIM} /></button>
                </div>
              ))}
            </div>
            <Mono size={9} color={FAINT} style={{ letterSpacing: "0.16em", fontWeight: 700, display: "block", marginTop: 16 }}>BLOCK LIBRARY</Mono>
            <div style={{ display: "grid", gap: 5, marginTop: 8 }}>
              {["Letter opening · corporate", "Inclusions · half board", "Cancellation · 14 days", "Group payment schedule"].map(b => (
                <div key={b} style={{ border: `1px dashed ${RULE}`, borderRadius: 6, padding: "5px 8px" }}>
                  <Mono size={9} color={DIM}>{b}</Mono>
                </div>
              ))}
            </div>
          </div>
          <div style={{ padding: "20px 26px", background: CREAM }}>
            <div style={{ background: SURFACE, border: `1px solid ${RULE}`, borderRadius: 8, padding: "26px 30px", maxWidth: 560, margin: "0 auto", boxShadow: "0 20px 50px -35px rgba(0,0,0,0.4)" }}>
              <div style={{ display: "flex", alignItems: "center", gap: 9, paddingBottom: 14, borderBottom: `1px solid ${RULE}` }}>
                <span style={{ width: 22, height: 22, borderRadius: 6, background: PLUM }} />
                <Mono size={10} color={INK} style={{ fontWeight: 700, letterSpacing: "0.18em" }}>MAREA HOTELS</Mono>
                <div style={{ flex: 1 }} />
                <Mono size={9} color={FAINT}>{lang}</Mono>
              </div>
              <h4 style={{ fontFamily: SERIF, fontSize: 23, fontWeight: 500, letterSpacing: "-0.02em", margin: "18px 0 12px", lineHeight: 1.2 }}>{t.h}</h4>
              <p style={{ fontSize: 12.5, fontWeight: 600, margin: "0 0 6px" }}>{t.greet}</p>
              <p style={{ fontSize: 12.5, color: DIM, lineHeight: 1.6, margin: "0 0 16px" }}>{t.lead}</p>
              <Mono size={9} color={FUCHSIA} style={{ letterSpacing: "0.16em", fontWeight: 700 }}>{t.inv.toUpperCase()}</Mono>
              <table style={{ width: "100%", borderCollapse: "collapse", marginTop: 8 }}>
                <tbody>
                  {[["Marea Sierra Blanca · double, BB", "€104", "3,200 RN"], ["Marea Club Marbella · double, BB", "€118", "2,400 RN"], ["Marea Cala Blava · suite, HB", "€162", "1,100 RN"]].map(([a, b, c]) => (
                    <tr key={a}>
                      <td style={{ fontSize: 11.5, padding: "6px 0", borderBottom: `1px solid ${RULE_SOFT}` }}>{a}</td>
                      <td style={{ fontFamily: MONO, fontSize: 11.5, padding: "6px 0", borderBottom: `1px solid ${RULE_SOFT}`, textAlign: "right" }}>{b}</td>
                      <td style={{ fontFamily: MONO, fontSize: 10.5, color: DIM, padding: "6px 0 6px 12px", borderBottom: `1px solid ${RULE_SOFT}`, textAlign: "right" }}>{c}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
              <div style={{ display: "flex", gap: 6, marginTop: 14, flexWrap: "wrap" }}>
                {["{{account.name}}", "{{deal.value}}", "{{hotel.list}}", "{{rep.name}}"].map(m => (
                  <span key={m} style={{ background: FUCHSIA_PALE + "70", color: FUCHSIA_DARK, borderRadius: 4, padding: "2px 6px", fontFamily: MONO, fontSize: 9.5 }}>{m}</span>
                ))}
              </div>
            </div>
          </div>
        </div>
      )}

      {mode === "client" && (
        <div style={{ background: PLUM, padding: "34px 30px", position: "relative", overflow: "hidden" }}>
          <div style={{ position: "absolute", inset: 0, background: `radial-gradient(120% 90% at 90% 0%, ${FUCHSIA}44, transparent 60%)` }} />
          <div style={{ position: "relative", maxWidth: 620, margin: "0 auto", color: "#F7F1EC" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 26 }}>
              <span style={{ width: 24, height: 24, borderRadius: 7, background: "#F7F1EC" }} />
              <Mono size={10} color="#F7F1EC" style={{ fontWeight: 700, letterSpacing: "0.2em" }}>MAREA HOTELS</Mono>
              <div style={{ flex: 1 }} />
              <Mono size={9.5} color="#F8B7CF">proposals.mareahotels.com/p/9f4c2e</Mono>
            </div>
            <Mono size={9.5} color="#F8B7CF" style={{ letterSpacing: "0.18em", fontWeight: 700 }}>PROPOSAL PR-2026-0184 · ISSUED 4 AUG 2026 · VALID 60 DAYS</Mono>
            <h4 style={{ fontFamily: SERIF, fontSize: 34, fontWeight: 300, letterSpacing: "-0.025em", lineHeight: 1.12, margin: "14px 0 14px", maxWidth: "22ch" }}>{t.h}</h4>
            <p style={{ fontSize: 14, color: "#D9D1CC", lineHeight: 1.6, maxWidth: "52ch", margin: 0 }}>{t.lead}</p>
            <div style={{ display: "flex", gap: 26, marginTop: 26, paddingTop: 18, borderTop: "1px solid rgba(255,255,255,0.18)", flexWrap: "wrap" }}>
              {[["ACCOUNT", "Nordwind Travel Group"], ["PROPERTIES", "5 hotels"], ["ROOM NIGHTS", "9,000"], ["VALUE", "€148,000"]].map(([k, v]) => (
                <div key={k}>
                  <Mono size={8.5} color="#A79BB0" style={{ letterSpacing: "0.16em", fontWeight: 700 }}>{k}</Mono>
                  <div style={{ fontFamily: SERIF, fontSize: 17, marginTop: 2 }}>{v}</div>
                </div>
              ))}
            </div>
            <div style={{ display: "flex", alignItems: "center", gap: 9, marginTop: 22 }}>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 6, background: "rgba(255,255,255,0.1)", border: "1px solid rgba(255,255,255,0.22)", borderRadius: 999, padding: "5px 12px" }}>
                <Icon name="eye" size={11} color="#F8B7CF" /><Mono size={9.5} color="#F8B7CF">VIEWED 9 TIMES</Mono>
              </span>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 6, background: "rgba(255,255,255,0.1)", border: "1px solid rgba(255,255,255,0.22)", borderRadius: 999, padding: "5px 12px" }}>
                <Icon name="shield" size={11} color="#F8B7CF" /><Mono size={9.5} color="#F8B7CF">STRICT CSP · UNGUESSABLE LINK</Mono>
              </span>
            </div>
          </div>
        </div>
      )}

      {mode === "accept" && (
        <div style={{ padding: "26px 30px", background: CREAM }}>
          <div style={{ maxWidth: 560, margin: "0 auto", background: SURFACE, border: `1px solid ${RULE}`, borderRadius: 10, padding: "22px 24px" }}>
            <Mono size={9} color={FUCHSIA} style={{ letterSpacing: "0.16em", fontWeight: 700 }}>{t.inv.toUpperCase()}</Mono>
            <div style={{ display: "flex", alignItems: "baseline", gap: 10, margin: "8px 0 16px" }}>
              <span style={{ fontFamily: MONO, fontSize: 28, fontWeight: 700, letterSpacing: "-0.03em" }}>€148,000</span>
              <Mono size={10} color={DIM}>9,000 RN · 5 PROPERTIES · 2027</Mono>
            </div>
            <Mono size={9} color={FAINT} style={{ letterSpacing: "0.16em", fontWeight: 700 }}>{t.terms.toUpperCase()}</Mono>
            <p style={{ fontSize: 11.5, color: DIM, lineHeight: 1.55, margin: "6px 0 16px" }}>
              Commission 12% settled monthly net 30. Cancellation 14 days with a 20% penalty. Allotment 60 rooms with a 21-day release.
            </p>
            <div style={{ borderTop: `1px dashed ${RULE}`, paddingTop: 16 }}>
              <Mono size={9} color={FAINT} style={{ letterSpacing: "0.16em", fontWeight: 700 }}>{t.sign.toUpperCase()}</Mono>
              <div onClick={() => setSigned(true)} style={{
                marginTop: 8, height: 78, border: `1px ${signed ? "solid" : "dashed"} ${signed ? GREEN : RULE}`, borderRadius: 8,
                background: signed ? "#F3F9F5" : PAPER, display: "grid", placeItems: "center", cursor: "pointer",
              }}>
                {signed ? (
                  <svg viewBox="0 0 240 50" style={{ width: 210, height: 46 }}>
                    <path d="M8 38 C30 6 44 44 62 24 C80 4 92 42 112 26 C130 12 142 40 160 26 C176 14 192 34 232 12"
                      fill="none" stroke={INK} strokeWidth="2" strokeLinecap="round" />
                  </svg>
                ) : <Mono size={10} color={FAINT}>SIGN HERE WITH FINGER, MOUSE OR STYLUS</Mono>}
              </div>
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: 12, flexWrap: "wrap" }}>
                <input placeholder="Lennart Brauwe" defaultValue={signed ? "Lennart Brauwe" : ""} style={{ flex: 1, minWidth: 160, height: 32, borderRadius: 7, border: `1px solid ${RULE}`, padding: "0 10px", fontFamily: SANS, fontSize: 12 }} />
                <button onClick={() => setSigned(true)} style={{
                  height: 32, padding: "0 14px", borderRadius: 7, border: "none", cursor: "pointer", fontFamily: SANS, fontSize: 12, fontWeight: 600,
                  background: signed ? GREEN : INK, color: "#fff",
                }}>{signed ? "Accepted" : t.accept}</button>
              </div>
              {signed && (
                <div style={{ marginTop: 14, background: "#E9F3EC", border: "1px solid #BFDDC9", borderRadius: 8, padding: "11px 12px" }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 7, marginBottom: 5 }}>
                    <Icon name="check" size={12} color="#256B45" strokeWidth={3} />
                    <span style={{ fontSize: 12, fontWeight: 600, color: "#256B45" }}>Acceptance recorded · the team has been notified</span>
                  </div>
                  <Mono size={9.5} color="#3d6b52" style={{ lineHeight: 1.6 }}>
                    12 AUG 2026 14:07 CEST · IP 85.62.14.203 · CHROME 141 / MACOS · LANGUAGE {lang} · SHA256:9F4C…E21B<br />
                    ACCEPTANCE DOES NOT CROSS THE APPROVAL-GATED STAGE. THE TEAM IS WARNED INSTEAD.
                  </Mono>
                </div>
              )}
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ── integrations ───────────────────────────────────────────
function IntegrationDiagram() {
  const box = (x, y, w, h, title, sub, fill = PAPER, stroke = RULE, tc = INK, sc = DIM) => (
    <g>
      <rect x={x} y={y} width={w} height={h} rx="9" fill={fill} stroke={stroke} />
      <text x={x + 16} y={y + 26} fontSize="13.5" fontWeight="600" fill={tc} fontFamily={SANS}>{title}</text>
      <text x={x + 16} y={y + 45} fontSize="11" fill={sc} fontFamily={MONO}>{sub}</text>
    </g>
  );
  return (
    <div style={{ background: SURFACE, border: `1px solid ${RULE}`, borderRadius: 11, padding: "18px 16px" }}>
      <svg viewBox="0 0 1060 330" style={{ width: "100%", height: "auto" }}>
        <defs>
          <marker id="b2bar" markerWidth="9" markerHeight="9" refX="8" refY="4.5" orient="auto"><path d="M0,0 L9,4.5 L0,9 z" fill={FUCHSIA} /></marker>
          <marker id="b2bar2" markerWidth="9" markerHeight="9" refX="8" refY="4.5" orient="auto"><path d="M0,0 L9,4.5 L0,9 z" fill={DIM} /></marker>
        </defs>
        {box(4, 34, 200, 62, "PMS", "reservations · stays · status")}
        {box(4, 124, 200, 62, "Booking engine", "rate & promo codes")}
        {box(4, 214, 200, 62, "Channel manager · CRS", "agency & IATA codes")}
        <path d="M208,66 L286,140" stroke={FUCHSIA} strokeWidth="1.6" fill="none" markerEnd="url(#b2bar)" />
        <path d="M208,155 L286,155" stroke={FUCHSIA} strokeWidth="1.6" fill="none" markerEnd="url(#b2bar)" />
        <path d="M208,245 L286,172" stroke={FUCHSIA} strokeWidth="1.6" fill="none" markerEnd="url(#b2bar)" />
        <rect x="294" y="98" width="228" height="116" rx="11" fill={PLUM} />
        <text x="316" y="130" fontSize="14" fontWeight="700" fill="#FFF9F3" fontFamily={SANS}>Attribution engine</text>
        {[["P1 agency code · IATA", 154], ["P2 promo code · rate plan", 172], ["P3 booking engine agency id", 190]].map(([t, y]) => (
          <text key={t} x="316" y={y} fontSize="11" fill="#D9D1CC" fontFamily={MONO}>{t}</text>
        ))}
        <text x="316" y="208" fontSize="11" fill="#F8B7CF" fontFamily={MONO}>P4 email domain · suggestion</text>
        <path d="M526,155 L602,155" stroke={FUCHSIA} strokeWidth="1.6" fill="none" markerEnd="url(#b2bar)" />
        {box(610, 20, 210, 58, "Production per account", "room nights · ADR · revenue", SURFACE)}
        {box(610, 92, 210, 58, "Commission ledger", "accrued · invoiced · settled", SURFACE)}
        {box(610, 164, 210, 58, "Allotment watch", "80% and 100% of commitment", SURFACE)}
        {box(610, 236, 210, 58, "Analytics & forecast", "18 metrics · one query", SURFACE)}
        <path d="M832,265 C946,265 946,104 892,92" stroke={DIM} strokeWidth="1.4" fill="none" strokeDasharray="5 4" markerEnd="url(#b2bar2)" />
        {box(842, 20, 214, 76, "Public API v1", "accounts · deals · contacts", CREAM)}
        <text x="858" y="82" fontSize="11" fill={DIM} fontFamily={MONO}>read and write · idempotent</text>
      </svg>
    </div>
  );
}

const JOBS = [
  ["Reservation matcher", "every 10 min", "Sweeps unattributed reservations from the last 90 days and accrues the commissions that follow."],
  ["Scheduled email send", "every 5 min", "Fires the one-to-one emails left scheduled, without duplicating on retry."],
  ["Activity reminder", "hourly", "Emails the owner of an overdue activity. Once per activity, never twice."],
  ["Renewal warning", "daily", "Raises the renewal task for the account manager 60 days before contract end."],
  ["Allotment watch", "daily", "Warns at 80% and again at 100% of the contracted room-night commitment."],
];

function JobsTable() {
  return (
    <div style={{ background: SURFACE, border: `1px solid ${RULE}`, borderRadius: 11, overflow: "hidden" }}>
      <table style={{ width: "100%", borderCollapse: "collapse", fontFamily: SANS }}>
        <thead><tr>{["Process", "Frequency", "What it does"].map((h, i) => (
          <th key={h} style={{ textAlign: "left", padding: "10px 14px", background: PAPER, borderBottom: `1px solid ${RULE}`, width: i === 0 ? "24%" : i === 1 ? "16%" : "auto" }}>
            <Mono size={9} color={DIM} style={{ letterSpacing: "0.14em", fontWeight: 700 }}>{h.toUpperCase()}</Mono></th>))}
        </tr></thead>
        <tbody>
          {JOBS.map(([p, f, w]) => (
            <tr key={p}>
              <td style={{ padding: "11px 14px", borderBottom: `1px solid ${RULE_SOFT}`, fontSize: 12.5, fontWeight: 600 }}>{p}</td>
              <td style={{ padding: "11px 14px", borderBottom: `1px solid ${RULE_SOFT}`, fontFamily: MONO, fontSize: 11, color: FUCHSIA_DARK }}>{f}</td>
              <td style={{ padding: "11px 14px", borderBottom: `1px solid ${RULE_SOFT}`, fontSize: 12, color: DIM, lineHeight: 1.5 }}>{w}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

// ── agenda ────────────────────────────────────────────────
function AgendaPanel() {
  const [filter, setFilter] = useState("all");
  const [done, setDone] = useState({});
  const groups = [["Overdue", ACTIVITIES.filter(a => a.state === "overdue"), RED], ["Today", ACTIVITIES.filter(a => a.state === "today"), FUCHSIA], ["Next 7 days", ACTIVITIES.filter(a => a.state === "planned"), SLATE]];
  const shown = filter === "all" ? groups : groups.filter(g => g[0].toLowerCase().startsWith(filter));
  return (
    <div style={{ background: SURFACE, border: `1px solid ${RULE}`, borderRadius: 11, overflow: "hidden" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 9, padding: "12px 14px", borderBottom: `1px solid ${RULE}`, flexWrap: "wrap" }}>
        <Icon name="cal" size={13} color={FUCHSIA} />
        <span style={{ fontSize: 13, fontWeight: 600 }}>My agenda</span>
        <div style={{ flex: 1 }} />
        {[["all", "All"], ["overdue", "Overdue"], ["today", "Today"], ["next", "7 days"]].map(([k, l]) => (
          <button key={k} onClick={() => setFilter(k)} style={{
            height: 26, padding: "0 10px", borderRadius: 999, cursor: "pointer", fontFamily: SANS, fontSize: 11, fontWeight: 600,
            border: `1px solid ${filter === k ? INK : RULE}`, background: filter === k ? INK : SURFACE, color: filter === k ? "#fff" : DIM,
          }}>{l}</button>
        ))}
        <ChromeButton icon="link">Subscribe</ChromeButton>
      </div>
      <div style={{ padding: "12px 14px 14px" }}>
        {shown.map(([label, items, tone]) => (
          <div key={label} style={{ marginBottom: 14 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 7, marginBottom: 7 }}>
              <Dot color={tone} size={6} />
              <Mono size={9.5} color={tone} style={{ letterSpacing: "0.16em", fontWeight: 700 }}>{label.toUpperCase()}</Mono>
              <Mono size={9.5} color={FAINT}>{items.length}</Mono>
            </div>
            <div style={{ display: "grid", gap: 6 }}>
              {items.map(a => (
                <div key={a.id} style={{ display: "flex", alignItems: "center", gap: 9, border: `1px solid ${RULE}`, borderRadius: 8, padding: "8px 10px", opacity: done[a.id] ? 0.5 : 1 }}>
                  <button onClick={() => setDone(d => ({ ...d, [a.id]: !d[a.id] }))} style={{
                    width: 17, height: 17, borderRadius: 4, cursor: "pointer", flexShrink: 0,
                    border: `1.5px solid ${done[a.id] ? GREEN : RULE}`, background: done[a.id] ? GREEN : SURFACE, display: "grid", placeItems: "center",
                  }}>{done[a.id] && <Icon name="check" size={9} color="#fff" strokeWidth={3.4} />}</button>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 12, fontWeight: 600, textDecoration: done[a.id] ? "line-through" : "none" }}>{a.title}</div>
                    <Mono size={9.5} color={FAINT}>{a.type} · {a.when} · {ACC_BY_ID[a.acc].name}</Mono>
                  </div>
                  <Avatar who={a.who} size={19} />
                </div>
              ))}
              {!items.length && <Mono size={10} color={FAINT}>Nothing here.</Mono>}
            </div>
          </div>
        ))}
        <div style={{ display: "flex", alignItems: "flex-start", gap: 8, paddingTop: 11, borderTop: `1px dashed ${RULE}` }}>
          <Icon name="refresh" size={12} color={FAINT} style={{ marginTop: 1 }} />
          <Mono size={10} color={FAINT} style={{ lineHeight: 1.6 }}>
            Completing an activity updates last-activity on the deal, which resets the rotting clock and satisfies the negotiation gate.
          </Mono>
        </div>
      </div>
    </div>
  );
}

// ── security ──────────────────────────────────────────────
const SECURITY = [
  ["Group isolation", "shield", "Row-level security on every table of the module, plus explicit group filtering in each service query. Two independent layers that would have to fail together."],
  ["Private documents", "lock", "Contracts and proposals live in private storage with a file-type allow list. Downloads use short-lived signed links, never direct paths."],
  ["Hardened public page", "globe", "The client proposal is served under a strict content policy. The only script allowed to run is the signature pad, authorised with a fresh nonce per request."],
  ["Unguessable links", "key", "Every proposal has a random address, and the acceptance link is cryptographically signed and issued at send time. Without that token, acceptance is refused."],
  ["Audit trail", "list", "Creations, edits, stage moves, sends and exports are written with user and timestamp, readable from Settings and Privacy."],
  ["Heavy work without loss", "layers", "Historical attribution on activation runs in a batched queue with retries, never inside a web request. Replaying a batch is safe by design."],
];

function SecurityGrid() {
  return (
    <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 12 }}>
      {SECURITY.map(([t, ic, b]) => (
        <div key={t} style={{ background: PAPER, border: `1px solid ${RULE}`, borderRadius: 9, padding: "16px 17px" }}>
          <Icon name={ic} size={15} color={FUCHSIA} />
          <h4 style={{ fontFamily: SERIF, fontSize: 16, fontWeight: 500, margin: "10px 0 7px", letterSpacing: "-0.01em" }}>{t}</h4>
          <p style={{ fontSize: 12, color: DIM, lineHeight: 1.55, margin: 0, textWrap: "pretty" }}>{b}</p>
        </div>
      ))}
    </div>
  );
}

// ── rollout + status ──────────────────────────────────────
const STEPS = [
  ["Activation & configuration", "The module is switched on for the group. Pipelines are created with the sales team's real stages, the approval-gated ones are marked and the named releasers assigned."],
  ["Account load", "Agencies, tour operators and companies imported with tax ID, IATA, agency codes, promo codes, commission and terms. By file or by API, up to 500 per call."],
  ["Historical attribution", "A batch job walks the reservation history and links it to accounts on the four criteria. Day one shows real production per agency, not an empty sheet."],
  ["Contacts & open deals", "Agency people arrive as B2B contacts tied to their account. Live deals load into their stage and their history starts there."],
  ["Mailboxes & senders", "Groups mailboxes connected, sending domains verified, enquiry routing to draft deals switched on."],
  ["Proposals & signature", "Templates adapted to the group's identity, own domain for proposals, target languages per market."],
  ["Parallel run", "A period with both systems side by side, measuring the same thing in each, before the old one is closed. The only honest way to migrate a CRM."],
];
const STATUS = [
  ["Pipelines, stages and field gates", "now"], ["Stage approval by named person", "now"],
  ["Reservation attribution and commissions", "now"], ["Proposals, signature and translation", "now"],
  ["Synced mailbox and auto-drafted deals", "now"], ["Public API for accounts and deals", "now"],
  ["Read-only calendar for Outlook and Google", "now"], ["Per-field edit permission by user", "soon"],
  ["Push rate and allotment to the booking engine", "soon"], ["Two-way calendar sync", "soon"],
  ["Duplicate account merge", "soon"], ["Write room blocks into the PMS", "tbc"], ["Multi-currency consolidation", "tbc"],
];

function RolloutSteps() {
  return (
    <ol style={{ listStyle: "none", counterReset: "s", padding: 0, margin: 0, display: "grid", gap: 11 }}>
      {STEPS.map(([t, b], i) => (
        <li key={t} style={{ display: "flex", gap: 13 }}>
          <span style={{ width: 26, height: 26, borderRadius: "50%", flexShrink: 0, background: SURFACE, border: `1px solid ${FUCHSIA_PALE}`, display: "grid", placeItems: "center" }}>
            <Mono size={10} color={FUCHSIA_DARK} style={{ fontWeight: 700 }}>{String(i + 1).padStart(2, "0")}</Mono>
          </span>
          <div>
            <div style={{ fontSize: 13.5, fontWeight: 600, letterSpacing: "-0.01em" }}>{t}</div>
            <p style={{ fontSize: 12.5, color: DIM, lineHeight: 1.55, margin: "3px 0 0", maxWidth: "58ch", textWrap: "pretty" }}>{b}</p>
          </div>
        </li>
      ))}
    </ol>
  );
}

function StatusTable() {
  return (
    <div style={{ background: SURFACE, border: `1px solid ${RULE}`, borderRadius: 11, overflow: "hidden" }}>
      <table style={{ width: "100%", borderCollapse: "collapse", fontFamily: SANS }}>
        <thead><tr>
          <th style={{ textAlign: "left", padding: "10px 14px", background: PAPER, borderBottom: `1px solid ${RULE}` }}><Mono size={9} color={DIM} style={{ letterSpacing: "0.14em", fontWeight: 700 }}>CAPABILITY</Mono></th>
          <th style={{ textAlign: "right", padding: "10px 14px", background: PAPER, borderBottom: `1px solid ${RULE}`, width: 150 }}><Mono size={9} color={DIM} style={{ letterSpacing: "0.14em", fontWeight: 700 }}>STATUS</Mono></th>
        </tr></thead>
        <tbody>
          {STATUS.map(([c, s]) => (
            <tr key={c}>
              <td style={{ padding: "10px 14px", borderBottom: `1px solid ${RULE_SOFT}`, fontSize: 12.5 }}>{c}</td>
              <td style={{ padding: "10px 14px", borderBottom: `1px solid ${RULE_SOFT}`, textAlign: "right" }}>
                <Pill tone={s}>{s === "now" ? "Available today" : s === "soon" ? "In development" : "To confirm"}</Pill>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}


Object.assign(window, { ProposalShowcase, IntegrationDiagram, JobsTable, AgendaPanel, SecurityGrid, RolloutSteps, StatusTable });
