/* ═══════════════════════════════════════════════
   ANASTASIA BAULA — components.css
   Masthead · index menu · buttons · placeholders
   ═══════════════════════════════════════════════ */

/* ── Masthead ──────────────────────────────── */
.masthead {
  position: fixed;
  top: 0;
  left: 0; right: 0;
  z-index: 120;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  /* the circle sits on the page's outer gutter — same inset top & right */
  padding: var(--gutter);
  color: #fff;
  pointer-events: none;
}
.masthead > * { pointer-events: auto; }
@media (max-width: 900px) {
  /* phones: the previous, deeper top inset (22px ruler offset + pad) */
  .masthead { padding-top: calc(22px + clamp(1rem, 2.5vw, 1.75rem)); }
}

/* one toggle everywhere: the frosted circle — two bars becoming an ✕ */
.index-toggle {
  width: 52px;
  height: 52px;
  display: grid;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--bone) 22%, transparent);
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 9%, transparent);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.index-toggle .index-toggle__label { display: none; }
.index-toggle__icon {
  display: grid;
  gap: 5px;
  width: 22px;
  transition: transform .55s var(--ease-out), width .5s var(--ease-out);
  will-change: transform; /* own layer — Safari re-rasters backdrop-filter
                             content on scroll and freezes the morph */
}
.index-toggle__icon i {
  height: 2px; /* even bar weight at every pixel density */
  background: #fff;
  will-change: transform;
  transition: transform .4s var(--ease-out);
  transform-origin: center;
}
.index-toggle[aria-expanded="true"] .index-toggle__icon i:first-child { transform: translateY(3.5px) rotate(45deg); }
.index-toggle[aria-expanded="true"] .index-toggle__icon i:last-child  { transform: translateY(-3.5px) rotate(-45deg); }
/* hover — the bars stretch a touch (same gesture as the CTA
   arrows) in both states, so hover → open never snaps back;
   when open, the ✕ also spins like the case-study close */
/* the icon spins a half turn as it morphs = ⇄ ✕ — part of the state
   change itself, so the gesture is identical on mouse and touch */
.index-toggle[aria-expanded="true"] .index-toggle__icon { transform: rotate(180deg); }
/* mouse-only extras (iOS sticky hover made taps and swipes trigger
   these): bars stretch; hovering the open ✕ spins another half turn */
@media (hover: hover) and (pointer: fine) {
  .index-toggle:hover .index-toggle__icon { width: 27px; }
  .index-toggle[aria-expanded="true"]:hover .index-toggle__icon { transform: rotate(360deg); }
}
/* touch gets the same stretch on press — :active is momentary, so it
   can't stick the way hover does on iOS */
.index-toggle:active .index-toggle__icon { width: 27px; }
/* while the menu is open the button floats on the menu's own blurred
   glass — drop the live blur so scrolling gives Safari nothing to
   re-sample mid-animation (the re-raster froze the ✕ spin) */
html.menu-open .index-toggle,
.index-toggle[aria-expanded="true"] {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background: rgba(13, 18, 20, .38);
}

/* ── Index menu ────────────────────────────── */
html.menu-open { overflow: hidden; } /* page locks while the menu is open */
.menu { position: fixed; inset: 0; z-index: 110; visibility: hidden; }
.menu__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(8, 15, 16, .35);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  opacity: 0;
  touch-action: none; /* iOS: touches on the backdrop can't scroll the page */
}
.menu__panel {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: min(30rem, 100%);
  background: color-mix(in srgb, var(--teal-900) 32%, transparent);
  -webkit-backdrop-filter: blur(12px) saturate(1.4);
  backdrop-filter: blur(12px) saturate(1.4);
  color: var(--bone);
  /* generous top padding — the eyebrow clears the close circle */
  padding: clamp(8rem, 15vh, 9.5rem) clamp(1.75rem, 4vw, 3.25rem) 2rem;
  display: flex;
  flex-direction: column;
  transform: translateX(101%);
  border-left: 1px solid rgba(239,233,223,.1);
  overflow-y: auto;
}
.menu__eyebrow {
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--bone-dim);
  padding-bottom: 1.25rem;
  border-bottom: 1px solid rgba(239,233,223,.15);
}
.menu__list { margin-top: 1rem; flex: 1; }
.menu__list > li { border-bottom: 1px solid rgba(239,233,223,.12); }
.menu__link {
  display: flex;
  align-items: baseline;
  gap: 1.25rem;
  padding: 1.1rem 0;
}
.menu__num {
  font-family: var(--font-mono);
  font-size: .85rem;
  color: var(--amber); /* DS accent — same amber as selection & email */
  min-width: 2.1rem;
  transform: translateY(-.35em);
}
.menu__num--icon svg { display: inline-block; vertical-align: middle; }
.menu__word {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-variation-settings: "wght" 360;
  line-height: 1.02;
  transition: font-variation-settings .45s var(--ease-out), color .35s;
}
.menu__link:hover .menu__word {
  /* the word swells slightly — same gesture as the hero's reactive type */
  font-variation-settings: "wght" 450;
  color: var(--amber); /* DS accent on hover */
}
.menu__sublist {
  /* num column (2.1rem) + gap (1.25rem) + the serif capitals' side
     bearing (~.35rem) so it aligns with the VISUAL edge of the glyphs */
  margin: -.35rem 0 1.1rem 3.7rem;
  display: grid;
  gap: .3rem;
}
.menu__sublist a {
  font-family: var(--font-mono);
  font-size: .74rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bone-dim);
  transition: color .3s, letter-spacing .45s var(--ease-out);
}
.menu__sublist a:hover {
  color: var(--amber);
  letter-spacing: .24em; /* the word breathes open — type moves, not the element */
}

