/* ---------- fgsl project page ---------- */

/* @font-face registers a font file that ships with the site, so visitors
   don't need it installed. "La Graziela" is the name we refer to it by
   in font-family below. */
@font-face {
  font-family: "La Graziela";
  src: url("fonts/La Graziela Script Demo.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html,
body {
  height: 100%;
}

body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}

/* The hero fills the whole screen. 100svh is the "small viewport height" —
   on phones it measures the screen with the browser's address bar showing,
   so the layout doesn't jump when that bar hides and reappears on scroll.

   The hero starts white; the gray/photo lives on its own layer (.hero__bg)
   that fades in on top, so the background itself animates in. */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  overflow: hidden;
  background: #ffffff;
}

/* The gray layer is now a translucent wash rather than a solid fill, so the
   slideshow photos underneath (.hero__slideshow) show through it. Sits
   behind the nav and logo, which are lifted above it with z-index. */
.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: rgba(70, 71, 77, 0.6);
}

/* ---------- background slideshow ---------- */

/* Sits below .hero__bg (z-index -1 vs its 0), filled in by script.js with
   one <img> per photo in images/main/. Solid black fallback avoids a white
   flash while the manifest and first photo are still loading. */
.hero__slideshow {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: #000000;
}

/* Every photo is stacked directly on top of the last one, full-bleed.
   Only .is-active is opaque; crossfading is just two of these transitioning
   opacity at the same time — the outgoing one down, the incoming one up. */
.hero__slideshow-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1800ms ease;
}

.hero__slideshow-photo.is-active {
  opacity: 1;
}

/* ---------- top nav ---------- */

/* Absolute = lifted out of the layout, so the logo stays centered on the
   full screen rather than being pushed down by the nav sitting above it. */
.hero__nav {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-between;
  padding: clamp(24px, 4.5vw, 48px) clamp(24px, 4.5vw, 56px);
  z-index: 2;
}

.hero__nav-link {
  color: #ffffff;
  text-decoration: none;
  font-size: clamp(11px, 1.15vw, 14px);
  letter-spacing: 0.12em;
  transition: opacity 300ms ease;
}

.hero__nav-link:hover,
.hero__nav-link:focus-visible {
  opacity: 0.6;
}

/* ---------- logo ---------- */

/* Width scales with the screen but never exceeds the source image's own size,
   so it can shrink freely without ever being blown up and going soft.
   z-index lifts it above the background layer. */
.hero__logo {
  position: relative;
  z-index: 1;
  width: clamp(280px, 62vw, 780px);
  height: auto;
  display: block;
}

/* Phones: the logo's long horizontal flourishes need more room proportionally,
   and the two nav links need space so they don't crowd toward each other. */
@media (max-width: 600px) {
  .hero__logo {
    width: 86vw;
  }

  .hero__nav-link {
    letter-spacing: 0.09em;
  }
}

/* ---------- about the project ---------- */

.about-page {
  background: #ffffff;
  color: #575757;
}

/* This page scrolls, so the nav scrolls away with it rather than being pinned
   to the screen the way the hero's nav is. */
.about__nav {
  display: flex;
  justify-content: space-between;
  padding: clamp(24px, 4.5vw, 48px) clamp(24px, 4.5vw, 56px);
}

.about__nav-link {
  color: #3d3d3d;
  text-decoration: none;
  font-size: clamp(11px, 1.15vw, 14px);
  letter-spacing: 0.12em;
  transition: opacity 300ms ease;
}

.about__nav-link--muted {
  color: #9a9a9a;
}

.about__nav-link:hover,
.about__nav-link:focus-visible {
  opacity: 0.55;
}

.about {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(20px, 4vw, 44px) 24px clamp(80px, 10vw, 140px);
}

.about__logo {
  width: clamp(185px, 21.5vw, 310px);
  height: auto;
  display: block;
}

/* The block itself stays centered on the page; the text inside it starts
   flush at the left edge of that block. Shares its width with
   .dedication__body below so the two sections line up. */
.about__body {
  margin-top: clamp(26px, 3.2vw, 46px);
  max-width: 820px;
  width: 100%;
  text-align: left;
  font-size: clamp(13px, 1.35vw, 16px);
  line-height: 1.7;
}

/* Space between paragraph blocks. "1.35em" means 1.35x the font size,
   so it scales along with the text instead of staying a fixed pixel gap. */
