/* ============================================================
   GRAPHICXO — CHAPTERED CASE STUDY  (a board-based project)

   Loaded by project.php for any project that ships a body of its
   own in components/case/{slug}.php, after portfolio.css and
   project.css. A project may still add assets/css/case-{slug}.css
   on top for anything genuinely its own; neither of the two that
   use this needs to.

   WHAT THIS IS FOR
   A presentation board — moodboard, rationale, logo variations,
   palette, type, applications, campaign, all on one sheet — read
   as chapters instead of as a grid of tiles. The chapter order is
   the order the board itself is laid out in.

   NOTHING HERE IS BRANDED. Every colour reads --accent /
   --accent-rgb off .pj, set inline from the project's own accent,
   exactly as project.css does. That is what lets one stylesheet
   carry a coffee identity and a technology identity without
   either looking like the other.

   Hover rules live inside @media (hover:hover) — see the note at
   the top of main.css.
   ============================================================ */

.cs{
  /* The ceiling on how far a plate may be blown up past its own pixels.
     These boards export at 1536px across three columns, so a single
     section arrives 370–670px wide. At 1.0 a section is a stamp on a
     desktop; past about 1.4 the 8px caption type on a board visibly
     softens. 1.35 is the last stop where the small type still holds.
     A project with higher-resolution artwork can raise it in its own
     case-{slug}.css and everything below follows. */
  --cs-upscale:1.35;

  --cs-gap:clamp(3.5rem,9vh,7.5rem);
}

/* ------------------------------------------------------------
   PLATE
   One rule for every image on the page. Board artwork is opaque
   and often light, so it needs a mount rather than a background:
   a hairline, a radius, and the project accent bleeding out from
   underneath the way .pj-plate does on every other case study.
   ------------------------------------------------------------ */
.cs-plate{
  margin:0;
  /* --w is the file's true width, set inline per plate. This is the whole
     no-upscaling contract: an image is never asked to be wider than its
     own pixels times the ceiling above, whatever room the column has. */
  width:min(100%, calc(var(--w) * var(--cs-upscale)));
  border-radius:16px;
  overflow:hidden;
  border:1px solid rgba(var(--accent-rgb),.20);
  box-shadow:0 40px 110px -55px rgba(var(--accent-rgb),.85),
             0 2px 40px -28px rgba(var(--accent-rgb),.5);
  transition:border-color .5s var(--ease), transform .7s var(--ease);
}
.cs-plate img{
  display:block;
  width:100%;height:auto;
  /* No object-fit anywhere in this file on purpose. Every plate is drawn
     at its own aspect ratio, so there is nothing to fit and nothing that
     could crop. */
}
@media (hover:hover){
  .cs-plate:hover{border-color:rgba(var(--accent-rgb),.55);transform:translateY(-4px)}
}

/* ------------------------------------------------------------
   THE OPENING BOARD
   ------------------------------------------------------------ */
.cs-open{padding-top:clamp(2rem,5vh,3.5rem)}
.cs-open .cs-plate{margin-inline:auto}

/* Visually hidden, still read. The opening section needs a heading for the
   document outline; printing one above the board would be a caption on a
   picture that introduces itself. */
.cs-sr{
  position:absolute;width:1px;height:1px;
  padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}

/* ------------------------------------------------------------
   LEDE — the concept label, and the read
   ------------------------------------------------------------ */
.cs-lede{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);
  gap:clamp(2rem,5vw,5rem);
  padding-block:var(--cs-gap);
}
.cs-lede__h{
  font-family:var(--serif);
  font-size:clamp(1.8rem,3.6vw,3rem);
  line-height:1.06;
  letter-spacing:-.02em;
  margin-top:1.4rem;
}
/* The concept badge. Accent-driven like .pj-head__tags rather than dressed
   in the brand's own colours: it is Graphicxo making a statement ABOUT the
   work — that nobody commissioned it — and it should read in the studio's
   voice, not in the voice of the brand it is labelling. */
