/* ENVOY — why.css
   the four-panel "Why Envoy?" rig walkthrough

   One part of a stylesheet split across files. The load order in
   index.html is part of the stylesheet — see css/base.css for the map.

   Same sticky-stage construction as the tour below it, run much longer: the
   stage is one screen tall and in the flow, followed by nine .why-step
   spacers, so the section is ten screens of which the stage can travel nine.
   js/why.js turns that travel into a slide index — one rig per 2¼ screens —
   and nothing else in here knows about the scroll. The pacing lives in the
   spacer count in index.html and nowhere else.

   ------------------------------------------------------------------------
   THE GRID

   Every proportion in this section is a pair of Fibonacci numbers. Not as
   decoration — as the only way any size in here is allowed to be decided, so
   that the copy, the rigs and the space around them are all measuring
   themselves against the same ruler.

   The three ratios that do the work:

     5 : 8    the slide, split into a copy column and a rig field. Adjacent
              Fibonacci numbers, so it is the golden section to three decimal
              places — 0.3846 against 0.6154, where φ wants 0.3820 / 0.6180.
     3 : 8    inside a rig, the arrow gap against a signal slot. One step
              further apart in the sequence, which is 1/φ² — the same
              relationship the slide has, applied one level down.
     2 : 3    the dash against the space in the dashed arrows, the tightest
              pair in the sequence and the only one small enough to read as
              texture rather than as structure.

   Lengths come from --u, and every one of them is a Fibonacci multiple of it.
   Type climbs the same ladder by φ: body, index and title are t0, t1 and t3,
   three steps apart end to end.

   The consequence worth knowing: the rigs are now sized as a fraction of
   their column rather than of the viewport, in fr units, so the drawings
   cannot drift out of proportion with the grid when the window changes. The
   only fixed number left in a rig is --fw, which is per-drawing and is about
   the file's own padding, not the layout.
   ------------------------------------------------------------------------ */

/* ------------------------------------------------------------------- why */

