/* ============================================================================
   SWORT media compositions: copy beside a single image
   ---------------------------------------------------------------------------
   WHY THIS FILE EXISTS, AND WHY IT IS NOT IN page.css
   ---------------------------------------------------
   These rules originally shipped inside page.css. page.css is loaded by exactly
   four routes (government-capabilities, investors, research-partnerships, team)
   and NOT by index.html. So on the homepage `.ssil-split` resolved to
   `display: block`, the SSIL electronics photograph lost its 45% column and
   rendered at the full 1065px container width and 710px tall, turning a
   two-column composition into a wall of photograph. Measured before the fix:

     .ssil-split   display   block          (expected grid)
                   columns   none           (expected 55fr 45fr)
     img           rendered  1065 x 710 px  (expected ~470 x 313)
     #ssil         height    1288 px        on a 900px viewport

   The image also looked soft, and that was the SAME bug rather than a second
   one: `sizes` promises 44vw, the browser picked the file for that promise, and
   the broken layout then stretched it across 1065 CSS px on a 2x display. Fix
   the column and the sharpness returns with it. No re-encoding was needed; the
   derivatives were verified correct on disk and correct when decoded.

   Splitting the rules out rather than adding page.css to index.html is
   deliberate. page.css redefines `.container` (max-width and horizontal
   padding, plus a breakpoint override). index.html has its own `.container`
   treatment, so linking page.css there to obtain four rules would have
   rewritten the grid every section on the homepage sits in. Of the 73 classes
   page.css defines, index.html uses 8, and 4 of those are the ones below.

   A shared component belongs in a shared file. That is what this is.

   Loaded by: index.html, research-partnerships.html, team.html.
   Guarded by scripts/verify-css-reachable.mjs, which fails the build if a page
   uses one of these classes without linking this stylesheet.
   ========================================================================= */

/* ── Two-column composition ───────────────────────────────────────────────
   Copy on the left, one image on the right, stacking to copy-then-image on
   narrow screens. Text leads on mobile in every case: the image illustrates
   something the copy has just said, so it should not arrive first.

   minmax(0, …) on both tracks because the default `auto` minimum refuses to
   shrink below content size, which is what makes a long unbroken string in the
   copy column push the image column off-grid. */
.p-hero-split, .ssil-split {
  display: grid;
  grid-template-columns: minmax(0, 55fr) minmax(0, 45fr);
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: center;
}
.p-hero-copy, .ssil-copy { min-width: 0; }

/* No card, no border, no radius, no shadow. The UAV source is already on black
   and sits directly on the section; framing it would reintroduce the boxed look
   the brief rules out. */
.p-hero-figure, .ssil-figure { margin: 0; min-width: 0; }
.p-hero-figure picture, .ssil-figure picture { display: block; }
.p-hero-figure img {
  display: block; width: 100%; height: auto;
  /* Matches the section's own black so the image edge is invisible. */
  background: var(--swort-black);
}

/* The electronics photo is a real photograph on a light section, so it gets a
   hairline rule rather than nothing: without an edge it floats.

   aspect-ratio is declared so the column reserves its height before the image
   decodes. The width/height attributes in the markup describe the SOURCE
   (1536x1024); this describes the SLOT, and without it the figure collapses to
   the caption height on first paint and the section reflows underneath the
   reader. Still no radius and no drop shadow. */
.ssil-figure img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 1536 / 1024;
  object-fit: cover;
  border: 1px solid var(--paper-rule);
}

.p-hero-figcap, .ssil-figcap {
  font-family: 'DM Mono', ui-monospace, monospace;
  font-size: var(--type-caption);
  line-height: var(--leading-body);
  margin-top: 0.75rem;
  max-inline-size: var(--measure-note);
  text-wrap: pretty;
}
.p-hero-figcap { color: var(--swort-gray); }
.ssil-figcap  { color: var(--paper-muted); }

/* Below the stacking point the image is no longer a column, so it would run the
   full container width. On a phone that is fine; on a tablet a 700px-wide
   photograph of an avionics bay is louder than the heading above it, so it is
   capped and left-aligned with the copy rather than centred. */
@media (max-width: 900px) {
  .p-hero-split, .ssil-split { grid-template-columns: 1fr; gap: clamp(1.5rem, 5vw, 2rem); }
  .p-hero-figure, .ssil-figure { max-inline-size: 560px; }
}