/* ── CTA buttons ───────────────────────────── */
/* A hairline pill — mono uppercase label with the self-extending
   arrow. Quietly fills on hover; unmistakably a button. */
.cta {
  display: inline-flex;
  align-items: center;
  gap: .9rem;
  padding: .85rem 1.5rem;
  border: 1px solid color-mix(in srgb, var(--sec-ink, var(--bone)) 32%, transparent);
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--sec-ink, var(--bone));
  transition: border-color .35s, background-color .35s;
}
.cta:hover {
  border-color: color-mix(in srgb, var(--sec-ink, var(--bone)) 58%, transparent);
  background: color-mix(in srgb, var(--sec-ink, var(--bone)) 7%, transparent);
}
.cta__line {
  position: relative;
  width: 1.4rem;
  height: 1px;
  background: color-mix(in srgb, currentColor 55%, transparent);
  transition: width .5s var(--ease-out), background-color .3s;
}
.cta__line::after {
  content: "";
  position: absolute;
  right: 0;
  top: -3.5px;
  width: 7px;
  height: 7px;
  border-top: 1px solid currentColor;
  border-right: 1px solid currentColor;
  transform: rotate(45deg);
}
.cta:hover .cta__line {
  width: 2.1rem;
  background: currentColor;
}

/* ── Case study overlay ────────────────────── */
/* Full-screen panel in the project's colour; scrolls internally.
   Sits under the grain (z 200) so the texture stays consistent. */
.case {
  position: fixed;
  inset: 0;
  z-index: 150;
}
html.case-open { overflow: hidden; }
.case__panel {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  background: var(--sec-bg);
  color: var(--sec-ink);
  /* NB: no permanent will-change — a promoted layer that never goes
     away leaves WebKit painting stale tiles for <video> inside it.
     case.js sets it for the slide and clears it again. */
}
.case__top {
  /* mirrors the masthead exactly — the Close circle sits where Index sits */
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 2;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--gutter) var(--gutter) 1.4rem;
  background: linear-gradient(to bottom, var(--sec-bg) 62%, transparent);
  font-family: var(--font-mono);
  font-size: .74rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  pointer-events: none;
}
.case__top > * { pointer-events: auto; }
@media (max-width: 900px) {
  /* phones: match the masthead's deeper top inset */
  .case__top { padding-top: calc(22px + clamp(1rem, 2.5vw, 1.75rem)); }
}
.case__meta { color: color-mix(in srgb, var(--sec-ink) 65%, transparent); }
/* Close — an ✕ in a frosted circle, same language as the Index toggle */
.case__close {
  width: 52px;
  height: 52px;
  display: grid;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--sec-ink) 22%, transparent);
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 9%, transparent);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.case__close .case__close-word { display: none; }
.case__x {
  position: relative;
  width: 22px;
  height: 14px;
  transition: transform .55s var(--ease-out), width .5s var(--ease-out);
}
/* same gesture pair as the Index toggle: stretch + spin (mouse only —
   iOS sticky hover kept the ✕ enlarged through the close animation) */
