/* ============================================================
   LINKEDIN IN-APP BROWSER (IAB) — COMPATIBILITY FIXES
   ============================================================
   Scope: All rules below are scoped to body.linkedin-iab
   Impact: Zero effect on any other browser or device.

   LinkedIn's iOS IAB is a WKWebView; Android IAB is a Chrome
   WebView. Both share these quirks vs. real mobile browsers:

   1. `svh` viewport units unsupported → hero/modal collapse
   2. `backdrop-filter` unreliable / silently broken
   3. CSS `@keyframe` animations that start at opacity:0 can
      freeze if the loading-screen JS finishes mid-paint
   4. `mix-blend-mode: difference` renders the custom cursor
      invisible (blend compositing disabled in WebView)
   5. `cursor: none` on <body> can suppress tap-highlight
      feedback on some WebView builds
   6. `@view-transition` at-rule throws a parse warning that
      can stall CSS processing on older WebViews
   7. `backdrop-filter` on `.modal-backdrop` must fall back
      to a solid semi-transparent colour so the overlay is
      actually visible when a project card is tapped
   ============================================================ */


/* ── 1. Fix `svh` units: hero height ──────────────────────── */
/* Hero uses `height: 100svh`. In LinkedIn IAB, svh is treated
   as 0 or falls back to nothing → hero has zero height.
   Replace with a safe 100vh (the IAB chrome is stable). */
body.linkedin-iab .hero {
  height: 100vh;
  height: 100dvh; /* progressive enhancement if supported */
  min-height: 600px;
}


/* ── 2. Fix `svh` units: modal panel height ───────────────── */
/* modal.css uses `height: 92svh` for the mobile modal body */
@media (max-width: 768px) {
  body.linkedin-iab .modal-body {
    height: 92vh;
    max-height: 92vh;
  }
}


/* ── 3. Fix backdrop-filter: nav scrolled state ───────────── */
/* The nav's `.scrolled` state relies on backdrop-filter blur.
   In LinkedIn IAB the blur is a no-op, leaving the nav
   transparent over content. Swap in a solid background. */
body.linkedin-iab .site-nav.scrolled {
  background: rgba(13, 13, 13, 0.97) !important;
  /* Disable the transition that animates backdrop-filter so
     the broken property doesn't cause a flash */
  transition: background 200ms ease !important;
}


/* ── 4. Fix backdrop-filter: modal overlay ────────────────── */
/* Without blur, the modal backdrop needs an opaque dark tone
   so the overlay is actually visible and the panel readable. */