.cs-tag{
  display:inline-block;
  font-size:.7rem;font-weight:600;letter-spacing:.22em;text-transform:uppercase;
  color:var(--accent);
  background:rgba(var(--accent-rgb),.10);
  border:1px solid rgba(var(--accent-rgb),.45);
  border-radius:100px;
  padding:.5rem 1.1rem;
}
.cs-lede__body p{
  font-size:clamp(1rem,1.35vw,1.16rem);
  font-weight:300;
  color:var(--grey);
  max-width:62ch;
}
.cs-lede__body p + p{margin-top:1.2rem}
.cs-lede__body strong{color:var(--white);font-weight:600}
.cs-lede__body em{color:var(--white);font-style:italic}

/* A small plate set into the lede — the board's own title block or credits
   panel, shown as evidence for the concept label rather than as artwork. */
.cs-lede__proof{margin-top:clamp(1.6rem,3vw,2.4rem)}
.cs-lede__proof .cs-plate{--cs-upscale:1}
.cs-lede__cap{
  font-size:.8rem;color:var(--grey-dim);
  margin-top:.8rem;max-width:52ch;
}

/* ------------------------------------------------------------
   CHAPTERS
   ------------------------------------------------------------ */
.cs-ch{padding-block:var(--cs-gap)}
.cs-ch__head{
  display:flex;align-items:baseline;gap:1.2rem;
  padding-bottom:1.6rem;
  margin-bottom:clamp(2rem,4vw,3.2rem);
  border-bottom:1px solid var(--line);
}
.cs-ch__num{
  font-family:var(--serif);
  font-size:clamp(1rem,1.6vw,1.3rem);
  color:var(--accent);
  letter-spacing:.08em;
}
.cs-ch__title{
  font-family:var(--serif);
  font-size:clamp(1.6rem,3.4vw,2.6rem);
  letter-spacing:-.02em;
  line-height:1.1;
}

.cs-ch__body{
  display:grid;
  grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(2rem,4.5vw,4.5rem);
  align-items:start;
}
/* Alternating sides down the page. Source order stays copy-then-image on
   every chapter — a screen reader and a phone both get the writing first,
   and only the grid placement swaps. */
.cs-ch--flip .cs-ch__body{grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr)}
.cs-ch--flip .cs-ch__copy{grid-column:2;grid-row:1}
.cs-ch--flip .cs-plate,
.cs-ch--flip .cs-plates{grid-column:1;grid-row:1}

/* A chapter carrying two plates, or a palette row, takes the full width for
   its copy rather than a column beside a picture. */
.cs-ch--wide .cs-ch__body{grid-template-columns:minmax(0,1fr)}
.cs-ch--wide .cs-ch__copy{max-width:74ch}

/* A landscape strip — an applications row, a campaign band — is wider than
   it is tall and looks stranded in a 45% column. It gets the full width
   with the copy above it. */
.cs-ch--band .cs-ch__body{grid-template-columns:minmax(0,1fr)}
.cs-ch--band .cs-ch__copy{max-width:74ch;margin-bottom:clamp(2rem,4vw,3rem)}
.cs-ch--band .cs-plate{margin-inline:auto}

/* The columns off a board are up to 1024px tall and the copy beside them is
   three or four short paragraphs, so a static column leaves most of a screen
   empty next to a very long picture. Sticking the writing to the top of the
   viewport keeps it with the plate it describes while that plate scrolls
   past — which is the whole reason the two are side by side. Grid item with
   align-self:start, so the sticky containing block is the full-height grid
   area rather than the copy's own box. Only above 900px: below that the two
   are stacked and there is nothing to track. */
@media (min-width:901px){
  .cs-ch:not(.cs-ch--wide):not(.cs-ch--band) .cs-ch__copy{
    position:sticky;
    top:clamp(6.5rem,14vh,9rem);
    align-self:start;
  }
}

