/* ═══════════════════════════════════════════════
   ANASTASIA BAULA — sections.css
   Hero · projects · contact · responsive
   ═══════════════════════════════════════════════ */

/* Sections paint their own color as fallback; when JS drives
   the background cross-fade, they go transparent and the body
   background tweens between section colors. */
.js-bgfade .hero,
.js-bgfade .project,
.js-bgfade .contact { background: transparent; }

/* pre-paint hide for the entrance targets — the inline head script
   sets .preload-hide before first paint; animations.js releases it
   the moment the reveal timeline takes over */
html.preload-hide .hero__title,
html.preload-hide .hero__portrait,
html.preload-hide .hero__aside > *,
html.preload-hide .hero__cta {
  visibility: hidden;
}

/* ── Hero / About ──────────────────────────── */
/* Full-viewport composition: giant name behind the cutout portrait,
   role + bio anchored bottom-left, CTA bottom-right. */
.hero {
  --sec-bg: var(--teal-900);
  --sec-ink: var(--bone);
  position: relative;
  min-height: 100svh;
  background: var(--teal-900);
  overflow: clip; /* nothing bleeds into the next section */
}
.hero::before {
  /* recreate the photo's lighting: lit wall behind her head,
     darker pooling toward the floor — so the cutout sits *in* the scene */
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(44% 50% at 55% 44%, rgba(30, 80, 81, .85) 0%, transparent 70%),
    radial-gradient(75% 55% at 50% 100%, rgba(3, 18, 20, .55) 0%, transparent 62%);
  pointer-events: none;
}
.hero::after {
  /* slight cinematic vignette — always the last hero layer */
  content: "";
  position: absolute;
  inset: 0;
  z-index: 6;
  background: radial-gradient(120% 105% at 50% 42%, transparent 58%, rgba(0, 0, 0, .26) 100%);
  pointer-events: none;
}
.hero__inner {
  position: relative;
  min-height: 100svh;
  padding: 0 var(--gutter);
}

/* Figma-style cursor replaces the native pointer on the hero canvas */
@media (hover: hover) and (pointer: fine) {
  /* doubled class so this outranks the `cursor: default` declarations on
     .hero__title / .hero__role below — same specificity would lose on
     source order and let the native arrow show alongside the Ana pointer */
  .hero.hero, .hero.hero * { cursor: none; }
  /* the CTA is a real control — hand cursor, Ana pointer steps aside */
  .hero.hero .hero__cta, .hero.hero .hero__cta * { cursor: pointer; }
}
.hero-pointer {
  position: absolute;
  top: 0;
  left: 0;
  /* sits above the name (1) and the bio + CTA (3) so it never slips
     under the copy, but stays below her portrait (5) — the tag slides
     under her edge, and the alpha hit-test fades the pointer out over
     her actual pixels. */
  z-index: 4;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  color: var(--bone);
  will-change: transform; /* stays on the compositor */
}
.hero__grid { transform: translateZ(0); } /* own layer, no scroll repaints */

