/* ============================================================
   THE SPACE OBSERVER — HOUSE LAYER  v1.0
   SpaceReturn///// The California Space Cluster
   ------------------------------------------------------------
   Additive only. Loaded AFTER styles.css and issue-NNN.css.
   Nothing here removes or overrides an approved design decision;
   it corrects desktop measure, column feet and section hierarchy.
   Mobile is deliberately left alone — it already reads correctly.
   ============================================================ */

:root{
  /* Modular type scale, 1.200 minor third, 17px base.
     Every editorial size in the paper resolves to one of these. */
  --t-micro : 10px;   /* mono codes, credits, rules            */
  --t-small : 12.5px; /* desk lines, captions, ledger rows     */
  --t-body  : 17px;   /* running text                          */
  --t-lead  : 19.5px; /* standfirsts and decks                 */
  --t-sub   : 24px;   /* module sub-heads                      */
  --t-head  : 34px;   /* module heads                          */
  --t-title : 46px;   /* the long-read title                   */

  /* Vertical rhythm. One unit, everything a multiple of it. */
  --rhythm  : 8px;

  /* Measure. The single most important number on the page. */
  --measure      : 66ch;  /* running prose        */
  --measure-tight: 52ch;  /* decks and standfirsts */
}

/* ------------------------------------------------------------
   1 — MEASURE
   Long-read lines ran past 100–120 characters
   per line at 1440px. Sustained reading degrades past ~75.
   Cap it. Narrow cells are unaffected because they are already
   below the cap.
   ------------------------------------------------------------ */
@media(min-width:1000px){
  .spread p,
  .spread li,
  .article-main p,
  .article-main li{
    max-width:var(--measure);
  }
  .article-deck,
  .memberfile__dek,
  .lead__dek,
  .band__sub{
    max-width:var(--measure-tight);
  }
  /* Wide span-12 modules are not measure-capped. */
  .spread__article p, .spread__article li,
  .spread__essca p, .spread__engage p, .spread__meeting p,
  .spread__next p, .spread__services p, .spread__sources p,
  .spread__stats p, .spread__quote p, .spread__market p,
  .spread__cofound p, .spread__legal p{
    max-width:none;
  }

  /* Elements that are structural, not prose, must not be capped. */
  .spread p.mod__small,
  .spread .dt-row p,
  .spread figure p,
  .spread figcaption,
  .spread table p{
    max-width:none;
  }
}

/* ------------------------------------------------------------
   2 — COLUMN FEET
   The blank areas are grid rows taking the height of their
   tallest cell while a short neighbour paints empty card.
   Print solves this with a column foot: the standing metadata
   line sits ON the bottom rule, not adrift under the text.
   Making each cell a flex column lets the byline fall to the
   floor of the cell, which closes the gap with intent.
   ------------------------------------------------------------ */
@media(min-width:1000px){
  .spread > *{
    display:flex;
    flex-direction:column;
  }
  .spread > * > .mod__byline,
  .spread > * > .mod__foot{
    margin-top:auto;
    padding-top:calc(var(--rhythm) * 3);
    border-top:1px solid var(--border);
  }
  /* A cell with no byline of its own gets a hairline foot. */
  .mod__foot{
    font-family:var(--font-mono);
    font-size:var(--t-micro);
    letter-spacing:.08em;
    text-transform:uppercase;
    color:var(--faint);
    display:flex;
    justify-content:space-between;
    gap:16px;
  }
  .mod__foot span:last-child{text-align:right}
}

/* ------------------------------------------------------------
   3 — SECTION HIERARCHY
   The module code read at the same weight as the desk
   line, so the eye cannot find the module boundary on a wide
   screen. Give the code a rule and more air; hold the desk line
   back. No colour change, no new typeface.
   ------------------------------------------------------------ */
@media(min-width:1000px){
  .spread .mod__code{
    font-size:var(--t-micro);
    letter-spacing:.13em;
    color:var(--steel);
    padding-bottom:calc(var(--rhythm) * 1.5);
    border-bottom:1px solid var(--border);
    margin-bottom:calc(var(--rhythm) * 2.5);
  }
  .spread .mod__byline{
    font-size:var(--t-micro);
    letter-spacing:.08em;
    color:var(--faint);
  }
}

