/* Equipment page — scoped additions built from the existing PGISR design system. */
.equipment-page main {
  background:
    radial-gradient(circle at 82% 8%, rgba(24, 50, 65, 0.18), transparent 32rem),
    var(--bg);
}

.equipment-hero {
  position: relative;
  overflow: hidden;
  min-height: min(680px, 76vh);
  padding: calc(var(--header-h) + clamp(3.25rem, 6vw, 5rem)) 0 clamp(3.5rem, 6vw, 5rem);
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(75% 65% at 78% 12%, rgba(42, 150, 136, 0.12), transparent 68%),
    linear-gradient(160deg, #141e2c 0%, var(--bg) 55%),
    var(--bg);
}

.equipment-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(183, 201, 210, 0.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(183, 201, 210, 0.025) 1px, transparent 1px);
  background-size: 44px 44px;
  mask-image: linear-gradient(90deg, transparent, #000 48%, #000);
}

.equipment-hero-grid {
  position: relative;
  z-index: 1;
  display: grid;
  /* Near-even split. The configurator reads as a single-column order list
     rather than a tile grid, so the frame no longer needs to dominate the
     row and the copy keeps a comfortable measure. */
  grid-template-columns: minmax(0, 0.95fr) minmax(28rem, 1.05fr);
  gap: clamp(2.25rem, 5vw, 5.25rem);
  align-items: start;
}

/* Grid items floor at min-content by default. The long display words in the
   title and the nowrap attribute chips pushed the copy column's floor to
   ~588px at 1600, so the fr split never applied and the diagram column was
   starved of the width its two views need. */
.equipment-hero-copy {
  min-width: 0;
}

.equipment-hero-title {
  max-width: 11ch;
  margin: 1rem 0 1.4rem;
  font-size: clamp(3.15rem, 5.5vw, 5.35rem);
  line-height: 0.96;
  letter-spacing: -0.055em;
}


.equipment-hero-lede {
  max-width: 39rem;
  margin: 0;
  color: var(--body);
  font-size: clamp(1rem, 1.4vw, 1.16rem);
  line-height: 1.72;
}

/* Deck: the one-sentence PGISR/PGI expansion functions as the subhead
   under the H1, so it needs to read as one — larger and brighter than the
   body copy below it (which was backwards before: 0.92-1.03rem body-grey
   text is indistinguishable from a paragraph), medium weight rather than
   the H1's bold so it stays subordinate, and a narrower measure so it
   reads as a deliberate deck line rather than a running paragraph.
   The title's own bottom margin is zeroed by the shared body.pgisr
   heading rule, so this line owns the gap under it. */
.equipment-hero-positioning {
  max-width: 34rem;
  margin: clamp(1rem, 1.6vw, 1.4rem) 0 0;
  /* var(--steel) was the obvious choice but reads almost identical to the
     body copy's var(--body) here — premium.css redefines --body to
     #a2afb9, nearly the same brightness as --steel's #9bacb8. A near-ink
     white gives real separation from body copy while staying clearly
     under the H1's full-opacity var(--ink) + bold weight. */
  color: rgba(255, 255, 255, 0.86);
  font-size: clamp(1.08rem, 1.6vw, 1.3rem);
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: -0.005em;
}

/* Intro paragraph: the one block of running prose in the column, so it
   owns a slightly wider gap above than the blocks that follow. */
/* A more deliberate break than the gaps between body blocks below it —
   this is the seam between the deck and the start of body copy. */
.equipment-hero-intro {
  margin-top: clamp(0.85rem, 1.3vw, 1.1rem);
}

/* Make the interactive diagram discoverable before someone has to infer it
   from the small plus marks inside the sensor box. On phones this also works
   as a direct jump from the copy to the configurator below it. */
.equipment-configurator-jump {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.75rem;
  max-width: 34rem;
  margin-top: 1.25rem;
  padding: 0.72rem 0.85rem;
  border: 1px solid rgba(87, 194, 181, 0.42);
  background: rgba(42, 174, 158, 0.055);
  color: var(--ink);
  text-decoration: none;
  transition: border-color 160ms ease, background-color 160ms ease;
}

.equipment-configurator-jump:hover,
.equipment-configurator-jump:focus-visible {
  border-color: var(--accent);
  background: rgba(42, 174, 158, 0.1);
  outline: none;
}

.equipment-configurator-jump:focus-visible {
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent);
}

.equipment-configurator-jump-mark {
  display: grid;
  width: 1.9rem;
  height: 1.9rem;
  place-items: center;
  border: 1px solid rgba(87, 194, 181, 0.65);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 1rem;
  line-height: 1;
}

.equipment-configurator-jump-copy {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 0.12rem;
}

.equipment-configurator-jump-copy strong {
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.equipment-configurator-jump-copy small {
  color: var(--body);
  font-size: 0.82rem;
  line-height: 1.4;
}

.equipment-configurator-jump-arrow {
  color: var(--accent);
  font-size: 1.05rem;
  transition: transform 160ms ease;
}

.equipment-configurator-jump:hover .equipment-configurator-jump-arrow,
.equipment-configurator-jump:focus-visible .equipment-configurator-jump-arrow {
  transform: translateX(0.2rem);
}

.equipment-hero-points {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  /* The lede above and the list below both set margin:0 on that edge, so
     the chip row owns the gap on both sides. Tightened from
     clamp(1.4rem, 2.1vw, 1.85rem): the chips and the three-statement list
     below them were reading as two separate feature sections stacked
     between the intro and the simulator, instead of shared supporting
     context leading into it. */
  margin: clamp(0.9rem, 1.4vw, 1.2rem) 0 clamp(0.9rem, 1.4vw, 1.2rem);
  padding: 0;
  list-style: none;
}

/* The three attribute lines. Set as a list rather than stacked paragraphs
   so the column scans instead of reading as one wall of prose. Markers are
   drawn as accent rules to match the diagram's drafting language rather
   than using default disc bullets. */
.equipment-hero-list {
  margin: 0;
  padding: 0;
  list-style: none;
  max-width: 39rem;
}

.equipment-hero-list li {
  position: relative;
  padding-left: 1.35rem;
  color: var(--body);
  font-size: clamp(0.98rem, 1.3vw, 1.1rem);
  line-height: 1.62;
}

.equipment-hero-list li + li {
  margin-top: 0.72rem;
}

.equipment-hero-list li::before {
  content: "";
  position: absolute;
  top: 0.72em;
  left: 0;
  width: 0.55rem;
  height: 1px;
  background: var(--accent);
}

/* The hero copy runs straight across rather than sitting in a column beside
   the diagram: title on one line the width of the shell, deck and lede on a
   shared measure below it, the three attribute lines as a row, and the
   configurator full width underneath. The configurator is the thing worth
   the width — at full width both of its views hold real size, and the copy
   keeps a single left edge instead of splitting into two reading orders.
   Below 1021px the stacked rules further down take over unchanged. */
@media (min-width: 1021px) {
  .equipment-hero-grid {
    display: block;
  }

  /* css/pgisr-system.css caps this at 14ch under body.pgisr and loads after
     this file, so the override carries a class more to outrank it. Ceiling
     lowered from 4.6rem and the vw coefficient trimmed from 4.9vw so this
     title stays clearly under the homepage hero's own 4.9vw/4.6rem scale
     across common desktop widths, not just at the ceiling. */
  body.pgisr .equipment-hero .equipment-hero-copy .equipment-hero-title {
    max-width: none;
    font-size: clamp(2.6rem, 4.6vw, 4.2rem);
    margin-bottom: 1.6rem;
  }

  /* The lede is a real paragraph, so it keeps a readable measure. The
     positioning line is meant to read as one line at this breakpoint —
     capping it at the same 62ch was what forced it to wrap. */
  body.pgisr .equipment-hero .equipment-hero-lede {
    max-width: 62ch;
  }

  body.pgisr .equipment-hero .equipment-hero-positioning {
    max-width: none;
    /* Tightened from the base -0.005em: at the shell's own 1440px cap the
       line is ~14px wider than that at the base tracking, just enough to
       force a second line. This closes the gap without changing size or
       wording. */
    letter-spacing: -0.012em;
  }

  /* Was clamp(2.2rem, 3.5vw, 3.2rem), then trimmed to clamp(1.3rem, 2vw,
     1.7rem) to bring "Build a sensor box" forward while the simulator still
     sat inside its own bordered card. With that card removed, this gap is
     now the only thing marking the simulator as its own section, so it's
     nudged back up partway — still well short of the original. */
  .equipment-hero-copy {
    margin-bottom: clamp(2rem, 2.8vw, 2.5rem);
  }

  /* Three facts across, under a rule: a row of short lines scans, where the
     same three stacked read as a paragraph broken into pieces. */
  .equipment-hero-list {
    display: grid;
    /* Uneven on purpose: the third line runs more than twice as long as the
       other two, so equal thirds wrapped it to 3 lines against their 1-2 —
       the row read bottom-heavy and lopsided. Weighting columns toward
       each line's own length settles all three within one line of each
       other instead. */
    grid-template-columns: 0.85fr 0.75fr 1.4fr;
    gap: 0 clamp(1.25rem, 2.5vw, 2.25rem);
    max-width: none;
    /* Trimmed from clamp(1.2rem, 2vw, 1.8rem) alongside the chip row's own
       margin above: the rule still separates this list from the chips, but
       it no longer needs a full section's worth of air to do it. */
    padding-top: clamp(0.75rem, 1.1vw, 1rem);
    border-top: 1px solid var(--line);
  }

  .equipment-hero-list li + li {
    margin-top: 0;
  }

  .equipment-hero-visual {
    width: 100%;
  }

  /* The configurator now follows the copy directly, so the jump link would
     scroll to something already in view — and it repeats the lead-in that
     now sits above the frame. Kept below this breakpoint, where the
     configurator really is a long way down the page. */
  .equipment-configurator-jump {
    display: none;
  }
}


.equipment-hero-points li {
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--line);
  color: var(--steel);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.equipment-status-note {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  max-width: 39rem;
  margin: 1.8rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.65rem;
  line-height: 1.5;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.equipment-status-note::before {
  content: "";
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--field-bright);
  box-shadow: 0 0 0 4px rgba(145, 164, 127, 0.1);
}

/* No border/panel fill/shadow: the simulator used to sit inside a bordered
   card (border + var(--bg-2) fill + drop shadow), which read as a separate
   dashboard widget dropped onto the page rather than part of it. The
   configurator's own inner background (.equipment-system-visual, near-black
   and close to the page's own --bg already) and its grid texture now carry
   the section on the page's own background — section separation comes from
   spacing (see .equipment-hero-copy's margin-bottom below), not a frame. */
.equipment-hero-visual {
  margin: 0;
}

.equipment-hero-visual img {
  width: 100%;
  height: auto;
}

/* Lead-in above the diagram: just the heading now (the supporting sentence
   was redundant with "01 CHOOSE YOUR SENSORS" and "GPS · BUILT IN" below,
   so it was removed). Margin-bottom trimmed from 1.9rem to match a
   one-line heading instead of the taller heading+paragraph block it used
   to close — at the old value the panel below read as stranded under it. */
.equipment-system-intro {
  max-width: 46rem;
  margin: 0 0 1.15rem;
}

.equipment-system-intro h2 {
  margin: 0 0 0.45rem;
  color: var(--ink);
  font-size: clamp(1.5rem, 2.2vw, 2rem);
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.equipment-system-intro p {
  margin: 0;
  color: var(--body);
  font-size: clamp(0.98rem, 1.3vw, 1.08rem);
  line-height: 1.6;
}

.equipment-system-intro b {
  color: var(--accent);
  font-family: var(--font-mono);
  font-weight: 500;
}

.equipment-system-visual {
  position: relative;
  display: grid;
  align-items: center;
  /* The 4x2 tile grid is shorter than the old 2x4 one, so the tallest
     content (the install view, ~17.8rem including its label) needs less
     canvas than before — was clamp(23rem, 34vw, 33rem), which centred a
     ~20rem-tall drawing in up to 33rem of height. Trimmed so there's still
     clear breathing room but not a visibly empty band top and bottom. */
  min-height: 0;
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 50%, rgba(42, 174, 158, 0.12), transparent 42%),
    #09131e;
}

.equipment-system-grid {
  position: absolute;
  inset: 0;
  opacity: 0.26;
  background-image:
    linear-gradient(rgba(183, 201, 210, 0.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(183, 201, 210, 0.055) 1px, transparent 1px);
  background-size: 32px 32px;
}

.equipment-system-layout {
  /* In flow, not absolutely positioned: the sensor box now grows with its
     tiles (icons, detail lines), so the frame has to grow with it instead
     of clipping. The visual's min-height is only a floor. */
  position: relative;
  z-index: 1;
  padding: 3rem 2.4rem 2.8rem;
  display: grid;
  /* The sensor box went from a 2x4 to a 4x2 tile grid, so its column needs
     more width. The centre column is a text-free connector: keeping the
     relationship as a line and arrow prevents redundant copy from spilling
     into either technical view.
     The install column's floor was 7.4rem, which is what the layout
     actually renders at across most real desktop widths (the shell's
     max-width plateaus at 1180px until 1600px, so there's rarely surplus
     for the 0.36fr share to add much) — too narrow for the "02 HOW THE
     SENSOR BOX IS INSTALLED" label, which wrapped to 3 lines jammed
     against the frame edge, and for the install box, which shrank enough
     that the GROUND LINE label overlapped the screw graphic. Floor raised
     to 10rem and its fr share increased so it actually gets room; the
     sensor-box column's floor came down to compensate. */
  /* The tile grid is 2 columns now (see .equipment-system-sensor-grid), so
     the box column needs less width than the old 4-column one and the
     install column can finally reach its 12rem max — which is what gives
     the GROUND LINE label room to clear the centred spike. */
  grid-template-columns: minmax(min-content, 1fr) 3rem minmax(16rem, 0.82fr);
  gap: 0.85rem;
  align-items: center;
}

/* equipment.html only: with the "Build a sensor box" intro trimmed to a
   bare heading (its supporting sentence was redundant and was removed),
   this panel's own 3rem top padding left the "01" label stranded under a
   tall empty band. Scoped to #sensor-configurator, not the base rule,
   because equipment-hero-mockups.html and sensor-configurator-mockups.html
   still build several of their own variants straight off the base padding. */
#sensor-configurator .equipment-system-layout {
  padding-top: 1.5rem;
}

/* The 02 column's own content (label + installation drawing) is much
   shorter than 01's sensor list, so the shared row's align-items: center
   was centering it within that taller row height — pushing "02 YOUR
   CONFIGURED SENSOR BOX" ~40-50px below where "01 CHOOSE YOUR SENSORS"
   starts. align-self here overrides that for the 02 column only, top-
   aligning the whole group (label + installation, moved together, same
   internal gap) so both headings share the same baseline. 01 already
   fills the row's full height, so it's unaffected by this. Scoped to
   #sensor-configurator, not the base rule, so the mockup pages keep their
   own centered treatment. */
#sensor-configurator .equipment-system-view--installed {
  align-self: start;
}