/* Figma-style blueprint: pixel grid + rulers (JS-populated) */
.hero__blueprint {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.hero__grid {
  position: absolute;
  inset: 0;
  /* 100px majors so grid lines land exactly on the ruler numbers */
  background-image:
    linear-gradient(rgba(239, 233, 223, .05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(239, 233, 223, .05) 1px, transparent 1px),
    linear-gradient(rgba(239, 233, 223, .018) 1px, transparent 1px),
    linear-gradient(90deg, rgba(239, 233, 223, .018) 1px, transparent 1px);
  background-size: 100px 100px, 100px 100px, 20px 20px, 20px 20px;
}
.hero__ruler {
  position: absolute;
  top: 0;
  left: 0;
  stroke: rgba(239, 233, 223, .30);
  stroke-width: 1;
}
.hero__ruler text {
  stroke: none;
  fill: rgba(239, 233, 223, .40);
  font-family: var(--font-mono);
  font-size: 8px;
  letter-spacing: .05em;
}
.hero__ruler-corner {
  position: absolute;
  top: 0;
  left: 0;
  width: 22px;
  height: 22px;
  border-right: 1px solid rgba(239, 233, 223, .18);
  border-bottom: 1px solid rgba(239, 233, 223, .18);
}

/* Layer for the ambient design ephemera (JS-populated) */
.hero__fx {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  /* components slide in under the rulers, never over them */
  clip-path: inset(22px 0 0 22px);
}
.hero__fx .fx {
  position: absolute;
  will-change: transform, opacity;
  color: var(--bone);
}
/* (stroke behavior is set per-element in JS: hairline strokes get
   non-scaling-stroke; dash-animated draw-on elements are exempt) */

/* Figma-style selection frame — screen-space overlay, so its line
   and handles keep their size while the component scales */
.hero__fx .fx-select {
  position: absolute;
  border: 1px solid color-mix(in srgb, var(--bone) 80%, transparent);
  pointer-events: none;
}
.hero__fx .fx-select i {
  position: absolute;
  width: 7px;
  height: 7px;
  background: var(--teal-900);
  border: 1px solid color-mix(in srgb, var(--bone) 80%, transparent);
}
.hero__fx .fx-select i:nth-child(1) { top: -4px; left: -4px; }
.hero__fx .fx-select i:nth-child(2) { top: -4px; right: -4px; }
.hero__fx .fx-select i:nth-child(3) { bottom: -4px; left: -4px; }
.hero__fx .fx-select i:nth-child(4) { bottom: -4px; right: -4px; }

/* Figma multiplayer-style name tag — a solid square chip tucked into
   the pointer's tail. Unscoped so the hero pointer and the ambient
   fx cursor share one look. */
.fx-cursor-tag {
  font-family: var(--font-mono);
  font-size: .625rem;
  font-weight: 500;
  letter-spacing: .06em;
  padding: .18rem .45rem .22rem;
  background: color-mix(in srgb, var(--bone) 9%, transparent);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  backdrop-filter: blur(10px) saturate(1.2);
  border: 1px solid color-mix(in srgb, var(--bone) 38%, transparent);
  color: color-mix(in srgb, var(--bone) 88%, transparent);
  white-space: nowrap;
  margin-left: .25rem;
  margin-top: .55rem;
  display: inline-block;
}
/* dark blade, bone outline — reads against the teal canvas */
.fx-cursor-arrow { filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .45)); }
.hero__fx .fx-amp {
  font-family: var(--font-display);
  font-style: italic;
  font-variation-settings: "SOFT" 0, "WONK" 1;
  line-height: 1;
}
.hero__title {
  position: absolute;
  top: clamp(4.25rem, 9vh, 6.5rem);
  left: var(--gutter);
  right: var(--gutter);
  z-index: 1;
  cursor: default;
  text-align: center;
  /* width-driven, but capped by height too — on short laptop screens the
     portrait (svh-sized) would otherwise swallow the name */
  font-size: clamp(3.2rem, min(12.8vw, 20svh), 13.5rem);
  color: var(--bone);
  text-transform: uppercase;
  letter-spacing: -.02em;
  line-height: .9;
}
.hero__line { display: block; }
/* split chars get invisible bleed — padding cancelled by negative
   margin — so the italic glyphs' ink overhang survives the per-char
   compositor layers Safari creates during the entrance animation */
.split-char { padding: .18em .3em; margin: -.18em -.3em; }
/* split words wrap as units — never mid-word */
.split-word { white-space: nowrap; }
/* the italic line is left-set a fixed em-distance from center so the
   B's slanted stem always continues the A's left diagonal — one unified
   line at every viewport size. "ANASTASIA" is centered and 5.41em wide,
   so its A starts at 50% − 2.70em; the B tucks 0.26em further left.
   (This also pins the word's right edge at 50% − 0.67em, safely clear
   of the portrait's hair at any size — no glyph ever gets swallowed.) */
.hero__line:last-child {
  text-align: left;
  padding-left: calc(50% - 2.96em);
}
.hero__line em { text-transform: none; font-variation-settings: "SOFT" 0, "WONK" 1; }

.hero__portrait {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  /* above the bio copy (3) and the pointer (4), so the cursor and its
     name tag tuck in behind her silhouette */
  z-index: 5;
  pointer-events: none;
}
.hero__portrait img {
  /* scales with the viewport so her head always tucks behind the name;
     the vw cap reins her in on near-square windows, where 78svh would
     otherwise swallow half the composition */
  height: min(78svh, 62vw);
  width: auto;
  max-width: none;
  /* soft ambient shadow hugging her silhouette — grounds the cutout */
  filter: drop-shadow(0 28px 50px rgba(3, 18, 20, .55));
}

