/* ==========================================================================
   Flowing Stories

   Type does three jobs and never crosses over:
     Playfair Display  — the identity only (wordmark, ink seal, monogram)
     Imbue             — editorial display (the tagline, story headlines)
     Old Standard TT   — running text and all letterspaced small caps

   1. Fonts
   2. Tokens + reset
   3. Paper (the single sheet everything sits on)
   4. Identity: wordmark lockup + ink seal
   5. Header
   6. Fit-to-width display type
   7. Newspaper sheet
   8. Torn scraps (the three ventures)
   9. Narrow screens + motion
   ========================================================================== */

/* == 1. Fonts ============================================================= */
/* Self-hosted: no third-party requests, so no visitor IPs leave the site. */

/* -- Imbue: condensed, high-contrast display serif. Stands in for Niagara
      Solid, which is a licensed Microsoft font and cannot be embedded. ----- */
@font-face {
  font-family: 'Imbue';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/imbue-latin.woff2') format('woff2');
  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: 'Imbue';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../fonts/imbue-latin-ext.woff2') format('woff2');
  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;
}

/* -- Playfair Display: the wordmark and the seal ------------------------- */
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('../fonts/playfair-latin.woff2') format('woff2');
  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: 'Playfair Display';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('../fonts/playfair-latin-ext.woff2') format('woff2');
  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;
}

@font-face {
  font-family: 'Playfair Display';
  font-style: italic;
  font-weight: 400 900;
  font-display: swap;
  src: url('../fonts/playfair-i-latin.woff2') format('woff2');
  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;
}

/* -- Old Standard TT: a revival of early-1900s book and newspaper type ---- */
@font-face {
  font-family: 'Old Standard TT';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/oldstandard-400-latin.woff2') format('woff2');
  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: 'Old Standard TT';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/oldstandard-400-latin-ext.woff2') format('woff2');
  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;
}

@font-face {
  font-family: 'Old Standard TT';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/oldstandard-700-latin.woff2') format('woff2');
  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: 'Old Standard TT';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/oldstandard-700-latin-ext.woff2') format('woff2');
  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;
}

@font-face {
  font-family: 'Old Standard TT';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/oldstandard-400i-latin.woff2') format('woff2');
  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;
}

/* == 2. Tokens + reset ==================================================== */

:root {
  --identity: 'Playfair Display', Georgia, serif;
  /* 'Niagara Solid' first: if a visitor happens to have it installed it wins,
     otherwise Imbue — the closest freely licensable match — takes over. */
  --display: 'Niagara Solid', 'Imbue', 'Old Standard TT', 'Times New Roman', serif;
  --text: 'Old Standard TT', 'Times New Roman', Times, serif;

  /* Grachtengroen is the only ink besides the near-black of the press. */
  --green: #23453a;
  --green-soft: #35604f;
  --ink: #211710;
  --ink-soft: #3a2a1b;
  --cream: #e4d8c0;

  /* --paper is the ground the texture multiplies over, so it is lighter than
     the parchment looks on screen. --paper-flat is what it averages out to,
     for anything sitting above the texture that has to match it. */
  --paper: #e8d3b0;
  --paper-flat: #cdba9b;
  --paper-edge: 0.46;        /* how dark the worn left/right edges go */

  --rule: rgba(33, 23, 16, 0.4);

  --gutter: clamp(1.25rem, 4vw, 3.5rem);
  --measure: 82rem;
  --bar-h: clamp(56px, 8vh, 72px);   /* the fixed menu */
}

*, *::before, *::after { box-sizing: border-box; }

html { height: 100%; }

body {
  margin: 0;
  min-height: 100%;
  background: var(--paper-flat);
  color: var(--ink);
  font-family: var(--text);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
  overflow-x: clip; /* display type is measured wide before it is condensed */

  /* Niagara Solid ships in one weight only. Without this, asking for 700/900
     would get a faux-bold that thickens an already very narrow face into
     mush. The other three have real weights, so they are unaffected. */
  font-synthesis-weight: none;
  -webkit-font-synthesis: none;
}

h1, h2, h3, p, figure, ul { margin: 0; padding: 0; }
ul { list-style: none; }
img { max-width: 100%; display: block; }

.u-visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Filter definitions live in the document; this only hides the carrier. */
.u-defs {
  position: absolute;
  width: 0; height: 0;
  overflow: hidden;
}

