/* The dependency dome. Three bands radiate from the SoftVerx mark: intelligence
   on the outside, connected under it, core platforms nearest the centre. Arrows
   on the baseline run inward, because everything above writes to what is below.
   Phone gets the same argument as three stacked rows — a 720px dome at 390px
   would be unreadable, and shrinking type is the wrong lever. */
const DOME_ICON = {
  "ai-agents": <><circle cx="9" cy="5.5" r="2.6" /><path d="M9 8.2v3.4M4 11.6h10v5.2H4z" /><path d="M6.4 14.2h.01M11.6 14.2h.01" strokeWidth="2" /><path d="M4 13.4H1.8M14 13.4h2.2" /></>,
  "document-intelligence": <><path d="M3.4 1.6h7.2l3 3v12.8H3.4z" /><path d="M6 6h4M6 8.8h5.4" /><rect x="5.6" y="11.4" width="7" height="3.4" /></>,
  "applied-ml": <><path d="M2 15.6V2.4M2 15.6h14" /><path d="M4.4 12.6l3.2-4 2.4 2.4 3.2-5.4" /><path d="M13.2 5.6l2.6 4.6" strokeDasharray="2 2" /></>,
  "computer-vision": <><path d="M1.8 9s2.8-5 7.2-5 7.2 5 7.2 5-2.8 5-7.2 5-7.2-5-7.2-5z" /><circle cx="9" cy="9" r="2.4" /></>,
  "industrial-iot": <><rect x="6" y="6" width="6" height="6" rx="1" /><path d="M9 6V2.4M9 12v3.6M6 9H2.4M12 9h3.6" /><circle cx="9" cy="2" r="1.2" /><circle cx="9" cy="16" r="1.2" /><circle cx="2" cy="9" r="1.2" /><circle cx="16" cy="9" r="1.2" /></>,
  "energy-tech": <><path d="M10.4 1.6L4.6 10h4L7.6 16.4 13.4 8h-4z" /></>,
  "agri-tech": <><path d="M9 16.4V7.6" /><path d="M9 8.6C9 5 6.4 2.4 3 2.4c0 3.6 2.6 6.2 6 6.2z" /><path d="M9 11.4c0-3 2.2-5.2 5.2-5.2 0 3-2.2 5.2-5.2 5.2z" /></>,
  "erp-billing": <><path d="M4 1.8h10v14.4l-2-1.4-1.6 1.4-1.4-1.4-1.6 1.4-1.4-1.4L4 16.2z" /><path d="M6.6 6h4.8M6.6 9.4h4.8M6.6 12.4h2.8" /></>,
  "data-platforms": <><ellipse cx="9" cy="4" rx="6" ry="2.2" /><path d="M3 4v4.6c0 1.2 2.7 2.2 6 2.2s6-1 6-2.2V4" /><path d="M3 8.6v4.8c0 1.2 2.7 2.2 6 2.2s6-1 6-2.2V8.6" /></>,
  "cloud-devops": <><path d="M5 13.6a3.6 3.6 0 01-.4-7.2 4.8 4.8 0 019.2 1.2 3 3 0 01-.4 6H5z" /><path d="M7.4 10.4l1.6 1.6 2.6-3" /></>,
};
const DOME_HUE = { core: "var(--sx-layer-core)", connected: "var(--sx-layer-connected)", intelligence: "var(--sx-layer-intelligence)" };

function DomeChip({ p, hue, x, y, w, mobile }) {
  return (
    <a href={"#" + p.slug} className="sx-dome-chip" style={{ "--hue": hue, left: x, top: y, width: w }}>
      <svg viewBox="0 0 18 18" width={mobile ? 15 : 17} height={mobile ? 15 : 17} fill="none" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round" aria-hidden>{DOME_ICON[p.slug]}</svg>
      <span>{p.title}</span>
    </a>
  );
}