.hero__aside {
  position: absolute;
  left: var(--gutter);
  bottom: clamp(2rem, 6vh, 4rem);
  z-index: 3;
  max-width: none;
}
.hero__role {
  /* magazine-cover credit — runs over the photo. Size is tuned to the
     first line's width ("Interaction & Visual", 9.25em in Fraunces 380)
     so its right edge just tucks behind the portrait — was
     clamp(1.93rem, 1.29rem + 2.85vw, 3.77rem) for the 10.05em-wide
     "Product & Interaction"; recalc on any title change */
  cursor: default;
  font-family: var(--font-display);
  font-size: clamp(2.1rem, 1.4rem + 3.1vw, 4.1rem);
  font-weight: 380;
  line-height: 1.06;
  color: var(--bone);
  text-shadow: 0 2px 24px rgba(3, 18, 20, .35);
}
.hero__role em {
  font-style: italic;
  font-variation-settings: "SOFT" 0, "WONK" 1;
}
.hero__biotext {
  margin-top: 1.25rem;
  max-width: 27rem;
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--bone-dim);
}

/* the split-text hero copy is interactive display type — selecting it
   highlights hundreds of char boxes and looks shattered */
.hero__title,
.hero__role,
.hero__biotext {
  -webkit-user-select: none;
  user-select: none;
}
.hero__biotext em {
  font-family: var(--font-display);
  color: var(--bone);
  /* Fraunces has a smaller x-height than Archivo — compensate so the
     italic word reads the same optical size as the surrounding text */
  font-size: 1.07em;
}

/* reactive type must never re-wrap while it swells — SplitText fixes
   the line breaks at split time; lock each line div to a single row */
.hero__biotext > div { white-space: nowrap; }
.hero__role { white-space: nowrap; }

/* Fit the aside to the free column left of the portrait.
   The portrait is min(78svh, 62vw) tall with aspect 1214:1600, so its
   half-width is min(29.6svh, 23.6vw) and the free run from the gutter
   to her edge is 50vw − that − gutter. On short-wide laptop screens
   (and near-square windows) that column shrinks while the type doesn't
   — cap role size and bio width by it so nothing disappears behind her.
   Desktop stays untouched: there the caps resolve larger than the
   existing sizes.
   The divisor is the role's first-line width in em (9.25em for
   "Interaction & Visual" in Fraunces 380) ÷ 1.05 — the 1.05 grants a
   deliberate ~5% tuck behind her edge. Was 9.56 for the 10.05em-wide
   "Product & Interaction"; recalc on any title change. */
@media (min-width: 901px) {
  .hero__role {
    font-size: min(
      clamp(2.1rem, 1.4rem + 3.1vw, 4.1rem),
      calc((50vw - min(29.6svh, 23.6vw) - var(--gutter)) / 8.8)
    );
  }
  .hero__biotext {
    max-width: min(27rem, calc(50vw - min(29.6svh, 23.6vw) - var(--gutter)));
  }
}

.hero__cta {
  position: absolute;
  right: var(--gutter);
  bottom: clamp(1.5rem, 5vh, 3.5rem);
  /* topmost hero layer — above the portrait (5) and the vignette (6):
     the CTA is the section's one control, nothing may ever cover it */
  z-index: 7;
  /* frosted fill — neutral ink tint so it reads the same over any
     section colour the background fades to */
  background: color-mix(in srgb, var(--ink) 9%, transparent);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border-color: color-mix(in srgb, var(--bone) 35%, transparent);
}

/* ── Projects ──────────────────────────────── */
.project {
  position: relative;
  min-height: 100svh;
  display: grid;
  background: var(--sec-bg);
  color: var(--sec-ink);
  /* isolate each section's paint — invalidations can't ripple
     across the whole page while scrolling */
  contain: paint;
}
.project::before {
  /* slight vertical gradient for depth — sits over the cross-faded body color */
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(255, 255, 255, .045) 0%,
    transparent 28%,
    transparent 72%,
    rgba(0, 0, 0, .09) 100%);
}
.project__inner {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: auto 1fr;
  column-gap: 1rem;
  align-items: center;
  width: 100%;
  max-width: 100rem;
  margin-inline: auto;
  padding: var(--space-l) var(--gutter) var(--space-xl);
}
.project__head {
  grid-column: 1 / -1;
  grid-row: 1;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: .16em;
  padding-bottom: var(--space-m);
  border-bottom: 1px solid color-mix(in srgb, var(--sec-ink) 25%, transparent);
  margin-bottom: var(--space-l);
}
/* header tags — same quiet voice as the old tag row */
.project__head-tags {
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--sec-ink) 62%, transparent);
}
/* the index numeral — same quiet mono voice as the tags */
.project__num {
  font-size: .72rem;
  letter-spacing: .16em;
}

