(function () {
// Personal portfolio — Nav + Footer
const {
  Button,
  IconButton
} = window.FireTailDesignSystem_df7a18;

// /ui_kits/portfolio/ only exists when serving the repo root directly for
// quick local iteration (no dist/ rebuild); everywhere else (wrangler dev,
// production) the page loads at "/" and dist/Resume/ is the real path.
const RESUME_PATH = location.pathname.includes("/ui_kits/portfolio/") ? "/dist/Resume/Smit_Waghela_Game_Programmer.pdf" : "/Resume/Smit_Waghela_Game_Programmer.pdf";
// #toolbar=0&navpanes=0 strips the browser's native PDF chrome (zoom, rotate,
// annotate, page nav, thumbnail sidebar) — we replace it with our own bar below,
// down to exactly Download / Print / Close. Not all browsers honor these open
// parameters equally; Chrome/Edge (PDFium) do.
const RESUME_SRC = RESUME_PATH + "#toolbar=0&navpanes=0&view=FitH";

// Deliberately matches Hero.jsx's PANEL_FROST_BLUR / PANEL_TINT_STRENGTH —
// same frosted-glass recipe (backdrop-filter blur + a translucent
// var(--surface-overlay) tint via color-mix) so Nav and Hero's own
// readability panel read as one consistent material where they meet.
const NAV_FROST_BLUR = "14px";
const NAV_TINT_STRENGTH = "55%";
function DownloadIcon() {
  return /*#__PURE__*/React.createElement("svg", {
    width: "18",
    height: "18",
    viewBox: "0 0 24 24",
    fill: "none",
    stroke: "currentColor",
    strokeWidth: "2",
    strokeLinecap: "round",
    strokeLinejoin: "round"
  }, /*#__PURE__*/React.createElement("path", {
    d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"
  }), /*#__PURE__*/React.createElement("polyline", {
    points: "7 10 12 15 17 10"
  }), /*#__PURE__*/React.createElement("line", {
    x1: "12",
    y1: "15",
    x2: "12",
    y2: "3"
  }));
}
function PrintIcon() {
  return /*#__PURE__*/React.createElement("svg", {
    width: "18",
    height: "18",
    viewBox: "0 0 24 24",
    fill: "none",
    stroke: "currentColor",
    strokeWidth: "2",
    strokeLinecap: "round",
    strokeLinejoin: "round"
  }, /*#__PURE__*/React.createElement("polyline", {
    points: "6 9 6 2 18 2 18 9"
  }), /*#__PURE__*/React.createElement("path", {
    d: "M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"
  }), /*#__PURE__*/React.createElement("rect", {
    x: "6",
    y: "14",
    width: "12",
    height: "8"
  }));
}
function ResumeOverlay({
  open,
  onClose,
  isDark
}) {
  const iframeRef = React.useRef(null);

  // Mirrors App.jsx's own ft-modal-open gate (which only tracks
  // active/activeCaseStudy/activePublished) so the background atmosphere
  // animations, BottomDock, and CursorGlow also pause behind this modal's
  // backdrop-filter blur, not just the other three. Safe as a standalone
  // effect rather than lifting state up to App.jsx: Nav sits at z-index 50
  // and every modal (this one included) renders at z-index 99-100 covering
  // it, so this overlay and the other three can never be open at once —
  // nothing for two independent toggles to race on.
  React.useEffect(() => {
    document.body.classList.toggle("ft-modal-open", open);
  }, [open]);
  React.useEffect(() => {
    if (!open) return;
    const onKey = e => {
      if (e.key === "Escape") onClose();
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, onClose]);
  if (!open) return null;
  const download = () => {
    const a = document.createElement("a");
    a.href = RESUME_PATH;
    a.download = "";
    a.click();
  };
  const print = () => {
    if (iframeRef.current) iframeRef.current.contentWindow.print();
  };
  return /*#__PURE__*/React.createElement("div", {
    onClick: onClose,
    style: {
      position: "fixed",
      inset: 0,
      zIndex: 100,
      display: "flex",
      justifyContent: "center",
      alignItems: "center",
      padding: "40px 20px",
      background: "var(--surface-overlay)",
      backdropFilter: "blur(10px)",
      animation: "ftFade var(--dur-base) var(--ease-out)"
    }
  }, /*#__PURE__*/React.createElement("div", {
    onClick: e => e.stopPropagation(),
    style: {
      position: "relative",
      width: "min(880px, 90vw)",
      height: "min(90vh, 1100px)",
      display: "flex",
      flexDirection: "column",
      background: "var(--bg-raised)",
      border: "1px solid var(--border-strong)",
      borderRadius: "var(--radius-xl)",
      overflow: "hidden",
      boxShadow: "var(--shadow-lg)",
      animation: "ftRise var(--dur-slow) var(--ease-out)"
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: "flex",
      justifyContent: "flex-end",
      gap: 8,
      padding: "10px 12px",
      borderBottom: "1px solid var(--border)",
      background: "var(--surface-card)",
      flexShrink: 0
    }
  }, /*#__PURE__*/React.createElement(IconButton, {
    label: "Download resume",
    variant: "ghost",
    onClick: download
  }, /*#__PURE__*/React.createElement(DownloadIcon, null)), /*#__PURE__*/React.createElement(IconButton, {
    label: "Print resume",
    variant: "ghost",
    onClick: print
  }, /*#__PURE__*/React.createElement(PrintIcon, null)), /*#__PURE__*/React.createElement(IconButton, {
    label: "Close",
    variant: "solid",
    onClick: onClose
  }, "\u2715")), /*#__PURE__*/React.createElement("div", {
    style: {
      flex: 1,
      minHeight: 0,
      filter: isDark ? "invert(1) hue-rotate(180deg)" : "none"
    }
  }, /*#__PURE__*/React.createElement("iframe", {
    ref: iframeRef,
    src: RESUME_SRC,
    title: "Resume",
    style: {
      width: "100%",
      height: "100%",
      border: "none",
      display: "block"
    }
  }))));
}

// Single source of truth for light/dark — Nav owns this and hands `mode` to
// both ThemeToggle (to render/flip it) and ResumeOverlay (to filter the PDF),
// so nothing else needs to re-derive or observe the theme independently.
function useThemeMode() {
  const osPrefersDark = () => window.matchMedia("(prefers-color-scheme: dark)").matches;
  const getEffective = () => {
    const stored = localStorage.getItem("firetail-theme");
    if (stored) return stored;
    return osPrefersDark() ? "dark" : "light";
  };
  const [mode, setMode] = React.useState(getEffective);
  const apply = m => {
    const cl = document.documentElement.classList;
    cl.remove("theme-light", "theme-dark");
    cl.add(m === "light" ? "theme-light" : "theme-dark");
  };
  React.useEffect(() => {
    apply(mode);
    const mq = window.matchMedia("(prefers-color-scheme: dark)");
    const onChange = () => {
      if (!localStorage.getItem("firetail-theme")) {
        const next = mq.matches ? "dark" : "light";
        setMode(next);
        apply(next);
      }
    };
    mq.addEventListener("change", onChange);
    return () => mq.removeEventListener("change", onChange);
  }, []);
  const toggle = () => {
    const next = mode === "dark" ? "light" : "dark";
    localStorage.setItem("firetail-theme", next);
    setMode(next);
    apply(next);
  };
  return [mode, toggle];
}
function ThemeToggle({
  mode,
  onToggle
}) {
  return /*#__PURE__*/React.createElement("button", {
    className: "ft-theme-toggle",
    onClick: onToggle,
    "aria-label": mode === "dark" ? "Switch to light mode" : "Switch to dark mode"
  }, mode === "dark" ? /*#__PURE__*/React.createElement("svg", {
    width: "16",
    height: "16",
    viewBox: "0 0 24 24",
    fill: "none",
    stroke: "currentColor",
    strokeWidth: "2",
    strokeLinecap: "round",
    strokeLinejoin: "round"
  }, /*#__PURE__*/React.createElement("circle", {
    cx: "12",
    cy: "12",
    r: "5"
  }), /*#__PURE__*/React.createElement("line", {
    x1: "12",
    y1: "1",
    x2: "12",
    y2: "3"
  }), /*#__PURE__*/React.createElement("line", {
    x1: "12",
    y1: "21",
    x2: "12",
    y2: "23"
  }), /*#__PURE__*/React.createElement("line", {
    x1: "4.22",
    y1: "4.22",
    x2: "5.64",
    y2: "5.64"
  }), /*#__PURE__*/React.createElement("line", {
    x1: "18.36",
    y1: "18.36",
    x2: "19.78",
    y2: "19.78"
  }), /*#__PURE__*/React.createElement("line", {
    x1: "1",
    y1: "12",
    x2: "3",
    y2: "12"
  }), /*#__PURE__*/React.createElement("line", {
    x1: "21",
    y1: "12",
    x2: "23",
    y2: "12"
  }), /*#__PURE__*/React.createElement("line", {
    x1: "4.22",
    y1: "19.78",
    x2: "5.64",
    y2: "18.36"
  }), /*#__PURE__*/React.createElement("line", {
    x1: "18.36",
    y1: "5.64",
    x2: "19.78",
    y2: "4.22"
  })) : /*#__PURE__*/React.createElement("svg", {
    width: "16",
    height: "16",
    viewBox: "0 0 24 24",
    fill: "none",
    stroke: "currentColor",
    strokeWidth: "2",
    strokeLinecap: "round",
    strokeLinejoin: "round"
  }, /*#__PURE__*/React.createElement("path", {
    d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"
  })));
}
function MenuGlyph({
  open
}) {
  return /*#__PURE__*/React.createElement("svg", {
    width: "20",
    height: "20",
    viewBox: "0 0 24 24",
    fill: "none",
    stroke: "currentColor",
    strokeWidth: "2",
    strokeLinecap: "round",
    "aria-hidden": "true",
    style: {
      display: "block"
    }
  }, open ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("line", {
    x1: "6",
    y1: "6",
    x2: "18",
    y2: "18"
  }), /*#__PURE__*/React.createElement("line", {
    x1: "18",
    y1: "6",
    x2: "6",
    y2: "18"
  })) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("line", {
    x1: "4",
    y1: "7",
    x2: "20",
    y2: "7"
  }), /*#__PURE__*/React.createElement("line", {
    x1: "4",
    y1: "12",
    x2: "20",
    y2: "12"
  }), /*#__PURE__*/React.createElement("line", {
    x1: "4",
    y1: "17",
    x2: "20",
    y2: "17"
  })));
}
function Nav({
  onHome,
  mode,
  onToggleTheme
}) {
  const [scrolled, setScrolled] = React.useState(false);
  const [resumeOpen, setResumeOpen] = React.useState(false);
  const [narrow, setNarrow] = React.useState(() => window.innerWidth < 768);
  const [menuOpen, setMenuOpen] = React.useState(false);
  React.useEffect(() => {
    const el = document.querySelector("#ft-scroll");
    const t = el || window;
    const fn = () => setScrolled((el ? el.scrollTop : window.scrollY) > 20);
    fn();
    t.addEventListener("scroll", fn, {
      passive: true
    });
    return () => t.removeEventListener("scroll", fn);
  }, []);
  React.useEffect(() => {
    const mq = window.matchMedia("(max-width: 767px)");
    const fn = e => setNarrow(e.matches);
    mq.addEventListener("change", fn);
    return () => mq.removeEventListener("change", fn);
  }, []);
  // How much further the shared frost backing (below) extends past Nav's own
  // navH band — 0 normally. A page-specific sticky panel (e.g. ProjectGrid's
  // pinned filter row) asks for extra height by dispatching ft-frost-extend
  // with its own height once it's actually pinned directly beneath Nav, so
  // the two read — and render — as one continuous blurred surface instead of
  // two independently-composited ones stacked back to back. Same
  // window-event pattern HeroGame.jsx uses for ft-hero-game-loaded: Nav has
  // no reason to know ProjectGrid exists, so this stays a generic contract
  // any future sticky toolbar can opt into rather than a direct dependency.
  const [frostExtra, setFrostExtra] = React.useState(0);
  React.useEffect(() => {
    const onFrostExtend = e => setFrostExtra(e.detail && e.detail.height || 0);
    window.addEventListener("ft-frost-extend", onFrostExtend);
    return () => window.removeEventListener("ft-frost-extend", onFrostExtend);
  }, []);
  // Mirrors Hero.jsx's own gameReady flag — Nav has no React relationship to
  // Hero (same reasoning as ft-frost-extend above), so it listens to the same
  // ft-hero-game-loaded broadcast HeroGame.jsx already emits for
  // BottomDock.jsx. Only matters on the home page; everywhere else this never
  // fires and frostVisible (below) just falls back to scrolled, unchanged.
  const [gameLoaded, setGameLoaded] = React.useState(false);
  React.useEffect(() => {
    const onGameLoaded = e => setGameLoaded(!!(e.detail && e.detail.loaded));
    window.addEventListener("ft-hero-game-loaded", onGameLoaded);
    return () => window.removeEventListener("ft-hero-game-loaded", onGameLoaded);
  }, []);
  // Whether the frosted backing should be visible at all. Scrolled or
  // extended (ProjectGrid's pinned panel) behave as before; gameLoaded covers
  // the home page at scroll 0 — once the Hero game canvas is up (now opaque
  // right to the top, see HeroGame.jsx), Nav needs the frost to stay readable
  // over it, but not before it's actually loaded (nothing to blur yet, same
  // gate Hero's own text scrim uses).
  const frostVisible = scrolled || gameLoaded || frostExtra > 0;
  // Soft edge only for the specific window where the frost is up purely
  // because the Hero game loaded — not yet scrolled, not backing an
  // extended panel. Once either of those kick in, the flat hard-edged
  // band (with its own borderBottom line once scrolled) takes back over.
  const softFrostEdge = gameLoaded && !scrolled && frostExtra === 0;
  // "Work" points at the shipped/case-study cluster (Published Work sits
  // right at its top); Projects is its own distinct destination — see
  // Content Revamp Plan for why these were split out of one vague link.
  const links = [{
    label: "Work",
    href: "/work"
  }, {
    label: "Projects",
    href: "/projects"
  }, {
    label: "About",
    href: "/about"
  }, {
    label: "Contact",
    href: "/contact"
  }];
  // Same brighter-in-dark-mode literal Hero.jsx's own paragraph uses (see
  // its PANEL comment) — needed here for the same reason: now that the game
  // canvas sits behind Nav (see HeroGame.jsx), var(--text-muted) alone
  // doesn't hold up against the bright sky backdrop in dark mode. Light
  // mode is untouched, same as Hero.
  const NAV_TEXT_COLOR = mode === "dark" ? "var(--paper-100)" : "var(--text-muted)";
  const linkStyle = {
    fontFamily: "var(--font-mono)",
    fontSize: 14,
    letterSpacing: "0.12em",
    textTransform: "uppercase",
    color: NAV_TEXT_COLOR,
    textDecoration: "none",
    transition: "color var(--dur-base) var(--ease-out)"
  };
  const onLinkEnter = e => e.currentTarget.style.color = "var(--text-strong)";
  const onLinkLeave = e => e.currentTarget.style.color = NAV_TEXT_COLOR;
  const openResume = e => {
    e.preventDefault();
    setMenuOpen(false);
    setResumeOpen(true);
  };
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
    style: {
      position: "sticky",
      top: 0,
      height: 0,
      zIndex: 3
    }
  }, /*#__PURE__*/React.createElement("div", {
    "aria-hidden": "true",
    style: {
      position: "absolute",
      top: 0,
      left: 0,
      right: 0,
      pointerEvents: "none",
      height: frostExtra > 0 ? `calc(var(--nav-h) + ${frostExtra}px + 10px)` : "var(--nav-h)",
      background: `color-mix(in srgb, var(--surface-overlay) ${NAV_TINT_STRENGTH}, transparent)`,
      backdropFilter: `blur(${NAV_FROST_BLUR})`,
      WebkitBackdropFilter: `blur(${NAV_FROST_BLUR})`,
      borderBottom: `1px solid ${scrolled || frostExtra > 0 ? "var(--border)" : "transparent"}`,
      opacity: frostVisible ? 1 : 0,
      maskImage: softFrostEdge ? "linear-gradient(to bottom, black calc(120% - 50px), transparent 100%)" : "none",
      WebkitMaskImage: softFrostEdge ? "linear-gradient(to bottom, black calc(120% - 50px), transparent 100%)" : "none",
      transition: "height var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out), opacity 2000ms ease"
    }
  }), /*#__PURE__*/React.createElement("div", {
    "aria-hidden": "true",
    style: {
      position: "absolute",
      top: "var(--nav-h)",
      left: 0,
      right: 0,
      height: 1,
      background: "var(--border)",
      pointerEvents: "none",
      opacity: frostExtra > 0 ? 1 : 0,
      transition: "opacity var(--dur-base) var(--ease-out)"
    }
  })), /*#__PURE__*/React.createElement("header", {
    style: {
      position: "sticky",
      top: 0,
      zIndex: 50,
      height: "var(--nav-h)",
      display: "flex",
      alignItems: "center",
      justifyContent: "space-between",
      padding: "0 clamp(20px, 5vw, 48px)"
    }
  }, /*#__PURE__*/React.createElement("a", {
    href: "#top",
    onClick: onHome,
    style: {
      display: "inline-flex",
      alignItems: "center",
      textDecoration: "none"
    }
  }, !narrow && /*#__PURE__*/React.createElement("span", {
    id: "ft-nav-namedock",
    style: {
      visibility: "hidden",
      fontFamily: "var(--font-display)",
      fontWeight: 600,
      fontSize: 29,
      letterSpacing: "-0.01em",
      lineHeight: 1,
      whiteSpace: "nowrap"
    }
  }, "Smit Waghela")), /*#__PURE__*/React.createElement("nav", {
    style: {
      display: "flex",
      alignItems: "center",
      gap: narrow ? 10 : "clamp(16px, 3vw, 34px)"
    }
  }, narrow ? /*#__PURE__*/React.createElement("button", {
    type: "button",
    onClick: () => setMenuOpen(v => !v),
    "aria-label": "Menu",
    "aria-expanded": menuOpen,
    style: {
      width: 36,
      height: 36,
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
      background: "transparent",
      border: "1px solid var(--border-strong)",
      borderRadius: "var(--radius-md)",
      color: "var(--text-body)",
      cursor: "pointer"
    }
  }, /*#__PURE__*/React.createElement(MenuGlyph, {
    open: menuOpen
  })) : /*#__PURE__*/React.createElement(React.Fragment, null, links.map(l => /*#__PURE__*/React.createElement("a", {
    key: l.label,
    href: l.href,
    style: linkStyle,
    onMouseEnter: onLinkEnter,
    onMouseLeave: onLinkLeave
  }, l.label)), /*#__PURE__*/React.createElement("a", {
    href: RESUME_PATH,
    onClick: e => {
      e.preventDefault();
      setResumeOpen(true);
    },
    style: linkStyle,
    onMouseEnter: onLinkEnter,
    onMouseLeave: onLinkLeave
  }, "Resume")), /*#__PURE__*/React.createElement(ThemeToggle, {
    mode: mode,
    onToggle: onToggleTheme
  }), /*#__PURE__*/React.createElement(Button, {
    as: "a",
    href: "#contact",
    size: "sm"
  }, "Open to work"))), narrow && menuOpen && /*#__PURE__*/React.createElement("div", {
    style: {
      position: "fixed",
      top: "var(--nav-h)",
      left: 0,
      right: 0,
      zIndex: 49,
      background: "var(--surface-overlay)",
      backdropFilter: "blur(14px)",
      borderBottom: "1px solid var(--border)",
      display: "flex",
      flexDirection: "column",
      padding: "8px clamp(20px, 5vw, 48px) 16px"
    }
  }, links.map(l => /*#__PURE__*/React.createElement("a", {
    key: l.label,
    href: l.href,
    onClick: () => setMenuOpen(false),
    style: {
      padding: "13px 0",
      fontFamily: "var(--font-mono)",
      fontSize: 16,
      letterSpacing: "0.1em",
      textTransform: "uppercase",
      color: "var(--text-body)",
      textDecoration: "none",
      borderBottom: "1px solid var(--border-faint)"
    }
  }, l.label)), /*#__PURE__*/React.createElement("a", {
    href: RESUME_PATH,
    onClick: openResume,
    style: {
      padding: "13px 0",
      fontFamily: "var(--font-mono)",
      fontSize: 16,
      letterSpacing: "0.1em",
      textTransform: "uppercase",
      color: "var(--text-body)",
      textDecoration: "none"
    }
  }, "Resume")), /*#__PURE__*/React.createElement(ResumeOverlay, {
    open: resumeOpen,
    onClose: () => setResumeOpen(false),
    isDark: mode === "dark"
  }));
}
function Footer() {
  const [narrow, setNarrow] = React.useState(() => window.innerWidth < 768);
  React.useEffect(() => {
    const mq = window.matchMedia("(max-width: 767px)");
    const fn = e => setNarrow(e.matches);
    mq.addEventListener("change", fn);
    return () => mq.removeEventListener("change", fn);
  }, []);
  const brand = /*#__PURE__*/React.createElement("div", {
    style: {
      marginBottom: 14
    }
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      fontFamily: "var(--font-display)",
      fontWeight: 600,
      fontSize: 22,
      color: "var(--text-strong)"
    }
  }, "Smit Waghela"));
  const tagline = /*#__PURE__*/React.createElement("p", {
    style: {
      margin: 0,
      fontFamily: "var(--font-sans)",
      fontSize: 17,
      color: "var(--text-faint)",
      maxWidth: 340,
      lineHeight: 1.6
    }
  }, "Gameplay programmer building systems and tools.");
  const copy = /*#__PURE__*/React.createElement("div", {
    style: {
      fontFamily: "var(--font-mono)",
      fontSize: 13,
      letterSpacing: "0.08em",
      color: "var(--text-faint)"
    }
  }, "\xA9 2026 SMIT WAGHELA");
  return /*#__PURE__*/React.createElement("footer", {
    style: {
      borderTop: "1px solid var(--border)",
      padding: "56px clamp(20px,5vw,48px) 40px",
      marginTop: 40,
      background: "var(--surface-overlay)",
      backdropFilter: "blur(14px)",
      position: "relative",
      zIndex: 2
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      maxWidth: "var(--container)",
      margin: "0 auto"
    }
  }, narrow ? /*#__PURE__*/React.createElement(React.Fragment, null, brand, tagline, /*#__PURE__*/React.createElement("div", {
    id: "ft-anchor-footer",
    style: {
      height: 48,
      marginTop: 20,
      display: "flex",
      alignItems: "center"
    }
  }), /*#__PURE__*/React.createElement("div", {
    style: {
      marginTop: 20
    }
  }, copy)) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
    style: {
      display: "flex",
      flexWrap: "wrap",
      gap: "20px 32px",
      justifyContent: "space-between",
      alignItems: "flex-start"
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      flex: "1 1 300px",
      minWidth: 0
    }
  }, brand, tagline), /*#__PURE__*/React.createElement("div", {
    id: "ft-anchor-footer",
    style: {
      height: 30,
      minWidth: 46,
      display: "flex",
      alignItems: "center",
      flexShrink: 0
    }
  })), /*#__PURE__*/React.createElement("div", {
    style: {
      marginTop: 34
    }
  }, copy))));
}
Object.assign(window, {
  Nav,
  Footer,
  useThemeMode
});
})();
