/* ==========================================================================
   home.css — styles unique to the landing page. Anything reused by a second
   page graduates out of here into css/components/.
   Depends on: tokens.css, base.css, components/reveal.css

   Layout follows the Caleb Moore reference: a full-bleed cinematic hero with
   the name stacked over it, then the work grid, then a closing connect band.
   The grid was alternating full-width artwork/copy rows until 2026-08-27; it
   is now a 1/2/3-column card grid holding every piece on the site.

   Styling stays with what the piece pages established: very large uppercase
   Montserrat (--font-display-alt) for display type, small muted body copy,
   uppercase letter-spaced micro-labels, accent-red kickers.
   ========================================================================== */

/* --- Hero -----------------------------------------------------------------
   Type sits over artwork, so it uses the --color-on-media group rather than
   the theme colors. tokens.css defines those once on purpose: the photograph
   underneath does not get lighter in light mode.
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  display: grid;
  align-content: center;
  isolation: isolate;
  overflow: hidden;
  /* The sticky header is in flow above this, so the hero only has to fill the
     rest: 88svh plus --header-h lands just about one screen. */
  min-height: min(88svh, 52rem);
  /* Bottom padding reserves the scroll cue's lane; align-content centres the
     copy in what is left, which seats it a little above the optical middle. */
  padding-block: var(--space-8) var(--space-10);
  background-color: var(--ink-950);
  color: var(--color-on-media);

  /* The plate is dark in both themes, so everything inside is pinned to the
     dark-theme accent pair instead of following the page theme. tokens.css
     contrast-checks that pair at 7.1:1 on a dark ground; the light-theme
     accent-600 would sit at a muddy 2:1 over this scrim. This also retints
     the focus ring and the primary button for the whole hero. */
  --color-accent:       var(--accent-400);
  --color-accent-hover: var(--accent-500);
  --color-on-accent:    var(--ink-950);
}

.hero__backdrop {
  position: absolute;
  inset: 0;
  z-index: -1;
}

/* Two stacked plates: the poster still, and the reel that fades in over it.
   Both are shipped sharp and blurred here, at display time, so the amount is
   a one-number edit rather than a re-encode — index.html sets --hero-blur on
   .hero__backdrop, and tokens.css holds the default.

   That one number drives two properties that must stay in step. A CSS blur
   samples past the element's edge, so it leaves a transparent border roughly
   1.5x the radius wide; the scale grows the plate enough to push that border
   outside the hero. 0.008 per unit of blur is about double what the geometry
   needs at hero proportions, so there is margin to turn the blur well up
   before any corner goes bare. */
.hero__backdrop-image,
.hero__backdrop-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  filter: blur(calc(var(--hero-blur) * 1px)) saturate(1.1);
  transform: scale(calc(1 + var(--hero-blur) * 0.008));
}

/* The reel sits above the still and is revealed only once it is actually
   playing — heroVideo.js sets data-hero-video="playing". Until then the still
   shows through, so there is never a black or empty box. */
.hero__backdrop-video {
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}
.hero__backdrop-video[data-hero-video="playing"] { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .hero__backdrop-video { transition: none; }
}

/* Two layers: a flat darkening pass for contrast, and a bottom-weighted
   gradient so the scroll cue keeps its footing over a bright plate. */
.hero__backdrop::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: linear-gradient(
    to bottom,
    var(--color-media-scrim-soft) 0%,
    var(--color-media-scrim) 55%,
    var(--color-media-scrim) 100%
  );
}

.hero__kicker {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-accent);
  text-shadow: var(--shadow-text);
}

/* The piece-page signature, at landing scale: stacked uppercase Montserrat. */
.hero__title {
  margin-top: var(--space-4);
  font-family: var(--font-display-alt);
  font-size: clamp(2.8rem, 9.5vw, 8rem);
  font-weight: 700;
  line-height: 0.9;
  letter-spacing: -0.035em;
  text-transform: uppercase;
  text-shadow: var(--shadow-text);
}
.hero__title-line { display: block; }

.hero__role {
  max-width: 34rem;
  margin-top: var(--space-5);
  font-size: var(--text-lg);
  color: var(--color-on-media-muted);
  text-shadow: var(--shadow-text);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

/* --- Scroll cue -----------------------------------------------------------
   A real anchor, not decoration: it moves focus and the viewport to the
   featured section, and html{scroll-padding-top} keeps the heading clear of
   the sticky header.
   -------------------------------------------------------------------------- */
.hero__scroll {
  position: absolute;
  bottom: var(--space-6);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  color: var(--color-on-media-muted);
  text-decoration: none;
  text-shadow: var(--shadow-text);
}
.hero__scroll:hover { color: var(--color-on-media); }

.hero__scroll-label {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

.hero__scroll-arrow {
  width: var(--space-5);
  height: var(--space-5);
}

@media (prefers-reduced-motion: no-preference) {
  .hero__scroll-arrow { animation: hero-scroll-bob 2.4s var(--ease-inout) infinite; }
}
@keyframes hero-scroll-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(25%); }
}