.project__art { grid-column: 7 / -1; grid-row: 2; }
.project__text { grid-column: 1 / 6; grid-row: 2; }
.project--flip .project__art { grid-column: 1 / 7; }
.project--flip .project__text { grid-column: 8 / -1; }
/* wide-art variants — desktop only, so the ID specificity can't
   override the stacked mobile layout */
@media (min-width: 901px) {
  /* google — the collage gets an extra column of stage */
  #p-google .project__art { grid-column: 1 / 8; }
  #p-google .project__text { grid-column: 9 / -1; }
  /* mastercard — same format, mirrored */
  #p-mastercard .project__art { grid-column: 6 / -1; }
  #p-mastercard .project__text { grid-column: 1 / 5; }
  /* meta — same format as google */
  #p-meta .project__art { grid-column: 1 / 8; }
  #p-meta .project__text { grid-column: 9 / -1; }
  /* meiso — same format as mastercard */
  #p-meiso .project__art { grid-column: 6 / -1; }
  #p-meiso .project__text { grid-column: 1 / 5; }
}

.project__art--pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}
/* the second frame anchors where the old parallax's midpoint sat —
   margin (not translate) so the offset takes real layout space and
   never crowds the text below */
.project__art--pair .ph:last-child { margin-top: calc(var(--space-m) + 64px); }

.project__title {
  font-size: var(--step-3);
  margin-bottom: var(--space-s);
}
.project__desc {
  max-width: 30rem;
  line-height: 1.6;
  color: color-mix(in srgb, var(--sec-ink) 82%, transparent);
}
.project__tags {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  margin-top: var(--space-m);
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--sec-ink) 62%, transparent);
}
.project__tags li:not(:last-child)::after {
  content: "·";
  margin: 0 .8rem;
  opacity: .6;
}
.project__text .cta { margin-top: var(--space-m); }

/* Growing media variant (01 Lumen): the centered image scales up as
   you scroll, ending at the full width of the header rule */
.project--grow .project__art {
  grid-column: 1 / -1 !important;
  will-change: transform;
}

/* Centered variant (03 Signal) */
.project--center .project__inner { grid-template-rows: auto auto auto; }
.project--center .project__art  { grid-column: 2 / -2; grid-row: 2; margin-bottom: var(--space-l); }
.project--center .project__text { grid-column: 3 / -3; grid-row: 3; text-align: center; }
.project--center .project__desc { margin-inline: auto; max-width: 44rem; }
.project--center .project__tags { justify-content: center; }
.project--center .project__text .btn { margin-inline: auto; }

/* ── Skills strip ──────────────────────────── */
/* a quiet ledger between the hero and the work — no data-bg,
   so it rides on the hero teal */
.skills {
  padding: clamp(3.5rem, 9vh, 6.5rem) var(--gutter);
}
.skills__inner {
  max-width: 100rem;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
}
.skills__eyebrow {
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--bone-dim);
}
.skills__list {
  display: flex;
  flex-wrap: wrap;
  row-gap: .85rem;
  font-family: var(--font-mono);
  font-size: .78rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--bone) 78%, transparent);
}
.skills__list li:not(:last-child)::after {
  content: "·";
  margin: 0 1.2rem;
  color: color-mix(in srgb, var(--bone) 38%, transparent);
}

/* ── Contact ───────────────────────────────── */
.contact {
  --sec-bg: var(--teal-900);
  --sec-ink: var(--bone);
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background: var(--teal-900);
  padding-top: var(--space-xl);
}
.contact__inner {
  text-align: center;
  padding: 0 var(--gutter);
  margin: auto;
}
.contact__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--bone-dim);
  margin-bottom: var(--space-m);
}
.contact__title { font-size: var(--step-3); }
.contact__line { display: block; }

/* the little sunflower — hairline line-art, same language
   as the CTA arrows: bone stem, amber bloom */
