/* custom.css — the site's own CSS on top of the Webflow sheet (Lenis,
   Swiper, Safari fixes, accessibility and contrast fixes). Loaded last, the
   same cascade position it had as an inline <style> at the top of <body>. */

/* ============================================
   TABLE OF CONTENTS
   ============================================
   1. Lenis Smooth Scroll
   2. Base Resets & Performance
   3. Logo & SVG Optimization
   4. Layout & Entrance Animations
   5. Typography & Text Styles
   6. Number Counter Components
   7. Interactive Elements
   8. Swiper Components
   9. Safari-Specific Fixes
   10. Animation Utilities
   11. Hero Card Surfaces
   12. Hero Portrait Position
   ============================================ */

/* ============================================
   1. LENIS SMOOTH SCROLL
   ============================================ */
html.lenis,
html.lenis body {
  height: auto;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-smooth [data-lenis-prevent] {
  overscroll-behavior: contain;
}

.lenis.lenis-stopped {
  overflow: hidden;
}

.lenis.lenis-scrolling iframe {
  pointer-events: none;
}

body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}


/* ============================================
   2. BASE RESETS & PERFORMANCE
   ============================================ */
.nesh-logo,
.nesh-logo svg,
.nav-logo-item,
.nesh-copyright-icon,
.nav-button,
.hero-cta-button,
.nav-button-secondary,
.hero-button {
  shape-rendering: geometricPrecision !important;
  will-change: width, height, transform !important;
  transform: translateZ(0);
  -webkit-font-smoothing: antialiased;
  backface-visibility: hidden;
}

.nav-logo-item {
  position: relative !important;
}

/* ============================================
   3. LOGO & SVG OPTIMIZATION
   ============================================ */
.nesh-logo-svg {
  shape-rendering: geometricPrecision;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  transform: translateZ(0);
}

/* ============================================
   4. LAYOUT & ENTRANCE ANIMATIONS
   ============================================ */
/* Hide entrance elements initially - only when a script is there to reveal
   them. html.js-entrance is set in <head> (Site.astro) and dropped if the
   animation engine has not started 4s later, so with JavaScript off, blocked
   or failing, the hero and the nav stay readable instead of invisible. The
   width condition is the one this rule already had in effect: below 767px the
   mobile block further down shows these elements. */
@media (width >= 767px) {
html.js-entrance .profile-img-item,
html.js-entrance .hero-navigation-link,
html.js-entrance .hero-navigation-sep,
html.js-entrance .hero-card-3,
html.js-entrance .hero-cards-left,
html.js-entrance .hero-left-text,
html.js-entrance .hero-right-text,
html.js-entrance .hero-buttons-wrap {
  opacity: 0;
  visibility: hidden;
}

html.js-entrance .hero-heading {
 visibility: hidden;
}
}

  /* ============================================
   DESIGN MODE — reveal hidden entrance elements
   ============================================ */
.wf-design-mode .profile-img-item,
.wf-design-mode .hero-navigation-link,
.wf-design-mode .hero-navigation-sep,
.wf-design-mode .hero-card-3,
.wf-design-mode .hero-cards-left,
.wf-design-mode .hero-left-text,
.wf-design-mode .hero-right-text,
.wf-design-mode .hero-buttons-wrap {
  opacity: 1;
  visibility: visible;
}

/* hero-heading only had visibility:hidden */
.wf-design-mode .hero-heading {
  visibility: visible;
}

/* Line mask for text animations */
.line-mask {
  overflow: hidden;
  display: block;
}

/* ============================================
   5. TYPOGRAPHY & TEXT STYLES
   ============================================ */
.hero-heading,
.nav-webflow-text {
  kerning: none;
}

.hero-webflow-projects-text,
.nav-webflow-text {
  line-height: 1.1 !important;
}

.nav-webflow-text {
  display: block;
}

