/*
 * Case study modules
 *
 * Every case study page is a stack of these blocks and nothing else, which
 * is what makes the five read as one site. To build a new case study, copy
 * mood.html and swap the modules and media. Full catalogue with intended
 * use: REDESIGN-SPEC.md Part 3.1.
 *
 *   cs-hero     full-bleed media with the title over it
 *   cs-intro    facts on the left, the brief on the right
 *   cs-meta     project type / deliverables / tools
 *   cs-full     one piece of media, edge to edge
 *   cs-pair     two up
 *   cs-triple   three up (once per page at most)
 *   cs-offset   big left + small right, staggered (add --reverse to flip)
 *   cs-tint     any of the above on the charcoal ground
 *   cs-motion   one video with a caption
 *   cs-detail   one image, centred, with room around it
 *   cs-quote    one sentence, set large
 *   cs-next     link to the next project; closes every page
 *
 * Loads after tokens.css and site.css.
 */

/* ---- Page frame ----------------------------------------------------- */

/* The hero stays pinned while the page body slides up over it. */
.cs-body {
  position: relative;
  z-index: 1;
  background: var(--paper);
  padding-top: var(--module-gap);
}

/* Vertical rhythm: one gap between every module. */
.cs-body > * + * {
  margin-top: var(--module-gap);
}

figure img,
figure video {
  width: 100%;
  height: auto;
}

figcaption {
  margin-top: var(--sp-2);
  color: var(--ink);
}

.cs-tint figcaption {
  color: var(--white);
}

/* ---- cs-hero -------------------------------------------------------- */

.cs-hero {
  position: sticky;
  top: 0;
  z-index: 0;
  height: 88svh;
  min-height: 480px;
  overflow: hidden;
  color: var(--white);
  background: var(--ground);
}

/* The art starts below the fixed nav bar, so none of it hides behind it. */
.cs-hero__media {
  position: absolute;
  inset: var(--nav-height) 0 0 0;
}

.cs-hero__media img,
.cs-hero__media video,
.cs-hero__media picture {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* For black-ground artwork that must not be cropped on phones (Disrupt):
   the hero turns black and the art is shown whole. */
.cs-hero--black {
  background: #000;
}

@media (max-width: 860px) {
  .cs-hero--black .cs-hero__media video,
  .cs-hero--black .cs-hero__media img {
    object-fit: contain;
    object-position: 50% 35%;
  }
}

/* Scrim so the title reads over any artwork. */
.cs-hero::after {
  content: "";
  position: absolute;
  inset: 35% 0 0 0;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.78), rgba(0, 0, 0, 0.4) 55%, rgba(0, 0, 0, 0));
  pointer-events: none;
}

.cs-hero__title {
  position: absolute;
  left: 0;
  right: 0;
  bottom: var(--sp-6);
  z-index: 1;
  /* A soft shadow on top of the scrim, for light artwork. */
  text-shadow: 0 1px 16px rgba(0, 0, 0, 0.35);
}

.cs-hero__title .label {
  margin-bottom: var(--sp-2);
  color: var(--white);
}

.cs-hero h1 {
  font-family: var(--font-display);
  font-weight: 200;
  font-size: var(--step-4);
  line-height: var(--leading-tight);
  letter-spacing: -0.015em;
}

@media (max-width: 860px) {
  .cs-hero {
    height: 72svh;
    min-height: 420px;
  }

  .cs-hero__title {
    bottom: var(--sp-5);
  }
}

/* ---- cs-intro ------------------------------------------------------- */

.cs-intro {
  row-gap: var(--sp-5);
  align-items: start;
}

.cs-intro__facts {
  grid-column: 1 / span 4;
  display: grid;
  gap: var(--sp-3);
}

.cs-intro__facts dt {
  color: var(--ink);
  margin-bottom: var(--sp-1);
}

.cs-intro__brief {
  grid-column: 6 / span 7;
}

.cs-intro__brief p {
  font-size: var(--step-1);
  line-height: var(--leading-body);
  max-width: 52ch;
}

.cs-intro__brief p + p {
  margin-top: var(--sp-3);
}

.cs-intro__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-5);
}