/* ── Hardware & Programs lede: editorial product composition ──────────────
   Copy column and board side by side, board weighted heavier, per the brief's
   35-40 / 60-65 split. The board is a transparent cut-out, so it needs no card,
   border, radius, shadow or glow: it sits directly on the section.

   Ratio is expressed in fr rather than percentages so the gap comes out of the
   grid rather than out of the columns, which is what keeps the measured split
   inside the requested band instead of drifting once the gap grows. */
/* THE STARFIELD STOPS AT THE TYPE.

   The page-wide star canvas was rendering at full strength directly behind this
   section's copy, so points of light sat inside the letterforms of the lede and
   the capability terms. That single thing is most of why the section read as
   cheap: the type looked dirty, and no amount of spacing fixes text competing
   with noise at the same tone.

   A radial scrim, densest behind the reading column and releasing toward the
   edges, gives the copy a clean field while leaving the starfield visible where
   it is doing decorative work. It is painted as the section's own background so
   it sits under every child without needing a stacking context. */
.hw-lede {
  padding: calc(var(--section-pad) + 56px) 0 var(--section-pad);
  background:
    radial-gradient(130% 100% at 34% 45%,
      rgba(5, 5, 5, 0.94) 0%,
      rgba(5, 5, 5, 0.86) 38%,
      rgba(5, 5, 5, 0.42) 72%,
      rgba(5, 5, 5, 0) 100%);
}
.hw-lede-grid {
  display: grid;
  /* 42/58 rather than 38/62. At 38 the reading column came out at 383px, which
     is a 40-character measure in this monospace: the lede wrapped five times
     and the kicker broke mid-word. */
  grid-template-columns: minmax(0, 42fr) minmax(0, 58fr);
  gap: clamp(2rem, 4vw, 4.5rem);
  align-items: center;
}
.hw-lede-copy { min-width: 0; }
.hw-lede-title { margin-bottom: 0.5em; }
.hw-lede-cta { margin-top: clamp(1.5rem, 2.5vw, 2.25rem); }

/* Three capability statements. A hairline rule per row, no box: a bordered card
   here would rebuild the card grid the brief rules out. */
.hw-points {
  margin: clamp(1.75rem, 3vw, 2.5rem) 0 0;
  padding: 0;
  border-top: 1px solid var(--swort-border-dark);
}
.hw-point {
  padding: clamp(0.9rem, 1.4vw, 1.15rem) 0;
  border-bottom: 1px solid var(--swort-border-dark);
}
.hw-point-term {
  font-family: 'DM Mono', ui-monospace, monospace;
  font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--swort-white); margin: 0 0 0.45rem;
}
.hw-point-desc {
  font-family: 'DM Mono', ui-monospace, monospace;
  font-size: 12px; line-height: 1.8;
  color: var(--swort-gray); margin: 0; max-inline-size: 52ch;
}

/* THE BOARD IS ON A STAGE, NOT FLOATING.

   A transparent cut-out dropped straight onto a starfield has nothing holding
   it: no ground plane, no edge, no relationship to the page. It reads as an
   image pasted over a background rather than an object being presented, which
   is the second half of why this section looked cheap.

   The stage is the fix, and it is deliberately not a "card": one hairline, a
   very slightly lifted surface, and a soft contact shadow under the board. That
   is how a specimen is presented on a plate. No radius beyond 2px, no glow, no
   drop shadow on the artwork itself, nothing that would read as a UI panel. */