/* == 3. Paper ============================================================= */

/* One sheet wraps the whole document — header included — so the texture runs
   through without a seam. Every layer here is height-independent (a
   horizontal gradient, or a tile), which is what lets it stretch over a page
   of any length without stretching the grain with it. */
.paper {
  position: relative;
  isolation: isolate;
  background-color: var(--paper);
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-image:
    /* Worn, shadowed edges down the left and right of the sheet.
       Everything is scaled off --paper-edge, so the whole falloff gets
       heavier or lighter from that one number. */
    linear-gradient(to right,
      rgba(84, 56, 26, calc(var(--paper-edge) * 1)) 0%,
      rgba(84, 56, 26, calc(var(--paper-edge) * 0.62)) 3%,
      rgba(84, 56, 26, calc(var(--paper-edge) * 0.28)) 8%,
      rgba(84, 56, 26, calc(var(--paper-edge) * 0.09)) 15%,
      rgba(84, 56, 26, 0) 26%,
      rgba(84, 56, 26, 0) 74%,
      rgba(84, 56, 26, calc(var(--paper-edge) * 0.09)) 85%,
      rgba(84, 56, 26, calc(var(--paper-edge) * 0.28)) 92%,
      rgba(84, 56, 26, calc(var(--paper-edge) * 0.62)) 97%,
      rgba(84, 56, 26, calc(var(--paper-edge) * 1)) 100%),
    /* A sheet lit slightly from above. */
    linear-gradient(to bottom,
      rgba(255, 252, 243, 0.14) 0%,
      rgba(255, 252, 243, 0) 18%,
      rgba(84, 56, 26, 0) 82%,
      rgba(84, 56, 26, 0.07) 100%);
}

/* Two turbulence scales at once: broad staining over a directional fibre.
   Both are SVG, so they are rasterised at whatever pixel density the screen
   has — the detail sharpens on a retina display instead of scaling up. */
.paper::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.44;
  mix-blend-mode: multiply;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='420' height='420'%3E%3Cfilter id='b'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.055%200.115' numOctaves='5' seed='29' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='420' height='420' filter='url(%23b)' opacity='0.6'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1200' height='1200'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.008' numOctaves='6' seed='17' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='1200' height='1200' filter='url(%23a)'/%3E%3C/svg%3E");
  background-size: 420px 420px, 1200px 1200px;
}

/* Fine paper tooth, close to one grain per device pixel. */
.paper::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.2;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' seed='5' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='256' height='256' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size: 256px 256px;
}

/* == 4. Identity ========================================================== */

/* -- Wordmark lockup (2a) -------------------------------------------------
   Every measurement is an em of the wordmark, so the whole lockup scales as
   one drawing from the ratios in the design: 3px + 3px gap + 1px above a
   52px wordmark, 1px below it, then the sub-line at 11px. */
.lockup {
  --w: clamp(1.9rem, 5vw, 4.2rem);
  font-size: var(--w);
  width: min(9.05em, 100%);
  margin: 0 auto;
  text-align: center;
  border-top: 0.058em solid var(--green);
  font-weight: 400;
}

.lockup__word {
  display: block;
  margin-top: 0.058em;                       /* the gap between the two rules */
  border-top: 0.019em solid var(--green);
  border-bottom: 0.019em solid var(--green);
  padding: 0.269em 0 0.192em;
  font-family: var(--identity);
  font-weight: 900;
  font-size: 1em;
  line-height: 1.12;
  letter-spacing: 0.015em;
  text-transform: uppercase;
  color: var(--green);
}