.why {
  /* ---- the Fibonacci scale ----
     One unit, and the sequence on top of it. Everything spatial in this file
     is one of these six; if a gap here is not on the list, it is a bug. */
  --u:   clamp(3px, 0.42vw, 7px);
  --f2:  calc(var(--u) *  2);
  --f3:  calc(var(--u) *  3);
  --f5:  calc(var(--u) *  5);
  --f8:  calc(var(--u) *  8);
  --f13: calc(var(--u) * 13);
  --f21: calc(var(--u) * 21);

  /* ---- the type ladder ----
     t0 is the paragraph and is the only one measured; the other two are
     multiples of φ away from it, so the three sizes in the section are one
     geometric run rather than three separate decisions.

     Width only. The ladder used to carry a vh cap so a short window could not
     spend its whole height on the title — but the cap was on t0, and since
     everything hangs off t0 it took the paragraph down with it and left 13px
     body copy on a laptop. The height limit belongs on the title alone, and
     that is where it is now. */
  --t0: clamp(14px, 1.35vw, 19px);
  --t1: calc(var(--t0) * 1.618);   /* the index — one step */
  --t3: calc(var(--t1) * 2.618);   /* the title — two more, so φ³ overall */

  /* ---- the dissolve ----
     Deliberately NOT on the Fibonacci scale: these are durations, and the eye
     does not read time in the proportions it reads space. They are tuned by
     feel and documented on their own terms.

     Both leads are measured against --out, which is how long the rig being
     replaced takes to go, and both clear it completely. They have to: a piece
     holds its opacity for the first part of its blur (see the transitions
     below), so the outgoing line is still readable well into --out.

       --copy-lead   just past --out. The old line is gone, then the new one.
       --lead        a long way past it, so the copy has the screen to itself
                     for a beat before the rig starts building beside it.

     --stagger is multiplied by a piece's --i, so the longest rig (nine
     pieces, slide 04) finishes at lead + 9 × stagger + in. If the whole thing
     wants to be quicker, this is the knob — it costs nine times whatever you
     change it by.

     The two fades are separate numbers because the two directions are not the
     same event. Coming in, a piece should be solid almost at once and spend
     its time pulling into focus, so --fade is short. Going out, it is the
     only thing the reader is watching leave, and a short one reads as the
     piece being switched off rather than let go — so --fade-out is most of
     the window and only the first fraction of the blur happens at full
     opacity.

     --carry and --hand are not part of the dissolve at all: they belong to
     the handover, where a piece that is on both rigs travels between its two
     slots instead of being replaced. --carry is how long that takes, kept
     inside --lead so a rig has finished rearranging itself before anything
     new starts blurring in beside it. --hand is how long the copy being
     replaced takes to fade off the one replacing it — short, because the two
     are superimposed and travelling together, so it is a safety net rather
     than something meant to be seen. Both are read by js/why.js, which is the
     only thing that can act on them: a handover is a measured distance, and
     there is no CSS property to put one in. */
  --why-out:       620ms;   /* blur away — everything together */
  --why-in:        760ms;   /* blur back — one piece at a time */
  --why-fade:      250ms;   /* the opacity tail on the way in */
  --why-fade-out:  440ms;   /* most of the window on the way out */
  --why-copy-lead: 660ms;
  --why-lead:     1000ms;
  --why-stagger:    85ms;
  --why-blur:       12px;
  --why-carry:     820ms;
  --why-hand:      320ms;
  /* Out at speed, settling long and soft — a piece being moved rather than
     one being thrown. Read by js/why.js and handed straight to the animation. */
  --why-carry-ease: cubic-bezier(0.33, 0, 0.15, 1);

  position: relative;
  z-index: 1;
  background: #000;
  /* The diagrams are eight separate SVGs that land at their own pace inside
     a sticky box. Left alone the browser re-anchors the scroll when one
     arrives and shunts the reader down the page — same reason the tour
     carries this. */
  overflow-anchor: none;
}

.why-step { height: 100vh; }

.why-stage {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
  overflow-anchor: none;
}

/* ---- heading ----
   Fixed for the whole section. Indented by --f21, the largest step on the
   scale, while the meter below runs to the very edge of the screen — which is
   what makes the rule read as a scale under the title rather than as an
   underline for it. That same --f21 is the slide's left edge below, so the
   mark, the paragraph and the title all hang off one line down the page. */

.why-head {
  display: flex;
  align-items: center;
  gap: var(--f8);
  flex: none;
  /* Tighter above and below than the scale's mid steps would suggest. The
     heading is fixed for the whole section and the rigs get whatever is left,
     so every step spent here is taken off slide 04 — which is the panel that
     runs out of room first. */
  padding: calc(var(--nav-h) + var(--f5)) var(--f13) var(--f3) var(--f21);
}

/* Drawn rather than placed: four diamonds in a plain fill, which is a
   handful of bytes inline and takes its colour from the stylesheet like
   every other mark on the page. Set to the title's own size so the two read
   as one lockup rather than as a bullet in front of a word. */
.why-mark {
  flex: none;
  display: block;
  width: min(var(--t3), 10.5vw, 9.5vh);
  color: var(--ink);
}

.why-mark svg {
  display: block;
  width: 100%;
  height: auto;
  fill: currentColor;
}

/* Bodoni Moda proper, not the body's Moda SC: the line is Title Case and has
   lowercase to set, and the small-cap face would flatten it to one height.

   Two caps, and they guard different failures. The vw one is for phones,
   where three φ steps up from a floored t0 is wider than the screen. The vh
   one is for short, wide windows, where a title sized purely off width takes
   a third of the height and the rig beside it has nowhere to go. */
.why-title {
  margin: 0;
  font-family: "Bodoni Moda", "Bodoni MT", Didot, serif;
  font-size: min(var(--t3), 10.5vw, 9.5vh);
  font-weight: 600;
  line-height: 1;
  color: var(--ink);
}

