/* ==========================================================================
   Jose Macena — portfolio
   Static rebuild of the Figma Make prototype. GSAP + ScrollTrigger + Lenis.
   ========================================================================== */

/* ---------- Typeface (self-hosted) ---------- */

@font-face {
  font-family: "Faculty Glyphic";
  src: url("assets/fonts/faculty-glyphic-400.woff2") format("woff2");
  font-weight: 400;
  font-display: block;
}

:root {
  --black: #000;
  --white: #fff;
  --placeholder: #d9d9d9;

  --pad: clamp(1rem, 2.2vw, 2.4rem);
  --frame-inset: max(1rem, 2.2vw);

  --fs-nav: clamp(0.95rem, 2.32vw, 2.5rem);
  --fs-display: clamp(1.6rem, 3.7vw, 4rem);
  --fs-small: clamp(0.7rem, 1.16vw, 1.25rem);

  --ease-in-out: cubic-bezier(0.7, 0, 0.2, 1);
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);

  --tap: 44px;

  --font: "Faculty Glyphic";
  --fw: 400;
  --tracking: -0.02em;

  font-family: var(--font), "Helvetica Neue", Arial, sans-serif;
  font-weight: var(--fw);
  font-synthesis: none;
  color: var(--black);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* ---------- Reset ---------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scrollbar-width: thin;
  -webkit-text-size-adjust: 100%;
}

/* Native smooth anchor scroll only when Lenis isn't running */
html:not(.lenis) {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  overflow-x: clip;
  background: var(--white);
}

h1,
h2,
p,
ul {
  margin: 0;
  padding: 0;
  font: inherit;
}

ul {
  list-style: none;
}

img {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 4px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  z-index: 100;
  top: 0.5rem;
  left: 0.5rem;
  padding: 0.6rem 0.9rem;
  color: var(--white);
  background: var(--black);
  font-size: 0.875rem;
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: none;
}

/* ---------- Nav link (roll + underline) ---------- */

.nav-link {
  position: relative;
  display: inline-block;
}

/* Expand the tap target without changing layout */
.nav-link::before {
  content: "";
  position: absolute;
  inset: -0.75rem -0.5rem;
}

.nav-link__roll {
  position: relative;
  display: inline-grid;
  overflow: hidden;
  padding-bottom: calc(0.08em + 2px); /* underline sits 2px further from the word */
  margin-bottom: -2px; /* ...without moving anything else */
}

.nav-link__roll > span {
  grid-area: 1 / 1;
  transition: transform 0.5s var(--ease-in-out);
}

.nav-link__roll > span:last-child {
  transform: translateY(125%);
  font-style: italic;
}

.nav-link__roll::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 0.08em;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.5s var(--ease-in-out);
}

@media (hover: hover) {
  .nav-link:hover .nav-link__roll > span:first-child {
    transform: translateY(-125%);
  }

  .nav-link:hover .nav-link__roll > span:last-child {
    transform: translateY(0);
  }

  .nav-link:hover .nav-link__roll::after {
    transform: scaleX(1);
    transform-origin: left;
  }
}

.nav-link:focus-visible .nav-link__roll::after {
  transform: scaleX(1);
}

/* ---------- Header ---------- */

.site-header {
  position: fixed;
  z-index: 50;
  inset: 0 0 auto;
  padding: clamp(1rem, 1.6vw, 1.75rem) var(--pad) 0;
  padding-top: max(clamp(1rem, 1.6vw, 1.75rem), env(safe-area-inset-top));
  color: var(--white);
  mix-blend-mode: difference;
  pointer-events: none;
  transition: transform 0.55s var(--ease-out);
}

.site-header.is-hidden {
  transform: translateY(-100%);
}

.site-header__nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 1rem;
  align-items: start;
  font-size: var(--fs-nav);
  letter-spacing: -0.02em;
  line-height: 1;
}

.site-header__nav > * {
  pointer-events: auto;
}

.site-header__nav > :nth-child(2) {
  justify-self: center;
}

.site-header__nav > :last-child {
  justify-self: end;
}

/* ---------- Wordmark ---------- */

.wordmark-wrap {
  position: relative;
  width: 100%;
  line-height: 0;
}

.wordmark {
  position: relative;
  display: inline-block;
  font-size: 23vw; /* replaced by JS fit-to-width */
  letter-spacing: var(--tracking);
  line-height: 0.74;
  white-space: nowrap;
}