.equipment-system-view {
  display: grid;
  gap: 0.8rem;
  min-width: 0;
}

.equipment-system-view-label {
  color: var(--steel);
  font-family: var(--font-mono);
  font-size: clamp(0.78rem, 0.92vw, 0.86rem);
  letter-spacing: 0.07em;
  line-height: 1.35;
  text-transform: uppercase;
  /* The 02 heading ("YOUR CONFIGURED SENSOR BOX") is long enough to wrap at
     narrower desktop widths; balance keeps it an even two lines instead of
     stranding "BOX" alone on its own. */
  text-wrap: balance;
}

/* Sits under the 02 label: the drawing changes as sensors are added, and
   without a line saying so the connection between the two views is missed. */
.equipment-system-view-note {
  margin-top: -0.45rem;
  color: rgba(198, 214, 223, 0.8);
  font-size: 0.85rem;
  line-height: 1.4;
  text-wrap: pretty;
}

.equipment-system-view-label b {
  margin-right: 0.45rem;
  color: var(--accent);
  font-weight: 500;
}

/* Plain list, not a framed panel — no border, fill, or glow around the
   whole set of rows. Each row's own divider (see .equipment-system-sensor)
   is the only line in the block. */
.equipment-system-box {
  position: relative;
  width: 100%;
  /* Back to a 2-column tile grid so each tile is wide enough to carry a
     readable label: at 4 columns the longest option (RADIOACTIVITY) capped
     the type at 8px, too small for a control people are meant to click.
     Two columns over four rows plus the GPS row needs the taller, narrower
     proportion. */
  max-width: 23rem;
  /* No fixed ratio: a nine-row list sets its own height. */
  aspect-ratio: auto;
  margin: 0 auto;
}

/* In-flow header row instead of two independently absolute-positioned
   labels: at the box's own min-content width (as narrow as ~13rem on some
   desktop viewports, where the 3-column layout gives the list column
   little more than its longest row needs) "0 / 8 CONFIGURED" and
   "SELECT TO ADD" are wide enough together to collide when each is just
   pinned to its own corner. A flex row reflows them instead of overlapping. */
.equipment-system-box-head {
  display: flex;
  /* At their larger sizes the instruction and the count no longer fit on one
     line in the list column, so the instruction keeps the first line to
     itself and the count sits under it. */
  flex-wrap: wrap;
  row-gap: 0.3rem;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0 0.1rem 1.1rem;
}

.equipment-system-box-label {
  color: var(--steel);
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--line-strong);
  border-radius: 2px;
  transition: color 200ms ease, border-color 200ms ease, background-color 200ms ease;
}

/* The instruction leads the row and is the one thing here set to read
   first: accent colour, larger than the count, with a pulsing marker so it
   is unmistakably a prompt and not a caption. */