/* ---- index and progress bar ----
   The bar is the section's whole state in one line, and it is the only thing
   here that moves continuously: it is written straight off the scroll
   position, so any amount of scroll moves it by that amount. Everything else
   in the section is a state that swaps.

   That also makes it the clock. The quarter marks are where the slides change
   — cross a quarter and the rig beside it is replaced — so the bar is not a
   report of which slide is up, it is the reason the next one arrives.

   It is quartered rather than divided on the scale, and that is not an
   oversight: there are four slides, so the marks are counting something real
   and have to be even. It is the one measure in the section that is not
   Fibonacci, because it is data rather than design. */

.why-meter {
  display: flex;
  /* Baseline, not centre: the rule runs along the foot of the figures rather
     than through the middle of them, so the index reads as a label sitting on
     a scale instead of as two things on a row. A 2px block has no text, so
     its baseline is its bottom edge — which is exactly the alignment wanted. */
  align-items: baseline;
  flex: none;
  gap: var(--f5);
  padding-left: var(--f3);
}

.why-index {
  flex: none;
  margin: 0;
  font-family: "Bodoni Moda", "Bodoni MT", Didot, serif;
  font-size: var(--t1);
  font-weight: 700;
  font-style: italic;
  letter-spacing: 0.04em;
  color: var(--ink);
  /* The figures are swapped in place by script. Proportional numerals would
     re-measure the label on every flip and shunt the bar sideways with it. */
  font-variant-numeric: tabular-nums;
}

.why-x { margin-right: 0.45em; }

/* Runs to the right edge of the screen — no padding on that side. The bar is
   a measure of the section, and stopping it short of the edge would make it
   look like it were measuring the column instead. */
.why-bar {
  flex: 1;
  height: 1px;
  background: rgba(243, 228, 226, 0.2);
}

.why-bar-fill {
  display: block;
  width: calc(var(--wp, 0) * 100%);
  height: 100%;
  background: var(--ink);
  /* No transition, and that is the point of it. --wp is written from the
     scroll position on every scroll, so an easing here would put the bar
     behind the page and make a short scroll look like it did nothing. Same
     call, and the same reason, as the tour's bar. */
}

/* ---- slides ----
   All four stacked in the same box, and one rig is dissolved into the next.

   THE GOLDEN SECTION IS HERE. Copy in the minor field, rig in the major, at
   5fr : 8fr. Two things fall out of that and both are the point:

     the paragraph gets a column about fifty characters wide at any window
     size, which is a measure rather than a line running the width of a
     screen — it was set as a full-width block when it held five words, and
     that stopped being right the moment it held sixty;

     the rig gets the whole height of the slide instead of whatever the
     paragraph left it. Slide 04 is five rows deep and was the panel that kept
     running out of room; stacked, it had ~350px and was still the first thing
     to clip. Beside the copy it has the lot.

   Both fields are centred on the same axis, so the four rigs dissolve around
   one horizon instead of jumping as their heights change.

   The slide itself does not animate — its pieces do, individually, which is
   what lets the two directions differ:

     out   everything at once, no delay. A rig that left a limb at a time
           would read as it falling apart rather than as it being replaced.
     in    the paragraph first, then the signal chain one piece at a time,
           left to right. The reader is told what they are looking at and then
           watches it get built, which is the order the argument is made in.

   Neither of those happens to a piece that is on both rigs — see the
   carry-over block below. Those are moved, not replaced, and they are taken
   out of the dissolve in both directions.

   The asymmetry is free: the delays are declared only on the .is-on rule, so
   they exist on the way in and simply are not there on the way out.

   visibility stays on the slide rather than its pieces — it is what keeps the
   three that are off out of the accessibility tree, and one delayed property
   on the parent is cheaper than nine. Its delay is the out duration, so the
   element is not taken away until the blur that hides it has finished. */