.lockup__sub {
  display: block;
  padding-top: 0.192em;
  font-family: var(--text);
  /* The design's ratio is 11px under a 52px wordmark. Held to that alone it
     falls to ~6px on a phone, so it stops shrinking at 0.6rem. */
  font-size: max(0.6rem, 0.212em);
  line-height: 1.5;
  letter-spacing: 0.34em;
  text-indent: 0.34em;                       /* re-centres the tracked line */
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* -- Ink seal (2b) --------------------------------------------------------
   Sized entirely off its own font-size, so one number sets the disc and
   everything inside follows the proportions of the 206px original. */
.seal {
  font-size: var(--seal, 13rem);
  width: 1em;
  height: 1em;
  border-radius: 50%;
  background: var(--green);
  display: grid;
  place-items: center;
  font-family: var(--identity);
}

.seal__ring {
  width: 0.864em;
  height: 0.864em;
  border-radius: 50%;
  border: max(1px, 0.005em) solid rgba(228, 216, 192, 0.55);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.039em;
}

.seal__flowing {
  font-family: var(--identity);
  font-style: italic;
  font-weight: 400;
  font-size: 0.185em;
  line-height: 1;
  color: var(--cream);
}

.seal__rule {
  width: 0.359em;
  height: max(1px, 0.005em);
  background: rgba(228, 216, 192, 0.6);
}

.seal__stories {
  font-family: var(--text);
  font-size: 0.068em;
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  text-transform: uppercase;
  color: var(--cream);
}

/* == 5. Header ============================================================ */

/* Full bleed: the film runs to all four edges with nothing around it, and
   the menu sits over the top of it. */
.hero {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  isolation: isolate;
  background: #0a0a0c;
}

.hero__media,
.hero__scrim,
.hero__grain {
  position: absolute;
  inset: 0;
}

.hero__media {
  z-index: 0;
  background: #0a0a0c url('../img/hero-poster.jpg') center / cover no-repeat;
}

/* Guarantees the menu, the name and the line read over whatever frame of the
   film happens to be showing. */
.hero__scrim {
  z-index: 1;
  pointer-events: none;
  /* Light at the top, where only the menu sits; heavy at the foot, which now
     carries the name and the line under it. */
  background: linear-gradient(to bottom,
    rgba(4, 6, 12, 0.46) 0%,
    rgba(4, 6, 12, 0.14) 13%,
    rgba(4, 6, 12, 0) 32%,
    rgba(4, 6, 12, 0) 44%,
    rgba(4, 6, 12, 0.30) 70%,
    rgba(4, 6, 12, 0.74) 100%);
}

/* Name and sub-title travel together, sitting at the foot of the film. */
.hero__titles {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(1rem, 4vh, 3rem);
  z-index: 3;
  padding: 0 clamp(0.5rem, 1.4vw, 1.5rem);
}

.hero__name,
.hero__tagline {
  text-align: center;
  color: #fbfdf9;
  font-family: var(--display);
  font-weight: 700;
  line-height: 1;
  text-shadow: 0 0.06em 0.5em rgba(0, 0, 0, 0.45);
}

.hero__name { font-size: clamp(1.5rem, 5vw, 3rem); }

.js .hero__name {
  /* A ceiling, not a size — the fit script solves down from here, so it has
     to sit above every size the solve can ask for. */
  font-size: max(2rem, 13vw);
  --fit-target: 0.42;
  --fit-size-floor: 0.5;
  --fit-squeeze-min: 0.7;
  --fit-squeeze-max: 1.05;
}

.hero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

/* Fine film grain, to match the analog look of the footage. */
.hero__grain {
  z-index: 2;
  pointer-events: none;
  opacity: 0.06;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
}

/* -- The menu ------------------------------------------------------------- */

.topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  height: var(--bar-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 clamp(1rem, 4.4vw, 4rem);
  color: #fbfdf9;
  border-bottom: 1px solid transparent;
  /* Switched, not faded. Halfway through a cross-fade between white-on-film
     and ink-on-parchment there is a moment where the menu reads as neither,
     and any environment that stalls transitions would leave it there. */
}

/* White over the film; ink on parchment once the film is behind you — and
   the same while the panel is open, since the panel is parchment too. */
.topbar.is-solid,
.topbar.is-open {
  background: var(--paper-flat);
  color: var(--ink);
  border-bottom-color: var(--rule);
}

.topbar a { color: inherit; text-decoration: none; }

.topbar__links {
  display: flex;
  gap: clamp(1rem, 2.4vw, 2.5rem);
  flex: 1 1 0;
}

.topbar__links--end { justify-content: flex-end; }

.topbar__links a {
  font-family: var(--text);
  font-size: clamp(0.62rem, 0.85vw, 0.78rem);
  letter-spacing: 0.24em;
  text-indent: 0.24em;
  text-transform: uppercase;
  padding-bottom: 0.2em;
  border-bottom: 1px solid transparent;
}

.topbar__links a:hover,
.topbar__links a:focus-visible { border-bottom-color: currentColor; }

.topbar__mark {
  flex: 0 0 auto;
  font-family: var(--identity);
  font-weight: 700;
  font-size: clamp(0.8rem, 1.15vw, 1.05rem);
  letter-spacing: 0.2em;
  text-indent: 0.2em;
  text-transform: uppercase;
  white-space: nowrap;
}

.topbar__toggle {
  display: none;
  appearance: none;
  background: none;
  border: 0;
  padding: 0.35rem 0;
  color: inherit;
  cursor: pointer;
  font-family: var(--text);
  font-size: 0.72rem;
  letter-spacing: 0.24em;
  text-indent: 0.24em;
  text-transform: uppercase;
}

/* The panel behind the MENU button on small screens. */
.menu-panel {
  position: fixed;
  inset: 0;
  z-index: 99;
  display: grid;
  place-items: center;
  background: var(--paper-flat);
  color: var(--ink);
}

.menu-panel[hidden] { display: none; }

.menu-panel__list {
  display: grid;
  gap: clamp(1.25rem, 5vh, 2.5rem);
  text-align: center;
}

.menu-panel__list a {
  font-family: var(--identity);
  font-weight: 700;
  font-size: clamp(1.75rem, 9vw, 3rem);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--green);
}