/* Mask for the rise-in animation. Generous side and bottom insets so glyph
   tips (the A's right foot) and round overshoot (the C's bottom) are never
   cut, even with negative letter-spacing shrinking each letter's box. */
.wordmark__letter {
  display: inline-block;
  padding-top: 0.04em;
  vertical-align: top;
  clip-path: inset(-0.3em -0.3em -0.1em -0.3em);
}

.wordmark__letter > span {
  display: inline-block;
  transform-origin: left bottom;
}

/* Hero hover effect: the WebGL canvas stands in for the text while active */
.wordmark-fx {
  position: absolute;
  z-index: 1;
  display: none;
  pointer-events: none;
}

.wordmark-wrap.is-fx .wordmark-fx {
  display: block;
}

.wordmark-wrap.is-fx .wordmark {
  color: transparent;
}

/* Zero-size marker whose offsetTop is the C's baseline */
.wordmark__probe {
  display: inline-block;
  width: 0;
  height: 0;
  vertical-align: baseline;
}

/* ---------- Hero ---------- */

.hero {
  position: relative;
  /* 75% of the travel expands the image, the rest holds it full-bleed */
  height: 260svh;
}

.hero__stage {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
}

/* Invisible box that defines the small, pre-scroll image position */
.hero__target {
  position: absolute;
  top: 40%;
  left: 50%;
  width: clamp(17.5rem, 23.55vw, 25.44rem);
  height: clamp(11.5rem, 15.45vw, 16.7rem);
  translate: -50% -50%;
  visibility: hidden;
  pointer-events: none;
}

/* ---------- Landing intro overlay ---------- */

.intro {
  position: fixed;
  z-index: 90;
  inset: 0;
  display: none;
  place-items: center;
  overflow: hidden;
  background: var(--white);
}

.is-loading .intro,
.intro.is-active {
  display: grid;
}

.is-repeat .intro {
  display: none !important;
}

.intro__row {
  display: flex;
  align-items: center;
  font-size: clamp(2.4rem, 11vw, 13rem);
  letter-spacing: var(--tracking);
  line-height: 0.8;
  white-space: nowrap;
}

.intro__word {
  display: inline-flex;
  padding-block: 0.08em 0.08em;
  /* mask top/bottom for the rise; sides stay open so glyph tips aren't cut */
  clip-path: inset(0 -0.3em);
}

.intro__word > span {
  display: inline-block;
}

/* Final inline size; JS starts it wide and closes it in */
.intro__media {
  position: relative;
  flex: none;
  width: 1.2em;
  height: 0.72em;
  margin-inline: 0.08em;
  overflow: hidden;
  background: var(--placeholder);
}