/* Gradient text styles */
.h2-style {
  background: linear-gradient(266deg, #3d3d3d 11.86%, #000 92.59%);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.h2-style .line {
  background: linear-gradient(266deg, #3d3d3d 11.86%, #000 92.59%);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.h2-style-white {
  background: linear-gradient(89deg, #d5d5d5 7.42%, #fff 95.11%);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.h2-style-white .line {
  background: linear-gradient(89deg, #d5d5d5 7.42%, #fff 95.11%);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.text-color-white {
  color: white !important;
}

/* ============================================
   6. NUMBER COUNTER COMPONENTS
   ============================================ */
[data-number-count] {
  display: inline-block;
  font-variant-numeric: tabular-nums;
}

.number-wrap {
  display: inline-flex;
  line-height: 1;
  overflow: hidden;
  vertical-align: bottom;
}

.digit-mask {
  position: relative;
  overflow: hidden;
  height: 1em;
  width: 0.65em;
  display: block;
}

.digit-track {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  line-height: 1;
  transform: translateZ(0);
  will-change: transform;
}

.digit-track span {
  display: block;
  height: 1em;
  line-height: 1em;
  text-align: center;
}

/* ============================================
   7. INTERACTIVE ELEMENTS
   ============================================ */
/* Work card hover effects */
.work-card:hover {
  opacity: 1;
}


@media (min-width: 992px) {
  /* When any card is hovered, show overlay on ALL cards */
  .work-track:hover .work-card .work-image-overlay {
    opacity: 1 !important;
  }
  /* Undo for the hovered card */
  .work-track:hover .work-card:hover .work-image-overlay {
    opacity: 0 !important;
  }
  /* When any card is hovered, dim ALL arrow wraps */
  .work-track:hover .work-card .work-card-arrow-wrap {
    background-color: #2F2F2F !important;
    color: #8C8C8C !important;
  }
  /* Undo for the hovered card */
  .work-track:hover .work-card:hover .work-card-arrow-wrap {
    background-color: #f97316 !important;
    color: black !important;
  }
}
/* Navigation marquee animation */
.nav-comapny-item {
  display: inline-flex;
  flex-shrink: 0;
  animation: marquee-move 25s linear infinite;
}

@keyframes marquee-move {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-100%);
  }
}

  .nav-email-item:hover .email-text,
  .nav-email-item:hover .clipboard-wrap {
    opacity: 0.35;
  }

/* ============================================
   8. SWIPER COMPONENTS
   ============================================ */
.swiper {
  margin-left: 0 !important;
  margin-right: 0 !important;
  overflow: visible !important;
}

.swiper-pagination {
  width: auto !important;
  display: flex;
  margin-bottom: 1.67vw;
  padding: 0.69vw;
  border: 1px solid rgba(255, 255, 255, 0.2) !important;
  border-radius: 0.56vw;
  position: relative !important;
}

.swiper-bullet.is-active {
  width: 2.5vw;
  background-color: #f97316;
}

.swiper-wrapper {
 cursor: none !Important;
}
/* ============================================
   9. SAFARI-SPECIFIC FIXES
   ============================================ */
/* Scroll blur fix */
[data-tl-to*="blur"] {
  -webkit-transform: translate3d(0, 0, 0);
  transform: translate3d(0, 0, 0);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  -webkit-perspective: 1000px;
  perspective: 1000px;
  will-change: filter, transform, opacity;
}

/* Image blur fix - prevents white borders/flashing */
.hero-profile-img {
  -webkit-transform: translateZ(0) scale(1.001);
  transform: translateZ(0) scale(1.001);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  will-change: filter;
}

/* ============================================
   10. ANIMATION UTILITIES
   ============================================ */
.anim-char {
  transform: translate3d(0, 0, 0);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.capa-card-item:hover .capa-card-arrow {
 rotate: 180deg;
}

.hero-navigation-link.w--current {
 color: black !important;
}

.hero-navigation-link.w--current ~ .nav-item-bg {
  background-color: #f97316 !Important;
}

.hero-navigation-link.w--current ~ .nav-item-icon {
  color: black !Important;
}

.faq-list.w--open .faq-answer-wrap {
 grid-template-rows: 1fr;
}

.faq-toggle.w--open .faq-icon-v-line {
 transform: rotate(90deg);
}

.faq-toggle:hover .faq-icon {
 background-color: #EDECDA;
}

[data-origin] {
  will-change: transform;
}

.nav-button-mask {
  overflow: hidden;
  position: relative;
  padding-left: 0.8vw;
  padding-right: 0.8vw;
}

.nav-button-mask .clone-p {
  position: absolute;
  inset: 0;
  margin-left: auto;
  margin-right: auto;
  padding-left: 0.8vw;
  padding-right: 0.8vw;
  text-align: center;
}

[data-button-hover].is-text-link {
  overflow: hidden;
  position: relative;
}

[data-button-hover].is-text-link .clone-text {
  position: absolute;
  top: 0;
  left: 0;
}

.nav-link:hover ~ .nav-item-bg {
 background-color: #C9C8BA !important;
}

.nav-link.w--current:hover ~ .nav-item-bg {
 background-color: #f97316 !important;
}


.nav-link:hover ~ .nav-item-bg.nav-item-dark {
 background: rgba(94, 94, 94, 0.50)!important;
}

.nav-link.w--current:hover ~ .nav-item-bg.nav-item-dark {
  background-color: #f97316 !important;
}

.nav-link:hover ~ .nav-item-icon {
 color: #f97316 !important;
}

.nav-link.w--current:hover ~ .nav-item-icon {
 color: black !important;
}

	.nav-webflow-bg {
	backdrop-filter: blur(15px) !important;
}

.social-link:hover {
 background-color: #C9C8BA !important;
}

.social-link.social-dark:hover {
 	background-color: #5E5E5E !important;
}

.social-link:hover .social-bg-path {
 color: #f97316 !important;
}

.social-link:hover .social-path-white {
 fill: #000 !important;
}

.popup-close:hover .popup-close-path-1{
  transform: rotate(90deg);
  background-color: white;
}

.popup-close:hover .popup-close-path-2{
  transform: rotate(-90deg);
  background-color: white;
} 

.work-card:hover .work-card-arrow-2 {
  margin: 0%;
}

  .work-card:hover .work-card-arrow {
  margin-left: 100%;
}

/* ============================================
   11. HERO CARD SURFACES
   ============================================

   The hero's three cards - "80+ Projects", "7+ Years of experience" and the
   attribute list - shipped from the capture as #c2b8ac at 30% over the cream
   ground. Composited that is #d0c8b9 against a #d5cfbe page: a 1.07:1 edge, so
   the cards read as smudges rather than objects, and their white text sits on
   them at 1.66:1 - legible only where the card happens to cross the
   photograph. Nothing in the hero except the portrait had any value separation
   at all.

   So the cards become the dark plane and keep everything else where it was.
   Three planes instead of one: cream ground, photograph, ink cards - and the
   yellow finally has something to be an accent against.

   Sampled out of a 1512x900 render, all three cards composite to rgb(44,44,46)
   over the cream, which is also what 0.88 alpha predicts analytically:

                          before      after
       card / ground      1.07:1      8.96:1
       white text / card  1.66:1     13.94:1
       yellow / card      1.55:1     12.99:1

   The Contact button is untouched at 19.58:1.

   12% translucent rather than solid, so backdrop-filter still blurs the
   photograph through the card and they stay part of the image rather than
   sitting on top of it.

   Scope is the hero. .nav-webflow-bg and .nav-experience-bg are in the nav's
   markup but are not nav furniture: GSAP Flip fits them onto the hero's two
   stat cards at the top of the page, and fades them to opacity 0 before the
   sidebar docks (script.js pairs .nav-webflow-bg with .hero-card-2-bg). They
   are the hero cards. The light pill behind the stats in the docked sidebar is
   separate markup and is deliberately left alone.

   The !important on those two is not decoration. Flip writes background-color
   as an inline style on them, which a plain rule cannot reach - the same reason
   the backdrop-filter rule above them in section 3 needs one. .hero-card-1/2/3
   are never given an inline background, so they do not need it.

   Set the four colours below back to #c2b8ac4d and rgba(255,255,255,.2) to
   restore the captured look. */

.hero-card-1,
.hero-card-2,
.hero-card-2-bg,
.hero-card-3 {
  background-color: rgba(21, 22, 26, 0.88);
}

.nav-webflow-bg,
.nav-experience-bg {
  background-color: rgba(21, 22, 26, 0.88) !important;
}

/* A light rim instead of a dark one: on the ink surface this reads as the edge
   catching the page, and it was invisible before. .hero-card-3 has
   `border: 1px #fff3` with no style keyword, so it has no border to colour. */
.hero-card-1,
.hero-card-2-bg,
.nav-webflow-bg,
.nav-experience-bg {
  border-color: rgba(245, 243, 236, 0.18);
}


/* ============================================
   12. HERO PORTRAIT POSITION
   ============================================

   The portrait sat too high: the wordmark's N and I ran straight across the
   eyes and glasses, which is the one part of a portrait that has to stay
   legible. Dropping it 4vh puts the face in the clear band of cream below the
   letters, so the wordmark crosses hair only.

   .profile-img-wrap is `position: fixed; inset: 0%` with the image
   bottom-anchored (align-items: flex-end, object-position: 50% 100%), and the
   image exactly fills the box height - so before this there was ~45px of ground
   above the head and nothing below. Moving it down therefore spends the bottom:
   at 4vh the frame loses 36px at 900px tall, which is trouser, not subject.

   `top` rather than `transform`. The wrap already carries a GSAP transform -
   Sidebar.scale() sets an inverse scale on it to cancel .nav-container's - so a
   transform here would be overwritten. `top` is nobody else's. Measured, a
   top of N px moves the wrap 0.94N to 1.00N depending on that sidebar scale,
   which is close enough that no correction factor is worth the confusion.

   It survives the scroll. Past the hero's midpoint script.js re-parents this
   element to <body> and freezes it with an inline `top: <its current
   rect.top>px !important` - it captures wherever this rule put it rather than
   resetting it - and on the way back up restores the inline cssText it recorded
   at init (empty), handing position back to this rule.

   Desktop and tablet only: the mobile breakpoint sets .profile-img-wrap to
   display:none and uses .mobile-hero-image-wrap, which has its own offset. */

.profile-img-wrap {
  top: 4vh;
}


/* ============================================
   MOBILE STYLES
   ============================================ */

@media (width < 767px) {
  /* ============================================
   4. LAYOUT & ENTRANCE ANIMATIONS
   ============================================ */
      /* Hide entrance elements initially */
      .profile-img-wrap,
      .hero-navigation-link,
      .hero-navigation-sep,
      .nav-stats-card,
      .hero-cards-left,
      .hero-card-3,
      .hero-cards-wrap,
      .hero-left-text,
      .hero-right-text,
      .hero-buttons-wrap {
        opacity: 1;
        visibility: visible;
      }
      
      .hero-heading {
         visibility: visible;
        }
        
      
      .swiper-pagination {
        width: auto !important;
        display: flex;
        margin-bottom: 0vw;
        padding: clamp(0.53rem, 2.67vw, 1.28rem);
        border: 1px solid rgba(255, 255, 255, 0.2) !important;
        clamp(0.43rem, 2.13vw, 1.02rem);
        position: relative !important;
      }
      
      .swiper-bullet.is-active {
          width: clamp(1.92rem, 9.6vw, 4.61rem);
          background-color: #f97316;
			}
      
      .capa-card-item:hover .capa-card-arrow {
           rotate: 0deg;
          }
          
      .faq-toggle:hover .faq-icon {
         background-color: transparent;
        }
}


/* ============================================
   13. ACCESSIBILITY
   ============================================ */

/* The page's <h1> wraps the hero tagline without becoming a layout box, so
   the tagline stays the flex child the Webflow sheet positions. The name it
   adds is the text alternative of the NAINIAA wordmark, which is an SVG. */
.hero-h1 { display: contents; font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit; }
.hero-h1 .hero-left-text { display: block; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Timeline captions ("@fst / 4 years ago"): black at 50% on the card's
   #dddbcb measured 3.68:1. 56% is the AA minimum (4.5:1); 58% leaves margin. */
.about-card-bottom-text { color: rgba(0, 0, 0, 0.58); }

/* Large bold text, so WCAG AA asks 3:1. The timeline years were the brand
   yellow (#f97316) on the card's #dddbcb, 1.29:1; this is the same 60-degree
   hue, darkened to 3.22:1. The CTA's light words were white at 65% (#f0eee8)
   on #d5cfbe, 1.34:1; this is a grey in the background's own hue, 3.20:1, and
   the outline follows the fill so it no longer lightens the edges. */
.about-card-year { color: #7b7b00; }
.cta-span-heading { color: #766f60; -webkit-text-stroke-color: #766f60; }

/* The Webflow sheet starts the sidebar nav at opacity 0 for GSAP to reveal.
   Without the engine (see html.js-entrance, section 4) it stays readable. */
html:not(.js-entrance) .nav-container { opacity: 1; }

/* Controls revealed by scroll (GSAP entrance: opacity 0, scale < 1) could be
   reached with Tab while still invisible - the sidebar's LinkedIn and email
   before the hero has scrolled, a timeline "Read more", a project card, the
   CTA's "Let's Talk" (0x0 for ~2s). Keyboard focus shows them at once, in the
   state their animation ends in (opacity 1, no transform - measured on every
   one), so the focus ring is on something visible. Pointer and scroll users
   keep the animation. */
.social-link:focus-visible,
.nav-email-wrap:has(:focus-visible),
.about-card:has(:focus-visible),
.about-card-button:focus-visible,
.work-card:focus-visible,
.cta-button-grid-item:has(:focus-visible) {
  opacity: 1 !important;
  transform: none !important;
  visibility: visible !important;
  transition: none !important; /* .work-card fades opacity over .4s */
}

/* One focus ring for every control. The Webflow sheet sets outline:0 on its
   dropdown toggles (the FAQ), which left them focusable but invisible. Black
   over a yellow halo reads on the light beige and on the dark cards alike. */
a:focus-visible, button:focus-visible, [tabindex]:focus-visible, [role="button"]:focus-visible {
  outline: 2px solid #111; outline-offset: 3px; box-shadow: 0 0 0 5px #f97316;
}

/* Popup close control: a <button> now, so the browser defaults go and the
   Webflow .popup-close box stays what it was. */
button.popup-close { appearance: none; border: 0; padding: 0; }
.popup-close-path-1, .popup-close-path-2 { display: block; }

/* Hit areas of at least 44px on touch screens, without changing what is
   drawn: the pseudo-element extends the element's own box. */
@media (pointer: coarse) {
  /* .nav-link is already position:absolute; only the static one needs a box. */
  .about-card-button { position: relative; }
  /* The menu's text links are 18.7px tall: taller box, same line. */
  .nav-menu .hero-navigation-link { padding-block: 13px; margin-block: -13px; }
  .nav-link::after, .nav-button-mobile::after, .about-card-button::after {
    content: ""; position: absolute; left: 0; right: 0; top: 50%;
    height: max(100%, 44px); transform: translateY(-50%);
    /* A generic family: the empty box must not fetch the element's webfont. */
    font: 0/0 sans-serif;
  }
}

/* The address scaled with the viewport while its box's padding did too, so
   it was clipped at every width from 768px up. It now shrinks to fit its box:
   in Hanken Grotesk the address is 13.1em wide, so 7.1 container units leaves
   a little air, never below 11px; only where 11px cannot fit does it break
   after the @ (Nav.astro). */
.nav-email-item { container-type: inline-size; }
.nav-email-item .email-text { font-size: max(11px, min(1em, 7.1cqi)); text-align: center; }

/* The captured stylesheet defines its accent as --yellow. Keeping that
   contract avoids disturbing its responsive layout and GSAP timelines while
   making every variable-driven accent state use the portfolio orange. */
body { --yellow: #f97316; }

/* A few captured components use literal yellow rather than --yellow. These
   narrow overrides cover those accents without changing their sizing, motion,
   or responsive positioning. */
.experience-number,
.nav-experience-numb { color: #f97316 !important; }
.hero-cta-button,
.hero-button,
.cta-button { background-color: #f97316 !important; }