function PracticeDome({ mobile }) {
  const groups = P.practiceGroups;
  const byId = { intelligence: groups[0], connected: groups[1], core: groups[2] };
  const order = [["intelligence", 330, [20, 62, 118, 160]], ["connected", 240, [42, 90, 138]], ["core", 170, [28, 90, 152]]];

  if (mobile) {
    return (
      <div className="sx-dome sx-dome-stack">
        {order.map(([id], i) => (
          <React.Fragment key={id}>
            <div className="sx-dome-row" style={{ "--hue": DOME_HUE[id] }}>
              <p className="sx-dome-row-name">{byId[id].label.toLowerCase()}</p>
              <div className="sx-dome-row-chips">
                {byId[id].practices.map((pr) => (
                  <a key={pr.slug} href={"#" + pr.slug} className="sx-dome-chip is-static" style={{ "--hue": DOME_HUE[id] }}>
                    <svg viewBox="0 0 18 18" width="15" height="15" fill="none" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round" aria-hidden>{DOME_ICON[pr.slug]}</svg>
                    <span>{pr.title}</span>
                  </a>
                ))}
              </div>
            </div>
            <span className="sx-dome-flow" aria-hidden>{i === 2 ? "all of it, one team" : "writes to"}</span>
          </React.Fragment>
        ))}
        <div className="sx-dome-core"><img src="assets/logo-mark.png" alt="SoftVerx" /><span>SoftVerx</span></div>
      </div>
    );
  }

  const W = 820, cx = 410, cy = 380, H = 452;
  const rad = (d) => (d * Math.PI) / 180;
  const arc = (r) => `M${cx - r} ${cy} A${r} ${r} 0 0 1 ${cx + r} ${cy}`;
  return (
    <div className="sx-dome" style={{ position: "relative", maxWidth: W, margin: "0 auto" }}>
      <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: "block", height: "auto", overflow: "visible" }} aria-hidden>
        <defs>
          {order.map(([id]) => (
            <radialGradient key={id} id={"sx-g-" + id} cx="50%" cy="100%" r="70%">
              <stop offset="60%" stopColor={DOME_HUE[id]} stopOpacity="0" />
              <stop offset="100%" stopColor={DOME_HUE[id]} stopOpacity="0.16" />
            </radialGradient>
          ))}
        </defs>
        {order.map(([id, r], i) => (
          <g key={id} className="sx-dome-band" style={{ animationDelay: `${i * 0.25}s` }}>
            <path d={`${arc(r)} Z`} fill={"url(#sx-g-" + id + ")"} />
            <path className="sx-dome-edge" style={{ "--len": Math.PI * r, animationDelay: `${i * 0.25}s` }} d={arc(r)} fill="none" stroke={DOME_HUE[id]} strokeWidth="1.6" opacity="0.85" />
          </g>
        ))}
        <line x1={cx - 348} y1={cy} x2={cx + 348} y2={cy} stroke="var(--border-default)" />
        {[[330, 240], [240, 170], [170, 92]].map(([a, b], i) => (
          <g key={i} className="sx-dome-arrow" style={{ animationDelay: `${0.9 + i * 0.3}s` }}>
            {[-1, 1].map((s) => (
              <g key={s}>
                <line x1={cx + s * (a - 12)} y1={cy - 14} x2={cx + s * (b + 20)} y2={cy - 14} stroke="var(--text-quiet)" strokeWidth="1" strokeDasharray="3 3" />
                <path d={`M${cx + s * (b + 12)} ${cy - 14} l${s * 9} -4.5 l0 9 z`} fill="var(--text-quiet)" />
              </g>
            ))}
          </g>
        ))}
        <text x={cx} y={cy + 42} textAnchor="middle" fill="var(--text-quiet)" style={{ font: "500 10px var(--font-mono)", letterSpacing: "0.04em" }}>every layer writes to the one beneath it — built by one team</text>
      </svg>
      {order.map(([id, r, angles]) =>
        byId[id].practices.map((pr, j) => {
          const t = rad(angles[j]);
          return <DomeChip key={pr.slug} p={pr} hue={DOME_HUE[id]} mobile={false}
            x={((cx - Math.cos(t) * r) / W) * 100 + "%"} y={cy - Math.sin(t) * r} />;
        })
      )}
      <div className="sx-dome-core" style={{ left: (cx / W) * 100 + "%", top: cy - 46 }}>
        <img src="assets/logo-mark.png" alt="SoftVerx" />
        <span>SoftVerx</span>
      </div>
      <ul className="sx-dome-key">
        {[["intelligence", "intelligence"], ["connected", "connected"], ["core", "core platforms"]].map(([id, label]) => (
          <li key={id}><span style={{ background: DOME_HUE[id] }} aria-hidden></span>{label}</li>
        ))}
      </ul>
    </div>
  );
}

