/* ==========================================================================
   nav.css - Fixed edge navigation and social rail
   ========================================================================== */

nav {
  position: fixed;
  inset: 0 0 auto 0;
  height: 0;
  z-index: 100;
  background: transparent;
  pointer-events: none;
}

nav.nav-scrolled {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.nav-logo {
  position: fixed;
  top: clamp(28px, 7.5svh, 68px);   /* svh: fixed nav must not drift as the mobile bar toggles */
  left: clamp(24px, 3.7vw, 68px);
  display: flex;
  align-items: center;
  justify-content: center;
  /* minhpham logo is 3rem (48px) on desktop — was 54px here. */
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: transparent;
  color: var(--color-loader-accent);
  overflow: hidden;
  pointer-events: auto;
  /* transform is intentionally NOT transitioned: the magnetic system (main.js) writes the
     transform every frame via its own lerp, and a CSS transition would smear/lag it. The
     :hover lift below is moot during hover anyway (the magnetic inline transform overrides it). */
  transition: opacity 0.22s ease, background-color 0.22s ease, color 0.22s ease;
  will-change: transform;
}

.nav-logo:hover,
.nav-logo:focus-visible {
  transform: translateY(-2px);
}

.nav-logo.is-magnetic,
.nav-logo:focus-visible {
  /* On magnetic latch the logo becomes an orange disc with a black "AS"
     mark; the orange .site-cursor (main.css) inverts within its own
     overlap. (The social icons use a different latch — colour-only, no
     disc — see .side-social-link.is-magnetic-side below.) */
  background: var(--color-accent);
  color: var(--color-bg);
}

.nav-logo-face {
  width: 100%;
  height: 100%;
  fill: currentColor;
  display: block;
  position: relative;
  z-index: 2;
  pointer-events: none;
  user-select: none;
}

.nav-links {
  position: fixed;
  top: clamp(30px, 7.7svh, 70px);   /* svh: fixed nav must not drift as the mobile bar toggles */
  right: clamp(28px, 4vw, 74px);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 11px;
  pointer-events: auto;
}

.nav-link {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 1.05em;
  overflow: hidden;
  /* Nav links pinned to Geist specifically — independent of Slot 2 (--font-body). */
  font-family: 'Geist', sans-serif;
  /* minhpham nav links (.desc) are 1rem (16px) on desktop — was 18px. */
  font-size: 16px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--color-muted);
}

.nav-link .link-default,
.nav-link .link-hover {
  display: block;
  transition: transform 0.35s cubic-bezier(0.76, 0, 0.24, 1);
  will-change: transform;
}

.nav-link .link-hover {
  color: var(--color-loader-accent);
  transform: translateY(0);
}

.nav-link:hover .link-default,
.nav-link:focus-visible .link-default {
  transform: translateY(-100%);
}

.nav-link:hover .link-hover,
.nav-link:focus-visible .link-hover,
.nav-link.is-active .link-hover {
  transform: translateY(-100%);
}

.nav-link.is-active .link-default {
  transform: translateY(-100%);
}

.hamburger {
  position: fixed;
  top: 28px;
  right: 24px;
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  width: 44px;
  height: 44px;
  align-items: center;
  padding: 0;
  pointer-events: auto;
}

.hamburger-line {
  display: block;
  width: 24px;
  height: 2px;
  background: var(--color-text);
  transition: transform 0.3s ease, opacity 0.3s ease;
}

.side-social {
  position: fixed;
  left: clamp(28px, 3.8vw, 70px);
  bottom: clamp(42px, 7.2svh, 72px);   /* svh: fixed nav must not drift as the mobile bar toggles */
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* minhpham spaces his social icons ~61px centre-to-centre (24px icon + ~37px gap). With our
     32px disc that's a 28px gap — was 52px, which read as too spread out. */
  gap: 28px;
}

.side-social-link {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: transparent;
  color: var(--color-loader-accent);
  opacity: 0.9;
  /* keeps the glyph inside the circular shape */
  overflow: hidden;
  /* transform NOT transitioned — driven every frame by the magnetic lerp (main.js); a CSS
     transition would lag it. The :hover lift is overridden by the magnetic transform anyway. */
  transition: opacity 0.22s ease, background-color 0.22s ease, color 0.22s ease;
  will-change: transform;
}