.why-slides {
  position: relative;
  flex: 1;
  min-height: 0;
}

.why-slide {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: 5fr 8fr;
  column-gap: var(--f13);
  align-items: center;
  /* left edge is the heading's, so the paragraph sits under the mark */
  padding: var(--f8) var(--f8) var(--f13) var(--f21);
  visibility: hidden;
  transition: visibility 0s linear var(--why-out);
}

.why-slide.is-on {
  visibility: visible;
  transition: visibility 0s;
}

/* The paragraph and every piece of the diagram. Blurred and clear are the two
   states; --i is the piece's place in the running order and is set further
   down, next to whatever else decides that piece's position.

   Blur and opacity are deliberately NOT on the same clock, and that is what
   makes a piece read as going out of focus rather than simply fading. Run the
   two together from zero and the piece is most of the way to transparent
   while the blur is barely started, so the blur never gets seen — what lands
   is a fade with a little softness on it.

   The offset is small on the way out and large on the way in, because the two
   directions are watched differently:

     out   the blur starts alone, and the fade joins it a fraction of a second
           later and then has most of the window — 440ms of 620ms — to take
           the piece away. It has to be a fade the reader can see happen. A
           departure is the only motion on screen at that moment, and now that
           the pieces common to both rigs stay put (see the carry-over below)
           it is the only thing leaving at all — so a short tail at the end of
           a long blur does not read as a piece being let go, it reads as one
           being switched off.
     in    the fade is the fast one, done inside --fade, so the piece is solid
           on screen for most of its own arrival and the reader watches it
           pull into focus rather than materialise.

   The fades are absolutes rather than fractions of --out and --in: they are
   the numbers here that are about legibility rather than pace, so they should
   not stretch when the rest of the section is slowed down.

   The two lists run in the order named by transition-property. */
.why-body,
.why-diagram > * {
  opacity: 0;
  filter: blur(var(--why-blur));
  transition-property: filter, opacity;
  transition-duration: var(--why-out), var(--why-fade-out);
  /* ease-out on the blur: most of the defocus happens early. linear on the
     opacity: a fade is the one thing here with no reason to be anywhere but
     even, and an eased one lands as a piece hanging on and then dropping. */
  transition-timing-function: ease-out, linear;
  transition-delay: 0s, calc(var(--why-out) - var(--why-fade-out));
}

.why-slide.is-on .why-body,
.why-slide.is-on .why-diagram > * {
  opacity: 1;
  filter: blur(0);
  transition-property: filter, opacity;
  transition-duration: var(--why-in), var(--why-fade);
  /* ease on the blur is a lens being pulled: it settles into sharp rather
     than snapping there */
  transition-timing-function: ease, ease-out;
  transition-delay: calc(var(--why-lead) + var(--i, 0) * var(--why-stagger));
}

/* Words first — it is the only piece with a lead of its own, and everything
   in the diagram is timed from the end of it. */
.why-slide.is-on .why-body { transition-delay: var(--why-copy-lead); }

