/*
 * Homepage
 *
 * The original opening (the wordmark and one line about Zoey on the
 * charcoal ground), then the work on a light section: a card grid of the
 * featured projects and a list of the rest. The wordmark is fixed and
 * shrinks into the nav on scroll; js/hero.js drives that. Loads after
 * tokens.css and site.css.
 */

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

.home-hero {
  /* The wordmark's top lines up with the nav links. --hero-top is set
     from the nav height so it holds at every size. */
  --hero-top: calc(var(--nav-height) / 2 - 0.36rem);
  padding-top: var(--hero-top);
  padding-bottom: var(--sp-6);
}

/* The real wordmark. Fixed, so it can travel into the nav; the spacer
   below holds its place in the layout. */
.hero__name {
  position: fixed;
  top: calc(var(--nav-height) / 2 - 0.36rem);
  /* Same left edge as the content column (and the nav), which stops
     growing at --max-width and centres on wide screens. */
  left: max(var(--margin), calc((100vw - var(--max-width)) / 2 + var(--margin)));
  z-index: 101;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 200;
  font-size: var(--step-5);
  line-height: 0.86;
  letter-spacing: -0.012em;
  color: var(--white);
  transform-origin: top left;
  will-change: transform;
  pointer-events: none;
}

.hero__spacer {
  font-family: var(--font-display);
  font-weight: 200;
  font-size: var(--step-5);
  line-height: 0.86;
  letter-spacing: -0.012em;
  visibility: hidden;
}

/* The open mobile menu shows its own logo; hide the travelling one. */
.menu-open .hero__name {
  opacity: 0;
}

/* Each letter is its own span so js/warp.js can give it a slow drift.
   The transforms never change layout, so nothing reflows. */
.hero__name .ch {
  display: inline-block;
}

.home-hero__lower {
  /* A hairline under the name gives the opening a horizon: the name
     above, a left column (bio and the cue) and the reel below. */
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--rule-light);
  row-gap: var(--sp-4);
}

/* The bio sits straight under the name; the reel fills the rest of the
   row to its right. */
.home-hero__bio {
  grid-column: 1 / span 4;
  grid-row: 1;
  align-self: start;
  font-size: var(--step-1);
  line-height: 1.45;
  max-width: 34ch;
}

/* The motion reel. The video is blended in the file itself: white-ground
   shots are lightness-inverted (colours kept) and black is mapped to the
   charcoal, so the work sits straight on the page with no box. The edges
   are feathered too. 16:9 here; phones get the square cut (index.html
   picks the file with a media query on <source>). */
.home-hero__media {
  grid-column: 7 / -1;
  grid-row: 1 / span 2;
}

.home-hero__media video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 4%, #000 96%, transparent), linear-gradient(to bottom, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to right, transparent, #000 4%, #000 96%, transparent), linear-gradient(to bottom, transparent, #000 6%, #000 94%, transparent);
  mask-composite: intersect;
}

/* Pause / Play. Sits under the reel like a caption. */
.reel__toggle {
  display: block;
  margin: var(--sp-2) 0 0 auto;
  padding: 0;
  color: var(--white);
  background: none;
  border: 0;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease);
}

.reel__toggle:hover {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* With reduced motion on, the reel gets the browser's own controls
   instead (js/lazy-video.js). */
@media (prefers-reduced-motion: reduce) {
  .reel__toggle {
    display: none;
  }
}

@media (pointer: coarse) {
  .reel__toggle {
    min-width: 44px;
    padding-block: 14px;
    margin-top: 2px;
  }
}

.home-hero__bio a {
  border-bottom: 1px solid var(--muted);
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.home-hero__bio a:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.home-hero__cue {
  grid-column: 1 / span 4;
  grid-row: 2;
  align-self: end;
  justify-self: start;
  color: var(--white);
  transition: color var(--dur-fast) var(--ease);
}

.home-hero__cue:hover {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

@media (max-width: 860px) {
  .home-hero__bio {
    grid-column: 1 / -1;
  }

  .home-hero__cue {
    display: none;
  }

  .home-hero__media {
    grid-column: 1 / -1;
    grid-row: auto;
  }
}

@media (max-width: 599px) {
  .home-hero__media video {
    aspect-ratio: 1 / 1;
  }
}

/* ---- Work section (light) ------------------------------------------- */

.work-area {
  color: var(--ink);
  background: var(--paper);
  padding-block: var(--module-gap);
}

.section-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-3);
  margin-bottom: var(--sp-6);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--rule-dark);
}

/* Section titles: display face, one step above the item titles under
   them. Same role and size on every page. */
.section-head h2 {
  font-family: var(--font-display);
  font-weight: 200;
  font-size: var(--step-3);
  line-height: var(--leading-tight);
  letter-spacing: -0.01em;
}

/* ---- Card grid ------------------------------------------------------ */
/* Zoey's original two-up grid, brought back from the 2020 site: two
   columns split by one thin vertical rule. Each piece reads top down: a
   small line of context, the name and discipline in a big grotesk on two
   lines, then the work. The rule is sticky, as it was on the old site, so
   it rides down the middle of the screen while you scroll the pairs. */