/* ------------------------------------------------------------
   4 — THE LONG READ
   A span-12 module with a single running column is the widest
   text on the page. Two balanced columns halve its height and
   are what a broadsheet does anyway. Only above 1280px, where
   each column still clears 45 characters.
   ------------------------------------------------------------ */
@media(min-width:1280px){
  .article-main > p{
    max-width:none;
  }
  .article-main{
    column-count:2;
    column-gap:44px;
    column-rule:1px solid var(--border);
    column-fill:balance;
  }
  /* Only genuinely full-width furniture spans both columns. 's
     finding: spanning every heading and pull quote forces a column
     break before and after each one, fragmenting the text into
     one-line stubs. Headings stay inside their column. */
  .article-main figure,
  .article-main table,
  .article-main .article-figure,
  .article-main .stats{
    break-inside:avoid;
    column-span:all;
  }
  .article-main h3,
  .article-main h4,
  .article-main .pullquote,
  .article-main blockquote{
    break-inside:avoid;
    break-after:avoid;
  }
  /* Three-line minimum kills the stub lines multi-column produces. */
  .article-main{orphans:3;widows:3}
  .article-main > p:first-of-type{
    font-size:var(--t-lead);
    line-height:1.5;
  }
}

/* ------------------------------------------------------------
   5 — RHYTHM
   One spacing unit, applied consistently, is most of what makes
   a page look edited rather than assembled.
   ------------------------------------------------------------ */
@media(min-width:1000px){
  .spread p + p{margin-top:calc(var(--rhythm) * 2)}
  .spread h3,.spread h4{margin-top:calc(var(--rhythm) * 4)}
  .spread h3 + p,.spread h4 + p{margin-top:calc(var(--rhythm) * 1.5)}
  .spread figure{margin-block:calc(var(--rhythm) * 3)}
}

/* ------------------------------------------------------------
   6 — ORPHANS AND WIDOWS
   Cheap, invisible, and the difference between set and typed.
   ------------------------------------------------------------ */
.spread p,.spread li{
  orphans:2;
  widows:2;
  text-wrap:pretty;
  hanging-punctuation:first last;
}
.spread h1,.spread h2,.spread h3,.spread h4,
.article-title,.rail__head{
  text-wrap:balance;
}

/* ------------------------------------------------------------
   7 — FIGURES
   Every photograph in the paper is a real photograph, in colour,
   at full module width, with a caption that names the subject
   and credits the publisher. This enforces the frame only.
   ------------------------------------------------------------ */
.memberfile__shot,
.article-main figure,
.spread figure{
  filter:none;
}
.memberfile__shot figcaption,
.spread figure figcaption{
  font-family:var(--font-mono);
  font-size:var(--t-micro);
  line-height:1.5;
  letter-spacing:.04em;
  color:var(--faint);
  margin-top:calc(var(--rhythm) * 1.5);
  padding-top:calc(var(--rhythm) * 1.5);
  border-top:1px solid var(--border);
}
.memberfile__shot figcaption b,
.spread figure figcaption b{
  display:block;
  color:var(--steel);
  letter-spacing:.02em;
  margin-bottom:4px;
}

/* ------------------------------------------------------------
   8 — THE LEGAL BLOCK IS NOT TOUCHED.
   .spread__legal inherits nothing from this sheet by design.
   ------------------------------------------------------------ */
.spread__legal p,
.spread__legal li{max-width:none}
.spread__legal .mod__code{border-bottom:0;padding-bottom:0;margin-bottom:14px}

/* ============================================================
   9 — IMAGE PLACEMENT AND TYPOGRAPHIC LAYER
   Additive. Issue 007 trial. Legal block untouched.
   ============================================================ */

.spread__memo{display:flex;flex-direction:column}