/* ---- carry-over ----
   The guitar is on all four rigs. The monitor is on three of them, and on the
   third it has moved from the end of the chain to underneath the interface.
   Dissolving those out and back in says they are different objects, which is
   the opposite of the point being made: the rigs are being compared, so what
   they have in common has to be seen to be the same thing in a new place.

   So a piece that is on two rigs in a row is handed over instead. js/why.js
   measures where the outgoing copy was standing, takes it away outright, and
   slides the incoming one over from that position — which is why the travel
   is nowhere in this file. There is no CSS property that means "from wherever
   that other element happened to be", so the distance is measured at the
   moment it is needed and animated on the transform from script.

   What is left here is the two states that make the handover invisible:

     .is-carry   the incoming copy — solid and in focus from its first frame.
                 It is the same piece the reader was already looking at, so it
                 has nothing to arrive from; it only has somewhere to go.
     .is-handed  the outgoing copy, fading off the one that replaced it over
                 --hand while travelling the same path, so the two stay
                 exactly superimposed the whole way.

   That the outgoing copy fades rather than cuts is the one thing here that is
   not about how the handover looks — it is what makes the guitar impossible
   to lose. A cut is only seamless if the replacement is painted in the very
   same frame, which is a guarantee no stylesheet can give across browsers;
   the fade means the worst case is the old copy lingering imperceptibly
   rather than a piece that is on all four rigs blinking out of the middle of
   the section. It is never seen otherwise: the copy replacing it is solid, in
   the same place, moving the same way, and the two are indistinguishable.

   transition: none on .is-carry, and it is load-bearing rather than tidiness:
   the class is set in the same frame the slide changes, so without it the
   piece would animate from the state it is replacing and flicker at exactly
   the moment it is supposed to be continuous. Its opposite number transitions
   for exactly the same reason — from solid, which is where it already is.

   The pairing itself is in the markup as data-carry, because which pieces
   recur is a fact about the rigs rather than about their styling.

   Written after the .is-on rules deliberately: .is-handed matches at the same
   weight as the dissolve rule it has to beat, so it wins on order. */
.why-slide.is-on .why-diagram > .is-carry {
  opacity: 1;
  filter: blur(0);
  transition: none;
}

.why-slide .why-diagram > .is-handed {
  opacity: 0;
  filter: blur(0);
  transition: opacity var(--why-hand) linear;
}

/* Slide 03's copy of the controller and the bracket: laid out, never drawn.
   They hold the two crown rows open so the chain underneath is in the same
   place on 03 as it is on 04, which is what leaves 04 with nothing to do but
   fade its two new pieces in over a rig that does not move. visibility rather
   than opacity — opacity 0 is what the dissolve itself uses, and these have
   to stay hidden through both states of it. */
.why-diagram > .is-ghost { visibility: hidden; }

/* Cormorant Garamond, not the heading's Bodoni. This slot used to hold a line
   of five words and was set as display type to match; it now holds a genuine
   paragraph, and the Bodoni at that size was unreadable at length. Garamond is
   what the rest of the site already uses for long-form — see the note in
   gear.css, and the tour cards, which set this kind of paragraph the same way.

   The 5fr column is now the measure, so the ch cap is only a backstop for
   very wide screens, where the column would otherwise outrun the type. */
.why-body {
  max-width: 62ch;
  margin: 0;
  font-family: "Cormorant Garamond", "EB Garamond", Garamond, serif;
  font-size: var(--t0);
  font-weight: 400;
  line-height: 1.5;
  color: rgba(243, 228, 226, 0.88);
}

/* ---- the rig diagrams ----
   Three signal slots with an arrow gap between each pair, at 8fr : 3fr —
   the same golden relationship the slide is split on, one level down.

   In fr rather than in px, which is the change that makes the rigs part of
   the grid rather than guests in it: a slot is a fixed share of whatever
   column it is given, so every drawing scales with the field and none of them
   can drift as the window moves. Both variants share the columns; only the
   two-row rigs name their slots.

   The vertical pieces — the row gaps, the drop, the bracket — come off the
   Fibonacci scale rather than off the column, so they stay the same weight
   whether they are sitting under a wide rig or a narrow one. */
.why-diagram {
  --aw:   max(2px, calc(var(--u) * 0.5));  /* line weight, arrows and bracket */
  --head: calc(var(--u) * 1.6);            /* arrowhead half-width */
  --dash: var(--f3);                       /* 3 : 2 against the gap */
  --dgap: var(--f2);
  --rgap: var(--f5);

  display: grid;
  grid-template-columns: 8fr 3fr 8fr 3fr 8fr;
  align-items: center;
  justify-items: center;
  /* Centred in the rig field, not stretched across it. It only matters for the
     two-row rigs, and only once their height guard below has capped them
     narrower than the column: a grid item with a max-width falls back to
     start-aligned, which parked slides 03 and 04 against the left edge of
     their own field on any short window while 01 and 02 stayed full width. */
  justify-self: center;
  width: 100%;
  row-gap: var(--rgap);
}