@media (hover: hover) and (pointer: fine) {
  .case__close:hover .case__x { width: 27px; transform: rotate(180deg); }
}
/* touch: stretch only while the finger is down, then back to normal */
.case__close:active .case__x { width: 27px; }
.case__x i {
  position: absolute;
  top: calc(50% - 1px); /* center the 2px stroke's ink, not its top edge */
  left: 0;
  width: 100%;
  height: 2px;
  background: currentColor;
}
.case__x i:first-child { transform: rotate(45deg); }
.case__x i:last-child { transform: rotate(-45deg); }
.case__scroll {
  flex: 1;
  overflow-y: auto;
  /* -webkit-overflow-scrolling: touch omitted on purpose: it is a
     no-op since iOS 13 and its legacy layer model renders media
     inside the scroller stale */
  overscroll-behavior: contain;
}
.case__inner {
  /* wide stage for the imagery — text blocks keep their own
     narrow measure, so reading width stays comfortable */
  max-width: 88rem;
  margin: 0 auto;
  /* extra top clearance — the chrome now floats over the scroll */
  padding: clamp(8rem, 14vh, 10rem) var(--gutter) var(--space-xl);
}
.case__title {
  font-size: var(--step-3);
  margin-bottom: var(--space-m);
}
.case__lede {
  font-size: var(--step-1);
  line-height: 1.5;
  max-width: 44rem;
  color: color-mix(in srgb, var(--sec-ink) 85%, transparent);
  margin-bottom: var(--space-l);
}
.case__fig { margin: 0; }
.case__fig + .case__fig { margin-top: 0; }
.case__fig figcaption {
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--sec-ink) 48%, transparent);
  margin-top: .65rem;
}
.case__block { margin-bottom: var(--space-m); }
.case__cols {
  display: grid;
  grid-template-columns: 2fr 3fr;
  gap: var(--space-m);
  align-items: start;
}
.case__cols--rev { grid-template-columns: 3fr 2fr; }
.case__cols--even { grid-template-columns: 1fr 1fr; }
.case__text {
  max-width: 40rem;
  margin: var(--space-l) 0;
}
.case__text h3 {
  font-family: var(--font-display);
  font-style: italic;
  font-variation-settings: "SOFT" 0, "WONK" 1;
  font-size: var(--step-1);
  font-weight: 380;
  margin-bottom: .8rem;
}
.case__text p {
  line-height: 1.7;
  color: color-mix(in srgb, var(--sec-ink) 82%, transparent);
}
.case__text p + p { margin-top: 1em; }
/* recognition list — mono ledger, hairline rules */
.case__awards ul {
  display: grid;
  gap: .7rem;
  margin-top: .4rem;
}
.case__awards li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1.5rem;
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--sec-ink) 85%, transparent);
  padding-bottom: .7rem;
  border-bottom: 1px solid color-mix(in srgb, var(--sec-ink) 18%, transparent);
  /* hover — the row wakes up: the type breathes open,
     the rule beneath brightens (same language as the stats) */
  transition: color .3s, letter-spacing .45s var(--ease-out), border-color .35s;
}
.case__awards li:hover {
  color: var(--sec-ink);
  letter-spacing: .19em;
  border-color: color-mix(in srgb, var(--sec-ink) 45%, transparent);
}
.case__awards li span {
  color: color-mix(in srgb, var(--sec-ink) 52%, transparent);
  text-align: right;
  flex: none;
  transition: color .3s;
}
.case__awards li:hover span {
  color: color-mix(in srgb, var(--sec-ink) 78%, transparent);
}
/* outcome stats — big ledger numbers over mono captions */
.case__stats ul {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-m);
}
.case__stats li {
  border-top: 1px solid color-mix(in srgb, var(--sec-ink) 18%, transparent);
  padding-top: 1rem;
  /* hover — the stat wakes up: the number lifts, the caption
     breathes open, the rule above brightens (same language as
     the recognition list) */
  transition: border-color .35s;
}
.case__stats li:hover {
  border-color: color-mix(in srgb, var(--sec-ink) 45%, transparent);
}
.case__stats strong {
  display: block;
  font-family: var(--font-display);
  font-style: italic;
  font-variation-settings: "SOFT" 0, "WONK" 1;
  font-weight: 380;
  font-size: var(--step-2);
  line-height: 1.1;
  margin-bottom: .6rem;
  transition: transform .45s var(--ease-out);
}
.case__stats li:hover strong {
  transform: translateY(-4px);
}
.case__stats span {
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--sec-ink) 55%, transparent);
  transition: color .3s, letter-spacing .45s var(--ease-out);
}
.case__stats li:hover span {
  color: color-mix(in srgb, var(--sec-ink) 82%, transparent);
  letter-spacing: .2em;
}
@media (prefers-reduced-motion: reduce) {
  .case__stats li:hover strong { transform: none; }
}
@media (max-width: 700px) {
  .case__stats ul { grid-template-columns: 1fr; }
}

