/* ============================================================================
   JT SAYINGS PAGE — v1.0.0
   Figma frame "Sayings" (491:23153). Built by build/sayings.js.

   Loads AFTER /styles/common.css, which owns the palette, the reset, the base,
   the skip link and the eyebrow. What is left here is one screen with one
   sentence on it.

   MEASURED AT THE 1920 REFERENCE WIDTH
     group · quote   x 439, y 419, 1042 wide; VERTICAL, gap 96,
                     padding 42 / 0 / 120 / 0, children centred
     eyebrow         y 461 — the shared component, Index=off, Line=off,
                     State=in view. Rendered by build/sayings.js, styled in
                     common.css; nothing here touches it.
     quote           y 574, 1042 wide, Tektur Medium 24 / +5px / #f2f7fc,
                     centred. Line height is AUTO in Figma and measures 31 —
                     three lines in 93px.
     footer          y 1070, i.e. 403px below the quote

   NO PANEL, NO TITLE, NO RELATED BAND. The comp draws none of them; the
   related-reading frame is parked outside the frame's own bounds, and the page
   opts out of it in frontmatter as well. The h1 the generator emits is
   visually hidden — see the note there.

   NO MOTION. There is no "Sayings — motion" frame, which per CLAUDE.md means
   the page is static, not that the motion is mine to invent. The quote does
   not fade in; it is simply there.

   NAMING
   The --jt- prefix belongs to the frozen modules and must not appear here.
   ========================================================================== */

/* ---------------------------------------------------------------------------
   ONE VIEWPORT TALL

   Instructed, and it supersedes the comp's vertical offsets. The comp's frame
   is 1305px — taller than the 1080 it would be read on — so its 419px top
   offset and 187px tail cannot both be honoured AND fit a screen. They are
   gone; what stays from the comp is everything horizontal and typographic,
   which is the part that was actually designed.

     desktop and tablet (≥768)   the whole document is 100svh: menu, quote and
                                 footer share one screen and nothing scrolls
     phone (≤767)                the quote alone gets 100svh and the footer sits
                                 below it, so the document is 100svh + footer

   Where 767 comes from: it is the site's existing phone/tablet line. Both the
   menu and the footer modules switch there, so this page changes shape at the
   same width the chrome around it does. Picking a new number here would put a
   band of widths where the page is laid out for a phone and the footer for a
   tablet.

   HOW. <body> is the flex column and <main> is the one item that grows, so
   "fill what the footer leaves" needs no knowledge of how tall the footer is —
   which is just as well, since it restacks at 1023 and again at 767. On a phone
   <main> additionally claims a full screen of its own; a flex item cannot be
   shrunk below its min-height, so that wins and the footer is pushed past the
   fold.

   THE BACKGROUND MODULE IS UNAFFECTED, and this was checked rather than
   assumed: #parallax-stage is fixed and #ambient-glows is absolute with
   top/left/right all set, so neither becomes a flex item and neither depends on
   a static position that flex would move. The menu is fixed and the skip link
   absolute. <main> and the footer are the only children in flow.

   IT IS A MINIMUM, NOT A CAP. A long saying on a short window grows the page
   and it scrolls, rather than being clipped. Capping the height is the one way
   this could ever hide text, so it does not.
   ------------------------------------------------------------------------- */
body.sayings {
  display: flex;
  flex-direction: column;
  min-height: 100vh;    /* fallback for browsers without the small viewport unit */
  min-height: 100svh;
}

/* svh, not vh or dvh: on mobile vh is the tallest the viewport ever gets, so a
   100vh section starts taller than the screen and settles once the address bar
   hides — the quote would load below the fold. svh is the smallest, so the
   section always fits and only ever gains room. dvh would resize mid-scroll. */
.sayings__page {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  /* The stage is centred in what the footer leaves. The comp puts the quote a
     little below centre — 47px, in a frame 225px taller than the screen it is
     read on — and that bias is not worth reconstructing once the page is one
     viewport: it exists because the comp had room the browser does not. */
  justify-content: center;
  width: 100%;
  margin-inline: auto;
  /* Top clears the fixed menu; the extra is symmetrical breathing room, so the
     centring above stays honest.

     `min(4vw, 6vh)` — the padding answers to whichever axis is scarcer. A wide,
     short window (a laptop with every toolbar open) is the case that breaks a
     width-only clamp: 4vw of 1440 is 58px of padding top and bottom on a
     viewport that has 319px to spend, and the quote is pushed out of a page
     that was supposed to fit one screen. */
  padding: calc(var(--menu-height) + clamp(24px, min(4vw, 6vh), 72px))
           clamp(24px, 3vw, 48px)
           clamp(24px, min(4vw, 6vh), 72px);
}