/* == 6. Fit-to-width display type ========================================= */

/* Baseline (no JS) sizing; the fit script takes over below. */
.hero__tagline {
  margin-top: clamp(0.4rem, 1.4vh, 1.1rem);
  font-size: clamp(0.9rem, 2vw, 1.4rem);
}

/* Same --fit-target as the name, so both lines close on exactly the same
   width. The sub-title is four times as long, so the solve lands it at a
   fraction of the name's size on its own — no second size to keep in step. */
.js .hero__tagline {
  font-size: max(1rem, 4vw);
  --fit-target: 0.42;
  --fit-size-floor: 0.2;
  --fit-squeeze-min: 0.85;
  /* The size is solved from the longest line, so on two lines the shorter
     one needs a little stretch to reach the same edges as the name. */
  --fit-squeeze-max: 1.09;
}


/* Avoid a flash of un-condensed type before the first measure. */
.js .fit:not(.is-fitted) { visibility: hidden; }

/* Flex centring keeps the line centred even while it is briefly wider than
   the frame (between layout and the first measure), so scaling it about its
   own centre lands it in the middle of the frame. */
.fit-line {
  display: flex;
  justify-content: center;
}

/* No transition on `transform` — the fit script owns it and must be able to
   apply a new scale immediately, including on the very first measure. */
.fit-line__in {
  flex: 0 0 auto;
  white-space: nowrap;
  transform-origin: 50% 50%;
}

/* Reveal, once the type has been measured and placed.
   Only opacity/filter — `transform` is owned by the fit script. */
.fit.is-fitted .fit-line__in {
  animation: reveal 1.2s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes reveal {
  from { opacity: 0; filter: blur(6px); }
  to   { opacity: 1; filter: blur(0); }
}

/* == 7. Newspaper sheet =================================================== */

.sheet {
  max-width: var(--measure);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 5rem) var(--gutter) clamp(2rem, 5vw, 4rem);
}

.sheet__masthead {
  border-top: 3px solid var(--green);
  border-bottom: 1px solid var(--green);
  padding: 0.55rem 0 0.4rem;
  font-family: var(--text);
  font-size: clamp(0.6rem, 1.15vw, 0.78rem);
  font-weight: 700;
  letter-spacing: 0.32em;
  text-indent: 0.32em;
  text-transform: uppercase;
  text-align: center;
  color: var(--green);
}

/* As the masthead of this page the lockup runs the full measure, so its
   rules line up with the column grid underneath.

   --w drives the rules and the spacing; the wordmark itself is measured by
   the fit script so it touches both rules exactly. The formula here tracks
   that measured size closely (the measure is 92vw until the 82rem cap takes
   over), which keeps the rule weights in proportion. */
.sheet .lockup {
  --w: min(9.33vw, 7.6rem);
  width: 100%;
  margin: clamp(1.75rem, 3.5vw, 3rem) auto 0;
}

/* A wordmark must never be stretched, so the squeeze is pinned to 1 and the
   fit solves for font-size alone. The ceiling is deliberately far higher
   than any real size — it only exists so the solved size is never clamped. */
.sheet .lockup__word {
  font-size: 40vw;
  --fit-target: 1;
  --fit-size-floor: 0.05;
  --fit-squeeze-min: 1;
  --fit-squeeze-max: 1;
}