/* The ghost button reads as invisible against a dark plate, so the hero gets
   its own variant keyed to the on-media colors instead of the theme border. */
.button--on-media {
  background-color: transparent;
  border-color: var(--color-on-media-muted);
  color: var(--color-on-media);
}
.button--on-media:hover {
  background-color: var(--color-on-media);
  border-color: var(--color-on-media);
  color: var(--ink-950);
}

/* --- Section head --------------------------------------------------------- */
.section-head {
  padding-bottom: clamp(var(--space-5), 3vw, var(--space-6));
  border-bottom: 1px solid var(--color-border);
}

.section-head__title {
  margin-top: var(--space-3);
  font-family: var(--font-display-alt);
  font-size: clamp(1.9rem, 4.4vw, 3.4rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  text-transform: uppercase;
}

.section-head__lede {
  margin-top: var(--space-4);
  font-size: var(--text-lg);
  color: var(--color-text-muted);
}

/* --- Featured grid --------------------------------------------------------
   This is the site's only work listing since 2026-08-27 — all thirteen pieces
   live here, newest first, and the separate /work/ grid is gone.

   It was two large alternating artwork/copy rows per screen; it is now a card
   grid that steps 1 -> 2 -> 3 columns. Each card stacks artwork over copy at
   every width, so the .feature--flip modifier that swapped sides row by row is
   gone with it. Column counts are chosen off the card, not the viewport: three
   across the 84rem container is a ~26rem card, which is about the narrowest a
   16:9 still plus a three-line paragraph reads well at.
   -------------------------------------------------------------------------- */
.feature-list {
  display: grid;
  grid-template-columns: 1fr;
  /* Row gap is generous, column gap is not — cards need air above and below
     more than beside, and a wide column gap eats card width at three across. */
  gap: clamp(var(--space-6), 5vw, var(--space-8)) var(--space-6);
  /* MARGIN, not padding. base.css resets `ul[role="list"] { padding: 0 }`,
     and an attribute selector outranks this class — a padding here is silently
     dropped, which is what happened to the padding-block this replaced.
     Asymmetric on purpose: see the closing-the-page note above .connect. The
     grid needs air under the section head, not under its last row. */
  margin-top: clamp(var(--space-5), 3vw, var(--space-7));
  margin-bottom: clamp(var(--space-5), 3vw, var(--space-7));
  list-style: none;
}

/* Positioned so .feature__link::after can stretch across the whole card.
   Column, not grid: the body has to be able to grow and push the link down. */
.feature {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);

  /* Display type has to shrink as the cards multiply, and vw alone cannot see
     the column count — a 1.8vw title is comfortable in one column and far too
     large in three at the same viewport. So each breakpoint sets its own. */
  --feature-title-size: clamp(1.5rem, 5.5vw, 2.2rem);
}

@media (min-width: 46rem) {
  .feature-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .feature { --feature-title-size: clamp(1.4rem, 2.6vw, 2rem); }
}

/* --- Desktop: bigger cards, tighter grid -----------------------------------
   Adam's call on 2026-08-28. Still three columns — he chose that over dropping
   to two — but the band goes wider than the rest of the page, the gutter and
   the column gap come in, and the width that frees up goes into the artwork:
   at 1920 the stills go from 240px tall to ~330px, and a row is a little under
   half the height of a 16:9 screen.

   The extra width is almost all from the container, not the gap. At 1440 the
   84rem page container is already narrower than the viewport, so tightening
   the gap alone bought about 5%; letting the band run to 112rem is what makes
   the difference on a 1920 screen, where 84rem had been leaving ~290px of
   empty margin down each side.

   112rem is not a new number — it is what .piece-media--bleed uses on the
   piece pages, so the whole site agrees on how wide "wider than the text
   column" is.
   -------------------------------------------------------------------------- */
