/* ============================================================
   product.css — product detail pages (/products/<slug>/)
   Load order: base -> layout -> components -> product -> responsive
   ONE file for every product page. Never a per-product stylesheet:
   the pages share structure by design (see _templates/product-page.html),
   and a per-product file is how they would start to drift.
   Breakpoints for these blocks live in responsive.css, not here.
   ============================================================ */

/* BREADCRUMB — sits under the 72px fixed nav */
.crumbs {
  padding: 96px 0 0;
  font-family: var(--font-ui);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-dim);
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.crumbs a { transition: color 0.2s; }
.crumbs a:hover { color: var(--vg); }
.crumbs .crumb-sep { color: var(--border-mid); }
.crumbs [aria-current="page"] { color: var(--vg); }

/* PRODUCT HERO */
.product-hero {
  padding: 48px 0 96px;
  background: var(--bg);
}
.product-hero-grid {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 72px;
  align-items: center;
}
/* Media-led hero (SNOW ANGEL): the promo video takes ~60% of the row so the
   text in it stays legible. responsive.css's <=900px stacking rule sits at
   the same (0,1,0) and loads later, so it still wins. The copy column is too
   narrow for four facts in a row, so they go 2x2 at every width, the same
   grid the <=600px strip uses. */
.product-hero-grid--media { grid-template-columns: 1fr 1.5fr; gap: 48px; }
.product-hero-grid--media .product-facts { display: grid; grid-template-columns: 1fr 1fr; }
.product-hero-grid--media .product-fact { margin-right: 0; padding-right: 16px; }
.product-hero-grid--media .product-fact:nth-child(2n) { border-right: none; padding-left: 16px; }
.product-hero .tag { margin-bottom: 24px; }
.product-hero .section-title { margin-bottom: 10px; }
.product-kicker {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 28px;
}
.product-lede {
  font-family: var(--font-body);
  font-size: var(--fs-lede);
  font-weight: 400;
  color: var(--text-mid);
  line-height: 1.8;
  margin-bottom: 36px;
}
/* Key-facts strip: a ruled row of label/value pairs. */
.product-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  border-top: 1px solid var(--border-mid);
  border-bottom: 1px solid var(--border-mid);
  margin-bottom: 40px;
}
/* As a direct child of the hero grid (LACE), the strip spans both columns
   under the photo and copy; the negative margin pulls the 72px row gap in
   to 48px. Pages with the strip inside the copy column are unaffected. */
.product-hero-grid > .product-facts { grid-column: 1 / -1; margin: -24px 0 0; }
/* The buttons follow it the same way (LACE), 32px under the strip. */
.product-hero-grid > .product-actions { grid-column: 1 / -1; margin-top: -40px; }
.product-fact {
  flex: 1 1 120px;
  padding: 16px 20px 16px 0;
  margin-right: 20px;
  border-right: 1px solid var(--border);
}
.product-fact:last-child { border-right: none; margin-right: 0; }
.product-fact-key {
  font-family: var(--font-ui);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 6px;
}
.product-fact-val {
  font-family: var(--font-ui);
  font-size: var(--fs-ui-sm);
  font-weight: 500;
  color: var(--vg);
  line-height: 1.5;
}
.product-actions {
  display: flex;
  gap: 16px;
  align-items: center;
  flex-wrap: wrap;
}
/* The hero photo reuses .card-media (4:3 frame, placeholder support). Only the
   bottom margin differs — bare, it is the last thing in its column. */
.product-hero .card-media { margin-bottom: 0; }
/* Captioned hero photo (LACE): the figure is the grid item and the caption
   follows the frame. Same specificity as the rule above, later, so it wins. */
.product-hero-figure .card-media { margin-bottom: 14px; }
/* Diagram frames (software pages). When a real diagram lands, set
   aspect-ratio inline on the element to the image's own ratio. */
.card-media--wide { aspect-ratio: 16 / 9; }
/* Video in a media frame (SNOW ANGEL promo): fills it like .card-media img.
   display:block drops the inline baseline gap under the element. */
.card-media video { display: block; width: 100%; height: 100%; object-fit: cover; }

/* STEPS — the Develop / Compile / Deploy band (software pages). Replaces
   the gallery. The biggest tiles on the site, because they are the story. */
.product-steps {
  padding: 0 0 96px;
  background: var(--bg);
}
.steps-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--border-mid);
  border: 1px solid var(--border-mid);
}
.step {
  background: var(--bg);
  padding: 40px 36px 36px;
  min-width: 0;
  position: relative;          /* anchors the arrow badge; never overflow:hidden here */
  display: flex;
  flex-direction: column;
}
.step-num {
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 44px;
  letter-spacing: 0.04em;
  line-height: 1;
  color: var(--gold);
  margin-bottom: 8px;
}
.step-title {
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 30px;
  letter-spacing: 0.07em;
  line-height: 1.1;
  color: var(--vg-dark);
  margin-bottom: 6px;
}
.step-who {
  font-family: var(--font-ui);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 18px;
}
.step-text {
  font-family: var(--font-ui);
  font-size: var(--fs-ui);
  font-weight: 400;
  color: var(--text-mid);
  line-height: 1.75;
  flex: 1;
}
/* An inline link in step copy (SNOW ANGEL -> LACE). base.css strips link
   colour and underline site-wide, so without this it would be invisible. */