.equipment-system-box-hint {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  flex: 1 1 auto;
  flex: 1 1 100%;
  color: #7fe0d3;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* The longer "Select a sensor to add it to the box." wraps to two lines at
   narrow widths; without this, "box." was landing alone on the second. */
.equipment-system-box-hint [data-hint-text] {
  text-wrap: pretty;
}

.equipment-system-box-hint i {
  flex: none;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 rgba(42, 174, 158, 0.6);
  animation: equipmentHintPulse 1.8s ease-out infinite;
}

@keyframes equipmentHintPulse {
  0% { box-shadow: 0 0 0 0 rgba(42, 174, 158, 0.6); }
  70% { box-shadow: 0 0 0 0.55rem rgba(42, 174, 158, 0); }
  100% { box-shadow: 0 0 0 0 rgba(42, 174, 158, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .equipment-system-box-hint i { animation: none; }
}

/* The instruction used to disappear on the first tap, which is when it still
   has something to say: nothing else on screen tells you a chosen row can be
   tapped again to take it out. It stays, and js/equipment-configurator.js
   swaps the wording. The marker stops pulsing once it is no longer a prompt. */
.equipment-system-box.has-selection .equipment-system-box-hint i {
  animation: none;
  background: rgba(87, 194, 181, 0.55);
}

.equipment-system-box.has-selection .equipment-system-box-label {
  color: var(--pgi-chip-ink, var(--accent));
  border-color: var(--pgi-chip-line, var(--accent));
  background: var(--pgi-chip-bg, transparent);
}

/* 6/6 — item 6: a visibly different state from "some selected", not just
   another number. Paired with the box-seal pulse already on .is-complete.
   Specificity has to at least match .equipment-system-box.has-selection's
   three classes, or this loses the tie despite coming later in the file. */
.equipment-system-visual.is-complete .equipment-system-box-label {
  color: #eafffb;
  border-color: #7fe0d3;
  box-shadow: 0 0 0 1px rgba(127, 194, 181, 0.25);
}

/* Clear-all, shown only once there is something to clear. */
.equipment-system-reset {
  flex: 0 0 auto;
  margin-left: auto;
  padding: 0.1rem 0;
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  border-bottom: 1px solid rgba(87, 194, 181, 0.5);
  background: none;
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 160ms ease, border-color 160ms ease;
}

.equipment-system-reset[hidden] {
  display: none;
}

.equipment-system-reset:hover,
.equipment-system-reset:focus-visible {
  color: #eafffb;
  border-bottom-color: #7fe0d3;
  outline: none;
}

.equipment-system-reset:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* GPS is an included line item, not an option: a full-width, pre-selected,
   non-interactive row at the top of the list. Borderless like the sensor
   rows below it — a bottom rule instead of a boxed pill. */
.equipment-system-gps {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.8rem 0.5rem;
  border-bottom: 1px solid rgba(87, 194, 181, 0.28);
  color: var(--accent);
  font-family: var(--font-mono);
  /* Matches the rows it shares the list with. */
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.equipment-system-gps::after {
  content: "\2713";
  margin-left: auto;
  font-size: 1.1rem;
  font-weight: 700;
}

.equipment-system-gps svg {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 0.35rem rgba(42, 174, 158, 0.6));
}

.equipment-system-sensor-grid {
  /* In flow rather than absolutely positioned: the tiles carry a second
     line now, and the box has to be able to grow to hold them in the
     narrowest side-by-side column instead of squeezing the rows. The
     aspect ratio on the box still sets its shape wherever there is room. */
  position: relative;
  display: grid;
  box-sizing: border-box;
  min-height: 100%;
  /* Top padding no longer has to clear the count/hint label — that pair
     lives in the in-flow .equipment-system-box-head above this now,
     instead of floating on top of the first row. */
  padding: 0 0.4rem 1.5rem;
  /* 4 columns x 2 rows (was 2x4) now that the box is wide enough to fit
     it: METAL/VIBRATION/ACOUSTIC/RADAR, then CAMERAS/FLIR/GASSES/
     RADIOACTIVITY, in DOM order, so no markup reorder was needed. */
  /* One column: the box is an order list, read top to bottom, not a tile
     grid. Two columns forced the box wide enough to squeeze the hero copy. */
  grid-template-columns: minmax(0, 1fr);
  /* Sensor rows share one height. Left to auto, the rows carrying a detail
     line (Radar, Cameras, FLIR) sat visibly taller than the rest and the
     corner marks stopped lining up down the list. */
  grid-template-rows: auto repeat(7, 1fr);
  /* Rows touch and separate with their own bottom rule instead of a gap —
     a plain list rather than a stack of spaced-out tiles. */
  gap: 0;
}

.equipment-system-sensor {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: 0.7rem;
  width: 100%;
  min-width: 0;
  /* A plain list row, not a tile: shorter now that it doesn't have to hold
     its own border box, so nine rows read closer in height to the install
     diagram beside them instead of towering over it. */
  min-height: 3.6rem;
  /* Right padding clears the add / added mark, which is now large enough to
     read as the control it is. */
  padding: 0.75rem 2.4rem 0.75rem 0.15rem;
  overflow: hidden;
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  border-bottom: 1px solid rgba(183, 201, 210, 0.16);
  border-radius: 0;
  background: transparent;
  color: rgba(210, 224, 230, 0.94);
  font-family: var(--font-mono);
  /* Was clamp(0.7rem, 0.86vw, 0.76rem) — around 12px, and set in all caps,
     which is the slowest way to read a list of unfamiliar words. Sentence
     case at 15px is the faster read and clears the size a control should
     have. */
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  line-height: 1.15;
  text-align: left;
  text-transform: none;
  cursor: pointer;
  transition: color 160ms ease, background-color 160ms ease;
}

.equipment-system-sensor:last-of-type {
  border-bottom: 0;
}

/* Line icon for each option, drawn from the same set the site uses
   elsewhere. Muted at rest so the name still leads; lit when selected. */
.equipment-system-sensor-icon {
  width: 1.5rem;
  height: 1.5rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: rgba(190, 209, 218, 0.85);
  transition: color 160ms ease;
}

.equipment-system-sensor:hover .equipment-system-sensor-icon,
.equipment-system-sensor:focus-visible .equipment-system-sensor-icon {
  color: rgba(127, 224, 211, 0.9);
}

.equipment-system-sensor.is-selected .equipment-system-sensor-icon {
  color: #7fe0d3;
  filter: drop-shadow(0 0 0.35rem rgba(42, 174, 158, 0.7));
}

.equipment-system-sensor-body {
  display: flex;
  flex-direction: column;
  gap: 0.24rem;
  min-width: 0;
}

/* Sensor detail under the name — radar coverage is the only one the source
   document supports. Sentence case and muted so the name stays the thing you
   read first. */
.equipment-system-sensor small {
  display: block;
  max-width: 100%;
  /* Buttons default to nowrap; the radar note is long enough to need a
     second line in the narrowest side-by-side column. */
  white-space: normal;
  overflow-wrap: anywhere;
  color: rgba(198, 214, 223, 0.88);
  font-size: 0.8rem;
  letter-spacing: 0.01em;
  line-height: 1.3;
  text-transform: none;
}

/* Add / added state mark in the tile's top-right corner: "+" reads as an
   orderable option, "\2713" as one in the box. */
.equipment-system-sensor::before {
  content: "+";
  position: absolute;
  top: 50%;
  right: 0.7rem;
  transform: translateY(-50%);
  color: #7fe0d3;
  font-size: 1.4rem;
  line-height: 1;
  transition: color 160ms ease;
}

/* Until the first click, the "+" glyphs breathe so the tiles read as
   controls rather than as annotations on a drawing. */
.is-untouched .equipment-system-sensor::before {
  animation: equipmentPlusHint 2.4s ease-in-out infinite;
}

@keyframes equipmentPlusHint {
  0%, 100% { color: rgba(87, 194, 181, 0.55); text-shadow: none; }
  50% { color: #7fe0d3; text-shadow: 0 0 0.5rem rgba(42, 174, 158, 0.9); }
}

.equipment-system-sensor:hover,
.equipment-system-sensor:focus-visible {
  background: rgba(87, 194, 181, 0.08);
  color: #eef8f7;
  outline: none;
}

.equipment-system-sensor:hover:not(.is-selected),
.equipment-system-sensor:focus-visible:not(.is-selected) {
  box-shadow: inset 2px 0 0 rgba(127, 224, 211, 0.4);
}

.equipment-system-sensor:hover::before,
.equipment-system-sensor:focus-visible::before {
  color: var(--accent);
}

.equipment-system-sensor:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* Selected rows keep a tint and a left rule instead of a full border box —
   the list stays flat; only the accent edge marks membership. */
.equipment-system-sensor.is-selected {
  background: rgba(42, 174, 158, 0.14);
  color: #eafffb;
  box-shadow: inset 2px 0 0 var(--accent);
}

.equipment-system-sensor.is-selected::before {
  content: "\2713";
  color: #7fe0d3;
  font-size: 1.15rem;
}

.equipment-system-sensor.is-selected:hover,
.equipment-system-sensor.is-selected:focus-visible {
  background: rgba(42, 174, 158, 0.08);
}

.equipment-system-sensor.is-selected:hover::before,
.equipment-system-sensor.is-selected:focus-visible::before {
  content: "\2715";
}

@keyframes equipmentSensorAdded {
  0% {
    box-shadow: inset 0 0 0 1px rgba(42, 174, 158, 0.4), 0 0 0 0 rgba(42, 174, 158, 0.45);
  }
  60% {
    box-shadow: inset 0 0 0 1px rgba(42, 174, 158, 0.4), 0 0 0 0.5rem rgba(42, 174, 158, 0.18);
  }
  100% {
    box-shadow: inset 0 0 0 1px rgba(42, 174, 158, 0.4), 0 0 0 0.7rem rgba(42, 174, 158, 0);
  }
}

.equipment-system-sensor.is-selected.just-added {
  animation: equipmentSensorAdded 520ms ease-out;
}

.equipment-system-port {
  position: absolute;
  right: -0.45rem;
  top: 50%;
  width: 0.8rem;
  height: 0.8rem;
  transform: translateY(-50%);
  border: 1px solid var(--accent);
  border-radius: 50%;
  background: #09131e;
}

.equipment-system-link {
  position: relative;
  display: block;
  /* 3px and a brighter resting start-stop (was 2px / 0.45 opacity): the
     line connecting the two views read as barely-there at rest. Same
     line, dot, arrowhead and send-pulse — just enough more contrast to
     read as a connector without becoming a glow or a graphic. */
  /* ~17% thicker again (was 3px): the 01 → 02 relationship still read as
     easy to miss at a glance. Track length (the 3rem centre column) is
     untouched — only the line/dot/arrowhead got more substantial, not
     longer or closer to either column. */
  height: 3.5px;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(42, 174, 158, 0.62), #7fe0d3);
}

.equipment-system-link::before {
  content: "";
  position: absolute;
  top: 50%;
  /* Half of width, negated, so the dot stays centred on the line's start. */
  left: -0.29rem;
  width: 0.58rem;
  height: 0.58rem;
  transform: translateY(-50%);
  border: 2.5px solid var(--accent);
  border-radius: 50%;
  background: #09131e;
}

.equipment-system-link::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -0.1rem;
  width: 0.73rem;
  height: 0.73rem;
  transform: translateY(-50%) rotate(45deg);
  border-top: 2.5px solid #7fe0d3;
  border-right: 2.5px solid #7fe0d3;
  border-radius: 1px;
}

/* Sending pulse: a glowing dot that runs the connector from the
   configured box to the installed one each time a sensor is added. */
.equipment-system-link i {
  position: absolute;
  top: 50%;
  left: 0;
  width: 0.68rem;
  height: 0.68rem;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: #d6fff8;
  box-shadow:
    0 0 0.5rem rgba(214, 255, 248, 0.95),
    0 0 1.1rem rgba(42, 174, 158, 0.9),
    0 0 2.2rem rgba(42, 174, 158, 0.55);
  opacity: 0;
  pointer-events: none;
}

/* Slow enough to actually be seen crossing the gap — at 420ms the dot read
   as a flicker rather than as something travelling. */
.equipment-system-link.is-sending i {
  animation: equipmentLinkSendX 560ms cubic-bezier(0.35, 0, 0.3, 1) forwards;
}

@keyframes equipmentLinkSendX {
  0% { left: 0; opacity: 0; }
  15% { opacity: 1; }
  85% { opacity: 1; }
  100% { left: 100%; opacity: 0; }
}

@keyframes equipmentLinkSendY {
  0% { top: 0; opacity: 0; }
  15% { opacity: 1; }
  85% { opacity: 1; }
  100% { top: 100%; opacity: 0; }
}

/* Once anything is in the box, the connector and the installed box come
   alive so the handoff reads as a live link, not a static diagram. */
.is-configured .equipment-system-link {
  background: linear-gradient(90deg, rgba(42, 174, 158, 0.75), #d6fff8);
  box-shadow: 0 0 0.7rem rgba(42, 174, 158, 0.55);
}

.is-configured .equipment-installation-enclosure {
  border-color: #7fe0d3;
  box-shadow: 0 0 2.4rem rgba(42, 174, 158, 0.28), inset 0 0 1.2rem rgba(42, 174, 158, 0.12);
}

/* Flash on the receiving box as the pulse lands, so the two halves of the
   diagram visibly belong to one action. */
.is-receiving .equipment-installation-enclosure {
  animation: equipmentBoxReceive 520ms ease-out;
}

@keyframes equipmentBoxReceive {
  0% { box-shadow: 0 0 2.4rem rgba(42, 174, 158, 0.28), inset 0 0 1.2rem rgba(42, 174, 158, 0.12); }
  30% { box-shadow: 0 0 3.4rem rgba(42, 174, 158, 0.75), inset 0 0 1.8rem rgba(42, 174, 158, 0.4); }
  100% { box-shadow: 0 0 2.4rem rgba(42, 174, 158, 0.28), inset 0 0 1.2rem rgba(42, 174, 158, 0.12); }
}

/* Full configuration: the box seals with a ring pulse, the spike drives
   into the ground, and the ground line lights up. */
.is-complete .equipment-system-box {
  animation: equipmentBoxComplete 900ms ease-out;
}

@keyframes equipmentBoxComplete {
  0% { box-shadow: 0 0 0 1rem rgba(42, 174, 158, 0.06), 0 0 5rem rgba(42, 174, 158, 0.18), 0 0 0 0 rgba(42, 174, 158, 0.5); }
  100% { box-shadow: 0 0 0 1rem rgba(42, 174, 158, 0.06), 0 0 5rem rgba(42, 174, 158, 0.18), 0 0 0 1.6rem rgba(42, 174, 158, 0); }
}

.is-complete .equipment-installation-spike {
  animation: equipmentSpikeDrive 900ms cubic-bezier(0.3, 0.9, 0.3, 1) 380ms both;
}

.is-complete .equipment-installation-spike::before {
  animation: equipmentSpikeThread 900ms linear 380ms both;
}

@keyframes equipmentSpikeDrive {
  0% { transform: translate(-50%, -1.56rem); }
  100% { transform: translate(-50%, 0); }
}

@keyframes equipmentSpikeThread {
  0% { background-position: 0 0; }
  100% { background-position: 0 1.96rem; }
}

.is-complete .equipment-installation-ground {
  border-top-color: #7fe0d3;
  box-shadow: 0 -0.3rem 1.2rem rgba(42, 174, 158, 0.3);
  transition: border-color 400ms ease 900ms, box-shadow 400ms ease 900ms;
}

.is-complete .equipment-installation-enclosure {
  box-shadow: 0 0 3rem rgba(42, 174, 158, 0.42), inset 0 0 1.4rem rgba(42, 174, 158, 0.18);
}

.equipment-installation {
  position: relative;
  /* Scaled ~1.2x against the configurator: at the previous size the box was
     close to twice its width and the right column read half-empty. Now
     that the sensor list reads as compact rows instead of bordered tiles
     it's shorter overall, so this view is scaled up again from its own
     base drawing to keep the two views close in visual weight rather than
     leaving the install view looking small beside the list. Scaling the
     whole box (instead of hand-adjusting every child's rem position) keeps
     the enclosure, collar, spike and ground line in the same proportion to
     one another; the origin is pinned to the top so the growth pushes
     outward and down, not up into the "02 HOW..." label above it. */
  width: min(100%, 19rem);
  /* -0.1rem under the enclosure's own -0.1rem net shrink (10.8 -> 10.7rem,
     see .equipment-installation-enclosure): the collar/spike/ground below it
     shift up by the same amount to stay attached to its new bottom edge. */
  height: 19.1rem;
  margin: 0 auto;
  transform: translateX(-0.1rem) scale(1.3);
  transform-origin: top center;
  /* The transform paints past the layout box by (scale - 1) x its own
     height, and the panel around this view clips overflow — without this
     margin the spike tip was cut off at the panel's bottom edge. Keep this
     in step with the scale: 19.1rem x 0.3 here, and see the 1021px and
     1400px blocks below, which raise the scale and so must raise this too.
     Anything following the drawing in this column (the integrations block)
     sits on this margin, so an undersized value shows up as an overlap. */
  margin-bottom: 5.75rem;
}

.equipment-installation-enclosure {
  position: absolute;
  top: 0.3rem;
  left: 50%;
  display: grid;
  /* Two bands: the fixed-hardware strip sits at the top at its natural
     height, and the configurable bay takes the rest and centres its grid in
     it. That split is the hierarchy — what ships with every box is stated
     once and compactly, and the part that actually changes as you configure
     gets the room. */
  grid-template-rows: auto 1fr;
  place-items: stretch;
  /* Clears the four corner rivets drawn at 0.66rem in from each edge (the
     radial gradients below) — at a tighter inset the "BUILT IN" label sat
     straight on top of the top-left one. */
  padding: 1rem 0.9rem;
  /* Was 6.8 x 7rem — only ~57% of the drawing's width, which made the box
     itself the smallest element in its own panel, and left the install view
     reading at roughly half the weight of the configurator beside it. */
  width: 11.3rem;
  height: 10.7rem;
  transform: translateX(-50%);
  border: 1px solid rgba(87, 194, 181, 0.55);
  border-radius: 0.34rem;
  background:
    radial-gradient(circle at 0.66rem 0.66rem, rgba(183, 201, 210, 0.7) 0 1px, transparent 1.5px),
    radial-gradient(circle at calc(100% - 0.66rem) 0.66rem, rgba(183, 201, 210, 0.7) 0 1px, transparent 1.5px),
    radial-gradient(circle at 0.66rem calc(100% - 0.66rem), rgba(183, 201, 210, 0.7) 0 1px, transparent 1.5px),
    radial-gradient(circle at calc(100% - 0.66rem) calc(100% - 0.66rem), rgba(183, 201, 210, 0.7) 0 1px, transparent 1.5px),
    rgba(11, 25, 34, 0.96);
  box-shadow: 0 0 2rem rgba(42, 174, 158, 0.1);
  color: var(--steel);
  font-family: var(--font-mono);
  font-size: 0.56rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}


/* Fixed-hardware band. GPS and the rechargeable battery are part of every
   box rather than choices, so they are drawn once across the top of the
   housing under a quiet "BUILT IN" label, with a rule separating them from
   the configurable bay below. They used to be lit, labelled badges pinned
   to the corners of the payload area — same rectangle, same glow, same type
   as the sensor slots, which made them read as more sensors you could add
   or drop. The row takes further fixtures if any are ever confirmed. */
.equipment-installation-fixed {
  /* Label above the row, not beside it: "RECHARGEABLE BATTERY" is long
     enough that label + both fixtures will not clear the housing's inner
     width on one line. */
  display: grid;
  justify-items: start;
  gap: 0.22rem;
  /* No rule underneath: the dashed bay border below already separates the
     fixed band from the configurable slots, and with the housing border,
     the aside's rule and the grid behind it, one more line was clutter. */
  padding-bottom: 0.5rem;
}

/* Deliberately the quietest type in the drawing — steel, not accent. It has
   to name the band without pulling the eye off the sensor slots, which are
   the only part of the box that changes. */
.equipment-installation-fixed-label {
  color: rgba(183, 201, 210, 0.4);
  font-size: 0.36rem;
  font-weight: 600;
  letter-spacing: 0.16em;
}

.equipment-installation-fixed-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.3rem;
  width: 100%;
}

.equipment-installation-fixture {
  display: flex;
  align-items: center;
  gap: 0.26rem;
}

/* Smaller than a payload slot (1.55rem) on purpose: a fixture is stated,
   not populated, so it should not carry the visual weight of a bay that
   fills up as you configure. */
.equipment-installation-fixture i {
  display: grid;
  place-items: center;
  width: 0.86rem;
  height: 0.86rem;
  /* Outline only, no fill and no glow: these are always present, so if they
     burn as bright as a populated payload slot there are four lit things
     competing with the one bay that actually lights up as you configure.
     The filled-and-glowing chip is reserved for a slot that has been
     chosen. */
  border: 1px solid rgba(127, 224, 211, 0.7);
  border-radius: 0.12rem;
  background: transparent;
}

.equipment-installation-fixture svg {
  width: 0.52rem;
  height: 0.52rem;
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* 0.4rem, under the old badges' 0.46rem: three labels have to clear one
   row inside an 11.3rem housing, and the drawing is scaled 1.3x on the page
   (see .equipment-installation), so this still lands around 8px on screen. */
.equipment-installation-fixture b {
  color: var(--accent);
  font-size: 0.4rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  white-space: nowrap;
}

/* Payload slots inside the installed box: one per configurator tile,
   lights up as sensors are added. Battery bar always lit, below the grid. */
.equipment-installation-payload {
  position: relative;
  place-self: center;
  display: grid;
  /* Six slots, one per selectable sensor, filling 3 x 2 exactly — a four-wide
     grid would leave two empty cells reading as missing parts. Sized to hold
     a legible icon (see .equipment-installation-slot-icon), not just a
     large-enough glow. */
  grid-template-columns: repeat(3, 1.55rem);
  gap: 0.42rem;
  padding: 0.44rem;
  /* The dashed frame used to sit on the housing itself, where it enclosed
     everything and so said nothing. Around the payload it earns its keep:
     it is the boundary between what ships fixed and what you configure. */
  border: 1px dashed rgba(87, 194, 181, 0.32);
  border-radius: 0.18rem;
}

.equipment-installation-payload i {
  display: grid;
  place-items: center;
  width: 1.55rem;
  height: 1.55rem;
  /* Empty slots read as waiting bays, so a filled one is obvious next to
     them: dashed and dim until a sensor lands. */
  border: 1px dashed rgba(183, 201, 210, 0.34);
  border-radius: 0.12rem;
  background: rgba(183, 201, 210, 0.03);
  transition: background-color 220ms ease, border-color 220ms ease, box-shadow 220ms ease;
}

/* Same paths as the sensor's own icon in 01 (see the sensor buttons),
   scaled down and dim at rest — a labelled position, not a blank bay — then
   lit on top of the filled slot once that sensor is chosen. Without this a
   filled slot was just an anonymous square: it told you a count changed,
   not which sensor arrived. */
.equipment-installation-slot-icon {
  width: 0.98rem;
  height: 0.98rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: rgba(183, 201, 210, 0.4);
  transition: color 220ms ease;
}

.equipment-installation-payload i.is-on .equipment-installation-slot-icon {
  /* Dark ink over the lit teal fill — reads like silkscreen on a populated
     board slot rather than losing the icon in its own glow. */
  color: #06231f;
}

.equipment-installation-payload i.is-on {
  border-style: solid;
  border-color: #7fe0d3;
  background: var(--accent);
  box-shadow: 0 0 0.7rem rgba(42, 174, 158, 0.85);
}

/* The pop is what makes the arrival legible — without it a slot simply
   exists in a new colour and the eye misses the change. */
.equipment-installation-payload i.is-on {
  animation: equipmentSlotLand 520ms cubic-bezier(0.2, 0.9, 0.3, 1.4);
}

@keyframes equipmentSlotLand {
  0% { transform: scale(0.55); box-shadow: 0 0 0 0 rgba(42, 174, 158, 0.7); }
  55% { transform: scale(1.22); box-shadow: 0 0 0 0.42rem rgba(42, 174, 158, 0.12); }
  100% { transform: scale(1); box-shadow: 0 0 0.7rem rgba(42, 174, 158, 0.85); }
}

.equipment-installation-collar {
  position: absolute;
  z-index: 3;
  top: 10.88rem;
  left: 50%;
  width: 2.82rem;
  height: 0.96rem;
  transform: translateX(-50%);
  border: 1px solid rgba(183, 201, 210, 0.5);
  background: #0d1a24;
}

.equipment-installation-ground {
  position: absolute;
  z-index: 1;
  top: 11.72rem;
  right: 0;
  bottom: 0;
  left: 0;
  border-top: 1px solid var(--accent);
  box-shadow: 0 -0.2rem 0.7rem rgba(42, 174, 158, 0.08);
  background:
    repeating-linear-gradient(135deg, rgba(183, 201, 210, 0.035) 0 1px, transparent 1px 9px),
    rgba(5, 13, 20, 0.68);
}

.equipment-installation-ground em {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  color: rgba(183, 201, 210, 0.78);
  font-family: var(--font-mono);
  /* Was shrunk to 0.44rem (7px) to clear the centred spike back when the
     install column could not reach its 12rem max. It can now, so the label
     goes back to a readable size; max-width keeps it inside the clear area
     to the left of the spike at any column width, wrapping instead of
     overlapping. */
  max-width: calc(50% - 1.44rem);
  font-size: 0.64rem;
  font-style: normal;
  letter-spacing: 0.07em;
  line-height: 1.3;
  text-transform: uppercase;
}

.equipment-installation-spike {
  position: absolute;
  z-index: 2;
  top: 11.48rem;
  left: 50%;
  width: 2.82rem;
  height: 6.9rem;
  transform: translateX(-50%);
  background:
    linear-gradient(90deg, transparent 0 42%, rgba(183, 201, 210, 0.26) 43% 47%, rgba(42, 174, 158, 0.42) 48% 52%, rgba(183, 201, 210, 0.26) 53% 57%, transparent 58% 100%);
}

.equipment-installation-spike::before {
  content: "";
  position: absolute;
  inset: 0.18rem 0 0.74rem;
  clip-path: polygon(12% 0, 88% 0, 70% 100%, 30% 100%);
  background:
    repeating-linear-gradient(
      158deg,
      transparent 0 0.41rem,
      rgba(87, 194, 181, 0.72) 0.42rem 0.56rem,
      rgba(183, 201, 210, 0.34) 0.58rem 0.65rem,
      transparent 0.66rem 0.98rem
    );
  filter: drop-shadow(0 0 0.25rem rgba(42, 174, 158, 0.24));
}

.equipment-installation-spike::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 0;
  height: 0;
  transform: translateX(-50%);
  border-right: 0.58rem solid transparent;
  border-left: 0.58rem solid transparent;
  border-top: 0.98rem solid rgba(87, 194, 181, 0.72);
}

.equipment-installation-spike-label {
  position: absolute;
  z-index: 3;
  right: 0.35rem;
  bottom: 0.45rem;
  color: rgba(183, 201, 210, 0.62);
  font-family: var(--font-mono);
  font-size: 0.43rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Integrated equipment: cameras and infrared are part of the same package
   but are not modules that go inside the box, so they are named above the
   drawing rather than offered in the configurator column. Built to the same
   pattern as the fixed-hardware band inside the housing (see
   .equipment-installation-fixed): quiet steel label, outline chips, hairline
   rule underneath. That band is drawn inside a housing scaled 1.32-1.4x, so
   its rem values render larger than they read in the source; the sizes here
   are that band's multiplied through, which is what makes the two match on
   screen rather than in the stylesheet. */
.equipment-integrations {
  /* Matches the drawn housing's own rendered width, not the drawing's
     bounding box: 11.3rem (.equipment-installation-enclosure) with no
     transform at this size. That makes the rule below terminate exactly at
     the box's edges instead of overhanging them, which is what stops the
     group reading as three unrelated lines floating above a diagram. See
     the 1021px and 1400px blocks for the scaled equivalents. */
  /* Spans the column rather than the housing: at desktop widths that is
     the room the two items need to sit on one row, which turns a
     three-line block into two. No rule underneath — the space below does
     the separating, and one fewer line above a housing that already has a
     border, a dashed bay and a grid behind it. */
  width: 100%;
  display: grid;
  justify-items: center;
  /* Clear of the 02 label above it: two mono labels stacked at the view's
     bare 0.8rem row gap read as one crowded block, not as a heading and a
     group under it. */
  margin-top: 0.45rem;
  gap: 0.35rem;
  /* Clears the housing below by more than the view's 0.8rem row gap so the
     aside reads as a caption above the box, not as part of its frame. */
  margin-bottom: 0.6rem;
}

/* The band's own label, one step up in size for a block that is not being
   scaled up by a parent transform. */
.equipment-integrations-title {
  /* Third uppercase mono label in a short stack (02 heading, this, "Built
     in"): pulled well down in tone and weight so only the 02 heading reads
     as a heading and the other two read as annotations on the diagram. */
  color: rgba(183, 201, 210, 0.42);
  font-family: var(--font-mono);
  font-size: 0.52rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.equipment-integrations-list {
  /* Always two rows, left-aligned with each other: the aside centres the
     list as a block (justify-items: center above), so on the stacked
     mobile layout the pair sits centred under the 02 heading while the
     two chips still line up instead of each row centring on its own. */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  row-gap: 0.3rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.equipment-integrations-list li {
  display: flex;
  align-items: center;
  gap: 0.36rem;
  min-width: 0;
}

/* The lit chip from the fixed-hardware band (.equipment-installation-fixture
   i), at the size that band renders once its housing's scale is applied. */
.equipment-integrations-list i {
  display: grid;
  place-items: center;
  flex: none;
  width: 1.2rem;
  height: 1.2rem;
  border: 1px solid rgba(127, 224, 211, 0.7);
  border-radius: 0.12rem;
  background: transparent;
}

.equipment-integrations-list svg {
  width: 0.72rem;
  height: 0.72rem;
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.equipment-integrations-list b {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Qualifier sits straight after the name behind a middot — the same
   "GPS · BUILT IN" construction the configurator column already uses. It
   was previously pushed into a second column by a min-width on the name,
   which opened a ragged gutter and made two short rows look like a table
   with holes in it. */
.equipment-integrations-list small {
  color: rgba(183, 201, 210, 0.72);
  font-family: var(--font-mono);
  font-size: 0.55rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
}

.equipment-integrations-list small::before {
  content: "\00b7";
  margin: 0 0.3rem 0 0.26rem;
  color: rgba(183, 201, 210, 0.45);
}

.equipment-hero-caption,
.equipment-card-caption {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.8rem 1rem;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  line-height: 1.45;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.equipment-hero-caption strong,
.equipment-card-caption strong {
  color: var(--steel);
  font-weight: 500;
}

/* Handoff row under the diagram caption, shown once a box is configured. */
.equipment-configurator-cta-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 1rem;
  border-top: 1px solid var(--line);
  animation: equipmentCtaIn 420ms ease-out both;
}

.equipment-configurator-cta-row[hidden] {
  display: none;
}

.equipment-configurator-cta-row .button {
  flex: none;
  min-height: 42px;
  padding: 0.5rem 1.35rem;
  font-size: 0.74rem;
}

/* What the button will send, so it reads as a handoff, not a second
   contact link. */
.equipment-configurator-summary {
  min-width: 0;
  margin: 0;
  color: var(--steel);
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  line-height: 1.5;
  text-transform: uppercase;
}

@keyframes equipmentCtaIn {
  0% { opacity: 0; transform: translateY(0.4rem); }
  100% { opacity: 1; transform: translateY(0); }
}

.equipment-lineup,
.equipment-components,
.equipment-box-components,
.equipment-close {
  padding-block: var(--section-space);
  border-bottom: 1px solid var(--line);
}

.equipment-lineup {
  background: var(--bg-2);
}

.equipment-section-head {
  display: grid;
  grid-template-columns: minmax(0, 0.88fr) minmax(18rem, 0.5fr);
  gap: clamp(2rem, 8vw, 8rem);
  align-items: end;
  /* Sized for a bare headline — neither header on this page fills the
     second grid column with a subtitle, so this shouldn't reserve room
     as if one were there. */
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
}

.equipment-section-head h2 {
  max-width: 13ch;
  margin: 0.85rem 0 0;
  font-size: clamp(2.35rem, 4.5vw, 4.5rem);
  line-height: 1;
}

.equipment-section-head p {
  margin: 0;
  color: var(--body);
  font-size: 0.98rem;
  line-height: 1.72;
}

.equipment-card-grid,
.equipment-direction-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
}

.equipment-direction-card {
  min-width: 0;
  min-height: 15rem;
  padding: clamp(1.5rem, 3vw, 2.2rem);
  border: 1px solid var(--line-strong);
  background:
    linear-gradient(145deg, rgba(47, 156, 142, 0.05), transparent 48%),
    #081119;
}

.equipment-direction-card h3 {
  margin: 1.2rem 0 0.8rem;
  font-family: var(--font-display);
  font-size: clamp(1.65rem, 2.5vw, 2.35rem);
  line-height: 1;
  letter-spacing: -0.035em;
}

.equipment-direction-card p {
  max-width: 31rem;
  margin: 0;
  color: var(--body);
  font-size: 0.92rem;
  line-height: 1.7;
}

.equipment-card {
  min-width: 0;
  border: 1px solid var(--line-strong);
  background: #081119;
}

.equipment-card-visual {
  margin: 0;
  border-bottom: 1px solid var(--line);
  background: #111c26;
}

.equipment-card-visual img {
  width: 100%;
  height: auto;
}

.equipment-card-body {
  padding: 1.35rem 1.4rem 1.55rem;
}

.equipment-card-code {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.equipment-card h3 {
  margin: 0.65rem 0 0.7rem;
  font-family: var(--font-display);
  font-size: clamp(1.55rem, 2.2vw, 2rem);
  line-height: 1;
  letter-spacing: -0.03em;
}

.equipment-card-body p {
  margin: 0;
  color: var(--body);
  font-size: 0.9rem;
  line-height: 1.65;
}

.equipment-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin: 1.15rem 0 0;
  padding: 0;
  list-style: none;
}

.equipment-card-meta li {
  padding: 0.36rem 0.48rem;
  border: 1px solid var(--line);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.57rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.equipment-components {
  background:
    linear-gradient(90deg, rgba(118, 134, 106, 0.035), transparent 30%),
    linear-gradient(180deg, var(--bg-2) 0, var(--bg) 240px),
    var(--bg);
  border-bottom-color: rgba(255, 255, 255, 0.04);
}

.equipment-behavior-system {
  overflow: hidden;
  border: 1px solid var(--line-strong);
  background: #06111a;
}

.equipment-story-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.96fr) minmax(0, 1.04fr);
  gap: clamp(0.85rem, 1.6vw, 1.35rem);
  padding: clamp(0.85rem, 1.6vw, 1.35rem);
}

.equipment-story-detect {
  display: grid;
  min-width: 0;
  min-height: clamp(470px, 35vw, 510px);
  grid-template-rows: minmax(0, 1fr) auto;
  margin: 0;
  border: 1px solid var(--line-strong);
  background: #06111a;
}

.equipment-story-visual {
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  background: #06111a;
}

.equipment-story-visual img,
.equipment-story-steps img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.equipment-story-visual-detect {
  min-height: 0;
  padding: clamp(0.45rem, 1vw, 0.8rem);
}

.equipment-story-detect figcaption {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: clamp(0.9rem, 1.6vw, 1.4rem);
  min-height: clamp(96px, 8vw, 124px);
  padding: 1rem clamp(1rem, 2vw, 1.6rem);
  border-top: 1px solid var(--line-strong);
}

.equipment-story-number {
  color: var(--accent);
  font-family: var(--font-display);
  font-size: clamp(4.6rem, 7vw, 7.5rem);
  font-weight: 700;
  letter-spacing: -0.07em;
  line-height: 0.78;
}

.equipment-story-detect strong,
.equipment-story-steps strong {
  color: var(--ink);
  font-family: var(--font-display);
  font-size: clamp(1.02rem, 1.35vw, 1.28rem);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.12;
  text-transform: none;
  text-wrap: balance;
}

.equipment-story-copy {
  display: grid;
  min-width: 0;
  gap: 0.35rem;
}

.equipment-story-copy > span {
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  line-height: 1;
  text-transform: uppercase;
}

.equipment-story-steps {
  display: grid;
  min-width: 0;
  grid-template-rows: repeat(3, minmax(0, 1fr));
  gap: clamp(0.75rem, 1.4vw, 1rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.equipment-story-steps li {
  display: grid;
  min-width: 0;
  grid-template-columns: clamp(4.6rem, 7vw, 7rem) minmax(170px, 1.05fr) minmax(185px, 1fr);
  align-items: center;
  gap: clamp(0.55rem, 1.2vw, 1rem);
  padding: clamp(0.55rem, 1.1vw, 0.9rem) clamp(0.8rem, 1.4vw, 1.2rem);
  border: 1px solid var(--line-strong);
  background: #06111a;
}

.equipment-story-steps li + li {
  position: relative;
}

.equipment-story-steps li + li::before {
  position: absolute;
  top: calc(clamp(0.75rem, 1.4vw, 1rem) * -1 - 1px);
  left: 50%;
  width: 1px;
  height: clamp(0.75rem, 1.4vw, 1rem);
  background: #35d6cf;
  content: "";
}

.equipment-story-steps img {
  min-height: 0;
  max-height: clamp(128px, 11vw, 165px);
}

@media (min-width: 861px) {
  .equipment-story-steps img {
    object-fit: contain;
    transform: none;
  }
}

@media (min-width: 641px) and (max-width: 860px) {
  .equipment-story-steps img {
    object-fit: contain;
    transform: none;
  }
}

.equipment-story-result {
  border-color: rgba(53, 214, 207, 0.92) !important;
  box-shadow: inset 3px 0 0 rgba(53, 214, 207, 0.9);
}

.equipment-story-note {
  margin: 0;
  padding: clamp(1rem, 2vw, 1.35rem);
  border-top: 1px solid var(--line-strong);
  color: var(--body);
  font-family: var(--font-sans);
  font-size: 0.86rem;
  font-weight: 400;
  line-height: 1.6;
  text-align: center;
}

@media (max-width: 1100px) {
  .equipment-story-grid {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  }

  .equipment-story-detect {
    min-height: 520px;
  }

  .equipment-story-steps li {
    grid-template-columns: 4.5rem minmax(115px, 0.88fr) minmax(150px, 1.12fr);
  }

  .equipment-story-number {
    font-size: clamp(4.35rem, 7.5vw, 5.6rem);
  }

  .equipment-story-detect strong,
  .equipment-story-steps strong {
    font-size: clamp(1.05rem, 1.9vw, 1.35rem);
  }
}

@media (max-width: 860px) {
  .equipment-story-grid {
    grid-template-columns: 1fr;
  }

  .equipment-story-detect {
    min-height: 510px;
  }

  .equipment-story-steps li {
    min-height: 180px;
    grid-template-columns: clamp(4.5rem, 12vw, 6rem) minmax(180px, 0.85fr) minmax(200px, 1.15fr);
  }

  .equipment-story-steps img {
    max-height: 160px;
  }
}

@media (max-width: 640px) {
  .equipment-story-grid {
    gap: 0.75rem;
    padding: 0.75rem;
  }

  .equipment-story-detect {
    min-height: 390px;
  }

  .equipment-story-visual-detect {
    min-height: 270px;
    padding: 0;
  }

  .equipment-story-detect figcaption {
    min-height: 92px;
    gap: 0.8rem;
    padding: 0.9rem;
  }

  .equipment-story-number {
    font-size: clamp(4rem, 19vw, 5.2rem);
  }

  .equipment-story-steps li {
    min-height: 205px;
    grid-template-columns: 4rem minmax(0, 1fr);
    grid-template-rows: minmax(112px, auto) auto;
    gap: 0.35rem 0.75rem;
    padding: 0.65rem 0.75rem 0.9rem;
  }

  .equipment-story-steps li .equipment-story-number {
    grid-row: 1 / 3;
  }

  .equipment-story-steps img {
    grid-column: 2;
    width: 100%;
    max-height: 125px;
  }

  .equipment-story-steps .equipment-story-copy {
    grid-column: 2;
  }

  .equipment-story-note {
    padding-inline: 1rem;
    text-align: left;
  }
}

.equipment-component-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--line-strong);
  border-left: 1px solid var(--line-strong);
}

.equipment-component {
  min-width: 0;
  padding: clamp(1.15rem, 2vw, 1.55rem);
  border-right: 1px solid var(--line-strong);
  border-bottom: 1px solid var(--line-strong);
}

.equipment-component-num {
  color: var(--field-bright);
  font-family: var(--font-mono);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.14em;
}

.equipment-component h3 {
  margin: 0.75rem 0 0.55rem;
  font-family: var(--font-display);
  font-size: 1.45rem;
  letter-spacing: -0.025em;
}

.equipment-component p {
  max-width: 46rem;
  margin: 0;
  color: var(--body);
  font-size: 0.82rem;
  line-height: 1.5;
}

.equipment-box-components {
  background:
    radial-gradient(circle at 15% 10%, rgba(47, 156, 142, 0.06), transparent 28rem),
    var(--bg-2);
}

.equipment-box-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  border-top: 1px solid var(--line-strong);
  border-left: 1px solid var(--line-strong);
}

.equipment-box-card {
  min-width: 0;
  padding: clamp(1.25rem, 2.3vw, 1.8rem);
  border-right: 1px solid var(--line-strong);
  border-bottom: 1px solid var(--line-strong);
}

.equipment-box-card h3 {
  margin: 0.8rem 0 0.6rem;
  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1.05;
  letter-spacing: -0.025em;
}

.equipment-box-card p {
  margin: 0;
  color: var(--body);
  font-size: 0.86rem;
  line-height: 1.62;
}

.equipment-close {
  background:
    linear-gradient(180deg, var(--bg) 0, var(--bg-2) 220px),
    var(--bg-2);
}

.equipment-close-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2rem;
  align-items: end;
}

.equipment-close h2 {
  max-width: 16ch;
  margin: 0.8rem 0 0;
  font-size: clamp(2.2rem, 4vw, 3.8rem);
  line-height: 1;
}

.equipment-close p {
  max-width: 44rem;
  margin: 1.2rem 0 0;
  color: var(--body);
  line-height: 1.7;
}

.equipment-close .button {
  white-space: nowrap;
}

/* Quiet engineering-status note — a caveat, not a closing headline section.
   Sits directly under the grid it qualifies. */
.equipment-status-footnote {
  padding-block: 1.75rem;
  border-top: 1px solid var(--line);
  background: var(--bg-2);
}
.equipment-status-footnote-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1.25rem 2rem;
}
.equipment-status-footnote-copy .ops-label {
  margin-bottom: 0.4rem;
}
.equipment-status-footnote-text {
  max-width: 56ch;
  margin: 0;
  color: var(--muted);
  font-size: 0.92rem;
  line-height: 1.55;
}
.equipment-status-footnote .button {
  flex-shrink: 0;
  white-space: nowrap;
}
@media (max-width: 700px) {
  .equipment-status-footnote-inner {
    flex-direction: column;
    align-items: flex-start;
  }
}

@media (max-width: 1020px) {
  .equipment-hero {
    min-height: 0;
  }

  .equipment-hero-grid {
    grid-template-columns: minmax(0, 0.85fr) minmax(24rem, 1fr);
    gap: 2.5rem;
  }

  .equipment-card-grid {
    grid-template-columns: 1fr;
  }

  .equipment-direction-grid {
    grid-template-columns: 1fr;
  }

  .equipment-direction-card {
    min-height: 0;
  }

  .equipment-box-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .equipment-card {
    display: grid;
    grid-template-columns: minmax(20rem, 0.9fr) minmax(0, 1.1fr);
  }

  .equipment-card-visual {
    border-right: 1px solid var(--line);
    border-bottom: 0;
  }

  /* Keep both technical views readable while the hero still shares a row. */
  .equipment-system-layout {
    inset-inline: 1.5rem;
    grid-template-columns: minmax(12rem, 1.1fr) 4.5rem minmax(8.5rem, 0.78fr);
    gap: 0.6rem;
  }

  .equipment-system-box {
    width: 100%;
    max-width: 17rem;
  }

  .equipment-system-sensor-grid {
    padding-inline: 1.3rem;
  }
}

@media (max-width: 760px) {
  .equipment-hero {
    padding-top: calc(var(--header-h) + 3.5rem);
  }

  .equipment-hero-grid,
  .equipment-section-head,
  .equipment-close-grid {
    grid-template-columns: 1fr;
  }

  .equipment-hero-title {
    font-size: clamp(3rem, 15vw, 4.6rem);
  }

  .equipment-section-head {
    gap: 1.25rem;
  }

  .equipment-card {
    display: block;
  }

  .equipment-card-visual {
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }

  .equipment-component-grid {
    grid-template-columns: 1fr;
  }

  .equipment-system-visual {
    min-height: 25rem;
  }

  .equipment-box-grid {
    grid-template-columns: 1fr;
  }

  .equipment-close-grid {
    align-items: start;
  }
}

/* Keep both technical views side by side on normal desktop widths. The old
   1599px cutoff stacked a 664px copy block beside a 1180px diagram at the
   common 1512px viewport, leaving the copy floating in a large empty field.
   Once the frame is genuinely narrow, stack only the diagram itself; the
   hero columns retain the shared top baseline set above. */
/* The two views sit side by side wherever the hero runs straight across: the
   frame has the full shell to itself there, which is width enough for the
   list and the install drawing to share a row. Was 1351px, from when the
   frame lived in half the hero. */
@media (min-width: 1021px) {
  .equipment-system-layout {
    /* Centre column was 4rem, which together with the grid's own 0.85rem
       gap on each side put ~5.7rem of dead channel between the two views —
       visual QA flagged the connector as floating in it. Cut to 3rem
       (~18% off that channel), still enough for the transfer pulse to read
       as travelling rather than blinking. */
    grid-template-columns: minmax(24rem, 1.3fr) 3rem minmax(15rem, 0.6fr);
  }

  .equipment-system-box {
    max-width: 37rem;
  }

  /* The 01 label sat flush against the panel's own top padding, reading as
     detached from the list below it rather than its heading. Nudged down
     10px and the row-gap tightened by the same amount so the label's own
     row grows by exactly what the gap gives up — the box beneath it (and
     the panel's overall height) doesn't move. Desktop-only: the stacked
     mobile layout centres this label differently and wasn't part of the
     ask. */
  .equipment-system-view--internal {
    row-gap: calc(0.8rem - 10px);
  }

  .equipment-system-view--internal .equipment-system-view-label {
    margin-top: 10px;
  }

  /* Matches the 10px nudge above so "02 YOUR CONFIGURED SENSOR BOX" lands on
     the exact same baseline as "01 CHOOSE YOUR SENSORS" now that the 02
     column is top-aligned (see #sensor-configurator .equipment-system-view--installed
     above) instead of centered in the row. Scoped to #sensor-configurator
     for the same reason as that rule. */
  #sensor-configurator .equipment-system-view--installed {
    row-gap: calc(0.8rem - 10px);
  }

  #sensor-configurator .equipment-system-view--installed .equipment-system-view-label {
    margin-top: 10px;
  }

  /* Scaled up from its 1.3 base only where the two views sit side by side —
     below this breakpoint the views stack and the frame is too narrow to
     hold the larger drawing without clipping it. Kept short of matching the
     list's height: 02 is the reference view, not a second thing to read.
     Left-aligned rather than centred in its column (base rule is
     margin: 0 auto): centring left equal empty margin on the connector
     side, which is exactly the "floating" gap this pass tightened. Moving
     the box to that edge is what "closer to centre" means for a column
     that sits right of the connector. */
  .equipment-installation {
    width: min(100%, 16.5rem);
    margin-left: 0;
    transform: translateX(-0.1rem) scale(1.32);
    /* 19.1rem x 0.32 — the overflow this scale paints. */
    margin-bottom: 6.15rem;
  }

  /* The housing is left-aligned here (11.3rem x 1.32 starting 0.69rem in),
     so the aside lines up with its left edge rather than centring on a
     column the housing doesn't centre in. */
  .equipment-integrations {
    justify-items: start;
    padding-left: 0.69rem;
  }

  /* The connector aims at the housing's vertical centre. The layout row is
     align-items: center, but the row's height is the 01 list's, so a
     centred connector lands wherever the list's midpoint happens to be —
     once the additional-equipment block stopped pushing the housing down
     that was the housing's bottom edge, level with the ground line. Top-
     aligned like the 02 column, with the housing's centre measured from
     the row top: label row + additional-equipment block + the drawing's
     own offset + half of the 11.3rem x 1.32 housing. */
  .equipment-system-link {
    align-self: start;
    margin-top: 14.2rem;
  }
}

/* Visual QA found the payload icons reading small once 01 took the larger
   column share, and asked for the drawing to grow in place. A flat +12%
   (18.5rem/1.48) clipped against the frame's own edge everywhere tested,
   1300-1600px included — the install column doesn't have that much spare
   width to give at any width this component actually ships at, only room
   for about +6% before the scaled box's right edge reaches the frame's own
   padding. Applied above 1400px, where that headroom exists; below it the
   box stays at its original 16.5rem/1.32 rather than clip. */
@media (min-width: 1400px) {
  .equipment-installation {
    width: min(100%, 17.5rem);
    transform: translateX(-0.1rem) scale(1.4);
    /* 19.1rem x 0.4 — the overflow this scale paints. */
    margin-bottom: 7.7rem;
  }

  /* Beside the housing, not above it. Where the column has the room (from
     here up), the additional-equipment block sits as a narrow strip to the
     right of the drawn box: chip on top, name and qualifier under it. That
     takes three rows out of the stack between the 02 heading and the box,
     and places these where they belong — attached to the box, outside it.
     The connector arrow enters from the left, so the right side is free.
     Geometry: the drawing is 17.5rem wide, shifted -0.1rem and scaled 1.4
     about top centre, so its centre is 8.65rem in; the housing is
     11.3rem x 1.4 = 15.82rem wide, so its right edge lands at 16.56rem. */
  #sensor-configurator .equipment-system-view--installed {
    position: relative;
  }

  .equipment-integrations {
    position: absolute;
    left: 17.4rem;
    top: 2.6rem;
    width: auto;
    margin: 0;
    padding: 0;
    justify-items: start;
    gap: 0.5rem;
  }

  .equipment-integrations-title {
    white-space: normal;
    line-height: 1.4;
    max-width: 5rem;
  }

  .equipment-integrations-list {
    row-gap: 0.6rem;
  }

  .equipment-integrations-list li {
    display: grid;
    justify-items: start;
    gap: 0.18rem;
  }

  .equipment-integrations-list small {
    margin: 0;
    white-space: normal;
    line-height: 1.3;
    max-width: 5rem;
  }

  .equipment-integrations-list small::before {
    content: none;
  }

  /* Housing centre from the row top with the additional-equipment block
     out of the stack: label row + drawing offset + half of 11.3rem x 1.4. */
  .equipment-system-link {
    margin-top: 9.65rem;
  }
}