const { Annotate: PA, Eyebrow: PE, Button: PB, Card: PC, Tag: PT, SectionHeader: PSH, ChartFrame: PCF, VisionFrame: PVF, AgentTrace, DocPipeline, TimeSeriesForecast: PTS, ArchitectureTiers: PAT, Stat: PStat, CTABand: PCTA } = window.SoftVerxDesignSystem_6fd95b;
const P = window.SX_DATA;

const FIGURES = {
  agent: (m) => <PCF title="Agent trace" subtitle="anomaly triage, 674ms end to end" sample note="Representative trace from a metering deployment."><AgentTrace mobile={m} /></PCF>,
  doc: (m) => <PCF title="Extraction pipeline" subtitle="supplier invoice, 14 fields" sample note="Representative page. Client documents never leave their tenancy."><DocPipeline mobile={m} /></PCF>,
  forecast: (m) => <PCF title="System load" subtitle="feeder 11, trailing 12 months" sample legend={[{ label: "actual", color: "var(--sx-accent)" }, { label: "forecast", color: "var(--sx-signal)", dashed: true }, { label: "80% confidence", color: "var(--sx-band)", swatch: true }]} note="Illustrative shape at representative magnitudes. Client figures available under NDA."><PTS height={m ? 170 : 230} mobile={m} /></PCF>,
  tiers: (m) => <PC padding={m ? "var(--sp-6)" : "var(--sp-8)"}><PAT mobile={m} /></PC>,
  vision: (m) => <PA label="cam-08 · line 3 · defect" conf={0.97} style={{ padding: 8 }}><PVF src="assets/industry/manufacturing.png" label="sector:manufacturing" conf={0.94} height={m ? 200 : 280} style={{ borderRadius: "var(--r-card)" }} /></PA>,
  utilities: (m) => <PA label="sub-station · feeder survey" conf={0.98} style={{ padding: 8 }}><PVF src="assets/industry/utilities.webp" label="sector:utilities" conf={0.97} height={m ? 200 : 280} style={{ borderRadius: "var(--r-card)" }} /></PA>,
  agri: (m) => <PA label="block 12 · irrigation anomaly" conf={0.91} style={{ padding: 8 }}><PVF src="assets/industry/agriculture.jpg" label="sector:agriculture" conf={0.92} height={m ? 200 : 280} style={{ borderRadius: "var(--r-card)" }} /></PA>,
  landing: (m) => (
    <PCF title="What lands, and how often" subtitle="four source classes, one schema" note="Cadences from live deployments. Every source lands in the same account, site, asset and period schema.">
      <ul style={{ listStyle: "none", margin: 0, padding: 0, display: "grid", gap: 1, background: "var(--border-default)", border: "1px solid var(--border-default)", borderRadius: "var(--r-control)", overflow: "hidden" }}>
        {[["device telemetry", "40–80 msgs / meter / day", "time-series store"], ["meter reads", "15-minute interval", "interval table + rolling history"], ["enterprise records", "nightly batch", "warehouse dimensions"], ["documents", "on arrival", "extracted facts + source page"]].map((r) => (
          <li key={r[0]} style={{ background: "var(--bg-page)", padding: m ? "12px 14px" : "14px 18px", display: "grid", gap: 4, gridTemplateColumns: m ? "1fr" : "minmax(0,4fr) minmax(0,4fr) minmax(0,5fr)", alignItems: "baseline" }}>
            <span className="sx-small" style={{ color: "var(--text-strong)" }}>{r[0]}</span>
            <span className="sx-caption sx-num" style={{ color: "var(--text-accent)", textTransform: "none" }}>{r[1]}</span>
            <span className="sx-caption" style={{ color: "var(--text-quiet)", textTransform: "none" }}>{r[2]}</span>
          </li>
        ))}
      </ul>
    </PCF>
  ),
  stats: (m) => (
    <PC padding={m ? "var(--sp-6)" : "var(--sp-8)"}>
      <p className="sx-caption" style={{ color: "var(--text-quiet)" }}>the reference deployment</p>
      <div style={{ display: "grid", gap: 24, gridTemplateColumns: m ? "1fr 1fr" : "repeat(4, 1fr)", marginTop: 20 }}>
        {P.projectsBySlug.lesco.metrics.map((x) => (
          <div key={x.l}><p className="sx-h2 sx-num" style={{ color: "var(--text-strong)" }}>{x.v}</p><p className="sx-caption" style={{ marginTop: 6, color: "var(--text-quiet)", textTransform: "none" }}>{x.l}</p></div>
        ))}
      </div>
    </PC>
  ),
};