/* 9.2  Co-founders — text wrap */
@media (min-width:861px){
  .cofound__grid{display:block}
  .cofound__photo{float:left;width:300px;margin:0 30px 16px 0;shape-margin:30px}
  .cofound__body{overflow:visible}
  .cofound__grid::after{content:"";display:block;clear:both}
}

/* 9.3  Lead — issue numeral and rule */
.spread__lead{position:relative;overflow:hidden}
.spread__lead > .lead__kicker,
.spread__lead > .mod__code{
  letter-spacing:.2em;
  border-bottom:2.5px solid currentColor;
  padding-bottom:10px;
  margin-bottom:20px;
}
.spread__lead::after{
  content:"007";
  position:absolute;right:-42px;bottom:-24px;
  font-family:var(--font-mono);font-size:112px;font-weight:700;line-height:1;
  letter-spacing:-.04em;
  color:currentColor;opacity:.06;
  pointer-events:none;user-select:none;
}

/* 9.4  Lead — signal list */
.lead__cols .lead__sig{display:block;font-size:9.5px;letter-spacing:.18em;color:var(--signal);margin-bottom:4px}
.lead__cols p{break-inside:avoid;margin-bottom:14px}

/* 9.5  Module foot */
.mod__foot{display:flex;justify-content:space-between;align-items:baseline;gap:20px;flex-wrap:wrap}

/* 9.6  Framing figure — colour */
.spread__memo .memo-scientist img{filter:none;opacity:1}

/* 9.7  Field signal */
.spread__quote:has(> .quote-portrait:empty){grid-template-columns:minmax(0,1fr)}
.spread__quote .pullquote{max-width:38ch;line-height:1.34;letter-spacing:.004em;font-weight:400}
.spread__quote cite{display:block;margin-top:18px;line-height:1.65;max-width:64ch}

/* 9.8  Prose and caption sizing */
.spread__memo .memo-scientist p{font-size:14px;line-height:1.6}
.spread__quote .pullquote{max-width:30ch}
.memberfile__photo figcaption,.quote-portrait figcaption{font-size:9.5px}

/* Framing figure — the panel is a four-column well, so the portrait
   and the text cannot sit side by side. Portrait across the panel at
   its own proportion, text beneath at a readable measure. */
.spread__memo .memo-scientist{grid-template-columns:minmax(0,1fr);align-items:start}
.spread__memo .memo-scientist figure{aspect-ratio:auto;height:auto;min-height:0;max-height:none;width:100%}
.spread__memo .memo-scientist figure img{width:100%;height:auto;object-fit:contain;object-position:50% 50%}

/* Every figure carries its credit. Framing figure credit sits beneath the
   portrait; the field signal credit takes a backing plate so it stays legible
   over whatever sits behind it. */