.case__tags {
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--sec-ink) 55%, transparent);
  border-top: 1px solid color-mix(in srgb, var(--sec-ink) 20%, transparent);
  padding-top: var(--space-s);
  margin-top: var(--space-l);
}
/* blocks fade up as the internal scroll reaches them —
   GSAP drives it (case.js) with the same ease as the homepage */
.case__block {
  opacity: 0;
  transform: translateY(52px);
}
@media (max-width: 900px) {
  .case__cols, .case__cols--rev { grid-template-columns: 1fr; }
  /* photo pairs stay side by side on mobile */
  .case__cols--pair { grid-template-columns: 1fr 1fr; gap: var(--space-s); }
}
@media (prefers-reduced-motion: reduce) {
  .case__block { opacity: 1; transform: none; }
}

/* project artwork is clickable — it opens the case study */
.project__art .ph { cursor: pointer; }
/* the work leans in on hover — subtle zoom inside the frame */
@media (hover: hover) and (pointer: fine) {
  .project__art .ph img {
    /* mouse-out speed — snappier release */
    transition: opacity .9s var(--ease-out), transform .55s var(--ease-out);
  }
  .project__art .ph:hover img {
    /* mouse-over speed — slow, quiet drift in */
    transition: opacity .9s var(--ease-out), transform 1.1s var(--ease-out);
    transform: scale(1.018);
  }
}

/* ── Placeholder image frames ──────────────── */
.ph {
  position: relative;
  width: 100%;
  background: color-mix(in srgb, var(--sec-ink, var(--bone)) 7%, transparent);
  border: 1px solid color-mix(in srgb, var(--sec-ink, var(--bone)) 22%, transparent);
  display: grid;
  place-items: center;
  overflow: hidden;
}
.ph::before,
.ph::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top right,
      transparent calc(50% - .5px),
      color-mix(in srgb, var(--sec-ink, var(--bone)) 14%, transparent) 50%,
      transparent calc(50% + .5px));
}
.ph::after { transform: scaleX(-1); }
/* real image inside a frame — no border, soft corners, no diagonals */
.ph--img {
  border: 0;
  border-radius: 14px;
}
.ph--img img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ph--img video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* whole frame, never cropped by the box */
  object-fit: contain;
}
/* Safari doesn't reliably clip a <video> to a rounded ancestor —
   square corners show through. Round the video itself instead. */
.ph--video { overflow: visible; }
.ph--video video { border-radius: inherit; }
.ph--img::before,
.ph--img::after { display: none; }
/* panel presentation — the screenshot floats at a crisp, capped
   size on its own background colour */
.ph--panel img {
  position: absolute;
  inset: 0;
  margin: auto;
  width: auto;
  height: auto;
  max-width: min(78%, 690px);
  max-height: 84%;
  object-fit: contain;
  border-radius: 6px;
}

/* curtain reveal — own compositor layer so the animated clip
   doesn't force per-frame repaints in Safari */
.ph[data-reveal="curtain"] {
  will-change: clip-path;
  transform: translateZ(0);
}

/* ── Carousel (project art) ─────────────────── */
.carousel .carousel__slide {
  opacity: 0;
  transition: opacity .9s var(--ease-out);
}
.carousel .carousel__slide.is-active { opacity: 1; }
/* small-native UI shots sit smaller on their panel — never upscaled
   into softness */
.carousel .carousel__slide--panel { padding: 6% 20%; }
.carousel { touch-action: pan-y; }
.carousel .carousel__slide {
  -webkit-user-drag: none;
  user-select: none;
  /* never crop the work — letterbox on the slide's own background */
  object-fit: contain;
}
.carousel__nav {
  display: flex;
  gap: .6rem;
  margin-top: .4rem;
}
/* generous hit area, hairline visual — the line lives in ::after */
.carousel__nav i {
  display: block;
  position: relative;
  flex: 1;
  max-width: 6.5rem;
  height: 20px;
  cursor: pointer;
}
.carousel__nav i::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  top: 50%;
  height: 3px;
  transform: translateY(-50%);
  background: color-mix(in srgb, var(--sec-ink, var(--bone)) 25%, transparent);
  transition: background-color .35s;
}
.carousel__nav i:hover::after { background: color-mix(in srgb, var(--sec-ink, var(--bone)) 45%, transparent); }
.carousel__nav i.is-active::after { background: var(--sec-ink, var(--bone)); }
.ph__label {
  position: relative;
  z-index: 1;
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--sec-ink, var(--bone)) 45%, transparent);
  background: var(--sec-bg, var(--teal-900));
  padding: .4rem .9rem;
}
