/* Dexilion — shared site chrome and section primitives.
   Header, footer, textures, editorial list, conversion band, contact form.
   Everything visual here traces to the design system; copy comes from
   window.SITE (content.js). */

(function () {
  const { Button, Card, Input, Textarea, Select, Checkbox } = window;

  /* ------------------------------------------------------------- primitives -- */

  const Ico = ({ n, s = 18, color }) => {
    React.useEffect(() => {
      window.lucide &&
        window.lucide.createIcons({
          attrs: { width: s, height: s, "stroke-width": 1.75 },
        });
    });
    return <i data-lucide={n} style={{ display: "inline-flex", color }}></i>;
  };

  const Grain = ({ dark }) => (
    <div
      aria-hidden="true"
      style={{
        position: "absolute",
        inset: 0,
        pointerEvents: "none",
        backgroundImage: "var(--texture-grain)",
        opacity: dark
          ? "var(--grain-opacity-dark)"
          : "var(--grain-opacity-light)",
      }}
    />
  );

  const Grid = ({
    dark,
    fade = "linear-gradient(180deg,#000 0%,rgba(0,0,0,.25) 70%,transparent 100%)",
  }) => (
    <div
      aria-hidden="true"
      style={{
        position: "absolute",
        inset: 0,
        pointerEvents: "none",
        backgroundImage: dark
          ? "var(--texture-grid-dark)"
          : "var(--texture-grid)",
        maskImage: fade,
        WebkitMaskImage: fade,
      }}
    />
  );

  const Eyebrow = ({ children, color = "var(--blue-500)", rule = true }) => (
    <div style={{ display: "flex", alignItems: "center", gap: "12px" }}>
      {rule && (
        <span
          style={{
            width: "28px",
            height: "1px",
            background: "currentColor",
            color,
            opacity: 0.5,
          }}
        />
      )}
      <span
        style={{
          font: "var(--text-eyebrow)",
          letterSpacing: "var(--ls-eyebrow)",
          textTransform: "uppercase",
          color,
        }}
      >
        {children}
      </span>
    </div>
  );

  /* The mark is used exactly as supplied — never recolored, cropped or boxed.
   DEXILION beside it is live text in Orbitron, cap height matched. */
  const Wordmark = ({ inverse, size = 20 }) => (
    <span
      style={{
        display: "inline-flex",
        alignItems: "center",
        gap: size * 0.42 + "px",
      }}
    >
      <img
        src="assets/logo.svg"
        alt={window.SITE.brand.name}
        style={{
          height: size * 1.5 + "px",
          width: "auto",
          display: "block",
        }}
      />
      <span
        style={{
          fontFamily: "var(--font-wordmark)",
          fontWeight: 600,
          fontSize: size + "px",
          textTransform: "uppercase",
          letterSpacing: "0.12em",
          color: inverse ? "var(--white)" : "var(--ink-900)",
        }}
      >
        {window.SITE.brand.name}
      </span>
    </span>
  );

  const Shell = ({ children, maxWidth = "var(--container-max)", style }) => (
    <div
      className="dx-shell"
      style={{
        maxWidth,
        margin: "0 auto",
        padding: "0 32px",
        position: "relative",
        ...style,
      }}
    >
      {children}
    </div>
  );

  /* Unwritten copy renders as a visible placeholder rather than as prose, so an
   unfinished claim can never be mistaken for a finished one. */
  const isTodo = (v) => typeof v === "string" && /^todo\b/i.test(v.trim());
  const tx = (v, key) =>
    isTodo(v) ? (
      <span className="dx-todo" key={key}>
        {v}
      </span>
    ) : (
      v
    );

  /* Labelled image placeholder — the design system ships these instead of
   decorative stand-ins, so a missing photo reads as a missing photo. */
  const ImageSlot = ({ label, src, ratio = "4 / 3", pos, dark, style }) => (
    <div
      className={"dx-slot" + (dark ? " dx-slot-dark" : "")}
      style={{ aspectRatio: ratio, ...style }}
    >
      {src && (
        <img
          src={src}
          alt={label}
          style={{ width: "100%", height: "100%", objectFit: "cover", objectPosition: pos }}
        />
      )}
      <span className="dx-slot-label">{label}</span>
    </div>
  );

  /* ----------------------------------------------------------------- header -- */

  function SiteHeader({ active }) {
    const [open, setOpen] = React.useState(false);
    const items = window.SITE.nav;
    const link = (it, extra) => (
      <a
        key={it.key}
        href={it.href}
        style={{
          border: "none",
          fontWeight: "var(--fw-medium)",
          color: active === it.key ? "var(--blue-500)" : "var(--text-body)",
          ...extra,
        }}
      >
        {it.label}
      </a>
    );
    return (
      <header
        style={{
          position: "sticky",
          top: 0,
          zIndex: 40,
          background: "rgba(250,248,243,.88)",
          backdropFilter: "blur(10px)",
          WebkitBackdropFilter: "blur(10px)",
          borderBottom: "1px solid var(--paper-200)",
        }}
      >
        <Shell>
          <div
            style={{
              height: "72px",
              display: "flex",
              alignItems: "center",
              gap: "40px",
            }}
          >
            <a
              href="index.html"
              style={{ border: "none", display: "flex", alignItems: "center" }}
            >
              <Wordmark />
            </a>
            <nav
              className="dx-nav"
              style={{
                display: "flex",
                gap: "28px",
                fontSize: "var(--fs-body-sm)",
              }}
            >
              {items.map((it) => link(it))}
            </nav>
            {/* <div className="dx-nav-cta" style={{ marginLeft: 'auto' }}>
          <Button size="sm" onClick={() => { window.location.href = 'contact.html'; }}>{window.SITE.ui.ctaLabel}</Button>
        </div> */}
            <button
              className="dx-nav-toggle"
              aria-label="Menu"
              aria-expanded={open}
              onClick={() => setOpen((o) => !o)}
              style={{
                display: "none",
                marginLeft: "auto",
                alignItems: "center",
                background: "none",
                border: "none",
                cursor: "pointer",
                padding: "8px",
                color: "var(--ink-900)",
              }}
            >
              <Ico n={open ? "x" : "menu"} s={22} color="var(--ink-900)" />
            </button>
          </div>
          {open && (
            <nav
              className="dx-nav-mobile"
              style={{
                display: "none",
                flexDirection: "column",
                padding: "4px 0 14px",
              }}
            >
              {items.map((it) =>
                link(it, {
                  padding: "12px 4px",
                  fontSize: "var(--fs-body)",
                  borderBottom: "1px solid var(--paper-200)",
                }),
              )}
            </nav>
          )}
        </Shell>
      </header>
    );
  }

  /* ----------------------------------------------------- inner-page masthead -- */
  /* No dither field here: the boid erosion texture is reserved for the single
     largest dark surface on the site, the home hero. Inner mastheads carry the
     engineering grid and grain instead. */

  function PageHero({ eyebrow, headline, lede, children }) {
    return (
      <section
        className="dx-page-hero"
        style={{
          background: "var(--ink-900)",
          color: "var(--white)",
          position: "relative",
          overflow: "hidden",
          padding: "84px 0 72px",
        }}
      >
        <Shell>
          <div style={{ position: "relative", maxWidth: "760px" }}>
            <Eyebrow color="var(--gold-400)">{eyebrow}</Eyebrow>
            <h1
              style={{
                font: "var(--text-display-2)",
                letterSpacing: "var(--ls-display)",
                margin: "20px 0 0",
                color: "var(--white)",
                textWrap: "balance",
              }}
            >
              {headline}
            </h1>
            {lede && (
              <p
                style={{
                  margin: "22px 0 0",
                  maxWidth: "56ch",
                  fontSize: "var(--fs-body-lg)",
                  lineHeight: "var(--lh-body)",
                  color: "var(--powder-500)",
                }}
              >
                {tx(lede)}
              </p>
            )}
            {children}
          </div>
        </Shell>
      </section>
    );
  }

  /* ------------------------------------------------------------ editorial list -- */
  /* The brand's default for "here are our N things": a sticky heading column,
   hairline-divided numbered rows, gold wash and an arrow on hover. */

  function EditorialList({
    eyebrow,
    heading,
    headingLine2,
    lede,
    action,
    rows,
    href,
  }) {
    const [open, setOpen] = React.useState(0);
    return (
      <div
        className="dx-services-grid"
        style={{
          display: "grid",
          gridTemplateColumns: "340px 1fr",
          gap: "56px",
          alignItems: "start",
        }}
      >
        <div
          className="dx-services-side"
          style={{ position: "sticky", top: "104px" }}
        >
          <Eyebrow>{eyebrow}</Eyebrow>
          <h2
            style={{
              font: "var(--text-h1)",
              letterSpacing: "var(--ls-heading)",
              margin: "18px 0 0",
              color: "var(--text-strong)",
            }}
          >
            {heading}
            {headingLine2 && (
              <React.Fragment>
                <br />
                {headingLine2}
              </React.Fragment>
            )}
          </h2>
          {lede && (
            <p
              style={{
                margin: "18px 0 0",
                fontSize: "var(--fs-body)",
                lineHeight: "var(--lh-body)",
                color: "var(--text-muted)",
                maxWidth: "32ch",
              }}
            >
              {tx(lede)}
            </p>
          )}
          {action && (
            <div style={{ marginTop: "26px" }}>
              <Button
                variant="secondary"
                onClick={() => {
                  window.location.href = action.href;
                }}
              >
                {action.label}
              </Button>
            </div>
          )}
        </div>
        <div style={{ borderTop: "1px solid var(--paper-200)" }}>
          {rows.map((r, i) => {
            const on = open === i;
            const rowHref = r.href || href;
            return (
              <div
                key={i}
                className="dx-service-row"
                onMouseEnter={() => setOpen(i)}
                onClick={() => {
                  if (rowHref) window.location.href = rowHref;
                }}
                style={{
                  borderBottom: "1px solid var(--paper-200)",
                  padding: "26px 20px",
                  display: "grid",
                  gridTemplateColumns: "52px 1fr auto",
                  gap: "20px",
                  alignItems: "start",
                  cursor: rowHref ? "pointer" : "default",
                  background: on
                    ? "linear-gradient(90deg,rgba(253,225,45,.10),transparent 60%)"
                    : "transparent",
                  transition: "background var(--dur-base) var(--ease-standard)",
                }}
              >
                <div
                  style={{
                    fontFamily: "var(--font-mono)",
                    fontSize: "13px",
                    color: on ? "var(--gold-600)" : "var(--neutral-400)",
                    paddingTop: "6px",
                  }}
                >
                  {String(i + 1).padStart(2, "0")}
                </div>
                <div>
                  <div
                    style={{
                      display: "flex",
                      alignItems: "center",
                      gap: "12px",
                    }}
                  >
                    {r.icon && (
                      <Ico
                        n={r.icon}
                        s={19}
                        color={on ? "var(--blue-500)" : "var(--neutral-500)"}
                      />
                    )}
                    <span
                      style={{
                        fontFamily: "var(--font-serif)",
                        fontSize: "26px",
                        fontWeight: "var(--fw-semibold)",
                        letterSpacing: "var(--ls-heading)",
                        color: "var(--text-strong)",
                      }}
                    >
                      {tx(r.title)}
                    </span>
                  </div>
                  <p
                    style={{
                      margin: "10px 0 0",
                      fontSize: "var(--fs-body)",
                      lineHeight: "var(--lh-body)",
                      color: "var(--text-body)",
                      maxWidth: "54ch",
                    }}
                  >
                    {tx(r.summary)}
                  </p>
                  {r.points && (
                    <ul
                      style={{
                        margin: "14px 0 0",
                        padding: 0,
                        listStyle: "none",
                        display: "flex",
                        flexDirection: "column",
                        gap: "7px",
                      }}
                    >
                      {r.points.map((p, j) => (
                        <li
                          key={j}
                          style={{
                            display: "flex",
                            gap: "10px",
                            alignItems: "baseline",
                            fontSize: "var(--fs-body-sm)",
                            color: "var(--text-body)",
                          }}
                        >
                          <span
                            aria-hidden="true"
                            style={{
                              flex: "0 0 auto",
                              width: "5px",
                              height: "5px",
                              borderRadius: "999px",
                              background: "var(--blue-300)",
                            }}
                          />
                          {tx(p)}
                        </li>
                      ))}
                    </ul>
                  )}
                  {r.meta && (
                    <div
                      style={{
                        marginTop: "12px",
                        fontFamily: "var(--font-mono)",
                        fontSize: "11px",
                        color: "var(--text-muted)",
                        letterSpacing: ".02em",
                      }}
                    >
                      {tx(r.meta)}
                    </div>
                  )}
                </div>
                <div
                  style={{
                    paddingTop: "8px",
                    opacity: on && href ? 1 : 0.25,
                    transform: on ? "translateX(0)" : "translateX(-6px)",
                    transition: "all var(--dur-base) var(--ease-standard)",
                  }}
                >
                  {href && (
                    <Ico n="arrow-right" s={18} color="var(--blue-500)" />
                  )}
                </div>
              </div>
            );
          })}
        </div>
      </div>
    );
  }

  /* ------------------------------------------------------------ contact form -- */

  function ContactForm() {
    // const c = window.SITE.contact;
    // const [state, setState] = React.useState("idle");
    // const submit = (e) => {
    //   e.preventDefault();
    //   if (!c.formEndpoint) {
    //     setState("unconfigured");
    //     return;
    //   }
    //   setState("sending");
    //   const data = Object.fromEntries(new FormData(e.target).entries());
    //   fetch(c.formEndpoint, {
    //     method: "POST",
    //     headers: {
    //       "Content-Type": "application/json",
    //       Accept: "application/json",
    //     },
    //     body: JSON.stringify(data),
    //   })
    //     .then((r) => setState(r.ok ? "sent" : "error"))
    //     .catch(() => setState("error"));
    // };
    // if (state === "sent")
    //   return (
    //     <div
    //       style={{
    //         display: "flex",
    //         flexDirection: "column",
    //         gap: "10px",
    //         padding: "22px 0",
    //       }}
    //     >
    //       <Ico n="circle-check" s={26} color="var(--success-500)" />
    //       <div
    //         style={{
    //           fontFamily: "var(--font-serif)",
    //           fontSize: "var(--fs-h4)",
    //           fontWeight: "var(--fw-semibold)",
    //           color: "var(--text-strong)",
    //         }}
    //       >
    //         {c.success.title}
    //       </div>
    //       <div
    //         style={{
    //           fontSize: "var(--fs-body-sm)",
    //           color: "var(--text-muted)",
    //           lineHeight: 1.6,
    //         }}
    //       >
    //         {tx(c.success.body)}
    //       </div>
    //     </div>
    //   );

    return (
      <iframe
        src="https://calendar.google.com/calendar/appointments/schedules/AcZssZ2G7_PXnDvVteM0wcok9yHiTSSxxylei_Ln1BzfheFBlvuWBNBR91NCUc-uIXcEYzEXygsi8DJu?gv=true"
        width="100%"
        height="700"
        frameBorder="0"
        style={{ border: 0 }}
      ></iframe>
    );
  }

  /* -------------------------------------------------------- conversion band -- */
  /* One full-bleed gradient band per page — the design system's only sanctioned
   use of --gradient-brand. `form` renders the request form inside it. */

  function ConversionBand({ form = false }) {
    const c = window.SITE.contact;
    return (
      <section
        id="contact"
        style={{
          background: "var(--gradient-brand)",
          padding: "var(--section-y) 0",
          color: "var(--white)",
          position: "relative",
          overflow: "hidden",
        }}
      >
        <Grid dark fade="linear-gradient(180deg,#000 0%,transparent 80%)" />
        <Grain dark />
        <Shell>
          <div
            className="dx-contact-grid"
            style={{
              display: "grid",
              gridTemplateColumns: form ? "1fr 710px" : "1fr auto",
              gap: "64px",
              alignItems: "center",
            }}
          >
            <div>
              <Eyebrow color="var(--gold-400)">{c.eyebrow}</Eyebrow>
              <h2
                style={{
                  font: "var(--text-h1)",
                  letterSpacing: "var(--ls-heading)",
                  margin: "18px 0 0",
                  color: "var(--white)",
                  maxWidth: "16ch",
                }}
              >
                {c.headline}
              </h2>
              <p
                style={{
                  margin: "20px 0 0",
                  maxWidth: "44ch",
                  fontSize: "var(--fs-body-lg)",
                  lineHeight: "var(--lh-body)",
                  color: "var(--powder-500)",
                }}
              >
                {tx(c.lede)}
              </p>
              <div
                style={{
                  marginTop: "30px",
                  display: "flex",
                  gap: "10px",
                  alignItems: "center",
                  fontFamily: "var(--font-mono)",
                  fontSize: "12px",
                  color: "var(--powder-300)",
                }}
              >
                <Ico n="clock" s={15} color="var(--gold-400)" />{" "}
                {tx(c.responseNote)}
              </div>
            </div>
            {form ? (
              <Card
                padding="lg"
                accent
                style={{ boxShadow: "var(--shadow-lg)" }}
              >
                <ContactForm />
              </Card>
            ) : (
              <Button
                variant="accent"
                size="lg"
                onClick={() => {
                  window.location.href = "contact.html";
                }}
              >
                {window.SITE.ui.ctaLabel}
              </Button>
            )}
          </div>
        </Shell>
      </section>
    );
  }

  /* ----------------------------------------------------------------- footer -- */

  function SiteFooter() {
    const f = window.SITE.footer;
    return (
      <footer
        style={{
          background: "var(--ink-900)",
          color: "var(--neutral-400)",
          padding: "64px 0 34px",
          position: "relative",
          overflow: "hidden",
        }}
      >
        <Shell>
          <div
            className="dx-footer-grid"
            style={{
              position: "relative",
              display: "grid",
              gridTemplateColumns: "1.4fr repeat(3,1fr)",
              gap: "40px",
            }}
          >
            <div>
              <Wordmark inverse />
              <p
                style={{
                  margin: "14px 0 0",
                  fontSize: "var(--fs-caption)",
                  lineHeight: 1.7,
                  maxWidth: "30ch",
                }}
              >
                {tx(window.SITE.brand.footerBlurb)}
              </p>
            </div>
            {f.columns.map((col) => (
              <div key={col.heading}>
                <div
                  style={{
                    font: "var(--text-eyebrow)",
                    letterSpacing: "var(--ls-eyebrow)",
                    textTransform: "uppercase",
                    color: "var(--white)",
                  }}
                >
                  {col.heading}
                </div>
                <div
                  style={{
                    display: "flex",
                    flexDirection: "column",
                    gap: "9px",
                    marginTop: "14px",
                  }}
                >
                  {col.links.map((l) =>
                    l.href ? (
                      <a
                        key={l.label}
                        href={l.href}
                        style={{
                          border: "none",
                          color: "var(--neutral-400)",
                          fontSize: "var(--fs-body-sm)",
                        }}
                      >
                        {l.label}
                      </a>
                    ) : (
                      <span
                        key={l.label}
                        className="dx-todo"
                        style={{ fontSize: "var(--fs-body-sm)" }}
                      >
                        {l.label}
                      </span>
                    ),
                  )}
                </div>
              </div>
            ))}
          </div>
          <div
            style={{
              position: "relative",
              marginTop: "48px",
              paddingTop: "20px",
              borderTop: "1px solid rgba(255,255,255,.10)",
              display: "flex",
              gap: "20px",
              fontSize: "var(--fs-caption)",
              flexWrap: "wrap",
            }}
          >
            <span>{f.copyright}</span>
            <span
              style={{ marginLeft: "auto", fontFamily: "var(--font-mono)" }}
            >
              {tx(f.credentials)}
            </span>
          </div>
        </Shell>
      </footer>
    );
  }

  /* ------------------------------------------------------------- mounting -- */

  /* Every page ends with mountPage(<Page />). The deployed HTML ships with the
     page already rendered into #root (tools/prerender.js, so crawlers see the
     copy without running React), and hydrating adopts that markup instead of
     throwing it away. Served straight from the repo — local dev — #root is
     empty and we render from scratch. */
  function mountPage(element) {
    const container = document.getElementById("root");
    if (container.dataset.prerendered) ReactDOM.hydrateRoot(container, element);
    else ReactDOM.createRoot(container).render(element);
  }

  Object.assign(window, {
    mountPage,
    Ico,
    Grain,
    Grid,
    Eyebrow,
    Wordmark,
    Shell,
    tx,
    isTodo,
    ImageSlot,
    SiteHeader,
    PageHero,
    EditorialList,
    ContactForm,
    ConversionBand,
    SiteFooter,
  });
})();