/* Guitar → box → output, all on one line. Five children, five columns, in
   order — no named areas needed. */

/* The interface rig: the same line, plus a drop from the middle slot to the
   monitors under it, and ENVOY and its bracket over the top of all of it.

   One template for both slides that use it, rather than a three-row hub with
   a five-row variant on top. Slide 03 fills the crown rows with an invisible
   copy of what slide 04 puts in them (see .is-ghost above), so the two rigs
   are the same shape to the pixel and the chain does not move between them —
   which means the shape is a property of the rig, not of the slide, and it
   belongs in one place. */
.why-diagram--hub {
  /* The one height guard left in the file, and the only place a raw number
     survives the move to fr units.

     This rig is five rows deep. Its height comes out at about half its own
     width plus the fixed pieces stacked through it (four row gaps, the
     bracket, the drop), so unlike everything else here, making it WIDER makes
     it TALLER — and on a short window width is what has to give. Hence a
     max-width in vh, which reads backwards until you see why.

     The two constants are a straight line fitted through the measured layout
     at 620px and 800px tall, not a derivation: too much of the input (the
     heading, the meter, the padding, the arrowheads) is itself clamped for a
     closed form to be honest. It binds only on short windows — above ~900px
     tall the 100% wins and the column decides. The floor stops the whole
     expression going negative on something pocket-sized.

     Re-measure this if the heading's size or padding changes. */
  max-width: min(100%, max(150px, calc(221vh - 1066px)));
  grid-template-areas:
    ".       .       envoy   .       ."
    "bracket bracket bracket bracket bracket"
    "src     a       hub     b       out"
    ".       .       down    .       ."
    ".       .       spk     .       .";
}

/* Named slots for the two-row rigs — everything in them has to be named or
   the auto-placed strays land in the blank cells beside the drop.

   These also carry --i, the order the pieces blur back in. It is the signal
   order: source, arrow, hub, arrow, out, then down to the monitor. Where a
   slide carries some of its pieces over rather than building them, the ones
   that do arrive keep their number and simply leave gaps in the count, which
   is what holds them in left-to-right order against each other.

   ENVOY and its bracket sit at the front of it, which is a reversal. They
   used to be numbered last, on the grounds that slide 04 arrives over a rig
   the reader has already been shown — but that is now literally true: the rig
   is carried across from 03 and never leaves the screen, so these two are the
   only pieces on 04 that arrive at all. There is nothing left for them to
   wait behind, and nine steps of stagger in front of the one thing the slide
   exists to show was nine steps of nothing happening. */
.wa-src   { grid-area: src;   --i: 3; }
.wa-a     { grid-area: a;     --i: 4; }
.wa-hub   { grid-area: hub;   --i: 5; }
.wa-b     { grid-area: b;     --i: 6; }
.wa-out   { grid-area: out;   --i: 7; }
.wa-down  { grid-area: down;  --i: 8; }
.wa-spk   { grid-area: spk;   --i: 9; }
.wa-envoy { grid-area: envoy; --i: 1; }

/* The flat rigs run left to right, which is both the markup order and the
   signal order, so they can be counted off where they stand. */
.why-diagram--row > :nth-child(1) { --i: 1; }
.why-diagram--row > :nth-child(2) { --i: 2; }
.why-diagram--row > :nth-child(3) { --i: 3; }
.why-diagram--row > :nth-child(4) { --i: 4; }
.why-diagram--row > :nth-child(5) { --i: 5; }