/* Outline button for "View the live site", "See the process". */
.cs-button {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.75em 1.3em;
  border: 1px solid currentColor;
  border-radius: 2px;
  font-size: var(--step-0);
  line-height: 1;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.cs-button:hover {
  color: var(--paper);
  background: var(--ink);
  border-color: var(--ink);
}

@media (max-width: 860px) {
  .cs-intro__facts,
  .cs-intro__brief {
    grid-column: 1 / -1;
  }

  .cs-intro__brief {
    order: -1;
  }

  .cs-intro__facts {
    grid-template-columns: 1fr 1fr;
  }
}

/* ---- cs-meta -------------------------------------------------------- */

.cs-meta dl {
  padding-top: var(--sp-3);
  border-top: 1px solid var(--rule-dark);
  row-gap: var(--sp-4);
}

.cs-meta dl > div {
  grid-column: span 4;
}

.cs-meta dt {
  color: var(--ink);
  margin-bottom: var(--sp-1);
}

.cs-meta dd {
  line-height: var(--leading-body);
}

@media (max-width: 860px) {
  .cs-meta dl > div {
    grid-column: 1 / -1;
  }
}

/* ---- cs-full -------------------------------------------------------- */

/* Edge to edge. Tall media is capped so one image never eats more than a
   screen. */
.cs-full figure > img,
.cs-full figure > video {
  max-height: 92svh;
  object-fit: cover;
}

/* For overview grids (a sheet of spreads, a wall of posters) where any
   crop would slice through real content: show the whole image, still no
   taller than the screen. */
/* The figure shrinks to the image, so the caption sits under the art. */
.cs-full--whole figure {
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
}

.cs-full--whole figure > img,
.cs-full--whole figure > video {
  width: auto;
  max-width: 100%;
  max-height: 100svh;
}

.cs-full.cs-full--whole figcaption {
  padding-inline: 0;
}

.cs-full figcaption {
  padding-inline: var(--margin);
}

/* ---- cs-pair / cs-triple -------------------------------------------- */

.cs-pair,
.cs-triple {
  row-gap: var(--sp-5);
  align-items: start;
}

.cs-pair > figure   { grid-column: span 6; }
.cs-triple > figure { grid-column: span 4; }

/* Matched pair: both items cropped to one shape so their bottoms line up.
   The shape comes from --ratio on the section. */
.cs-pair--fit > figure > img,
.cs-pair--fit > figure > video {
  aspect-ratio: var(--ratio, 1 / 1);
  object-fit: cover;
}

/* Tablets keep pairs and triples side by side; only phones stack them. */
@media (max-width: 599px) {
  .cs-pair > figure,
  .cs-triple > figure {
    grid-column: 1 / -1;
  }
}

/* ---- cs-offset ------------------------------------------------------ */

.cs-offset {
  row-gap: var(--sp-5);
  align-items: start;
}

.cs-offset > figure:first-child {
  grid-column: 1 / span 7;
}

.cs-offset > figure:last-child {
  grid-column: 8 / span 5;
  margin-top: var(--sp-7);
}

.cs-offset--reverse > figure:first-child {
  grid-column: 6 / span 7;
  grid-row: 1;
}

.cs-offset--reverse > figure:last-child {
  grid-column: 1 / span 5;
  grid-row: 1;
}

@media (max-width: 860px) {
  .cs-offset > figure:first-child,
  .cs-offset > figure:last-child,
  .cs-offset--reverse > figure:first-child,
  .cs-offset--reverse > figure:last-child {
    grid-column: 1 / -1;
    grid-row: auto;
    margin-top: 0;
  }

  /* Keep a little stagger on phones so it still reads as a pair. */
  .cs-offset > figure:last-child {
    width: 72%;
    margin-left: auto;
  }
}

/* ---- cs-tint -------------------------------------------------------- */

.cs-tint {
  color: var(--white);
  background: var(--ground);
  padding-block: var(--module-gap);
}

/* For artwork on pure black (Disrupt), so the art doesn't sit in a
   charcoal frame. */
.cs-tint--black {
  background: #000;
}

/* Modules stacked inside a tint get the same rhythm as the page. */
.cs-tint > * + * {
  margin-top: var(--module-gap);
}

/* ---- cs-motion ------------------------------------------------------ */

.cs-motion figure {
  grid-column: 1 / -1;
}

/* Narrow variant for portrait video (phone recordings, stories). Four
   columns keeps a 9:16 clip to roughly one screen tall. */
.cs-motion--narrow figure {
  grid-column: 5 / span 4;
  /* Never taller than about 80% of the screen. */
  width: min(100%, calc(80svh * 9 / 16));
  justify-self: center;
}

@media (max-width: 860px) {
  .cs-motion--narrow figure {
    grid-column: 2 / span 10;
  }
}

/* ---- cs-detail ------------------------------------------------------ */

.cs-detail figure {
  grid-column: 4 / span 6;
}

@media (max-width: 860px) {
  .cs-detail figure {
    grid-column: 2 / span 10;
  }
}

/* ---- cs-quote ------------------------------------------------------- */

.cs-quote {
  padding-block: var(--module-half);
}

.cs-quote blockquote {
  grid-column: 3 / span 8;
  font-family: var(--font-display);
  font-weight: 200;
  font-size: var(--step-3);
  line-height: var(--leading-tight);
  letter-spacing: -0.01em;
  text-align: center;
  text-wrap: balance;
}

.cs-quote blockquote footer {
  margin-top: var(--sp-4);
  color: var(--ink);
  letter-spacing: normal;
}

@media (max-width: 860px) {
  .cs-quote blockquote {
    grid-column: 1 / -1;
  }
}

/* ---- cs-next -------------------------------------------------------- */

.cs-next {
  display: block;
  color: var(--white);
  background: var(--ground);
  /* The footer below brings its own full top gap, so no bottom padding
     and no rule here. */
  padding-block: var(--module-gap) 0;
}

.cs-next .label {
  color: var(--white);
  margin-bottom: var(--sp-3);
}

.cs-next__title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  font-family: var(--font-display);
  font-weight: 200;
  font-size: var(--step-2);
  line-height: var(--leading-tight);
  letter-spacing: -0.01em;
}