.sheet__standfirst {
  margin: clamp(0.75rem, 1.6vw, 1.25rem) auto 0;
  max-width: 46rem;
  font-size: clamp(1rem, 1.5vw, 1.25rem);
  font-style: italic;
  line-height: 1.5;
  text-align: center;
  color: var(--ink-soft);
}

.sheet__rule {
  height: 0;
  margin: clamp(1.5rem, 3vw, 2.25rem) 0;
  border-top: 1px solid var(--green);
  border-bottom: 3px solid var(--green);
  padding-top: 3px;
}

/* -- the column grid ------------------------------------------------------ */

/* Every cell carries a left and bottom rule and the container closes the
   block off on the top and right. No cell needs to know whether it happens
   to start a row — which, with mixed spans, CSS cannot tell anyway. */
.cols {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 0;
  border-top: 1px solid var(--rule);
  border-right: 1px solid var(--rule);
}

.story {
  grid-column: span 4;
  padding: clamp(1rem, 2vw, 1.75rem);
  border-left: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}

.story--lead { grid-column: span 8; }
.story--half { grid-column: span 6; }
.story--full { grid-column: span 12; }

.story__kicker {
  margin-bottom: 0.5rem;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.24em;
  text-indent: 0.24em;
  text-transform: uppercase;
  color: var(--green);
}

.story__title {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.75rem, 3.4vw, 3.25rem);
  line-height: 0.94;
  letter-spacing: 0.005em;
  color: var(--ink);
}

.story--lead .story__title {
  font-size: clamp(2.5rem, 6vw, 5.5rem);
  text-transform: uppercase;
}

.story__body {
  margin-top: 0.85rem;
  font-size: clamp(0.95rem, 1.05vw, 1.05rem);
  line-height: 1.58;
  text-align: justify;
  hyphens: auto;
}

.story__body > p + p { margin-top: 0.75em; text-indent: 1.4em; }

/* Newspaper column flow inside the wider cells. */
.story--lead .story__body,
.story--full .story__body {
  columns: 2;
  column-gap: clamp(1.25rem, 2.5vw, 2.25rem);
  column-rule: 1px solid var(--rule);
}

.story__figure { margin-top: 1rem; }

.story__figure img {
  width: 100%;
  /* Halftone-ish: newsprint never reproduced photographs cleanly. */
  filter: grayscale(1) contrast(1.12) sepia(0.35);
  mix-blend-mode: multiply;
}

.story__caption {
  margin-top: 0.4rem;
  font-size: 0.78rem;
  font-style: italic;
  color: var(--ink-soft);
}

.story__more {
  display: inline-block;
  margin-top: 0.9rem;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-indent: 0.2em;
  text-transform: uppercase;
  color: var(--green);
  text-decoration: none;
  border-bottom: 2px solid var(--green);
  padding-bottom: 0.15em;
}

.story__more:hover,
.story__more:focus-visible { color: var(--green-soft); border-color: var(--green-soft); }

/* == 8. Torn scraps ======================================================= */

.ventures {
  padding: clamp(3rem, 7vw, 6rem) var(--gutter) clamp(3.5rem, 8vw, 7rem);
}

.ventures__heading {
  font-family: var(--text);
  font-size: clamp(0.62rem, 1.1vw, 0.78rem);
  font-weight: 700;
  letter-spacing: 0.32em;
  text-indent: 0.32em;
  text-transform: uppercase;
  text-align: center;
  color: var(--green);
  border-top: 1px solid var(--green);
  padding-top: 0.6rem;
  max-width: var(--measure);
  margin: 0 auto clamp(2.5rem, 5vw, 4rem);
}

.ventures__list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 3vw, 3rem);
  align-items: start;
  max-width: var(--measure);
  margin: 0 auto;
}

.venture__link {
  display: block;
  text-decoration: none;
  color: inherit;
}

/* The paper is a separate layer from the logo: the torn-edge filter
   displaces every pixel it touches, and a warped logo would look broken. */