.card-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 1px minmax(0, 1fr);
  row-gap: var(--sp-8);
  align-items: start;
}

.card-grid__rule {
  grid-column: 2;
  grid-row: 1 / span 3;
  align-self: start;
  position: sticky;
  top: calc(var(--nav-height) + var(--sp-4));
  height: calc(100vh - var(--nav-height) - var(--sp-7));
  background: var(--rule-dark);
}

.tile {
  display: flex;
  flex-direction: column;
  color: var(--ink);
}

/* Odd pieces on the left, even on the right, with room on both sides of
   the rule. */
.tile:nth-of-type(odd) { grid-column: 1; padding-right: var(--sp-7); }
.tile:nth-of-type(even) { grid-column: 3; padding-left: var(--sp-7); }

.tile__meta {
  margin-bottom: var(--sp-5);
}

.tile__desc {
  margin-bottom: var(--sp-2);
  color: var(--ink);
}

.tile__title {
  font-family: var(--font-text);
  font-weight: 400;
  font-size: var(--step-2);
  line-height: var(--leading-tight);
  letter-spacing: -0.01em;
}

.tile__media {
  position: relative;
  overflow: hidden;
  border-radius: 4px;
  aspect-ratio: 5 / 4;
  background: #DADAD8;
}

.tile__media img,
.tile__media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 700ms var(--ease);
}

@media (prefers-reduced-motion: no-preference) {
  .tile:hover .tile__media img,
  .tile:hover .tile__media video {
    transform: scale(1.03);
  }
}

/* Round "View" bubble that follows the cursor over the work (desktop,
   js/site.js), in the joy colour. It squashes and stretches as it moves. */
.view-cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  width: 84px;
  height: 84px;
  border-radius: 50%;
  font-size: var(--step--1);
  color: var(--ink);
  background: var(--pop);
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.4);
  /* js/site.js drives the movement and squash every frame, so only the
     fade is a transition here. */
  transition: opacity var(--dur-fast) var(--ease);
}

.view-cursor.is-on {
  opacity: 1;
}

@media (max-width: 860px) {
  /* One column on phones. The vertical rule turns into a hairline above
     each piece after the first. */
  .card-grid {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 0;
  }

  .card-grid__rule {
    display: none;
  }

  .tile:nth-of-type(n) {
    grid-column: 1;
    padding-inline: 0;
  }

  .tile + .tile {
    margin-top: var(--sp-6);
    padding-top: var(--sp-4);
    border-top: 1px solid var(--rule-dark);
  }

  .tile__meta {
    margin-bottom: var(--sp-3);
  }

  .tile__desc {
    margin-bottom: var(--sp-2);
  }

  .view-cursor {
    display: none;
  }
}

/* ---- More work list ------------------------------------------------- */
/* The rest of the work as a quiet index: hairlines above, between and
   below the rows, and four aligned columns (number, name, type, arrow).
   No hover effect on the names; on a mouse, a preview of the project
   follows the cursor while you hover a row (js/site.js). */

.more {
  margin-top: var(--module-gap);
}

.more__list {
  list-style: none;
  border-top: 1px solid var(--ink);
}

.more__list li {
  border-bottom: 1px solid var(--rule-dark);
}

/* On hover the row inverts: ink fill, paper text. The fill bleeds a
   little past the column (negative margin) so the text keeps its place. */
.more__row {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
  align-items: baseline;
  margin-inline: calc(var(--sp-2) * -1);
  padding: var(--sp-4) var(--sp-2);
  transition: color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}

.more__row:hover,
.more__row:focus-visible {
  color: var(--paper);
  background: var(--ink);
}

.more__row:focus-visible {
  outline-offset: 0;
}

.more__num {
  grid-column: 1;
  font-variant-numeric: tabular-nums;
}

.more__name {
  grid-column: 2 / span 6;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--step-2);
  line-height: var(--leading-tight);
}

.more__type {
  grid-column: 9 / span 3;
}

.more__ext {
  grid-column: 12;
  justify-self: end;
  font-size: var(--step-1);
  line-height: 1;
}

.more__preview {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 50;
  width: 300px;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 10px;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease);
  background: #D9D9D7;
}

.more__preview.is-on {
  opacity: 1;
}

.more__preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (max-width: 860px) {
  /* Number and arrow keep their places; the type drops under the name. */
  .more__row {
    grid-template-columns: var(--sp-5) minmax(0, 1fr) auto;
    row-gap: var(--sp-1);
    padding-block: var(--sp-3);
  }


  .more__num { grid-column: 1; grid-row: 1; }
  .more__name { grid-column: 2; grid-row: 1; }
  .more__ext { grid-column: 3; grid-row: 1; }
  .more__type { grid-column: 2; grid-row: 2; }

  .more__preview {
    display: none;
  }
}

/* ---- Reduced motion ------------------------------------------------- */
/* No travelling wordmark: it sits in the hero as ordinary text and the
   nav logo appears once the bar turns solid past it. */
@media (prefers-reduced-motion: reduce) {
  .hero__name {
    position: static;
  }

  .hero__spacer {
    display: none;
  }

  .page-home .site-nav.is-solid .site-nav__logo {
    opacity: 1;
  }
}