.step-text a {
  color: var(--vg);
  text-decoration: underline;
  text-decoration-color: var(--border-mid);
  text-underline-offset: 3px;
  transition: color 0.2s, text-decoration-color 0.2s;
}
.step-text a:hover { color: var(--gold); text-decoration-color: currentColor; }
/* in -> out strip: reads across the row as a chain */
.step-io {
  font-family: var(--font-ui);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--vg);
  margin-top: 22px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
/* Arrow badge centered on the hairline between tiles. responsive.css moves
   it to the top edge and points it down when the tiles stack. */
.step + .step::before {
  content: '\2192';
  position: absolute;
  left: -13px;
  top: 50%;
  transform: translateY(-50%);
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--border-mid);
  color: var(--gold);
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
}
/* Pillars variant (LACE): the same tiles carrying parallel points, not a
   sequence — so no arrow badges. (0,3,1) outranks the (0,2,1) arrow rules
   above and in responsive.css. With no .step-who, the title needs its own gap. */
.product-steps--pillars .step + .step::before { content: none; }
.product-steps--pillars .step-title { margin-bottom: 14px; }
/* Flow variant (SWS): five steps, mission concept to on-orbit support. Same
   tiles and arrow badges at a fifth of the width, so tighter padding and a
   smaller title. Each tile is number + title only, so the title is the last
   thing in it and drops its gap. The column rule is a bare class (0,1,0) on
   purpose: responsive.css stacks it with an equal-specificity rule that wins
   only because it loads later. */
.steps-grid--five { grid-template-columns: repeat(5, 1fr); }
.product-steps--flow .step { padding: 32px 24px 28px; }
.product-steps--flow .step-title { font-size: 24px; margin-bottom: 0; }

/* GALLERY */
.product-gallery {
  padding: 0 0 96px;
  background: var(--bg);
}
.product-gallery-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}
.product-gallery figure { margin: 0; }
.product-gallery .card-media { margin-bottom: 14px; }
.product-gallery figcaption,
.product-hero-figure figcaption {
  font-family: var(--font-ui);
  font-size: var(--fs-ui-sm);
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  line-height: 1.6;
}

/* OVERVIEW */
.product-overview {
  padding: 96px 0;
  background: var(--surface);
}
.product-overview-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 80px;
  align-items: start;
}
.product-prose p {
  font-family: var(--font-body);
  font-size: var(--fs-lede);
  font-weight: 400;
  color: var(--text-mid);
  line-height: 1.85;
  margin-bottom: 22px;
}
/* Inline links in prose. Base `a` inherits color with no underline, which
   would leave a link indistinguishable from the text around it. */
.product-prose a {
  color: var(--vg);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color 0.2s;
}
.product-prose a:hover { color: var(--vg-light); }
.product-prose p:last-child { margin-bottom: 0; }
.product-highlights {
  border-top: 1px solid var(--border-mid);
}
.product-highlights h3 {
  font-family: var(--font-ui);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
  padding: 20px 0 6px;
}
.product-highlights ul { list-style: none; }
.product-highlights li {
  font-family: var(--font-ui);
  font-size: var(--fs-ui);
  font-weight: 400;
  color: var(--text-dim);
  line-height: 1.7;
  padding: 14px 0 14px 22px;
  border-bottom: 1px solid var(--border);
  position: relative;
}
.product-highlights li strong {
  font-weight: 500;
  color: var(--text);
}
.product-highlights li::before {
  content: '';
  position: absolute;
  left: 0; top: 24px;
  width: 10px; height: 1px;
  background: var(--vg-light);
}

/* Dataflow figure (SNOW ANGEL): a full-width strip under the overview prose.
   The image is ~4:1, so below 600px responsive.css gives it a minimum width
   and this wrapper scrolls it sideways instead of shrinking it unreadably. */
.product-dataflow { margin: 64px 0 0; }
.product-dataflow-scroll {
  overflow-x: auto;
  border: 1px solid var(--border-mid);
  border-radius: 2px;
  margin-bottom: 14px;
}
.product-dataflow img { display: block; width: 100%; height: auto; }
.product-dataflow--plain .product-dataflow-scroll { border: none; }
.product-dataflow figcaption {
  font-family: var(--font-ui);
  font-size: var(--fs-ui-sm);
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  line-height: 1.6;
}