function practiceProjects(title) { return P.projects.filter((p) => p.practice === title); }
function practiceSolutions(title) { return P.solutions.filter((s) => s.practice === title); }

function PracticeBlock({ p, i, mobile }) {
  const projects = practiceProjects(p.title);
  const sols = practiceSolutions(p.title);
  const fig = window.PRACTICE_FIGURES[p.slug];
  return (
    <Section mobile={mobile} id={p.slug}>
      <div style={{ display: "grid", gap: mobile ? 28 : 48, gridTemplateColumns: mobile ? "1fr" : "minmax(0,6fr) minmax(0,6fr)", alignItems: "start" }}>
        <div>
          <h2 className={mobile ? "sx-h2" : "sx-h1"} style={{ marginTop: mobile ? 10 : 16 }}>{p.title}</h2>
          <p className="sx-lead" style={{ marginTop: mobile ? 10 : 16 }}>{p.what}</p>
          {mobile && fig && <div style={{ marginTop: 18 }}>{fig(true)}</div>}
          <ul style={{ listStyle: "none", margin: mobile ? "16px 0 0" : "28px 0 0", padding: 0, display: "grid", gap: mobile ? 7 : 10 }}>
            {(mobile ? p.caps.slice(0, 4) : p.caps).map((c) => (
              <li key={c} className="sx-small" style={{ display: "grid", gridTemplateColumns: "18px 1fr", gap: 10, color: "var(--text-body)" }}>
                <span aria-hidden className="sx-micro" style={{ color: "var(--sx-accent)" }}>—</span>{c}
              </li>
            ))}
          </ul>
          <p className="sx-caption" style={{ marginTop: mobile ? 16 : 24, padding: mobile ? 13 : 16, background: "var(--surface-raised)", borderRadius: "var(--r-control)", color: "var(--text-body)", textTransform: "none", letterSpacing: 0, fontFamily: "var(--font-body)" }}>
            <span style={{ color: "var(--text-strong)" }}>Typical outcome — </span>{p.outcome}
          </p>
          {(sols.length || projects.length) && (
            <div style={{ marginTop: mobile ? 18 : 28, display: "grid", gap: mobile ? 14 : 16, gridTemplateColumns: mobile ? "1fr 1fr" : "1fr 1fr", alignItems: "start" }}>
              {sols.length > 0 && (
                <div style={{ border: "1px solid var(--border-default)", borderRadius: "var(--r-card)", background: "var(--surface-card)", padding: mobile ? 13 : 16 }}>
                  <p className="sx-caption" style={{ color: "var(--text-quiet)" }}>solutions in this practice</p>
                  <ul className="sx-small" style={{ listStyle: "none", margin: "10px 0 0", padding: 0, display: "grid", gap: 6 }}>
                    {sols.map((s) => <li key={s.id}><a href={"/solutions#" + s.id}>{s.name}</a></li>)}
                  </ul>
                </div>
              )}
              {projects.length > 0 && (
                <div style={{ border: "1px solid var(--border-default)", borderRadius: "var(--r-card)", background: "var(--surface-card)", padding: mobile ? 13 : 16 }}>
                  <p className="sx-caption" style={{ color: "var(--text-quiet)" }}>delivered here ({projects.length})</p>
                  <ul className="sx-small" style={{ listStyle: "none", margin: "10px 0 0", padding: 0, display: "grid", gap: 6 }}>
                    {projects.slice(0, mobile ? 3 : 5).map((pr) => <li key={pr.slug}><a href={pr.slug === "lesco" ? "/lesco" : "/work#" + pr.slug}>{mobile ? pr.short : pr.short + " — " + pr.title.toLowerCase()}</a></li>)}
                  </ul>
                </div>
              )}
            </div>
          )}
        </div>
        {!mobile && <div style={{ position: "sticky", top: 88 }}>
          {fig ? fig(mobile) : (
            <PC padding="var(--sp-6)">
              <p className="sx-caption" style={{ color: "var(--text-quiet)" }}>what you get on handover</p>
              <ul className="sx-small" style={{ listStyle: "none", margin: "14px 0 0", padding: 0, display: "grid", gap: 10, color: "var(--text-body)" }}>
                {["Architecture and integration documentation", "Environments provisioned and documented", "Runbooks and monitoring dashboards", "Role-based training for the operating team"].map((x) => <li key={x}>{x}</li>)}
              </ul>
            </PC>
          )}
        </div>}
      </div>
    </Section>
  );
}