.side-social-link:hover,
.side-social-link:focus-visible {
  opacity: 1;
  transform: translateY(-2px);
  /* No bg/colour change here — the inversion over the icon is the global
     mix-blend-mode:difference .site-cursor (main.css). */
}

.side-social-link.is-magnetic-side {
  /* Cream→orange on magnetic latch. No disc — the orange global
     mix-blend-mode:difference .site-cursor (main.css) flips this orange
     glyph to black and the dark page to orange within its own circle. */
  color: var(--color-accent);
}

/* === Cursor-invert effect ===
   The invert lives on the global mix-blend-mode:difference .site-cursor
   (main.css). It is on top (z 9999) and inverts whatever it overlaps — logo,
   social icons, text, sections. The icons themselves carry NO blend (that was
   tried and produced an opaque-orange cover instead of an invert, because the
   cursor paints above them — the page's z-index range goes up to 2000, so the
   cursor can't sit below the icons the way minhpham's does). */

.side-social-link--github {
  font-size: 0;
}

.side-social-github-icon {
  /* minhpham social icons are 1.5rem (24px) — was 27px. */
  width: 24px;
  height: 24px;
}

.side-social-link--linkedin {
  align-items: baseline;
  font-family: Arial, sans-serif;
  /* match the 24px icon scale — was 28px. */
  font-size: 24px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.08em;
}

body.menu-open {
  overflow: hidden;
}

.hamburger[aria-expanded="true"] .hamburger-line:nth-child(1) {
  transform: translateY(8px) rotate(45deg);
}

.hamburger[aria-expanded="true"] .hamburger-line:nth-child(2) {
  opacity: 0;
}

.hamburger[aria-expanded="true"] .hamburger-line:nth-child(3) {
  transform: translateY(-8px) rotate(-45deg);
}