.venture__sheet {
  position: relative;
  aspect-ratio: 1 / 1;
  display: grid;
  place-items: center;
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.venture__sheet::before {
  content: '';
  position: absolute;
  inset: 6%;
  background: #f7f4ec;
  filter: url('#torn-1') drop-shadow(0 6px 14px rgba(60, 40, 20, 0.32));
}

.venture:nth-child(2) .venture__sheet::before { filter: url('#torn-2') drop-shadow(0 6px 14px rgba(60, 40, 20, 0.32)); }
.venture:nth-child(3) .venture__sheet::before { filter: url('#torn-3') drop-shadow(0 6px 14px rgba(60, 40, 20, 0.32)); }

/* Slightly different angles, so they read as three torn pieces rather than
   three copies of one. */
.venture:nth-child(1) .venture__sheet { transform: rotate(-1.5deg); }
.venture:nth-child(2) .venture__sheet { transform: rotate(2deg); }
.venture:nth-child(3) .venture__sheet { transform: rotate(-0.5deg); }

.venture__link:hover .venture__sheet,
.venture__link:focus-visible .venture__sheet { transform: rotate(0deg) scale(1.03); }

/* The disc inside a scrap is 72% of it, whatever the scrap measures. */
.venture__disc {
  position: relative;
  width: 72%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  overflow: hidden;
  display: grid;
  place-items: center;
}

.venture__disc img { width: 100%; height: 100%; object-fit: cover; }

/* The seal is its own disc — it sizes off the scrap that holds it, so it
   lands at the same 72% as the placeholder discs without being nested. */
.venture__sheet { container-type: inline-size; }
.venture .seal { font-size: 72cqw; }

/* Placeholder discs, until the real marks arrive. */
.venture--dark .venture__disc { background: var(--ink); }

.venture--blank .venture__disc {
  background: rgba(35, 69, 58, 0.06);
  border: 2px dashed rgba(35, 69, 58, 0.35);
}

.venture__disc-text {
  font-family: var(--identity);
  font-weight: 700;
  font-size: clamp(1.1rem, 3vw, 2rem);
  line-height: 1.05;
  color: var(--cream);
  text-align: center;
  padding: 0 0.5em;
}

.venture--blank .venture__disc-text { color: rgba(35, 69, 58, 0.4); }

.venture__caption {
  display: block;
  margin-top: clamp(0.5rem, 1.5vw, 1rem);
  font-family: var(--identity);
  font-weight: 900;
  font-size: clamp(1.1rem, 2.4vw, 2rem);
  line-height: 1.05;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  text-align: center;
  color: var(--green);
}

.venture__note {
  display: block;
  margin-top: 0.35rem;
  font-family: var(--text);
  font-weight: 400;
  font-size: 0.72rem;
  font-style: italic;
  letter-spacing: 0.04em;
  text-transform: none;
  color: var(--ink-soft);
}

/* == 9. Narrow screens + motion =========================================== */

@media (max-width: 1023px) {
  .story,
  .story--lead,
  .story--half { grid-column: span 6; }

  .story--lead .story__body { columns: 1; }
}

@media (max-width: 767px) {
  /* 42% of the frame reads as a caption on a phone, not as a name. Both
     lines move together so they keep closing on the same width. */
  .js .hero__name { --fit-target: 0.85; font-size: 22vw; }

  .js .hero__tagline {
    --fit-target: 0.85;
    font-size: 14vw;
    line-height: 1.14;
  }

  /* The inline links fold into the MENU button and its panel. */
  .topbar__links { display: none; }
  .topbar__toggle { display: block; }
  .topbar__mark { flex: 1 1 auto; }

  /* At this size the tracked sub-line no longer fits on one line; loosen it
     a little and let it break instead of overflowing. */
  .lockup__sub { letter-spacing: 0.2em; text-indent: 0.2em; }

  .venture__caption { font-size: clamp(1.5rem, 7vw, 2.5rem); }

  .story,
  .story--lead,
  .story--half,
  .story--full { grid-column: span 12; }

  .story--full .story__body { columns: 1; }

  .ventures__list { grid-template-columns: minmax(0, 1fr); gap: 2.5rem; }
  .venture__sheet { max-width: 22rem; margin: 0 auto; }
}

/* Phones held in landscape: the name and the line would meet in the middle
   of the frame, so both come down a size. */
@media (max-height: 560px) and (orientation: landscape) {
  .js .hero__name { font-size: max(1.5rem, 8vw); --fit-target: 0.34; }
  .js .hero__tagline { --fit-target: 0.34; }
}

@media (prefers-reduced-motion: reduce) {
  .fit.is-fitted .fit-line__in { animation: none; }
  .venture__sheet { transition: none; }
}