/* SPECIFICATIONS */
.product-specs {
  padding: 96px 0;
  background: var(--bg);
}
.spec-groups {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px 80px;
}
.spec-group h3 {
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 22px;
  letter-spacing: 0.07em;
  color: var(--vg-dark);
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border-mid);
  margin-bottom: 4px;
}
.spec-list {
  display: grid;
  grid-template-columns: minmax(120px, 0.8fr) 1.2fr;
}
.spec-list dt, .spec-list dd {
  padding: 13px 0;
  border-bottom: 1px solid var(--border);
}
.spec-list dt {
  font-family: var(--font-ui);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-dim);
  padding-right: 16px;
  /* Center the label INSIDE the cell, never with align-self: center — that
     shrinks the dt to its content height and its border-bottom no longer
     lines up with the dd's, so the hairline steps at every row. */
  display: flex;
  align-items: center;
}
.spec-list dd {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 400;
  color: var(--text);
  line-height: 1.5;
}
.spec-note {
  font-family: var(--font-ui);
  font-size: var(--fs-ui-sm);
  font-weight: 400;
  color: var(--text-dim);
  line-height: 1.7;
  margin-top: 40px;
  max-width: 720px;
}
/* Sensor portfolio (SWS): spec groups whose rows are capabilities, not
   key/value pairs. Each row matches a .spec-list dd. */
.spec-points { list-style: none; }
.spec-points li {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 400;
  color: var(--text);
  line-height: 1.5;
  padding: 13px 0;
  border-bottom: 1px solid var(--border);
}
/* A spec group whose only content is an action (SNOW ANGEL Availability).
   .btn-secondary is inline-flex, so margin applies; without it the button
   sits 4px under the h3's hairline. */
.spec-group .btn-secondary { margin-top: 20px; }

/* PERFORMANCE / STATUS — stat tiles for measured figures, or for development
   milestones (LACE). responsive.css stacks them at <=900px: a word value
   like "Validated" would otherwise break mid-word in a third of 601px. */
.product-perf {
  padding: 96px 0;
  background: var(--surface);
}
/* The preliminary note is deliberately the first thing under the heading. */
.perf-note {
  display: inline-flex;
  align-items: flex-start;
  gap: 12px;
  font-family: var(--font-ui);
  font-size: var(--fs-ui-sm);
  font-weight: 400;
  color: var(--text-mid);
  line-height: 1.7;
  padding: 14px 18px;
  border: 1px solid var(--border-gold);
  background: var(--gold-tint);
  margin-bottom: 40px;
  max-width: 760px;
}
.perf-note strong {
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
  white-space: nowrap;
}
/* Same ruling trick as .card-grid: the 1px gaps ARE the hairlines. */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--border-mid);
  border: 1px solid var(--border-mid);
}
.stat {
  background: var(--bg);
  padding: 32px 32px 28px;
  min-width: 0;                /* grid items default to min-width:auto and refuse to
                                  shrink below a long .stat-val — widening the page */
}
.stat-key {
  font-family: var(--font-ui);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 14px;
}
.stat-val {
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 44px;
  letter-spacing: 0.04em;
  line-height: 1;
  color: var(--vg);
  margin-bottom: 10px;
  overflow-wrap: anywhere;
}
.stat-val small {
  font-size: 22px;
  letter-spacing: 0.06em;
  color: var(--vg-light);
  margin-left: 4px;
}
.stat-cond {
  font-family: var(--font-ui);
  font-size: var(--fs-ui-sm);
  font-weight: 400;
  color: var(--text-dim);
  line-height: 1.6;
}

/* COMING-SOON VALUES — a spec or fact whose number is not published yet.
   Mono and dimmed so it reads as a deliberate "not yet", not a missing value.
   Remove the span (or the class on .stat-val) when the real value lands. */
.tbd {
  font-family: var(--font-ui);
  font-size: var(--fs-label);
  font-weight: 400;
  font-style: normal;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
  opacity: 0.75;
}
.stat-val.tbd {
  font-family: var(--font-head);
  font-size: 44px;
  letter-spacing: 0.04em;
  opacity: 0.35;
}

/* CTA BAND */
.product-cta {
  padding: 96px 0;
  background: var(--bg);
  text-align: center;
}
.product-cta .section-title { margin-bottom: 20px; }
.product-cta p {
  font-family: var(--font-body);
  font-size: var(--fs-lede);
  font-weight: 400;
  color: var(--text-mid);
  line-height: 1.8;
  /* 800px: the widest cap at which no product's CTA copy ends on a stub
     line at desktop width (620px left every one with a short last line).
     text-wrap: pretty guards narrower widths where browsers support it. */
  max-width: 800px;
  text-wrap: pretty;
  margin: 0 auto 36px;
}
.product-cta .product-actions { justify-content: center; }