.cs-next__arrow {
  color: var(--white);
  font-family: var(--font-text);
  font-weight: 400;
  font-size: var(--step-1);
  transition: transform var(--dur-base) var(--ease);
}

@media (prefers-reduced-motion: no-preference) {
  .cs-next:hover .cs-next__arrow {
    transform: translateX(12px);
  }
}

/* The block is full width, so an outside focus ring would fall off the
   screen. Draw it inside instead. */
.cs-next:focus-visible {
  outline-offset: -12px;
}

.cs-next:hover .cs-next__title span:first-child {
  color: var(--accent);
  transition: color var(--dur-fast) var(--ease);
}

/* Square variant: both items framed as identical white squares, for
   artwork on white of different proportions (logos, type animations). */
.cs-pair--square > figure > img,
.cs-pair--square > figure > video {
  aspect-ratio: 1 / 1;
  object-fit: contain;
  background: var(--white);
}


/* On phones, figures inside one module sit closer than modules do, so a
   pair still reads as a pair. */
@media (max-width: 860px) {
  .cs-pair,
  .cs-triple,
  .cs-offset {
    row-gap: var(--sp-4);
  }
}

/* Touch screens get 44px tall buttons so they are easy to hit. */
@media (pointer: coarse) {
  .cs-button {
    min-height: 44px;
  }
}

/* ---- Process pages -------------------------------------------------- */
/* A plain title, one line of intro, then a loose masonry board of
   sketches and drafts. No hero, so the body starts below the nav. */
.cs-body--process {
  padding-top: calc(var(--nav-height) + var(--module-gap));
}

.process-head .label {
  grid-column: 1 / -1;
  color: var(--ink);
  margin-bottom: var(--sp-2);
}

.process-head h1 {
  grid-column: 1 / -1;
  font-family: var(--font-display);
  font-weight: 200;
  font-size: var(--step-3);
  line-height: var(--leading-tight);
  letter-spacing: -0.015em;
}

.process-head__intro {
  grid-column: 1 / span 6;
  margin-top: var(--sp-3);
  font-size: var(--step-1);
  line-height: var(--leading-body);
}

.process-board {
  columns: 3 280px;
  column-gap: var(--gutter);
}

.process-board figure {
  break-inside: avoid;
  margin-bottom: var(--sp-5);
}

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