@media (min-width: 70rem) {
  .feature-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* Wider cards can carry more display type than the old three-across could. */
  .feature { --feature-title-size: clamp(1.45rem, 2vw, 1.95rem); }

  .featured > .container {
    max-width: min(112rem, 100%);
    padding-inline: var(--space-6);
  }

  /* Column gap halves. The row gap comes down too but not as far — cards still
     need more air above and below than beside — and it goes flat rather than
     staying a clamp, because at this width the vw term was pinning it to its
     4rem ceiling anyway and 4rem of dead space between rows is most of what
     was keeping the second row off the screen. */
  .feature-list {
    gap: var(--space-6) var(--space-4);
    margin-top: var(--space-5);
  }

  /* Landing the header's Work button here should show that the grid carries on
     below the fold. A screen that ends flush on the first row reads as the
     whole list, which is what this section looked like before.

     html{scroll-padding-top} clears the sticky header; a NEGATIVE scroll
     margin pulls the landing a further --space-6 down the page. That comes out
     of this section's own top padding, which is empty space, so nothing
     visible is cut off — and it is enough to put ~75px of the second row's
     artwork on screen at 1366x768, the tightest 16:9 laptop worth designing
     for. Wider or taller screens get more.

     Desktop only. At phone widths --section-y is down to 2rem, and there is no
     empty padding to spend — the same rule would clip the eyebrow.
     ---------------------------------------------------------------------- */
  .featured { scroll-margin-top: calc(-1 * var(--space-6)); }
}

/* Artwork: 16:9, soft corners, slow hover zoom — the treatment the retired
   /work/ card used, kept because it is what the piece pages echo.
   Not a link itself — .feature__link is stretched over the card, so a click
   here still opens the piece without adding a second, unnamed tab stop. */
.feature__media {
  overflow: hidden;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  background-color: var(--color-bg-sunken);
  box-shadow: var(--shadow-md);
  transition: box-shadow var(--dur-med) var(--ease-out);
}

.feature__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}

/* Driven from the whole card, so hovering the copy lights the artwork too, and
   :focus-within gives keyboard users the same cue when the link takes focus. */
.feature:hover .feature__media,
.feature:focus-within .feature__media {
  box-shadow: var(--shadow-lg);
}
.feature:hover .feature__image,
.feature:focus-within .feature__image {
  transform: scale(1.04);
}

/* Grows to fill the card so "See more" can sit on the bottom edge — without
   this, a row whose titles wrap to one, two and three lines puts its links at
   three different heights. */
.feature__body {
  display: flex;
  flex-direction: column;
  flex: 1;
}

.feature__client {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-accent);
}

/* The cards run newest to oldest. Without a visible year that ordering reads
   as arbitrary, so the client label carries the year, set back a step so the
   client still leads. */
.feature__year {
  color: var(--color-text-subtle);
  font-variant-numeric: tabular-nums;
}

.feature__title {
  margin-top: var(--space-3);
  font-family: var(--font-display-alt);
  font-size: var(--feature-title-size);
  font-weight: 600;
  line-height: 0.98;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  text-wrap: balance;
}
.feature__title-line { display: block; }
/* Second line sits lighter, so the stack has hierarchy — as on piece pages. */
.feature__title-line--soft { color: var(--color-text-muted); }

/* margin-top:auto pins it to the bottom of the card, which is what keeps the
   links level across a row when titles wrap to different depths. align-self
   keeps the underline the width of its own text rather than the whole column,
   and the gap above it is padding, not margin, or the auto margin would lose. */
.feature__link {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: auto;
  padding-top: var(--space-4);
  padding-bottom: var(--space-1);
  border-bottom: 1px solid var(--color-border-strong);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.feature__link:hover {
  color: var(--color-accent);
  border-bottom-color: var(--color-accent);
}

/* The stretched hit area. The link stays static so this resolves against
   .feature, which makes the whole card — artwork included — clickable while
   the card keeps exactly one link and one tab stop. The focus ring still draws
   on the visible link text, not on this. */
.feature__link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius-lg);
}

.feature__link-arrow {
  transition: transform var(--dur-fast) var(--ease-out);
}
.feature:hover .feature__link-arrow {
  transform: translateX(var(--space-1));
}

/* --- Closing the page -----------------------------------------------------
   The landing page ends tight on purpose. It used to close on ~16rem of empty
   background — a full --section-y under .featured plus another over the connect
   band — which read as "the document ended" a screen and a half early.
   .featured now contributes no bottom padding and the grid carries a short
   bottom margin; the band's own padding and its sunken background do the rest.

   The band itself lives in css/components/connect.css — it is on every piece
   page too since 2026-08-28.
   -------------------------------------------------------------------------- */
.featured { padding-bottom: 0; }