.contact__flower {
  width: clamp(58px, 6vw, 80px);
  margin: var(--space-m) auto 0;
}
.contact__flower svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}
.flower__stem,
.flower__leaf {
  stroke: color-mix(in srgb, var(--bone) 58%, transparent);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.flower__petal {
  stroke: var(--amber);
  stroke-width: 1.8;
  stroke-linejoin: round;
}
.flower__disc {
  stroke: color-mix(in srgb, var(--bone) 58%, transparent);
  stroke-width: 1.8;
}
/* seed rings — dotted circles, evenly spaced round caps */
.flower__seeds {
  stroke: var(--amber);
  stroke-width: 1.8;
  stroke-linecap: round;
}
.flower__seeds--outer { stroke-dasharray: 0.1 4.612; }
.flower__seeds--inner { stroke-dasharray: 0.1 3.67; }
.contact__flower + .contact__email { margin-top: var(--space-m); }
.contact__email {
  display: inline-block;
  margin-top: var(--space-l);
  font-family: var(--font-display);
  font-style: italic;
  font-variation-settings: "SOFT" 0, "WONK" 1;
  font-size: var(--step-1);
  color: var(--amber);
  position: relative;
  /* no underline — the amber glows brighter on hover:
     still clearly amber, never mistaken for body text */
  transition: color .3s;
}
.contact__email:hover { color: color-mix(in srgb, var(--amber) 55%, var(--bone)); }

.contact__meta {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--space-m);
  flex-wrap: wrap;
  margin-top: var(--space-l);
}
.contact__social { display: flex; gap: 1.5rem; }
.contact__social a {
  font-family: var(--font-mono);
  font-size: .78rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bone-dim);
  transition: color .25s;
}
.contact__social a:hover { color: var(--amber); }

.footer {
  display: flex;
  justify-content: space-between;
  padding: 1.5rem var(--gutter);
  border-top: 1px solid rgba(239,233,223,.12);
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bone-dim);
}
.footer a { transition: color .25s; }
.footer a:hover { color: var(--amber); }

/* ── Responsive ────────────────────────────── */
@media (max-width: 900px) {
  /* stacked composition for portrait screens: name, credit and bio
     read in sequence on clean background; her portrait sits smaller,
     anchored to the bottom of the frame */
  .hero__inner {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: clamp(5.5rem, 11vh, 7rem) 2.4rem 0;
  }
  .hero__title {
    position: static;
    text-align: left;
  }
  .hero__line:last-child { padding-left: 0; }
  .hero__aside {
    position: static;
    margin-top: 1.3rem;
    max-width: none;
  }
  .hero__portrait { left: 50%; }
  .hero__portrait img {
    height: 43svh;
    /* Safari draws drop-shadow on alpha cutouts as a boxy smudge —
       swap it for a soft radial shadow layer behind her */
    filter: none;
  }
  .hero__portrait::before {
    content: "";
    position: absolute;
    inset: -10% -24%;
    z-index: -1;
    background: radial-gradient(58% 52% at 50% 60%, rgba(3, 18, 20, .72) 0%, transparent 72%);
  }
  .hero::before {
    /* the lit-wall glow follows her head — the bottom-anchored portrait
       puts it ~65% down on phones, not 44% like desktop; kept soft so
       it reads as room light, not a halo */
    background:
      radial-gradient(72% 49% at 50% 65%, rgba(30, 80, 81, .42) 0%, transparent 78%),
      radial-gradient(75% 55% at 50% 100%, rgba(3, 18, 20, .55) 0%, transparent 62%);
  }
  .hero__biotext {
    max-width: 30rem;
    color: color-mix(in srgb, var(--bone) 92%, transparent);
    text-shadow: 0 1px 14px rgba(3, 18, 20, .55);
  }
  .hero__cta {
    /* centered — auto margins, no transform, so GSAP's entrance stays intact */
    left: 0;
    right: 0;
    bottom: 1.5rem;
    margin-inline: auto;
    width: fit-content;
  }

  .project { min-height: auto; }
  /* header stacks — the tags line gets its own row instead of
     colliding with the numeral and the fixed Index toggle */
  .project__head {
    flex-direction: column;
    align-items: flex-start;
    gap: .55rem;
  }
  .project__head-tags {
    font-size: .68rem;
    letter-spacing: .12em;
  }
  .project__art,
  .project--flip .project__art { grid-column: 1 / -1; grid-row: 2; margin-bottom: var(--space-l); max-width: 34rem; width: 100%; justify-self: center; }
  .project__art--pair .ph:last-child { margin-top: var(--space-m); }
  .project__text,
  .project--flip .project__text { grid-column: 1 / -1; grid-row: 3; }
  /* stacked layout centers every section's text — consistent with
     the --center variant */
  .project__text { text-align: center; }
  .project__desc { margin-inline: auto; }
  .project__tags { justify-content: center; }
  .project--center .project__art { grid-column: 1 / -1; max-width: none; }
  .project--center .project__text { grid-column: 1 / -1; }
  /* the case-study button centers on every section, not just
     the --center variants */
  .project__text .cta {
    display: flex;
    width: fit-content;
    margin-inline: auto;
  }
}

@media (max-width: 540px) {
  .contact__meta { flex-direction: column; gap: 1.25rem; }
  .footer { flex-direction: column; gap: .5rem; text-align: center; }
}