.about__body p + p {
  margin-top: 1.35em;
}

/* Each line is its own block so the line breaks match the design exactly
   instead of being decided by wherever the text happens to wrap. */
.line {
  display: block;
}

.about__dedication {
  position: relative;
  margin-top: clamp(56px, 8vw, 104px);
  display: inline-block;
  padding: 10px 4px;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: inherit;
  color: #8a8a8a;
  text-decoration: none;
  font-size: clamp(11px, 1.15vw, 14px);
  letter-spacing: 0.12em;
  transition: color 300ms ease;
}

/* The underline. "::after" adds an extra element via CSS alone, with no
   markup for it in the HTML. It sits flat at scaleX(0) — squashed to nothing
   from its center — and grows outward on hover, or stays out while open.
   The negative left/right values let it run wider than the text itself. */
.about__dedication::after {
  content: "";
  position: absolute;
  left: -22px;
  right: -22px;
  bottom: 0;
  height: 1px;
  background: #8a8a8a;
  transform: scaleX(0);
  transform-origin: center;
  transition: transform 700ms cubic-bezier(0.22, 0.61, 0.36, 1),
              background-color 300ms ease;
}

/* Stays extended once the dedication is open, and only goes black on hover. */
.about__dedication[aria-expanded="true"]::after,
.about__dedication:hover::after,
.about__dedication:focus-visible::after {
  transform: scaleX(1);
}

.about__dedication:hover::after,
.about__dedication:focus-visible::after {
  background: #111111;
}

.about__dedication:hover,
.about__dedication:focus-visible {
  color: #111111;
}

/* ---------- dedication panel ---------- */

/* Collapsed by default. "grid-template-rows: 0fr" is a way to animate a
   collapse without knowing the content's height in advance: the row starts
   at zero fraction of the space and grows to its natural size (1fr). */
.dedication {
  display: grid;
  grid-template-rows: 0fr;
  width: 100%;
  opacity: 0;
  visibility: hidden;
  transition: grid-template-rows 1400ms cubic-bezier(0.22, 0.61, 0.36, 1),
              opacity 1600ms ease,
              visibility 0s linear 1600ms;
}

.dedication.is-open {
  grid-template-rows: 1fr;
  opacity: 1;
  visibility: visible;
  transition: grid-template-rows 1400ms cubic-bezier(0.22, 0.61, 0.36, 1),
              opacity 1900ms ease 200ms,
              visibility 0s linear 0s;
}

/* The overflow clip is what actually hides the content while the row
   above it is collapsed to zero height. */
.dedication__inner {
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Same 820px column as .about__body, so the left edges of the two sections
   line up. Line length is set by the forced breaks, not by this width. */
.dedication__body {
  margin-top: clamp(26px, 3.2vw, 42px);
  max-width: 820px;
  width: 100%;
  text-align: left;
  font-size: clamp(13px, 1.35vw, 16px);
  line-height: 1.7;
}

/* Each sentence starts on its own line. Unlike .line above, this one stays
   broken on phones too — the per-sentence rhythm is the point here. */
.sentence {
  display: block;
}

.dedication__body p + p {
  margin-top: 1.35em;
}

/* The closing reflection sits apart from the list of thank-yous. */
.dedication__body--closing {
  margin-top: clamp(44px, 5.5vw, 76px);
}

/* ---------- gallery ---------- */

.gallery-page {
  background: #ffffff;
  color: #575757;
}

.gallery {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(6px, 1vw, 14px) clamp(20px, 4vw, 56px) clamp(80px, 10vw, 140px);
}

.gallery__logo-link {
  display: block;
}

.gallery__logo {
  width: clamp(185px, 21.5vw, 310px);
  height: auto;
  display: block;
}

/* auto-fit + minmax means the browser picks the column count itself:
   as many columns as fit at 180px or wider, so 4 across on a laptop
   and fewer as the window narrows. No breakpoints needed. */
.gallery__grid {
  margin-top: clamp(48px, 7vw, 96px);
  width: 100%;
  max-width: 1080px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: clamp(28px, 5vw, 76px) clamp(24px, 4.5vw, 68px);
  justify-items: center;
}

.gallery__item {
  position: relative;
  display: block;
  margin: 0;
  width: 100%;
  max-width: 210px;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: 4px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.13);
}

/* Photos start drained of color — grayscale(1) — and ease back to full
   color on hover. The slight scale-up runs alongside it. */
