// tokens.jsx: Locate2u tokens + shared building blocks (PH page)
window.l2uTokens = {
  primary: "#2B93FF",
  primaryDeep: "#0B73D1",
  bluishGrey: "#1C3E61",
  darkBlue: "#01101F",
  navy: "#1C3E61",
  navyDeep: "#01101F",
  navyDarkest: "#01101F",
  navyMid: "#0A2540",
  cream: "rgb(251,250,247)",
  cream2: "#F4F1EA",
  border: "rgb(226,228,234)",
  borderSoft: "rgba(28,62,97,0.10)",
  borderHair: "rgba(28,62,97,0.06)",
  body: "rgb(68,88,122)",
  mute: "rgba(28,62,97,0.7)",
  mute2: "rgba(28,62,97,0.55)",
  muteOnDark: "rgba(255,255,255,0.7)",
  muteOnDark2: "rgba(255,255,255,0.5)",
  success: "rgb(45,210,122)",
  warn: "rgb(244,161,29)",
  danger: "#E5484D",
  shadowToast: "0 8px 24px rgba(0,0,0,0.25)",
  shadowPop: "0 6px 18px rgba(0,0,0,0.20)",
  shadowCTA: "0 8px 28px rgba(43,147,255,0.40)",
  shadowCard: "0 1px 2px rgba(15,31,56,0.04)",
  fontSans: '"Roboto", system-ui, -apple-system, sans-serif',
  fontMono: '"JetBrains Mono", ui-monospace, Menlo, monospace',
};
const T = window.l2uTokens;

window.L2U_Eyebrow = function Eyebrow({ children, color, onDark }) {
  return (
    <span style={{
      fontFamily: T.fontMono, fontWeight: 500, fontSize: 12,
      letterSpacing: "1.6px", textTransform: "uppercase",
      color: color || (onDark ? "#6EC1F7" : T.primaryDeep),
    }}>{children}</span>
  );
};