body.linkedin-iab .modal-backdrop.is-open {
  background: rgba(6, 6, 6, 0.92) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
body.linkedin-iab .modal-backdrop {
  /* Remove the animated blur transition to avoid stutter */
  transition: background 0.45s ease !important;
}


/* ── 5. Fix mix-blend-mode: custom cursor invisible ──────────
   The cursor dot uses mix-blend-mode:difference which is
   composited on the GPU; LinkedIn IAB disables GPU compositing
   for blend modes, making the cursor invisible.
   Fall back to the accent colour without blending. */
body.linkedin-iab .cursor {
  mix-blend-mode: normal !important;
  background: #c9b99a !important; /* var(--accent) */
}


/* ── 6. Ensure cursor:none doesn't suppress touch feedback ───
   Some WKWebView builds propagate cursor:none on body to
   suppress the iOS tap highlight ring, making interactive
   elements feel unresponsive. Re-enable for touch targets. */
body.linkedin-iab {
  cursor: auto !important;
}
body.linkedin-iab .cursor,
body.linkedin-iab .cursor-ring {
  display: none !important;
}
body.linkedin-iab .cursor-toggle-btn {
  display: none !important;
}
/* Restore pointer cursors on interactive elements */
body.linkedin-iab a,
body.linkedin-iab button,
body.linkedin-iab [role="button"],
body.linkedin-iab .work-card,
body.linkedin-iab .skill-item,
body.linkedin-iab .contact-link-item {
  cursor: pointer !important;
  -webkit-tap-highlight-color: rgba(201, 185, 154, 0.2);
}


/* ── 7. Ensure hero content is always visible ─────────────── */
/* In LinkedIn IAB, JS-driven loading screens can silently
   stall (especially on first cold launch), leaving
   .hero-title-line elements permanently at opacity:0.
   We don't skip the animation — instead we ensure a
   fallback transition kicks in after a generous delay. */
body.linkedin-iab .hero-title-line {
  /* Keep the slide-up animation; add a fallback that fires
     after 4s in case the main loading JS hasn't completed */
  animation:
    slideUp 0.9s cubic-bezier(0.16, 1, 0.3, 1) forwards,
    linkedinIabReveal 0.5s ease 4s forwards;
}
body.linkedin-iab .hero-title-line:nth-child(1) {
  animation-delay: 0.5s, 4s;
}
body.linkedin-iab .hero-title-line:nth-child(2) {
  animation-delay: 0.65s, 4s;
}
body.linkedin-iab .hero-title-line:nth-child(3) {
  animation-delay: 0.8s, 4s;
}

@keyframes linkedinIabReveal {
  to { opacity: 1; transform: translateY(0); }
}

/* Same treatment for hero eyebrow labels */
body.linkedin-iab .hero-eyebrow .label {
  animation:
    slideUp 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.3s forwards,
    linkedinIabReveal 0.5s ease 4s forwards;
}

/* And the hero meta / scroll hint */
body.linkedin-iab .hero-meta {
  animation:
    fadeIn 0.8s cubic-bezier(0.16, 1, 0.3, 1) 1.2s forwards,
    linkedinIabReveal 0.5s ease 4s forwards;
}


/* ── 8. Reveal elements even if IntersectionObserver lags ────
   LinkedIn IAB can throttle IntersectionObserver callbacks
   while its chrome UI is animating in. Elements with class
   `.reveal` that never get `.revealed` stay invisible.
   After a 3.5s safety delay, force all reveals visible. */
body.linkedin-iab .reveal,
body.linkedin-iab .stagger-grid > * {
  transition:
    opacity 0.7s ease,
    transform 0.7s ease;
}

/* CSS-only fallback: after 3.5s, animate all .reveal in */
body.linkedin-iab .reveal {
  animation: linkedinIabReveal 0.6s ease 3.5s forwards;
}
body.linkedin-iab .stagger-grid > *:nth-child(1) { animation: linkedinIabReveal 0.6s ease 3.6s forwards; }
body.linkedin-iab .stagger-grid > *:nth-child(2) { animation: linkedinIabReveal 0.6s ease 3.75s forwards; }
body.linkedin-iab .stagger-grid > *:nth-child(3) { animation: linkedinIabReveal 0.6s ease 3.9s forwards; }
body.linkedin-iab .stagger-grid > *:nth-child(4) { animation: linkedinIabReveal 0.6s ease 4.05s forwards; }
body.linkedin-iab .stagger-grid > *:nth-child(5) { animation: linkedinIabReveal 0.6s ease 4.2s forwards; }
body.linkedin-iab .stagger-grid > *:nth-child(6) { animation: linkedinIabReveal 0.6s ease 4.35s forwards; }

/* If IntersectionObserver does fire and adds .revealed, use
   that immediately (transition wins over the delayed anim) */
body.linkedin-iab .reveal.revealed,
body.linkedin-iab .stagger-grid.revealed > * {
  opacity: 1 !important;
  transform: translateY(0) !important;
  animation: none !important;
}


/* ── 9. nav-logo / nav-links visibility fallback ─────────── */
/* These start at opacity:0 and become visible via JS after
   the loading screen finishes. Same fallback as hero. */
body.linkedin-iab .nav-logo,
body.linkedin-iab .nav-links {
  animation: linkedinIabReveal 0.6s ease 4s forwards;
}
body.linkedin-iab .nav-logo.visible,
body.linkedin-iab .nav-links.visible {
  opacity: 1 !important;
  transform: translateY(0) !important;
  animation: none !important;
}


/* ── 10. Suppress @view-transition side effects ───────────── */
/* The @view-transition at-rule in transitions.css can produce
   a brief white flash on first navigation in some WebViews.
   Override the generated pseudo-element animations to no-ops.*/
body.linkedin-iab::view-transition-old(root),
body.linkedin-iab::view-transition-new(root) {
  animation: none !important;
}