.gallery__photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: grayscale(1);
  transition: filter 900ms ease,
              transform 900ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.gallery__item:hover .gallery__photo,
.gallery__item:focus-within .gallery__photo {
  filter: grayscale(0);
  transform: scale(1.04);
}

/* The hover layer: a translucent gray wash with the name centered on it.
   Invisible until the square is hovered, then it fades in. */
.gallery__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(90, 90, 90, 0.42);
  opacity: 0;
  transition: opacity 700ms ease;
}

.gallery__item:hover .gallery__overlay,
.gallery__item:focus-within .gallery__overlay {
  opacity: 1;
}

.gallery__name {
  font-family: "La Graziela", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: clamp(26px, 3.4vw, 40px);
  line-height: 1;
  color: #ffffff;
  text-transform: lowercase;
}

/* Placeholder tint for a square whose photo hasn't been chosen yet. */
.gallery__item--empty {
  background: #ededed;
}

/* ---------- person page ---------- */

.person-page {
  background: #ffffff;
  color: #575757;
}

/* Two panes side by side: the photo on the left, everything else on the right.
   The photo pane is a touch wider than half. */
.person {
  min-height: 100svh;
  display: grid;
  grid-template-columns: 1fr 1fr;
}

/* The photo is pinned to all four edges of its pane so it always fills the
   space completely, cropping whatever doesn't fit rather than shrinking. */
.person__photo-pane {
  position: relative;
  overflow: hidden;
}

.person__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* The right pane is a three-part stack: logo at top, name and thumbnails
   in the middle, back link at the bottom. */
.person__info-pane {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: clamp(28px, 4vw, 56px) clamp(24px, 4vw, 56px);
  text-align: center;
}

.person__logo-link {
  display: block;
}

.person__logo {
  width: clamp(120px, 13vw, 190px);
  height: auto;
  display: block;
}

.person__center {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.person__name {
  font-family: "La Graziela", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: clamp(44px, 6vw, 88px);
  font-weight: 400;
  line-height: 1;
  color: #a5a5a5;
  text-transform: lowercase;
}

/* The big photo fades by transparency only — no drift, no scaling. */
.person__photo.fade {
  transform: none;
  transition: opacity 900ms ease;
}

.person__photo.fade.is-visible {
  transform: none;
}

/* The little squares under the name — one per photo. */
.person__thumbs {
  margin-top: clamp(20px, 2.6vw, 34px);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.person__thumb {
  appearance: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  width: 11px;
  height: 11px;
  background: #dcdcdc;
  transition: background-color 400ms ease, transform 400ms ease;
}

.person__thumb:hover {
  background: #b8b8b8;
}

/* The one currently showing sits slightly larger and darker. */
.person__thumb.is-active {
  background: #a5a5a5;
  transform: scale(1.35);
}

.person__back {
  color: #a5a5a5;
  text-decoration: none;
  font-size: clamp(10px, 1vw, 12px);
  letter-spacing: 0.12em;
  transition: color 300ms ease;
}

.person__back:hover,
.person__back:focus-visible {
  color: #575757;
}

/* Phones and narrow windows: stack the two panes instead of side by side. */
@media (max-width: 760px) {
  .person {
    grid-template-columns: 1fr;
  }

  .person__photo-pane {
    height: 62svh;
  }

  .person__info-pane {
    gap: clamp(28px, 6vw, 44px);
    padding-top: clamp(24px, 5vw, 40px);
    padding-bottom: clamp(32px, 6vw, 48px);
  }
}

/* ---------- fade in ---------- */

/* Everything marked "fade" starts invisible and slightly low, then drifts up
   into place. The script staggers them so they arrive one after another. */
.fade {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 2000ms ease, transform 2000ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.fade.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Phones: let the text reflow naturally. The design's line breaks assume a
   wide screen, and forcing them on a narrow one leaves ragged short lines. */
@media (max-width: 700px) {
  .line {
    display: inline;
  }

  .about__body {
    text-align: left;
    max-width: 34em;
  }

  .about__logo {
    width: 51vw;
  }
}

/* Respect the system "reduce motion" setting — show the text, skip the drift. */
@media (prefers-reduced-motion: reduce) {
  .fade {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .dedication,
  .dedication.is-open {
    transition: opacity 200ms ease;
  }

  .about__dedication::after {
    transition: none;
  }

  .hero__slideshow-photo {
    transition: none;
  }
}