window.L2U_Btn = function Btn({ children, variant = "primary", glow, onDark, onClick, href, arrow, style }) {
  const base = {
    display: "inline-flex", alignItems: "center", gap: 8,
    fontFamily: T.fontSans, fontWeight: 600, fontSize: 15,
    border: "none", cursor: "pointer", borderRadius: 10,
    padding: "14px 22px", whiteSpace: "nowrap",
    transition: "transform .12s ease, filter .12s ease, background .12s ease",
  };
  const map = {
    primary: { ...base, background: T.primary, color: "#fff", boxShadow: glow ? T.shadowCTA : "none" },
    primaryLg: { ...base, background: T.primary, color: "#fff", padding: "16px 26px", fontSize: 16, borderRadius: 12, boxShadow: glow ? T.shadowCTA : "none" },
    secondary: {
      ...base,
      background: onDark ? "rgba(255,255,255,0.10)" : "#fff",
      color: onDark ? "#fff" : T.bluishGrey,
      border: onDark ? "1px solid rgba(255,255,255,0.20)" : "1px solid rgba(28,62,97,0.14)",
    },
    ghost: { ...base, background: "transparent", color: onDark ? "#fff" : T.bluishGrey, padding: "10px 14px" },
    link: {
      ...base, padding: 0, background: "transparent",
      color: T.primary, fontWeight: 700, fontSize: 14,
    },
  };
  const v = map[variant] ? variant : "primary";
  const st = { ...map[v], ...(style || {}) };
  const secBorder = onDark ? "rgba(255,255,255,0.20)" : "rgba(28,62,97,0.14)";
  // Every variant gets a hover state (colour/tint shift + slight lift).
  const hover = {
    primary: { background: "#1C82EF" },
    primaryLg: { background: "#1C82EF" },
    secondary: { background: onDark ? "rgba(255,255,255,0.16)" : "rgba(43,147,255,0.07)", borderColor: onDark ? "rgba(255,255,255,0.40)" : "rgba(43,147,255,0.55)" },
    ghost: { background: onDark ? "rgba(255,255,255,0.10)" : "rgba(28,62,97,0.06)" },
    link: { color: "#1C82EF" },
  }[v];
  const handleClick = onClick || (href ? () => { window.location.href = href; } : undefined);
  return (
    <button
      style={st}
      onClick={handleClick}
      onMouseEnter={(e) => { Object.assign(e.currentTarget.style, hover); e.currentTarget.style.transform = "translateY(-1px)"; }}
      onMouseLeave={(e) => {
        e.currentTarget.style.background = st.background || "transparent";
        e.currentTarget.style.color = st.color || "";
        if (v === "secondary") e.currentTarget.style.borderColor = secBorder;
        e.currentTarget.style.transform = "";
      }}
      onMouseDown={(e) => (e.currentTarget.style.transform = "scale(0.98)")}
      onMouseUp={(e) => (e.currentTarget.style.transform = "translateY(-1px)")}
    >{children}{arrow && (<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" style={{ flexShrink: 0 }}><path d="M5 12h14M13 6l6 6-6 6" /></svg>)}</button>
  );
};

window.L2U_Dot = function Dot({ color = T.success, size = 8, pulse }) {
  return (
    <span style={{
      display: "inline-block", width: size, height: size, borderRadius: "50%",
      background: color,
      animation: pulse ? "l2uPulse 1.6s ease-in-out infinite" : "none",
    }} />
  );
};

window.L2U_Section = function Section({ background, padding, children, style }) {
  return (
    <section style={{
      background: background || T.cream,
      padding: padding || "120px 80px",
      fontFamily: T.fontSans,
      ...(style || {}),
    }}>
      <div style={{ maxWidth: 1280, margin: "0 auto" }}>{children}</div>
    </section>
  );
};

window.L2U_SectionHead = function SectionHead({ eyebrow, title, body, align = "center", onDark, eyebrowColor, maxBody = 720 }) {
  return (
    <div style={{
      textAlign: align,
      marginBottom: 56,
      maxWidth: align === "center" ? 880 : "none",
      margin: align === "center" ? "0 auto 56px" : "0 0 56px",
    }}>
      {eyebrow && <window.L2U_Eyebrow color={eyebrowColor} onDark={onDark}>{eyebrow}</window.L2U_Eyebrow>}
      <h2 style={{
        margin: "16px 0 16px", fontSize: 52, fontWeight: 900,
        lineHeight: "60px", letterSpacing: "-1.4px",
        color: onDark ? "#fff" : T.bluishGrey,
        textWrap: "balance",
      }}>{title}</h2>
      {body && (
        <p style={{
          margin: align === "center" ? "0 auto" : 0,
          fontSize: 18, lineHeight: "28px",
          color: onDark ? T.muteOnDark : T.mute,
          maxWidth: maxBody,
        }}>{body}</p>
      )}
    </div>
  );
};

// Responsive helper: returns true on phone/narrow viewports. Re-renders on resize.
window.useIsMobile = function useIsMobile(bp) {
  const q = "(max-width: " + (bp || 820) + "px)";
  const [m, setM] = React.useState(
    typeof window !== "undefined" && window.matchMedia ? window.matchMedia(q).matches : false
  );
  React.useEffect(() => {
    const mq = window.matchMedia(q);
    const on = () => setM(mq.matches);
    on();
    mq.addEventListener ? mq.addEventListener("change", on) : mq.addListener(on);
    return () => { mq.removeEventListener ? mq.removeEventListener("change", on) : mq.removeListener(on); };
  }, []);
  return m;
};

// Hero route-map data: each entry is a real (dark) map image with an optimized
// route + markers traced from the matching "-hero-mapdone.png" guide. Coordinates
// are in the map image's native 849×585 space. Keyed by map name; product/use-case
// and city heroes reference these by name.
window.L2U_HERO_MAPS = {
  "bgc": { img: "bgc-hero-map.png", gps: [218,356], stops: [[471,266], [522,344], [375,384]], pin: [531,116],
    route: "218,356 236,344 262,340 298,376 326,390 356,392 402,362 438,358 471,266 498,278 498,302 486,340 522,344 540,270 572,238 572,208 602,170 606,154 594,138 562,134 531,116" },
  "metromanila": { img: "metromanila-hero-map.png", gps: [189,369], stops: [[338,236], [471,257], [590,332]], pin: [711,174],
    route: "189,369 272,394 292,354 274,332 316,292 330,270 346,216 348,188 396,188 408,194 471,257 502,270 570,328 622,346 638,292 711,174" },
  "ortigaspasig1": { img: "ortigaspasig1-hero-map.png", gps: [194,365], stops: [[668,129], [440,144], [369,219], [353,368]], pin: [552,311],
    route: "194,365 220,378 252,342 266,342 322,394 353,368 316,334 316,322 358,268 358,240 369,219 360,200 360,138 386,112 396,112 420,136 440,144 460,138 584,138 668,129 670,190 610,300 582,328 552,311" },
  "cavitemakati": { img: "cavitemakati-hero-map.png", gps: [207,401], stops: [[459,98], [423,179], [431,279]], pin: [595,170],
    route: "207,401 218,382 332,362 431,279 398,264 398,248 423,179 428,104 502,94 538,162 558,182 595,170" },
  "ortigaspasig2": { img: "ortigaspasig2-hero-map.png", gps: [149,288], stops: [[369,164], [540,167], [426,260]], pin: [696,273],
    route: "149,288 180,278 246,338 294,260 318,176 332,162 369,164 390,158 400,158 424,182 426,260 446,268 466,266 468,184 478,174 626,166 628,268 696,273" },
  "quezoncity": { img: "quezoncity-hero-map.png", gps: [185,381], stops: [[366,261], [296,311], [503,353]], pin: [679,227],
    route: "185,381 190,346 288,344 294,338 296,311 366,261 412,262 434,272 442,292 434,340 530,358 540,316 540,292 530,268 534,264 562,248 679,227" },
  "makati": { img: "makati-hero-map.png", gps: [213,369], stops: [[563,236], [365,282], [501,375]], pin: [697,252],
    route: "213,369 228,350 365,282 501,375 510,356 510,338 563,236 612,270 622,270 630,262 697,252" },
  "cebu": { img: "cebu-hero-map.png", gps: [99,200], stops: [[285,129], [332,266], [468,449]], pin: [630,189],
    route: "99,200 158,164 285,129 292,160 300,168 308,230 324,246 376,398 392,414 468,449 490,346 508,326 522,272 534,260 542,260 566,284 586,278 646,220 630,189" },
  "davao": { img: "davao-hero-map.png", gps: [269,378], stops: [[443,192], [590,204], [473,273]], pin: [664,288],
    route: "269,378 444,336 456,322 473,273 444,244 443,192 514,142 560,190 588,172 590,204 628,254 664,288" },
  "clarkpampanga": { img: "clarkpampanga-hero-map.png", gps: [156,335], stops: [[420,239], [293,254], [420,339]], pin: [513,131],
    route: "156,335 138,324 140,312 200,292 226,268 293,254 322,324 340,342 368,342 400,332 440,348 454,314 454,294 420,239 434,186 474,152 513,131" },
};

// Shared hero route-map renderer: dark map image + animated optimized route
// (dark casing + blue line + moving flow highlight) with a GPS-location start
// dot, stop.png waypoints, and a PIN-STOP destination. Renders the map layer
// only; callers wrap it in their card and overlay any floating labels.
window.L2U_HeroRouteMap = function HeroRouteMap({ img, route, gps, stops, pin }) {
  const T = window.l2uTokens;
  const VW = 849, VH = 585;
  const L = (x) => (x / VW * 100) + "%";
  const Tp = (y) => (y / VH * 100) + "%";
  return (
    <React.Fragment>
      <img src={"assets/" + img} alt="" aria-hidden="true" style={{ display: "block", width: "100%", height: "auto" }} />
      <svg viewBox={"0 0 " + VW + " " + VH} preserveAspectRatio="none" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", pointerEvents: "none" }} aria-hidden="true">
        <polyline points={route} fill="none" stroke="#0A1524" strokeWidth="15" strokeLinejoin="round" strokeLinecap="round" pathLength="100" style={{ strokeDasharray: 100, animation: "l2uDrawN 1.2s cubic-bezier(0.2,0.8,0.2,1) 0.55s both" }} />
        <polyline points={route} fill="none" stroke={T.primary} strokeWidth="11" strokeLinejoin="round" strokeLinecap="round" pathLength="100" style={{ strokeDasharray: 100, animation: "l2uDrawN 1.2s cubic-bezier(0.2,0.8,0.2,1) 0.55s both" }} />
        <polyline points={route} fill="none" stroke="#BFE0FF" strokeWidth="11" strokeLinecap="round" strokeLinejoin="round" pathLength="100" style={{ strokeDasharray: "3 97", opacity: 0, animation: "l2uFadeIn 0.4s ease 1.95s forwards, l2uFlowN 2.6s linear 1.95s infinite" }} />
      </svg>
      {stops.map((s, i) => (
        <img key={i} src="assets/stop.png" alt="" aria-hidden="true" style={{ position: "absolute", left: L(s[0]), top: Tp(s[1]), width: 18, height: 18, transform: "translate(-50%,-50%)", transformOrigin: "center", animation: "l2uPopS 0.4s cubic-bezier(0.2,0.9,0.3,1.2) " + (0.3 + i * 0.12).toFixed(2) + "s both", pointerEvents: "none" }} />
      ))}
      <span style={{ position: "absolute", left: L(gps[0]), top: Tp(gps[1]), width: 36, height: 36, transform: "translate(-50%,-50%)", pointerEvents: "none", animation: "l2uPopS 0.45s cubic-bezier(0.2,0.9,0.3,1.2) 0.15s both" }} aria-hidden="true">
        <span style={{ position: "absolute", left: "50%", top: "50%", width: 32, height: 32, marginLeft: -16, marginTop: -16, borderRadius: "50%", background: "rgba(43,147,255,0.22)", animation: "l2uPulse 1.9s ease-in-out infinite" }} />
        <span style={{ position: "absolute", left: "50%", top: "50%", width: 18, height: 18, marginLeft: -9, marginTop: -9, borderRadius: "50%", background: "#fff", boxShadow: "0 2px 5px rgba(0,0,0,0.45)" }} />
        <span style={{ position: "absolute", left: "50%", top: "50%", width: 10, height: 10, marginLeft: -5, marginTop: -5, borderRadius: "50%", background: T.primary }} />
      </span>
      <svg viewBox="0 0 60 71" fill="none" style={{ position: "absolute", left: L(pin[0]), top: Tp(pin[1]), width: 34, aspectRatio: "60 / 71", transform: "translate(-50%,-79.6%)", transformOrigin: "50% 79.6%", filter: "drop-shadow(0 2px 5px rgba(0,0,0,0.4))", animation: "l2uPopS 0.5s cubic-bezier(0.2,0.9,0.3,1.3) 0.5s both", pointerEvents: "none" }} aria-hidden="true">
        <circle cx="30.5" cy="56.5" r="14.5" fill="#0C2035" />
        <circle cx="30.5" cy="56.5" r="10.875" fill="#fff" />
        <circle cx="30.5" cy="56.5" r="5.4375" fill="#0C2035" />
        <path d="M31 7C20.5 7 11 15.05 11 27.5C11 35.8 17.675 45.625 31 57C44.325 45.625 51 35.8 51 27.5C51 15.05 41.5 7 31 7ZM31 32C28.25 32 26 29.75 26 27C26 24.25 28.25 22 31 22C33.75 22 36 24.25 36 27C36 29.75 33.75 32 31 32Z" fill="#FE5425" />
        <path d="M31 32C28.25 32 26 29.75 26 27C26 24.25 28.25 22 31 22C33.75 22 36 24.25 36 27C36 29.75 33.75 32 31 32Z" fill="#fff" />
      </svg>
    </React.Fragment>
  );
};