function PracticesPage({ mobile }) {
  return (
    <main>
      <PageHero mobile={mobile} title={`${P.practices.length} practices, delivered by one team`}
        lead="Each page lists the solutions inside the practice and the programmes delivered under it. Where a practice has no delivered programme of its own yet, it says so rather than borrowing one from next door."
        actions={<><PB as="a" href="/about#start">Book a call</PB><PB as="a" href="/solutions" variant="secondary">{`All ${P.solutions.length} solutions`}</PB></>}
        meta={[{ l: "practices", v: P.practices.length }, { l: "named solutions", v: P.solutions.length }, { l: "programmes delivered", v: P.projects.length }, { l: "years", v: P.company.years }]} />
      <Section mobile={mobile}>
        <PSH title="Three groups, and the order matters" lead="Intelligence sits on connected systems, which sit on core platforms. Buyers who start at the top and skip the bottom end up integrating four vendors themselves." />
        <div style={{ marginTop: mobile ? 18 : 30 }}><PracticeDome mobile={mobile} /></div>
      </Section>
      {P.practices.map((p, i) => <PracticeBlock key={p.slug} p={p} i={i} mobile={mobile} />)}
      <Section mobile={mobile} well>
        <PSH title="The same shape, whatever the input" lead={`All ${P.practices.length} practices run through one pipeline. That is why a vision project and a billing project are managed the same way here.`} />
        <div style={{ marginTop: 40 }}><PipelineFigure mobile={mobile} /></div>
      </Section>
      <PCTA mobile={mobile} title="Not sure which of these you need?" lead="Describe the problem and we will tell you what it usually takes to fix, including when the answer is a smaller piece of work than you expected. There are three ways in, smallest first, on the about page." />
    </main>
  );
}

Object.assign(window, { PracticesPage, FIGURES, practiceProjects, practiceSolutions });