/* The group. `align-items: center` is the comp's counter-axis CENTER, which is
   what centres the eyebrow over a quote of any width. */
.sayings__stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* 96 is the comp's gap and it is reached at the reference size — min(5vw,9vh)
     is 96 at 1920×1080. Below that it answers to whichever axis is scarcer, for
     the same reason the padding does: 96px between an eyebrow and a quote is a
     sixth of a 600px-tall window. */
  gap: clamp(40px, min(5vw, 9vh), 96px);
  width: 100%;
  max-width: 1042px;
  margin-inline: auto;
}

/* The eyebrow carries no margin of its own — on the landing page its spacing
   comes from a flex gap, and it does here too. */

/* ---------------------------------------------------------------------------
   The quotes

   Every saying is in the document; one is shown. `hidden` does the hiding, so
   the fallback when this stylesheet fails to load is the browser's own — a
   readable list, not 238 sayings stacked on top of each other. The rule below
   only has to keep `display: flex` from overriding it, which it would.
   ------------------------------------------------------------------------- */
.sayings__list {
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sayings__list [hidden] { display: none; }

.sayings__quote {
  margin: 0;
  color: var(--ink);
  font-family: var(--display);
  /* 24px at the comp width. It is a display size on a page with nothing else
     on it, so it is allowed to shrink further than body copy would. */
  font-size: clamp(17px, 0.55rem + 0.72vw, 24px);
  font-weight: 500;
  /* Figma reads AUTO and measures 31px on 24 — Tektur's own metrics. */
  line-height: 1.8;
  letter-spacing: 3px;
  text-align: center;
  /* The tracking is applied after every character including the last, which
     pushes centred text half a step left. Pulling it back is the standard fix
     and it is what makes the comp's centring match. */
  text-indent: 5px;
  text-wrap: balance;
}

/* ---------------------------------------------------------------------------
   Phones — 100svh PLUS the footer

   Instructed: on a phone the quote gets a screen to itself and the footer is
   found by scrolling. `min-height` is what does it — a flex item cannot be
   shrunk below it, so <main> claims a full screen and the footer is pushed
   past the fold instead of sharing the space.

   767 is the site's phone/tablet line, the same one the menu and footer
   modules use. A tablet keeps the desktop behaviour, which is what was asked
   for and also what fits: 768×1024 has room for all three parts at once.

   The comp draws one width, so the type adjustments below are derived and are
   candidates for a mobile frame. 5px of tracking is a lot of a 360px line, and
   it is the first thing to cost a word its own line.
   ------------------------------------------------------------------------- */
@media (max-width: 767px) {
  .sayings__page {
    min-height: 100vh;
    min-height: 100svh;

    /* Symmetric, unlike the desktop rule, where the top padding also clears the
       fixed menu. Carrying that clearance on one side only pushes anything
       centred inside down by half of it. On a phone the stage sits mid-screen
       and comes nowhere near the menu — checked at 400px tall, where the
       eyebrow still lands 48px clear of it — so the clearance buys nothing here
       and its bias is exactly what we are removing. */
    padding-block: clamp(24px, min(4vw, 6vh), 72px);
  }

  /* CENTRE THE QUOTE, NOT THE STAGE.

     Centring the stage puts the quote BELOW the middle of the screen, by half
     of everything stacked above it — the eyebrow and its gap, so about 30px.
     Small, but on a page holding one sentence it is the thing the eye measures.

     Three rows, the first and last an equal 1fr, put the middle row dead centre
     whatever the eyebrow's height turns out to be. The third row is empty and
     exists only to be the first one's mirror; the row gap falls on both sides
     of the quote, so it shortens the two 1fr rows equally and the centring
     survives it.

     The alternative — pulling the stage up by a measured offset — would need
     the eyebrow's height written here as a number, and it would be wrong the
     first time the eyebrow wraps or its type changes. This asks the browser
     instead. */
  .sayings__stage {
    flex: 1;
    display: grid;
    grid-template-rows: 1fr auto 1fr;
    align-items: end;        /* the eyebrow sits at the foot of its row */
    justify-items: center;
  }

  /* Keep the assigned Display/Quote style on narrow screens too. The size may
     scale, but its +5px tracking is part of the Figma text style. */
  .sayings__quote { letter-spacing: 5px; }
}