/* Stacked presentation: 01 above 02 with a vertical connector between them.
   Was max-width: 1350px, lowered to meet the side-by-side block above now
   that the frame is full width from 1021px. */
@media (max-width: 1020px) {
  .equipment-system-visual {
    min-height: 0;
  }

  .equipment-system-layout {
    /* Cancels the inset-inline: 1.5rem set a little above (also under
       max-width: 1020px, for a two-column tablet state) - this rule always
       wins for grid-template-columns at every width in this range, so that
       two-column state can never actually occur and its offset is now just
       dead weight nothing resets. On a position:relative element, left
       (which is what inset-inline resolves to, and wins over right per
       spec when both are set) shifts the box from its normal position
       rather than insetting it from the container, which is what pushed
       the whole "02" view ~24px right of centre and off the edge of its
       own column. */
    inset-inline: 0;
    padding: 2.4rem 1.25rem 2.6rem;
    grid-template-columns: 1fr;
    grid-template-rows: auto 3rem auto;
    gap: 0.9rem;
  }

  .equipment-system-view {
    gap: 0.85rem;
  }

  .equipment-system-view-label,
  .equipment-system-view-note {
    text-align: center;
  }

  .equipment-system-box {
    /* Stacked, the box has the full width to itself, so it runs wider than
       the desktop column allows — but not so wide that two tiles per row
       stretch into empty space. */
    max-width: 27rem;
  }

  .equipment-system-link {
    width: 3.5px;
    height: 2.8rem;
    justify-self: center;
    background: linear-gradient(180deg, rgba(42, 174, 158, 0.62), #7fe0d3);
  }

  .equipment-system-link::before {
    top: -0.29rem;
    left: 50%;
    transform: translate(-50%, 0);
  }

  .equipment-system-link::after {
    top: auto;
    right: auto;
    bottom: -0.1rem;
    left: 50%;
    transform: translateX(-50%) rotate(45deg);
    border-top: 0;
    border-right: 2.5px solid #7fe0d3;
    border-bottom: 2.5px solid #7fe0d3;
  }

  .equipment-system-link i {
    top: 0;
    left: 50%;
  }

  .equipment-system-link.is-sending i {
    animation-name: equipmentLinkSendY;
  }

  .is-configured .equipment-system-link {
    background: linear-gradient(180deg, rgba(42, 174, 158, 0.75), #d6fff8);
  }

  .equipment-installation {
    height: 18.5rem;
    /* At this width the base rule's width: min(100%, 19rem) already claims
       ~100% of the available column - there's no spare width left for the
       desktop scale(1.3) to grow into, so it only pushes the box past its
       own edges. The clipping panel around it (.equipment-system-visual,
       overflow: hidden) is meant to absorb exactly that kind of overflow,
       but here it has almost no margin to spare either, so the clip line
       lands inside real content - it was cutting "GROUND LINE" down to
       "OUND LINE". The two views also stack instead of sitting side by
       side at this width, which was the scale's original reason for
       existing (matching 02's visual weight against 01 beside it), so
       there's nothing left for it to do here anyway. */
    transform: none;
    margin-bottom: 0;
  }
}

@media (max-width: 480px) {
  .equipment-hero-caption,
  .equipment-card-caption {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.2rem;
  }

  .equipment-configurator-cta-row {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.7rem;
  }
}

/* Below ~600px two columns cannot hold icon, name and detail line at a
   readable size, so the box becomes a single-column order list. */
@media (max-width: 600px) {
  .equipment-system-sensor-grid {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    /* Edge to edge: with the frame's own side padding trimmed below, the
       rows now sit about 1rem in from the frame edge instead of ~2.25rem
       (1.25rem frame padding + 1rem here). */
    padding-inline: 0.25rem;
    gap: 0.55rem;
  }

  .equipment-system-box {
    aspect-ratio: auto;
  }

  /* Frame side padding 1.25rem -> 0.75rem on phones: the sensor list runs
     nearly the frame's full width, and the install drawing below gets the
     same extra width to scale into. */
  #sensor-configurator .equipment-system-layout {
    padding-inline: 0.75rem;
  }

  /* Contents of the housing one size up on phones. The housing keeps its
     own size (so the box-to-ground proportion holds and the scale steps
     below still fit the frame); it is the slot grid and the built-in band
     inside it that were leaving most of the box empty. Inner width is
     9.5rem: three 2.1rem slots plus gaps and padding come to ~8.4rem. */
  .equipment-installation-payload {
    grid-template-columns: repeat(3, 2.1rem);
    gap: 0.5rem;
    padding: 0.5rem;
  }

  .equipment-installation-payload i {
    width: 2.1rem;
    height: 2.1rem;
  }

  .equipment-installation-slot-icon {
    width: 1.3rem;
    height: 1.3rem;
  }

  /* Side padding 0.9rem -> 0.6rem gives the built-in band 10.1rem inside
     instead of 9.5rem: "GPS" and "RECHARGEABLE BATTERY" have to clear one
     row, and at 0.5rem the battery label ran past the housing's edge.
     0.44rem with the tracking eased to 0.06em fits with a few px spare.
     Top and bottom padding stay at 1rem, clear of the corner rivets. */
  .equipment-installation-enclosure {
    padding-inline: 0.6rem;
  }

  .equipment-installation-fixed-label {
    font-size: 0.44rem;
  }

  .equipment-installation-fixture i {
    width: 1.1rem;
    height: 1.1rem;
  }

  .equipment-installation-fixture svg {
    width: 0.66rem;
    height: 0.66rem;
  }

  .equipment-installation-fixture b {
    font-size: 0.44rem;
    letter-spacing: 0.06em;
  }

  /* And the additional-equipment block above it, to match. */
  .equipment-integrations {
    gap: 0.45rem;
    margin-bottom: 0.8rem;
  }

  .equipment-integrations-title {
    font-size: 0.6rem;
  }

  .equipment-integrations-list {
    row-gap: 0.4rem;
  }

  .equipment-integrations-list i {
    width: 1.5rem;
    height: 1.5rem;
  }

  .equipment-integrations-list svg {
    width: 0.9rem;
    height: 0.9rem;
  }

  .equipment-integrations-list b {
    font-size: 0.7rem;
  }

  .equipment-integrations-list small {
    font-size: 0.64rem;
  }
}

/* Phones: the install drawing is capped at 19rem (304px) while the sensor
   list above it is fluid, so left alone the two only match at one width.
   Scaled as one piece (housing, collar, ground block and spike keep their
   proportions) in steps chosen so the drawing's width tracks the list's —
   the list runs the frame's content width less 0.25rem each side, i.e.
   about (viewport - 64px) — within a few px at 375, 390, 414 and 430px.
   Each step's margin-bottom is 18.5rem x (scale - 1), the overflow the
   scale paints below its layout box. Below 385px the natural 19rem is
   already within ~4px of the list, so no scale. */
@media (min-width: 385px) and (max-width: 409px) {
  .equipment-installation {
    transform: scale(1.08);
    transform-origin: top center;
    margin-bottom: 1.5rem;
  }
}

@media (min-width: 410px) and (max-width: 439px) {
  .equipment-installation {
    transform: scale(1.17);
    transform-origin: top center;
    margin-bottom: 3.15rem;
  }
}

@media (min-width: 440px) and (max-width: 600px) {
  .equipment-installation {
    transform: scale(1.28);
    transform-origin: top center;
    margin-bottom: 5.2rem;
  }
}

/* Below ~450px, four columns no longer fit RADIOACTIVITY at a readable
   size in the sensor-box diagram — falls back to the original 2x4 tile
   grid rather than shrinking the type further. DOM order is unchanged, so
   this still reads METAL/VIBRATION/.../RADIOACTIVITY top to bottom. */
/* Covers both true mobile AND the 761-1000px range: there the diagram
   stacks (system-layout goes to 1 column below 1180px) but the hero grid
   is still 2 columns until 760px, so the box only gets ~64% of a
   already-narrow viewport — narrower than the 4-col grid needs, verified
   by testing down from 1180px (bisected: overflow starts ~980px). */
@media (prefers-reduced-motion: reduce) {
  .equipment-page *,
  .equipment-page *::before,
  .equipment-page *::after {
    scroll-behavior: auto !important;
  }

  .equipment-system-sensor,
  .equipment-system-sensor::before,
  .equipment-system-box,
  .equipment-installation-payload i {
    transition: none !important;
  }

  .equipment-system-sensor.just-added,
  .equipment-system-sensor::before,
  .equipment-system-link i,
  .equipment-system-box,
  .equipment-installation-spike,
  .equipment-installation-spike::before,
  .equipment-installation-payload i,
  .equipment-installation-enclosure,
  .equipment-configurator-cta-row {
    animation: none !important;
  }
}

/* Platform designation line — separated from the source copy above it so it
   reads as a name, not a fifth claim in the hero. Needs the parent selector
   to beat the .equipment-hero-lede colour it shares. */
/* The shared body.pgisr page-title rule caps this at 5vw, which fitted the
   old wider copy column. With the column narrowed to give the diagram more
   room, "Flexible Sensor" no longer fitted on one line and the headline
   broke to three. 4.5vw restores the intended two-line break. Scoped by an
   extra ancestor so it beats the shared rule without touching other pages'
   titles, which still use 5vw. */
body.pgisr .equipment-hero-copy .equipment-hero-title {
  font-size: clamp(2.6rem, 4.5vw, 4.4rem);
}

/* Closing identity statement: more air above the rule than the list uses
   between its own items, so it lands as the column's final takeaway rather
   than a fourth attribute line. */
.equipment-hero-copy .equipment-hero-platform {
  margin-top: clamp(1.75rem, 2.6vw, 2.3rem);
  padding-top: clamp(1.2rem, 1.7vw, 1.5rem);
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.92rem;
}

.equipment-hero-copy .equipment-hero-platform strong {
  color: var(--ink);
  font-weight: 600;
  letter-spacing: 0.02em;
}