.cs-ch__copy p{
  font-size:clamp(.98rem,1.2vw,1.08rem);
  font-weight:300;
  color:var(--grey);
  max-width:56ch;
}
.cs-ch--wide .cs-ch__copy p,
.cs-ch--band .cs-ch__copy p{max-width:70ch}
.cs-ch__copy p + p{margin-top:1.1rem}
.cs-ch__copy strong{color:var(--white);font-weight:600}
.cs-ch__copy em{color:var(--white);font-style:italic}
/* Small-caps runs off a board — EST. 2024, RICH · SMOOTH · BALANCED — kept
   on one line so a break never invents a second meaning. */
.cs-nw{white-space:nowrap;color:var(--white)}

/* Two plates side by side, each still capped at its own width.
   A grid rather than wrapping flex: the caps mean two natural widths added
   together can overflow the page, and flex then drops the second plate onto
   its own line and leaves half the page empty beside each. Two equal columns
   give each plate a box narrower than its own ceiling, so they sit level and
   neither is upscaled to fill. */
.cs-plates,
.cs-sheets__grid{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(1.2rem,2.5vw,2.4rem);
  align-items:start;
  justify-items:center;
}

/* ------------------------------------------------------------
   PALETTE
   The row itself is project.css's .pj-pal__row — chips, contrast
   flip and copy-on-click all inherited. This is only its setting
   inside a chapter.
   ------------------------------------------------------------ */
.cs-pal{margin-top:clamp(2.5rem,5vw,4rem)}
.cs-pal__note{
  font-size:.85rem;color:var(--grey-dim);
  margin-bottom:1.2rem;max-width:60ch;
}

/* ------------------------------------------------------------
   THE SHEETS — full-height columns off the board
   ------------------------------------------------------------ */
.cs-sheets{padding-block:var(--cs-gap)}
.cs-sheets__note{
  font-size:clamp(.98rem,1.2vw,1.08rem);
  font-weight:300;color:var(--grey);
  max-width:60ch;
  margin-bottom:clamp(2rem,4vw,3rem);
}
.cs-sheets__grid{gap:clamp(1.2rem,3vw,3rem)}

/* ------------------------------------------------------------
   NARROW
   One column, image after copy, everything full width up to its
   own pixel ceiling. Nothing is hidden on a phone — a case study
   that drops half its evidence on the device most people read it
   on is not a case study.
   ------------------------------------------------------------ */
@media (max-width:900px){
  /* minmax(0,1fr) rather than a bare 1fr, to match the wide layout above.
     `1fr` is minmax(AUTO,1fr), and a track's auto minimum is the min-content
     of its contents — which for a column holding an image is that image's
     intrinsic width. It does not bite here, because .cs-plate carries
     width:min(100%,…) and an <img> at width:100% has a min-content of zero.
     It is written this way so it stays true if a plate is ever given a
     min-width, or a table or a long unbroken string lands in the copy. */
  .cs-lede{grid-template-columns:minmax(0,1fr);gap:1.8rem}
  .cs-ch__body,
  .cs-ch--flip .cs-ch__body{grid-template-columns:minmax(0,1fr)}
  .cs-ch--flip .cs-ch__copy,
  .cs-ch--flip .cs-plate,
  .cs-ch--flip .cs-plates{grid-column:1;grid-row:auto}
  .cs-plate{margin-inline:auto}
  /* Below this width two columns would put each plate under 300px, which is
     smaller than the artwork's own pixels and throws away detail the file
     has. One per row instead. */
  .cs-plates,.cs-sheets__grid{grid-template-columns:minmax(0,1fr)}
}

@media (max-width:560px){
  .cs-ch__head{flex-direction:column;gap:.4rem}
  .cs{--cs-gap:clamp(2.5rem,7vh,4rem)}
}

@media (prefers-reduced-motion:reduce){
  @media (hover:hover){
    .cs-plate:hover{transform:none}
  }
}
