/* =============================================================================
   case-study.css — the frame the project pages share.

   Four pages, one layout:

   site/smart-home-design-system.html (the page it was first written for),
   site/hairdresser-website.html, site/econudge-sustainable-tool.html and
   site/website-redesign.html. What they
   share is the DOCUMENT — an Inter-set intro, a centred column of --cs-measure
   (800px unless a page asks for more), and media that sits in that column. What they
   do NOT share is the media itself, or the page's own typographic policy: those stay
   in a per-page file (design-system.css stacks the design
   system's three specimen sheets; hairdresser-website.css and
   econudge-sustainable-tool.css each re-point the one token that decides what face the
   headings are set in, the second of them also caps the width of a portrait
   recording, and website-redesign.css re-points the column itself — its three flat
   screenshots are 2290-2604px wide and want 1000px of document, not 800px).

   NOT to be confused with site/system/ — that directory is the site's own
   informal design system (tokens, base, components).

   Loaded after system/tokens.css, system/base.css, system/components.css and
   portfolio.css, so it inherits rather than restates:

     --c-bg / --c-fg   the monochrome pair (system/tokens.css), so "white
                       background" is the page's own token, not a new hex
     --pad-page        the page inset (system/tokens.css) — the gutter the
                       document keeps on a phone, where 800px is wider than the
                       screen
     --s-3 / --fs-body the spacing and body-size steps the blocks are built from
     --font-page       Funnel Display first (portfolio.css): the page chrome and
                       — on a page that asks for it — the headings
     .header .burger .nav .lang .container .ds-skip
                       the shared header chrome, from portfolio.css,
                       system/base.css and system/components.css
   ========================================================================== */

/* --- Inter ----------------------------------------------------------------
   The case-study BODY face. The paragraphs are the one part of these pages that
   is prose rather than chrome, so they are set in a text face while the page
   around them stays on Funnel Display.

   SELF-HOSTED, for the same two reasons Funnel Display is in portfolio.css: the
   site keeps its rule of zero runtime third-party requests, and the files then
   fall under the existing /system/fonts/(.*) immutable cache header in
   vercel.json instead of a new origin. latin + latin-ext are the official Inter
   subsets, and the variable file covers every weight 100-900, so one file per
   subset carries the bold title, the bold labels and the body copy.

   @font-face MUST sit at the top level — nested inside :root it is invalid CSS
   and is dropped silently, and the family just falls back with no console error. */