.spread__memo .memo-scientist figcaption{display:block;position:static;margin-top:7px;font-size:9.5px;line-height:1.45;letter-spacing:.09em;color:#C9B8D8;background:none;width:auto;max-width:none;padding:0}
.spread__quote .quote-portrait figcaption{left:10px;right:10px;bottom:9px;width:max-content;max-width:calc(100% - 20px);color:#EDEFF4;background:rgba(10,12,16,.82);padding:5px 7px;font-size:9px;line-height:1.5;letter-spacing:.09em}

/* When the panel runs full width the measure must not run with it. */
.spread__memo .memo-scientist{max-width:none}
.spread__memo .memo-scientist > div{max-width:62ch}
.spread__memo .memo-scientist p{max-width:62ch}
.spread__memo .memo-scientist figure{max-width:420px}
.spread__memo .memo-scientist figcaption{max-width:420px}

/* Reading rhythm. Leading pulled back from 1.78, measure brought inside
   the comfortable range, and the hard word-space removed from card heads. */
.article-main p:not(.article-deck){line-height:1.62;max-width:68ch}
.reader-card b{word-spacing:normal}

/* §10 TABLET BAND — corrections from measured review, 5 Aug 2026
   10.1 The 420px caps added for the measure fix leave a ragged right edge once
        the memo panel goes full width below 1000px. Fill the cell instead. */
@media (max-width:999px){
  .spread__memo .memo-scientist figure,
  .spread__memo .memo-scientist figcaption{max-width:none;width:100%}
  .spread__memo .memo-scientist > div{max-width:none}
  .spread__memo .memo-scientist > div p{max-width:62ch}
}
/* 10.2 Reader map runs five cards on a two-column grid, orphaning the fifth.
        Let the last card take the full row when the count is odd. */
.reader-map > *:last-child:nth-child(odd){grid-column:1/-1}

/* 10.3 Member ledger hero stays two-column into the tablet band because the
   per-issue overrides collapse only at 560-640px, leaving a 290-350px hole
   beside the portrait at 834. Collapse it with everything else. */
@media (max-width:999px){
  .memberfile__hero{grid-template-columns:minmax(0,1fr)}
  .memberfile__portrait{max-width:320px}
}

/* 10.4 Framing figure quotation. Set in the sans, not the serif italic, so it
   reads as an editorial callout rather than an elegy. */
.spread__memo .memo-scientist .memo-quote{
  font-family:'General Sans',system-ui,sans-serif;
  font-weight:500;font-style:normal;
  font-size:21px;line-height:1.42;letter-spacing:-.005em;
  color:#F3F6FA;margin:0 0 14px;max-width:26ch;
  text-wrap:balance;
}
@media (max-width:640px){.spread__memo .memo-scientist .memo-quote{font-size:19px}}

/* 10.5 Framing-figure photographs sit on a dark panel. Where the image itself
   carries dark ground it bleeds into the panel and reads as a void. Frame it. */
.spread__memo .memo-scientist figure img{
  border:1px solid rgba(243,246,250,.20);
  border-radius:2px;
  display:block;
}

/* ===========================================================================
   §11  THIRD-GATE CORRECTIONS — legibility and the empty rail.
   Added after check_design.py measured 245 contrast failures below WCAG AA
   and an empty right rail of 359–3,512px in every issue at 1440 and 1280.
   Nothing structural changes. styles.css is untouched.
   ========================================================================= */

/* 11.1 Tertiary labels were #8A93A0 on white — 3.11:1, under the 4.5 floor for
   text below 24px. Darkened to the first value that clears AA. */
:root{ --steel-2:#69737F; --signal-text:#C0400F; }

/* 11.2 Signal orange is a display colour. At label size on paper it measured
   3.04–3.55:1. Small orange type now uses the darker signal; display keeps it. */
.mod__code.mono, .lead__kicker, .watch-stamp, .memberfile__label,
.engage-card__label, .service-link .mono, .watch-card > .mono,
.article-desk h5, .memberfile__contact span, .cap-title,
.reader-card__num, .mod__byline, a.readmore{ color:var(--signal-text) }

/* 11.3 On the dark panels the same labels need to go lighter, not darker. */
.spread__memo .mod__code.mono, .spread__quote .mod__code.mono,
.masthead__sub, .foot__line, .foot__note,
.band--dark .mod__code.mono{ color:#9AA4B2 }
.spread__memo .mod__code.mono, .spread__quote .mod__code.mono{ color:#A7B0BD }

/* 11.4 An unstyled mailto in the dark footer region rendered as browser blue
   on near-black — 2.08:1. Links inherit the panel's own ink from here on. */
.spread__memo a, .foot a, .band--dark a{ color:#EAEEF3; text-decoration-color:#69737F }

/* 11.5 The empty rail. The rail carries 543–894px of content beside an article
   running 1,100–4,242px, so a two-column grid always ends in a hole. The rail
   now travels with the reader instead of stopping. Markup untouched. */
@media (min-width:1001px){
  .article-side{ position:sticky; top:88px; align-self:start }
}

/* 11.6 The rail would not stick: .spread and .spread__article carry
   overflow:hidden, which makes any descendant sticky element inert. Horizontal
   clipping is what those rules were for, so keep it on x and free the y axis. */
@media (min-width:1001px){
  .spread, .spread__article{ overflow-x:clip; overflow-y:visible }
}