.hw-feature {
  margin: 0; min-width: 0;
  position: relative;
  border: 1px solid var(--swort-border-dark);
  background:
    radial-gradient(88% 74% at 50% 34%, #131313 0%, #0d0d0d 58%, #090909 100%);
  padding: clamp(1.25rem, 2.6vw, 2.25rem);
}
/* A small plate label, so the frame reads as intentional presentation rather
   than a box that happened to appear around an image. */
.hw-feature::before {
  content: 'ILLUSTRATIVE ARCHITECTURE';
  position: absolute; top: 0; left: 0;
  padding: 7px 12px;
  font-family: 'DM Mono', ui-monospace, monospace;
  font-size: 9px; letter-spacing: 0.22em; color: #6d6d6d;
  border-right: 1px solid var(--swort-border-dark);
  border-bottom: 1px solid var(--swort-border-dark);
}
.hw-feature picture { display: block; position: relative; }
/* The contact shadow. Sits under the board's lower edge and is what actually
   grounds it; without it the object still hovers no matter how the frame is
   drawn. */
.hw-feature picture::after {
  content: '';
  position: absolute; left: 15%; right: 15%; bottom: 7%;
  height: 46px;
  background: radial-gradient(50% 50% at 50% 50%, rgba(0, 0, 0, 0.68), rgba(0, 0, 0, 0));
  filter: blur(8px);
  /* NOT z-index:-1. A negative index escapes the picture and drops the shadow
     behind the stage's own background, where it is invisible. The shadow needs
     to sit above the stage and below the board, so both are given an explicit
     index in the same stacking context. */
  z-index: 0;
}
.hw-feature img {
  display: block;
  width: 100%;
  height: auto;
  position: relative;
  z-index: 1;
  /* Capped because the transparent master is 996px wide; beyond this the fine
     silkscreen in the source stops resolving and the board only gets softer. */
  max-inline-size: 760px;
  aspect-ratio: 996 / 758;
  margin-inline: auto;
}
/* The disclaimer is load-bearing and must stay, but it was set at body weight
   across 72 characters and competed with the section it belongs to. It is now a
   footnote inside the stage, separated by the same hairline as the frame. */
.hw-feature-cap {
  font-family: 'DM Mono', ui-monospace, monospace;
  font-size: 10px;
  line-height: 1.75;
  color: #7a7a7a;
  margin: clamp(1rem, 2vw, 1.5rem) 0 0;
  padding-top: clamp(0.85rem, 1.6vw, 1.15rem);
  border-top: 1px solid var(--swort-border-dark);
  max-inline-size: none;
  text-wrap: pretty;
}

/* Stack below the split point, copy first: the board illustrates what the copy
   has just said, so it should not arrive ahead of it. */
@media (max-width: 900px) {
  .hw-lede-grid { grid-template-columns: 1fr; gap: clamp(1.75rem, 5vw, 2.5rem); }
  .hw-feature img { max-inline-size: 620px; }
}

/* ── Program publication strip ────────────────────────────────────────────
   Replaces a full-height section that existed to say content was not ready. */
.s-programs { padding: clamp(2.5rem, 5vw, 4.5rem) 0; }
.prog-strip {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(1.5rem, 3vw, 3rem);
  align-items: center;
  padding: clamp(1.5rem, 2.6vw, 2.25rem) 0;
  border-top: 1px solid var(--swort-border-dark);
  border-bottom: 1px solid var(--swort-border-dark);
}
.prog-strip-kicker {
  font-family: 'DM Mono', ui-monospace, monospace;
  font-size: 10px; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--swort-gray); margin: 0 0 0.6rem;
}
.prog-strip-title {
  font-family: 'Bebas Neue', sans-serif; font-weight: 400;
  font-size: clamp(20px, 2.2vw, 28px); letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--swort-white); margin: 0 0 0.6rem;
}
.prog-strip-body {
  font-family: 'DM Mono', ui-monospace, monospace;
  font-size: 12px; line-height: 1.85;
  color: var(--swort-gray); margin: 0; max-inline-size: 72ch;
}
.prog-strip-cta { justify-self: end; white-space: nowrap; }
@media (max-width: 760px) {
  .prog-strip { grid-template-columns: 1fr; }
  .prog-strip-cta { justify-self: start; }
}

/* ── Founder portrait ─────────────────────────────────────────────────────
   Lives here rather than in page.css for the same reason as the rules above:
   one place for image compositions, so the next page that needs one links a
   single file instead of inheriting a page-scoped stylesheet. */
.t-founder-media {
  margin: 0;
  min-width: 0;
}
.t-founder-media picture { display: block; }
.t-founder-media img {
  display: block;
  width: 100%;
  height: auto;
  /* Natural portrait proportion, not a circle and not a forced square. */
  aspect-ratio: 1320 / 1661;
  object-fit: cover;
  /* Eyeline sits in the upper third; centring crops the forehead when the slot
     is short. */
  object-position: 50% 42%;
  border: 1px solid var(--paper-rule);
}
@media (max-width: 860px) {
  .t-founder-media { max-inline-size: 420px; }
}