@font-face {
  font-family: "Inter";
  src: url("system/fonts/Inter-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  src: url("system/fonts/Inter-latin-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* The body stack: Inter first (it is self-hosted just above and will be
     there), then the platform's own UI sans, so a failed request degrades to a
     grotesque rather than to Times. Deliberately NOT chained onto --font, whose
     first family is Funnel Display — the one face these paragraphs must not
     fall back to, since Inter is what makes them read as prose. */
  --font-inter: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Which face a case study's headings — the project title and its section
     labels — are set in. INTER by default, which is what the design system page
     was built and checked with.

     A token rather than a rule per page, so the pages can differ on this one
     question and on nothing else: hairdresser-website.css and
     econudge-sustainable-tool.css each re-point it at --font-page, and that
     single line is the whole difference on either page. */
  --cs-heading-font: var(--font-inter);

  /* The document's column: ~800px, the brief's number, and the thing that stops
     the media stretching across a monitor. The intro, the labels and the media
     all take it, and that shared column is all that lines them up.

     A TOKEN rather than a number written into the two rules below, because one
     page asks for a different document: website-redesign.css re-points it at
     1000px (62.5rem) so its three flat screenshots can be read — and answers the
     prose question separately, by capping .cs-text at this same 50rem, since a
     1000px line of Inter is ~115 characters. */
  --cs-measure: 50rem;

  /* The column stated ONCE, as a length anything can take. `min()` rather than
     `max-width`, so the number is the CONTENT width: 800px exactly on a wide
     screen, and the viewport minus a gutter on a phone (where 800px would be
     wider than the screen). design-system.css spends it on .ds-sheet too —
     which is why it is a token here rather than a rule on .cs-intro. */
  --cs-measure-inline: min(100% - 2 * var(--pad-page), var(--cs-measure));
}

.cs-intro,
.cs-section {
  inline-size: var(--cs-measure-inline);
  margin-inline: auto;
}

/* --- Intro ----------------------------------------------------------------
   The one Inter-set block on a case study: the project's title, its "About"
   label and its description, read before the media. Left-aligned inside the
   centred column — the column is what is centred, the prose is not — and set in
   the page's own ink rather than a muted grey, because this is the page's lede
   and not meta text. */
.cs-intro {
  font-family: var(--font-inter);
  padding-block: clamp(2rem, 6vw, 4.5rem) clamp(1.5rem, 4vw, 3rem);
}

.cs-intro__title {
  /* Uppercased in CSS, not typed in caps: the DOM keeps real words, so a screen
     reader reads "Hairdresser website" instead of spelling out a string of
     letters — the same trick the hero headline uses on index.html. */
  font-family: var(--cs-heading-font);
  font-size: clamp(2rem, 5vw, 3.25rem);
  font-weight: 800; /* a real axis stop on both faces (Inter 100-900, Funnel 300-800) */
  line-height: 1.02;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}

/* German titles are longer than the English they replace, and one of them runs
   past a 320px phone's column at the 2rem floor: "ECOnudge Nachhaltigkeits-Tool"
   overflows by 11px where "ECOnudge sustainable tool" does not. The floor comes
   down for German only — the 5vw term and the 3.25rem ceiling are untouched, so
   nothing above ~560px changes at all (where 5vw is already the larger of the
   two). The hero headline used to need the same kind of treatment; it is the same
   English in both languages now, so this is the only German type ramp left. */
html:lang(de) .cs-intro__title {
  font-size: clamp(1.75rem, 5vw, 3.25rem);
}

.cs-label {
  /* The brief's "smaller, bold subtitle" — a label for what follows, not a
     second title, which is why it is a step of type rather than another size of
     headline. */
  font-family: var(--cs-heading-font);
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1.2;
}

/* --- Air between the blocks ------------------------------------------------
   `* + *` rather than a plain margin, so a block that OPENS a section gets that
   section's spacing instead of that spacing plus its own — the same reasoning
   as .stack in system/base.css. The label rule is the more specific of the two
   (two classes to one), so it wins without depending on source order. */
.cs-intro > * + *,
.cs-section > * + * {
  margin-block-start: var(--s-3);
}

.cs-intro > * + .cs-label,
.cs-section > * + .cs-label {
  margin-block-start: clamp(1.5rem, 4vw, 2.5rem);
}

.cs-text {
  font-family: var(--font-inter);
  font-size: var(--fs-body);
  line-height: 1.6;
}

/* --- Paragraph breaks inside one translated paragraph ----------------------
   A translated paragraph is swapped in with `el.textContent = value` (see
   portfolio.js), so a break cannot be markup: `<br>` written into a `data-de`
   would render as those four characters. A paragraph whose German runs to two
   or three paragraphs therefore carries its blank lines in the attribute as
   newlines (`&#10;&#10;`), and this rule is what turns a newline into a break.

   Scoped twice over so nothing else can move: to `lang="de"` — the English
   setting collapses the newlines to spaces exactly as before, and the English
   strings are single-paragraph anyway — and to the pages' own prose (.cs-text),
   so no other German element on the page is touched. `pre-line` keeps the
   normal word wrapping and space collapsing; it only adds the newline breaks. */
html[lang="de"] .cs-text[data-de] {
  white-space: pre-line;
}

/* --- Sections --------------------------------------------------------------
   A case study is read as a sequence of statements — what it is, how it works,
   what it became — and it only reads that way if there is air between them. The
   margins are fluid, because a phone cannot spend 6rem on a gap, and they are
   margins rather than padding so that the two of adjacent sections COLLAPSE
   into one gap instead of adding up: what sits between two sections is the
   larger of the two numbers, and what closes the document is the last one's own
   bottom margin. */
.cs-section {
  margin-block: clamp(2.5rem, 6vw, 4.5rem) clamp(3rem, 8vw, 6rem);
}

/* --- Media -----------------------------------------------------------------
   The diagram and the video are both "a picture of the work", so they share one
   box: centred in the document's column, never wider than it, never cropped.
   Responsiveness is `max-inline-size: 100%` (system/base.css already puts it on
   every img and video) rather than a forced `inline-size: 100%`, so media
   NARROWER than the column keeps its own size instead of being upscaled into a
   blur — and media wider than it lands exactly on the column's edge. */
.cs-media {
  /* figure, so a browser's default indent has to go; `* { margin: 0 }` in
     system/base.css already does it, restated because a figure is the one
     element that can still arrive with one from a legacy style sheet. */
  margin: 0;
  margin-block-start: clamp(1.25rem, 3vw, 2rem);
}

.cs-media img,
.cs-media video {
  display: block;
  max-inline-size: 100%;
  block-size: auto;
  margin-inline: auto;
}

.cs-media video {
  /* `inline-size: 100%` is for the FALLBACK, not for the video. A video whose
     metadata has not arrived is the spec's 300x150 default box, and in a browser
     that cannot play the file at all (`.mov` is QuickTime) the paragraph inside
     the element is what gets rendered — squeezed into that 300px box unless the
     element is told to take the column. A playable file pays nothing for this:
     object-fit: contain letterboxes a narrower recording instead of cropping it,
     and the box is the column's width the moment metadata lands anyway.

     A page may still CAP this — econudge-sustainable-tool.css does, because its
     recording is portrait and a column-wide 750x1476 file would be a 1574px
     block. A max caps this width rather than replacing it, which is the reason
     this rule and that one do not fight.

     The opposite is a page's own business too: hairdresser-website.css lets its
     closing recording BREAK OUT of the column altogether, on a class, because a
     desktop-sized screen capture is unreadable at 800px. This box stays the
     default for every page; a page caps it or leaves it. */
  inline-size: 100%;
}