.intro__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.intro__count {
  position: absolute;
  left: var(--pad);
  bottom: max(var(--pad), env(safe-area-inset-bottom));
  display: flex;
  gap: 0.5em;
  overflow: hidden;
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.intro__count > span {
  display: inline-block;
}

/* Pre-intro states, so nothing flashes before GSAP takes over */
.is-loading [data-letter] {
  transform: translateY(135%);
}

.is-loading [data-intro-letter] {
  transform: translateY(110%);
}

.is-loading .availability,
.is-loading .site-header__nav > a {
  opacity: 0;
}

/* The frame is always full size; JS clips it down to the target box */
.hero__frame {
  position: absolute;
  z-index: 2;
  inset: var(--frame-inset);
  overflow: hidden;
  background: var(--placeholder);
}

.js .hero__frame {
  visibility: hidden;
}

.hero__slides {
  position: absolute;
  inset: 0;
  transform-origin: 50% 50%;
  will-change: transform;
}

.hero__slide {
  position: absolute;
  /* 6% bleed top and bottom so the scroll parallax never shows an edge */
  inset: -6% 0;
  width: 100%;
  height: 112%;
  object-fit: cover;
  user-select: none;
  -webkit-user-drag: none;
}

.hero__slide:first-child {
  z-index: 1;
}

.hero__intro {
  position: absolute;
  z-index: 4;
  inset: auto 0 0;
  padding: 0 var(--pad) max(var(--pad), env(safe-area-inset-bottom));
}

.hero__links {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: calc(max(0.4vw, 0.4rem) + 6px);
}

.hero__link {
  display: inline-block;
  padding-bottom: 2px;
  font-size: var(--fs-small);
  letter-spacing: 0;
  white-space: nowrap;
  background: linear-gradient(currentColor, currentColor) left bottom / 0 2px no-repeat;
  transition: background-size 0.4s var(--ease-in-out);
}

.hero__link:hover,
.hero__link:focus-visible {
  background-size: 100% 2px;
}

/* Thin arrow: an SVG line drawing, about the weight of the type */
.arrow {
  width: 0.8em;
  height: 0.8em;
  margin-left: 0.15em;
  vertical-align: -0.02em;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
  stroke-linecap: butt;
  stroke-linejoin: miter;
}

/* ---------- Project viewer ---------- */

.project-ui {
  position: absolute;
  z-index: 5;
  inset: 0;
  color: var(--white);
  background: linear-gradient(0deg, rgb(0 0 0 / 0.5), transparent 45%);
  touch-action: pan-y; /* vertical scroll stays native; horizontal = swipe */
}

.js .project-ui {
  visibility: hidden;
  opacity: 0;
}

.project-ui__copy {
  position: absolute;
  z-index: 1;
  left: clamp(1.25rem, 2.85vw, 2.95rem);
  bottom: clamp(1.25rem, 3vw, 3.125rem);
  display: flex;
  width: min(56.5%, 58rem);
  flex-direction: column;
  gap: clamp(0.75rem, 2vw, 2.125rem);
  line-height: 1;
  pointer-events: none;
}

.project-ui__client {
  font-size: var(--fs-nav);
  letter-spacing: -0.02em;
}

.project-ui__blurb {
  font-size: var(--fs-display);
  letter-spacing: -0.01em;
  line-height: 1;
  text-wrap: balance;
}

/* SplitText line masks. Each mask is exactly one line tall, so it clipped
   descenders, accents and any glyph taller than the line box. Pad the clip
   area on all four sides and cancel it with negative margins, so the layout
   doesn't move. (The reveal tweens travel far enough to stay hidden.) */
.line-mask {
  padding: 0.25em 0.15em;
  margin: -0.25em -0.15em;
}

.project-ui__controls {
  position: absolute;
  z-index: 2;
  right: clamp(1.25rem, 2.85vw, 2.95rem);
  bottom: clamp(1.25rem, 3vw, 3.125rem);
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.project-ui__count {
  min-width: 2.6em;
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.project-ui__btn {
  display: grid;
  place-items: center;
  width: var(--tap);
  height: var(--tap);
  border-radius: 50%;
}

.project-ui__btn img {
  width: 1.1rem;
  height: auto;
  filter: invert(1);
}

.project-ui__btn--prev img {
  transform: rotate(-90deg);
}

.project-ui__btn--next img {
  transform: rotate(90deg);
}

.project-ui__btn:active {
  background: rgb(255 255 255 / 0.15);
}

/* Each half of the image is a hit zone on pointer devices */
.project-ui__zone {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50%;
  cursor: none;
}

.project-ui__zone--prev {
  left: 0;
}

.project-ui__zone--next {
  right: 0;
}

.project-ui__zone:focus-visible {
  outline-offset: -8px;
}

.project-ui__cursor {
  position: absolute;
  z-index: 3;
  top: 0;
  left: 0;
  visibility: hidden;
  pointer-events: none;
}

.project-ui__cursor img {
  width: clamp(2.5rem, 4.17vw, 4.5rem);
  height: auto;
  filter: invert(1) drop-shadow(0 1px 5px rgb(0 0 0 / 0.4));
}

/* Pointer devices: cursor + zones; hide the touch buttons */
@media (hover: hover) and (pointer: fine) {
  .project-ui__btn {
    display: none;
  }
}

/* Touch devices: swipe, tap either side of the image, or use the buttons.
   The side zones stay (invisible, under the copy and buttons); only the
   custom cursor goes. */
@media not ((hover: hover) and (pointer: fine)) {
  .project-ui__cursor {
    display: none;
  }
}

/* ---------- About ---------- */

.about {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(1.5rem, 2.5vw, 2.75rem);
  padding: clamp(13rem, 21vw, 25rem) clamp(1.25rem, 6.9vw, 8.25rem) clamp(14rem, 23vw, 28rem);
  text-align: center;
}

.about__portrait {
  position: absolute;
  z-index: 2;
  top: 0;
  left: 0;
  width: clamp(8.8rem, 14.3vw, 15.4rem); /* +10% */
  aspect-ratio: 339 / 369;
  overflow: hidden;
  pointer-events: none;
  background: var(--placeholder);
  visibility: hidden;
}

.about__portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.05);
}

.about__label,
.about__copy {
  position: relative;
  z-index: 3;
}

.about__label {
  font-size: var(--fs-nav);
  letter-spacing: -0.02em;
}

.about__copy {
  max-width: 78.5rem;
  font-size: clamp(1.6rem, 3.7vw, 4rem);
  letter-spacing: -0.01em;
  line-height: 1.03;
  /* balance where the browser supports it (short paragraphs), pretty as the
     fallback; the last two words are also tied together in the HTML */
  text-wrap: balance;
}

@supports not (text-wrap: balance) {
  .about__copy {
    text-wrap: pretty;
  }
}

/* Desktop: portrait follows the cursor, text inverts over it */
@media (hover: hover) and (pointer: fine) and (min-width: 768px) {
  .about {
    cursor: crosshair;
  }

  .about__label,
  .about__copy {
    color: var(--white);
    mix-blend-mode: difference;
  }
}

/* Touch / small screens: portrait sits statically above the copy */
@media not ((hover: hover) and (pointer: fine) and (min-width: 768px)) {
  .about {
    padding-block: 9rem 10rem;
  }

  .about__portrait {
    position: relative;
    order: -1;
    width: min(56vw, 15rem);
    margin-bottom: 0.5rem;
    visibility: visible;
  }

  .about__copy {
    line-height: 1.05;
  }
}

/* ---------- Experience ---------- */

.experience {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(2rem, 3.6vw, 3.875rem);
  padding: 0 clamp(1rem, 1.4vw, 1.5rem) clamp(5rem, 7.75vw, 8.375rem);
  font-size: var(--fs-nav);
  letter-spacing: -0.02em;
  line-height: 1;
}

.experience__list {
  width: 100%;
  text-transform: uppercase;
}

.experience__row {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1rem;
  min-height: clamp(4rem, 6.4vw, 6.875rem);
  border-top: 4px solid var(--black);
  white-space: nowrap;
  transition:
    background-color 0.3s,
    color 0.3s,
    padding 0.4s var(--ease-in-out);
}

.experience__studio {
  text-align: center;
}

.experience__years {
  text-align: right;
}

@media (hover: hover) {
  a.experience__row:hover {
    padding-inline: clamp(0.5rem, 1vw, 1rem);
    color: var(--white);
    background: var(--black);
  }
}

/* ---------- Footer ---------- */

.footer {
  position: relative;
  display: flex;
  min-height: 68svh; /* 20% shorter than the original 85svh */
  flex-direction: column;
  justify-content: flex-end;
  padding: 0 var(--pad) max(clamp(1.4rem, 2.6vw, 2.8rem), env(safe-area-inset-bottom));
  overflow: hidden;
  color: var(--white);
  background: var(--black);
}

.footer__meta {
  /* Above the wordmark: its tall letter boxes otherwise sit on top of
     this row and swallow the clicks */
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 1rem;
  align-items: baseline;
  margin-top: clamp(0.75rem, 1.1vw, 1.3rem); /* close under MACENA */
  font-size: var(--fs-small);
  letter-spacing: 0;
  line-height: 1.1;
  text-transform: uppercase;
}

.footer__meta > :nth-child(2) {
  font-variant-numeric: proportional-nums;
  text-align: center;
}

.footer__meta > :last-child {
  text-align: right;
}

.footer__meta a {
  text-decoration: none;
  transition: opacity 0.25s;
}

.footer__meta a:hover,
.footer__meta a:focus-visible {
  opacity: 0.55;
}

/* The footer wordmark is decorative: never let it intercept the pointer */
.footer .wordmark {
  pointer-events: none;
}

.footer__nav {
  position: absolute;
  top: var(--pad);
  left: var(--pad);
  right: var(--pad);
  display: grid;
  grid-template-columns: 1fr auto 1fr; /* LinkedIn left, Contact centre, Instagram right */
  gap: 1rem;
  align-items: start;
  font-size: var(--fs-nav);
  letter-spacing: -0.02em;
  line-height: 1;
}

.footer__nav > :nth-child(2) {
  justify-self: center;
}

.footer__nav > :last-child {
  justify-self: end;
}

/* ==========================================================================
   Mobile
   ========================================================================== */

@media (max-width: 767px) {
  :root {
    --pad: 1rem;
    --fs-nav: calc(0.95rem * 1.05); /* nav + ABOUT label: +5% */
  }

  /* Hero: shorter travel, larger preview so the first screen isn't empty */
  .hero {
    height: 230svh;
  }

  /* Portrait preview: closer to the tall full-bleed frame, so less is cropped */
  .hero__target {
    top: 42%;
    width: 62vw;
    height: min(78vw, 46svh);
  }

  .hero__links {
    margin: -0.95rem -0.7rem calc(-0.45rem + 4px) -0.7rem;
  }

  .hero__link {
    /* ~44px-tall tap areas around both 12px labels, layout unchanged */
    padding: 0.95rem 0.7rem calc(0.95rem + 2px);
    font-size: 0.75rem;
    background-origin: content-box;
    background-position: left 0 bottom -2px;
  }

  .availability {
    /* Align with the M's stem rather than its slightly wider foot serif. */
    padding-left: calc(0.7rem + var(--wm-size, 0px) * 0.018);
  }

  .project-ui {
    background: linear-gradient(0deg, rgb(0 0 0 / 0.6), transparent 55%);
  }

  .project-ui__copy {
    left: 1rem;
    right: 1rem;
    bottom: calc(1rem + var(--tap) + 0.5rem);
    width: auto;
    gap: 0.6rem;
  }

  .project-ui__client {
    font-size: calc(0.875rem * 1.05);
  }

  .project-ui__blurb {
    font-size: clamp(1.35rem, 6.48vw, 1.89rem); /* -10% */
    line-height: 1.02;
  }

  /* Controls become a full-width bar: count left, arrows right */
  .project-ui__controls {
    left: 0.25rem;
    right: 0.25rem;
    bottom: 0.5rem;
    justify-content: space-between;
  }

  .project-ui__count {
    order: -1;
    padding-left: 0.75rem;
    text-align: left;
    font-size: 0.8rem;
  }

  .project-ui__btn--prev {
    margin-left: auto;
  }

  .about__copy {
    font-size: clamp(1.35rem, 6.66vw, 1.98rem); /* -10% */
  }

  /* Experience: studio leads, years right, role as a quiet second line */
  .experience {
    gap: 1.5rem;
    padding-bottom: 4rem;
    font-size: 1.15rem;
  }

  .experience__label {
    font-size: calc(0.95rem * 1.05);
  }

  .experience__row {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "studio years"
      "role   role";
    align-items: baseline;
    row-gap: 0.35rem;
    column-gap: 0.75rem;
    min-height: 0;
    padding-block: 0.85rem 0.95rem;
  }

  .experience__studio {
    grid-area: studio;
    text-align: left;
  }

  .experience__years {
    grid-area: years;
    font-size: 0.875rem;
  }

  .experience__role {
    grid-area: role;
    font-size: 0.7rem;
    letter-spacing: 0;
  }

  /* Footer: nav flows above the wordmark; 20% shorter than before (60svh) */
  .footer {
    min-height: 48svh;
    justify-content: flex-start;
    padding-top: 1.25rem;
  }

  /* Wordmark and the row under it sit together at the bottom */
  .footer__wordmark-wrap {
    margin-top: auto;
  }

  .footer__nav {
    position: static;
    font-size: calc(0.8rem * 1.05);
  }

  /* "SITE BY / TOMÁS LOURO" left, the clock in the middle,
     "COLOPHON: / FACULTY GLYPHIC" right */
  .footer__meta {
    margin-top: 0.7rem;
    grid-template-columns: 1fr auto 1fr;
    gap: 0.5rem;
    align-items: start;
    font-size: 0.55rem;
    line-height: 1.25;
  }

  .footer__meta > :nth-child(2) {
    text-align: center;
  }

  .footer__meta > :last-child {
    text-align: right;
  }

  .footer__meta a {
    display: block;
  }

  /* Small type on mobile: no letter-spacing */
  .site-header__nav,
  .footer__nav,
  .project-ui__client,
  .about__label,
  .experience,
  .experience__label {
    letter-spacing: 0;
  }

  /* Full-bleed viewer starts below the nav so the links never sit on the image */
  .hero__frame {
    inset: calc(max(1rem, env(safe-area-inset-top)) + 1.9rem) var(--frame-inset) var(--frame-inset);
  }
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
  }

  html:not(.lenis) {
    scroll-behavior: auto;
  }
}

/* ---------- Toast (e.g. "email copied") ---------- */

.toast {
  position: fixed;
  z-index: 120;
  left: 50%;
  bottom: max(1.5rem, env(safe-area-inset-bottom));
  padding: 0.7rem 1rem;
  color: var(--white);
  background: var(--black);
  font-size: var(--fs-small);
  letter-spacing: 0;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
  transform: translate(-50%, 0.75rem);
  pointer-events: none;
  transition:
    opacity 0.3s,
    transform 0.4s var(--ease-out);
}

.toast.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
}