@media (max-width: 768px) {
  /* minhpham-style: keep nav links as a small inline top-right stack —
     no hamburger, no dropdown panel. Base .nav-link height:1.05em is kept
     (NOT 1.4em) so only .link-default shows — no ghost/double text. */
  .nav-logo {
    top: 16px;
    left: 16px;
    width: 42px;
    height: 42px;
  }

  .nav-links {
    top: 18px;
    right: 18px;
    gap: 8px;
  }

  .nav-link {
    font-size: 14px;
  }

  .hamburger {
    display: none;
  }

  .side-social {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .nav-logo,
  .nav-link .link-default,
  .nav-link .link-hover,
  .hamburger-line,
  .side-social-link {
    transition: none !important;
  }
}

/* ── Theme toggle — DARK THEME DISABLED ────────────────────────────────────
   Button removed from HTML. Uncomment this block + index.html + theme.js to re-enable.

.theme-toggle {
  position: fixed;
  bottom: clamp(42px, 7.2vh, 72px);
  right: clamp(28px, 4vw, 74px);
  width: 54px;
  height: 28px;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  background: rgba(255, 255, 255, 0.08);
  padding: 3px;
  display: flex;
  align-items: center;
  cursor: pointer;
  pointer-events: auto;
  z-index: 100;
  transition: background 0.3s ease, border-color 0.3s ease;
}

.theme-toggle__thumb {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #f2613f;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transform: translateX(26px);
  transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1), background 0.3s ease;
}

.theme-icon {
  width: 11px;
  height: 11px;
  pointer-events: none;
  flex-shrink: 0;
  color: #fff;
  stroke: #fff;
}

.theme-icon--sun  { display: none; }
.theme-icon--moon { display: block; }

:root.theme-light .theme-toggle {
  background: rgba(0, 0, 0, 0.06);
  border-color: rgba(0, 0, 0, 0.12);
}

:root.theme-light .theme-toggle__thumb {
  background: #3557ff;
  transform: translateX(0);
}

:root.theme-light .theme-icon--sun  { display: block; }
:root.theme-light .theme-icon--moon { display: none; }

@media (max-width: 768px) {
  .theme-toggle {
    bottom: auto;
    top: 18px;
    right: 76px;
  }
}
   ── end DARK THEME DISABLED ── */

/* Light theme social icons — bare glyphs, NO disc (only the main logo gets a
   fill). They rest at a calm navy and, on magnetic latch, recolour to the cursor
   colour (electric blue) with no background — like minhpham's bare social glyphs.
   The earlier `background: var(--color-text)` here was the unwanted ring/fill. */
:root.theme-light .side-social-link:not(.is-magnetic-side) {
  color: var(--color-accent);   /* navy at rest */
}
:root.theme-light .side-social-link.is-magnetic-side {
  background: transparent;       /* no disc */
  color: var(--color-text);      /* recolour glyph to the cursor's electric blue */
}

/* Cursor-overlap negative on the social glyphs (light theme).
   The .side-social-invert layer is the photographic negative of the glyph — a
   white glyph on an electric-blue field. It's revealed ONLY inside a circle that
   tracks the cursor disc (--x/--y/--size written by initGlobalCursor's tick),
   exactly the mask method the hidden-text reveal lenses use. So as the disc sweeps
   the glyph: outside the circle = electric-blue glyph on white; inside = white
   glyph on electric blue — a true white<->blue swap. Confined to the link's own
   32px circle by the parent's overflow:hidden, so it never bleeds onto the page.
   Dark theme already gets inversion free from the global difference cursor, so
   this layer is light-theme only. */

/* Raise the social rail ABOVE the cursor disc (z 9000) in light theme so the
   invert layer paints over the multiply disc instead of under it — that's what
   lets the WHITE glyph read white without hiding the disc (minhpham's cursor-
   under-icons layering). Still below the preloader (9999). Dark theme keeps the
   rail at z 100 so the difference cursor inverts it from on top. */
:root.theme-light .side-social {
  z-index: 9500;
}

.side-social-invert {
  display: none;
}
:root.theme-light .side-social-invert {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: inherit;          /* match the base glyph's centring (linkedin = baseline) */
  justify-content: inherit;
  background: var(--color-text);  /* electric-blue field */
  color: #fff;                    /* white glyph (svg fill:currentColor / text) */
  pointer-events: none;
  --size: 0px;
  --x: 50%;
  --y: 50%;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='50' fill='%23000'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='50' fill='%23000'/%3E%3C/svg%3E");
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: calc(var(--x) - var(--size) / 2) calc(var(--y) - var(--size) / 2);
          mask-position: calc(var(--x) - var(--size) / 2) calc(var(--y) - var(--size) / 2);
  -webkit-mask-size: var(--size) var(--size);
          mask-size: var(--size) var(--size);
}

/* ── Logo cursor-overlap invert (light theme) ──────────────────────────────
   The logo keeps its background FILL (unlike the bare social glyphs), so its
   latched look in light theme is an electric-blue disc with a white "AS" — the
   same electric blue the social glyphs latch to, for one consistent identity.
   On cursor overlap it swaps exactly like the icons: white disc + electric-blue
   "AS" inside the disc-tracking circle. (Dark theme keeps the base orange-disc
   rule above and inverts for free via the difference cursor.) */
:root.theme-light .nav-logo.is-magnetic,
:root.theme-light .nav-logo:focus-visible {
  background: var(--color-text);   /* electric-blue disc (== social latch colour) */
  color: #fff;                     /* white "AS" mark */
}

/* Raise the whole nav ABOVE the cursor disc (z 9000) in light theme so the logo's
   invert layer can paint OVER the multiply disc — the same reason the social rail
   sits at 9500. nav is the logo's stacking context (z 100), so the logo can't clear
   the cursor on its own; the context has to move. Still below the preloader (9999). */
:root.theme-light nav {
  z-index: 9500;
}

/* The masked negative of the latched logo — a white disc with an electric-blue "AS",
   revealed only inside the cursor-tracking circle (--x/--y/--size written by
   updateCursorInverts), the same mask method as .side-social-invert. The parent
   .nav-logo (border-radius:50%; overflow:hidden) clips it to the disc; the mask
   confines it to the cursor circle → a true white<->blue swap as the disc sweeps. */
.nav-logo-invert {
  display: none;
}
:root.theme-light .nav-logo-invert {
  position: absolute;
  inset: 0;
  z-index: 3;                      /* above .nav-logo-face (z-index:2) */
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;                /* white disc */
  color: var(--color-text);       /* electric-blue "AS" (svg fill:currentColor) */
  pointer-events: none;
  --size: 0px;
  --x: 50%;
  --y: 50%;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='50' fill='%23000'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='50' fill='%23000'/%3E%3C/svg%3E");
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: calc(var(--x) - var(--size) / 2) calc(var(--y) - var(--size) / 2);
          mask-position: calc(var(--x) - var(--size) / 2) calc(var(--y) - var(--size) / 2);
  -webkit-mask-size: var(--size) var(--size);
          mask-size: var(--size) var(--size);
}