/* ---- figures ----
   Every file is 680 units wide, but the drawing inside is not: the guitar and
   the laptop fill 88% of their frame, the amp 79%, and the monitor only 41% —
   it is a tall, narrow box sitting in a wide one. Sizing the <img> alone would
   therefore make the monitor a third the size of everything beside it.

   --fw is that difference divided back out, as a share of the slot the
   drawing sits in, so a slot means one thing across all eight of them:
   roughly how wide the ink comes out. The numbers were set from each file's
   own bbox against the proportions in the reference, so they are not free —
   changing a drawing's padding changes its --fw. */
.why-fig {
  display: block;
  width: calc(var(--fw, 1) * 100%);
}

.why-fig img {
  display: block;
  width: 100%;
  height: auto;
}

.wf-guitar  { --fw: 1; }
.wf-board   { --fw: 0.84; }
.wf-amp     { --fw: 0.83; }
.wf-modeler { --fw: 0.74; }
.wf-iface   { --fw: 0.7; }
.wf-laptop  { --fw: 0.79; }
.wf-envoy   { --fw: 0.62; }

/* 41% ink, so it is scaled a little past its slot to read at the same size as
   the rest. The 5% it borrows lands in an arrow column ten times that wide,
   so nothing collides. In the two-row rig it stays inside its slot — it is a
   secondary element there, hanging off the interface rather than ending the
   chain. */
.wf-monitor { --fw: 1; }
.why-diagram--row .wf-monitor { --fw: 1.05; }

/* ---- arrows ----
   Drawn in CSS rather than as an eighth and ninth SVG: a repeating gradient
   for the dashes and a border triangle for each head, which means one weight
   and one dash length for the whole section and both of them come off the
   Fibonacci scale like everything else. The heads live outside the bar's own
   box and the bar is shortened by their width, so the overall run is exactly
   the column. */
.why-arrow {
  position: relative;
  display: block;
}

.why-arrow--x {
  width: calc(100% - var(--head) * 2);
  height: var(--aw);
  background: repeating-linear-gradient(to right,
    var(--red) 0 var(--dash), transparent var(--dash) calc(var(--dash) + var(--dgap)));
}

.why-arrow--x::before,
.why-arrow--x::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 0;
  height: 0;
  border: var(--head) solid transparent;
  transform: translateY(-50%);
}

.why-arrow--x::before {
  right: 100%;
  border-left: 0;
  border-right-color: var(--red);
}

.why-arrow--x::after {
  left: 100%;
  border-right: 0;
  border-left-color: var(--red);
}

/* One head only, pointing down: the monitors are the end of the chain. */
.why-arrow--y {
  width: var(--aw);
  height: var(--f8);
  margin-bottom: var(--head);
  background: repeating-linear-gradient(to bottom,
    var(--red) 0 var(--dash), transparent var(--dash) calc(var(--dash) + var(--dgap)));
}

.why-arrow--y::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 100%;
  width: 0;
  height: 0;
  border: var(--head) solid transparent;
  border-bottom: 0;
  border-top-color: var(--red);
  transform: translateX(-50%);
}

/* ---- the ENVOY bracket ----
   Solid and headless where everything else is dashed and pointed, because it
   is not signal — it is one thing reaching over the rig and taking hold of
   both ends of it. Three borders of one box: the arms drop to the guitar and
   the laptop, and ::before is the stem back up to the board.

   Its width is the span between the centres of the outer two slots. On a
   30fr grid of 8-3-8-3-8 that is the full width less one slot, so 22/30 —
   which is why the columns have to be a fixed share rather than auto. */
.why-bracket {
  grid-area: bracket;
  /* straight after the controller: the thing appears, and then it reaches
     down and takes hold of the rig that was already there */
  --i: 2;
  position: relative;
  width: 73.3333%;
  height: var(--f5);
  border: var(--aw) solid var(--red);
  border-bottom: 0;
}

.why-bracket::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 100%;
  width: var(--aw);
  /* the row gap, plus the border it starts from, so there is no seam */
  height: calc(var(--rgap) + var(--aw));
  margin-left: calc(var(--aw) / -2);
  background: var(--red);
}
