/* ==========================================================================
   Case study data sections: Results, stat boxes, compare table, Impact

   The dark sections and their framed variant. Split out of case-study.css
   because the grid-row bookkeeping here is dense enough to read on its own.
   ========================================================================== */


/* ---- Results ---- */
/* Results (dark) */
.results {
  background: var(--bg-dark);
  color: var(--on-dark);
  padding: 60px 40px;
}
.results-inner { max-width: var(--content-width); margin: 0 auto; }
/* Full-strength cream, the same as Impact's own heading. Node 429:152466
   fills "Results" with #FDFAF2 (--paper), not the slightly dimmer --on-dark
   this carried. */
.results h2 { font-family: var(--font-serif); font-weight: 400; font-size: 28px; color: var(--paper); margin: 6px 0 0; }
.results-header {
  display: flex;
  border: 1px solid var(--border-dark);
  margin-bottom: -1px;
}
/* Figma node 385:61994: the header cell is 226px wide including its
   32/32/96/32 padding, and the label and title sit at the top of it. */
.results-header-copy {
  flex: 0 0 226px;
  min-height: 179px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  padding: 32px 32px 96px;
  border-right: 1px solid var(--border-dark);
}
.results-header-fill {
  flex: 1;
  background-image: var(--hatch-dark);
}
/* ---- Results, framed variant (Calendly) ----
   Figma node 289:166306 is a 3x3 grid, not a header bar over a full-width
   table. Columns 162 | 989 | 129 at a 1280 content width; rows 130 | auto |
   130. The table's left edge lands exactly where the "Results" cell ends
   (x=130 for both in the 0.749x export), and the hatch fills the gutters
   beside it plus the bands above and below.

     row 1   Results cell (bordered)  |  hatch (bordered)  |  plain
     row 2   hatch (no border)        |  table (bordered)  |  hatch (no border)
     row 3   plain                    |  hatch (bordered)  |  plain

   Verified per cell against the export: the body gutters carry hatch with no
   outer rule (x=10 and x=964 are lit only where a stripe crosses), and row 3
   column 1 is empty -- the rule under the Results cell stops at x=130.

   The other three case-study pages keep the flex header, so every rule here
   is scoped to .results--framed. */
/* The side gutters bleed to the viewport edge rather than stopping at the
   1280 content box. Above about 1360 the design's own frame runs out, and
   three hatch rectangles floating in plain dark read as stacked boxes rather
   than one field. overflow clips the bleed back to the section. */
.results--framed {
  padding: 0 40px;
  overflow: hidden;
}
/* The Figma columns are 162 | 989 | 129. Both gutters are 162 here, which is
   what the design width gives once the table is capped at 956, and it keeps
   the frame symmetric.

   The gutters are the flexible part, not the table. The table carries four
   paragraph pairs and reflows them on every pixel it loses; the gutters carry
   hatch. So both gutters shrink together and the table holds 956 all the way
   down to the breakpoint.

   The "Results" cell sits in the left gutter but does not shrink with it. It
   is a fixed 162px that overhangs the track once the gutter drops below that,
   which is everything under a 1360px viewport. Three constraints compete here
   and only two can hold: equal gutters, an untouched label, and the design's
   alignment of the table's left edge with the cell's right edge. The
   alignment is the one that gives. Below 1360 the cell's right rule sits to
   the right of the table's left rule, by up to 100px at the breakpoint.

   Overhanging costs the cell two declarations. It precedes .hatch-top in the
   DOM, so without a stacking bump the hatch paints over it; and it has no
   background of its own, so without one the stripes read straight through the
   label. */
.results--framed .results-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 956px) minmax(0, 1fr);
  grid-template-rows: 130px auto 130px;
}
/* The Figma frame is a fixed 130px tall with 32/32/96 padding, so its 96px
   bottom padding never fits and the text simply sits at the top. Writing the
   bottom padding as 0 reproduces the render without the dead declaration. */
.results--framed .results-header-copy {
  grid-area: 1 / 1;
  justify-self: start;
  width: 162px;
  position: relative;
  z-index: 1;
  background: var(--bg-dark);
  flex: none;
  min-height: 0;
  height: 130px;
  padding: 32px 32px 0;
  border: 1px solid var(--border-dark);
}
.results--framed .hatch {
  background-image: var(--hatch-dark);
}
.results--framed .hatch-top {
  grid-area: 1 / 2;
  border-top: 1px solid var(--border-dark);
  border-right: 1px solid var(--border-dark);
}
.results--framed .hatch-left,
.results--framed .hatch-right {
  margin-top: -1px;
  border-top: 1px solid var(--border-dark);
  border-bottom: 1px solid var(--border-dark);
}
.results--framed .hatch-left   { grid-area: 2 / 1; border-left: 1px solid var(--border-dark); }
.results--framed .hatch-right  { grid-area: 2 / 3; border-right: 1px solid var(--border-dark); }
.results--framed .compare-table {
  grid-area: 2 / 2;
  margin: -1px 0 0;
  max-width: none;
}
.results--framed .hatch-bottom {
  grid-area: 3 / 2;
  margin-top: -1px;
  border: 1px solid var(--border-dark);
  border-top: none;
}

@media (max-width: 1160px) {
  .results--framed .results-inner {
    grid-template-columns: 162px minmax(0, 1fr);
  }
  .results--framed .hatch-left,
  .results--framed .hatch-right { display: none; }
  .results--framed .compare-table { grid-area: 2 / 1 / 3 / 3; }
  .results--framed .hatch-bottom { grid-area: 3 / 1 / 4 / 3; }
}

@media (max-width: 900px) {
  .stat-fill, .results-header-fill { display: none; }
  .results-header-copy { flex: 1; border-right: none; }
  /* Two 40-word paragraphs cannot share a phone screen, so the table stacks.
       A plain stack loses the comparison, though: eight unlabelled paragraphs
       in a column read as one list. The BEFORE/AFTER head is dropped and each
       cell states its own side instead, and the pair is bound by padding --
       tight between the two halves, with the row rule separating one pair from
       the next. */
  .results--framed .results-inner {
      grid-template-columns: minmax(0, 1fr);
      grid-template-rows: auto auto auto;
    }
  .results--framed .results-header-copy {
    grid-area: auto;
    height: auto;
    padding: 24px;
  }
  .results--framed .hatch-top { display: none; }
  .results--framed .compare-table { grid-area: auto; }
  .results--framed .hatch-bottom { grid-area: auto; height: 90px; }
  .results { padding: 70px 20px; }
  .results-header-copy { padding: 32px 24px; min-height: 0; }
  /* The hatch is decoration, and at this width it competes with the copy for
       the little contrast the dark section has. */
  .results--framed { padding: 0 20px; }
  .results--framed .hatch { display: none; }
  .results--framed .results-header-copy { padding: 28px 20px 24px; }
}


/* ---- Stat boxes ---- */
/* Four shared rows -- label, number, slack, sub -- and every cell subgrids
   onto them. The sub sits in row 4, so the three subs share one row and start
   on one line whatever their line counts, while the slack in row 3 keeps them
   anchored to the bottom of the cell as the design has them. Before this the
   cells were bottom-packed flex columns, so a one-line sub started a line
   lower than the two-line ones beside it. */
.stat-row {
  display: grid;
  grid-template-columns: 1.5fr 1fr 0.3fr;
  grid-template-rows: auto auto 1fr auto;
  gap: 0px;
  margin-bottom: 1px;
}
/* The hatch column was 0.5fr, which took 183px of the row at a 1700px
   viewport and left each cell 237.7px of content. The longest label needs 288
   -- "NEW CUSTOMER ACQUISITION" on DocDraft, measured at the 20px mono size --
   so all three pages wrapped a label onto a second line. 0.25fr plus the
   lighter padding below gives 297.9. */
.stat-row.three { 
  grid-template-columns: 1fr 1.1fr 1fr 0.1fr;
  grid-template-rows: auto auto 1fr auto;
  border-bottom: 1px solid var(--border-dark) !important;
 }
/* Figma node 385:61994 gives each row its own cell padding: the featured row
   is 20/32 and the three-up row is 32/64. */
.stat-box {
  background: var(--bg-dark);
  padding: 20px 32px;
  display: grid;
  grid-template-rows: subgrid;
  grid-row: 1 / -1;
  /* space-between leaves no gap once the box runs out of slack, which it does
     when the growth note wraps under the number: the note then sat on top of
     "in 11-month period". The gap only applies in that case. */
  gap: 12px;
  min-height: 316px;
  border: 1px solid var(--border-dark) !important;
  border-bottom: 0px !important;
  margin-top:-1px;
}
/* The Figma 64px side padding assumed the frame's own wider cells. At the
   width this grid actually produces it costs more than the labels can spare,
   so the three-up row carries 48. */
.stat-row.three .stat-box {
  padding: 32px 48px;
  min-height: 248px;
}
.stat-fill {
  grid-row: 1 / -1;
  background: var(--bg-dark);
  background-image: var(--hatch-dark);
}
.stat-box .label {
  font-family: var(--font-mono);
  font-size: 20px;
  letter-spacing: 0;
  color: var(--on-dark);
  margin-bottom: 0;
}
/* The featured cell carries the larger label and the larger number. */
.stat-row:not(.three) .stat-box:first-child .label { font-size: 24px; }
/* The Figma sizes are 165px and 100px, and the number is sized to fit its own
   cell rather than the viewport.

   A vw term was the old proxy for cell width, and the two stopped agreeing.
   .results-inner caps at 1280, so the cells stop widening above about 1360
   while vw keeps climbing; the .stat-row.three padding also drops from 64 to
   32 below 1440, which widens the cell as vw narrows. The clamp sat at its
   100px max across the whole desktop range, and "60-100/wk" and "5m -> 20s"
   wrapped onto a second line at every width above 900.

   cqi is 1% of the cell's own content width, so the cell is measured directly.
   --stat-fit is the widest value's width per 1px of font-size: at 165px,
   "$140M+" is 165 * 2.77 wide. Dividing the cell by it gives the largest size
   that still sets on one line, and the clamp caps that at the Figma value.

   Set --stat-fit as an inline style in the page's HTML. Put it on .stat-row
   for a three-up row, so all three numbers share one size, and on the
   .stat-box for the two-up row, whose cells are meant to differ. Measure
   it the same way: render the string at 100px in --font-serif and divide its
   width by 100, then add about 2% of headroom. Recompute it when the copy
   changes.

   The clamp floors are 40 and 60, not the design's 60 and 84. A floor beats
   the fit term, so a floor set too high reintroduces the exact wrap it is
   there to prevent. The binding case is DocDraft's "60-100/wk" between 900
   and 1000, where the three-up cells fall to 176px of content width and the
   decorative .stat-fill column still takes 120px of the row. */
/* The container is .big-row, not .stat-box. Containment forces an independent
   formatting context, and a grid container with containment cannot be a
   subgrid -- Chrome computes grid-template-rows: subgrid to none. So the cell
   keeps the subgrid and the wrapper around the number carries the container.
   It is a block at the cell's content width, so cqi is unchanged. */
.big-row { container-type: inline-size; }
/* The next four lines are the row scheme, kept together on purpose: .label,
   .big-row and .sub each get a second rule further down for their own type and
   spacing. Read as one statement about row order, not as duplicates to merge. */
.stat-box .label { grid-row: 1; }
.stat-box .big-row { grid-row: 2; }
.stat-box .sub { grid-row: 4; }
.stat-box .big {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(40px, calc(100cqi / var(--stat-fit, 3.9)), 100px);
  line-height: 1;
  color: var(--accent);
}
.stat-box .big.white {
  font-size: clamp(60px, calc(100cqi / var(--stat-fit, 3.9)), 165px);
  color: var(--on-dark);
}
.big-row {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}
.stat-box .sub {
  font-size: 18px;
  color: var(--on-dark);
  margin-top: 0;
}
/* The design brackets the two lines in one pair of tall hairline parentheses,
   centred on the copy rather than sitting on its first baseline.

   The two demands fight each other: a paren set large enough to span both
   lines is also drawn four times as heavy as the one in the export. So the
   glyph keeps a modest size, which sets its stroke weight, and is stretched
   vertically to reach the height. scaleY leaves the horizontal stroke alone,
   which is what keeps it a hairline. The flex row does the centring, so the
   parens no longer ride the first line's baseline. */
/* .growth is a box, .growth-inner is the type. The split is what makes the
   note shrink instead of wrapping.

   .growth takes the space the number leaves -- flex: 1 1 0 against the 165px
   "900+" -- and declares itself a container. .growth-inner then sizes its type
   off that width in cqi, so the note is always as large as the leftover space
   allows and never wider than it. At 22px the whole assembly measures 10.98
   times the font size, so 100 / 10.98 = 9.11cqi fills the box exactly; 8.9
   keeps 2% of headroom. Every part is in em, so the brackets and the gaps
   follow the copy down. */
.stat-box .growth {
  container-type: inline-size;
  /* Shrink first, wrap second. The 160px basis is the point where the note
     stops getting smaller and drops to its own line under the number instead,
     where it has the whole cell and returns to full size. Without it the box
     kept shrinking to 45px and ran the copy to five lines. */
  flex: 1 1 160px;
}
.stat-box .growth-inner {
  display: flex;
  align-items: center;
  gap: 0.73em;
  font-family: var(--font-sans);
  font-size: clamp(12px, 8.9cqi, 22px);
  font-weight: 300;
  color: var(--on-dark);
  line-height: 1.25;
}
/* Both lines are centred between the brackets, not ragged right. */
.stat-box .growth .growth-copy { text-align: center; }
/* 1.6em sets the stroke weight; 2.05 sets the height. Measured off the design
   crop: the bracket stands about 1.4x the height of the two-line block it
   holds, and about 3.2x the copy's own font size. */
.stat-box .growth .paren {
  display: inline-block;
  flex: 0 0 auto;
  font-size: 1.6em;
  line-height: 1;
  transform: scaleY(2.05);
}

@media(max-width: 1120px) {
  .growth{
    margin-top: -40px;
  }
  .growth .growth-copy{
    font-size: 15px;
  }
  .growth .growth-inner span:nth-child(1){
    margin-left:auto;
  }
  .stat-box .growth .paren {
    font-size: 1.1em !important; 
  }
}

@media(max-width: 475px) {
  .growth{
    margin-top: -40px !important;
  }
  .growth .growth-copy{
    font-size: 13px;
  }
  .growth .growth-inner span:nth-child(1){
    margin-left:auto !important;
  }
  .stat-box .growth .paren {
    font-size: .8em !important; 
  }
}

@media (max-width: 1440px) {
  .stat-row.three .stat-box { padding: 32px; }
}

@media (max-width: 1240px) {
  .stat-row.three .stat-box .label { font-size: 16px; }
}

@media (max-width: 1200px) {
  .stat-row:not(.three) .stat-box:first-child .label { font-size: 20px; }
  .stat-box .label { font-size: 16px; }
  .stat-box .sub { font-size: 16px; }
}

@media (max-width: 900px) {
  /* Stacked, each cell is its own row of the grid, so the shared rows have to
       go: leaving them would stack all four cells on top of each other. Back to
       the bottom-packed flex column, where one cell per row makes the sub
       alignment moot. */
  .stat-row, .stat-row.three { grid-template-columns: 1fr; grid-template-rows: none; }
  .stat-box {
    grid-row: auto;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }
  .growth{
      margin-top: 0;

  }
  .growth .growth-inner span:nth-child(1){
    margin-left:0;
  }
  /* The desktop scale puts "+4-10%" onto two lines in a 309px cell. */
  .stat-box .big.white { font-size: 84px; }
  .stat-box .big { font-size: 60px; margin: 18px 0px; }
  .stat-row:not(.three) .stat-box:first-child .label { font-size: 15px; }
  /* .stat-box .label { font-size: 13px; letter-spacing: 0.04em; } */
  .stat-box .sub { font-size: 15px; }
  .stat-box,
  .stat-row.three .stat-box { padding: 32px 24px; min-height: 0; }
}


/* ---- Before / after compare table ---- */
/* ---- Before / after compare table (Results) ----
   Sizes measured off the Figma export, not estimated. The rows carry no
   separator: the only horizontal rule inside the table sits under
   BEFORE/AFTER (y=180 in the export). Rows butt flush against each other, so
   the per-row right border on the first cell still draws one unbroken centre
   divider.

   Line pitch measured 22.96px against an 18px face -- Geist's own default
   leading, so line-height is 1.28 rather than the 1.55 this used to carry.

   The design also centres the AFTER cell's content and adds 24px of side
   padding to it, which pushes its icon 81px in against BEFORE's 27px and
   leaves the AFTER heading out of line with its own body text. That is a slip
   in the file, not an intent, so both columns use the same 24px here. */
.compare-table {
  border: 1px solid var(--border-dark);
  max-width: var(--content-width);
  margin: 24px auto 0;
}
.compare-head { display: grid; grid-template-columns: 1fr 1fr; border-bottom: 1px solid var(--border-dark); }
.compare-head span {
  font-family: var(--font-mono);
  font-size: 24px;
  text-transform: uppercase;
  color: var(--paper);
  line-height: 1.28;
  padding: 32px 24px;
}
.compare-head span:first-child { border-right: 1px solid var(--border-dark); }
.compare-row { display: grid; grid-template-columns: 1fr 1fr; border-bottom: 1px solid var(--border-dark); }
.compare-cell { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-start; padding: 24px; }
.compare-cell:first-child { border-right: 1px solid var(--border-dark); }
.compare-row:last-child .compare-cell { padding-bottom: 36px; }
/* The stacked layout drops the BEFORE/AFTER head, so each cell carries its
   own label there. Hidden by default; the flex-basis keeps it on its own
   line above the icon and copy once it is shown. */
.compare-cell::before {
  content: attr(data-label);
  display: none;
  flex: 0 0 100%;
  margin: 0 0 -2px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(var(--paper-rgb), 0.5);
}
.compare-cell .icon { flex-shrink: 0; width: 20px; height: 20px; margin-top: 3px; }
.compare-cell.before .icon { color: var(--accent); }
.compare-cell.after .icon { color: var(--icon-success); }
.compare-cell p { margin: 0; flex: 1; min-width: 0; font-size: 18px; line-height: 1.4; color: var(--paper); }
.compare-cell strong { font-weight: 700; }

@media (max-width: 900px) {
  .compare-head { display: none; }
  .compare-row { grid-template-columns: 1fr; border-bottom: 1px solid var(--border-dark); }
  .compare-row:last-child { border-bottom: none; }
  .compare-cell::before { display: block; }
  .compare-cell { padding: 20px; }
  .compare-cell:first-child { border-right: none; }
  .compare-cell.before { padding-bottom: 10px; }
  .compare-cell.after { padding-top: 10px; }
  .compare-row:last-child .compare-cell.after { padding-bottom: 28px; }
  .compare-cell p { font-size: 16px; line-height: 1.4; }
  .compare-cell { padding: 18px 20px; }
  .compare-cell.before { padding-bottom: 10px; }
  .compare-cell.after { padding-top: 10px; }
}


/* ---- Impact (dark, 3-col) ---- */
/* ---- Impact (dark, 3-col) ----
   Figma node 429:153991. Three points about that frame drive the rules below.

   1. The eyebrow and "Impact" sit INSIDE the first column, not in a full
      width bar above the grid. The rule under them stops at x=425, and
      columns two and three run hatch all the way to y=0.
   2. The hatch bands are not one fixed height. Each column pads its copy with
      a different amount above and below, which is what staggers the three
      text blocks down the section. The Figma heights are 158/233, 229/220 and
      266/216. They are used here as ratios rather than as pixels, so the
      stagger survives any column height, and column two's has since been
      tuned by eye to 270/220.
   3. Every rule and every stripe in this section is --border-dark-accent, the
      desaturated blue, and the copy is full-strength --paper. The section used
      cream rules, --on-dark headings and muted 15.5px body copy, all of which
      the export contradicts.

   Columns one and three share the grid's rows (see below), so the copy in them
   sits at one height and one top edge. Column two staggers on its own. */
.impact-dark { background: var(--bg-dark); }
/* Four shared rows: head, top hatch, copy, bottom hatch.

   Columns one and three subgrid onto them. Column one puts .impact-head in row
   1 and column three leaves that row empty, so the head's real height -- which
   moves with the wrap and with the padding step at 1200px -- is added to both
   columns alike. Their copy then starts at the same y and shares one height at
   every width, with nothing measured.

   This is what the old --fill-top: 158 / 308 pair was hand-copying: the 150px
   between those two Figma numbers IS the design's head height. Written as
   fixed ratios it only held at one head height.

   The 158/233 ratio is column one's Figma top:bottom fill, now the ratio for
   the shared hatch rows. minmax keeps the old 90px floor on each band. */
.impact-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto minmax(90px, 158fr) auto minmax(90px, 233fr);
  max-width: var(--content-width);
  margin: 0 auto;
  /* The design column is 764px. A floor, not a fixed height: a long body at a
     narrow width grows past it. */
  min-height: 764px;
}

.impact-grid:last-child{
  border-right: 1px solid var(--border-dark-accent)
}

.impact-grid:last-child .top{
  border-top: 1px solid var(--border-dark-accent)
}

.impact-col {
  grid-row: 1 / -1;
  display: grid;
  grid-template-rows: subgrid;
  border-left: 1px solid var(--border-dark-accent);
}
/* .impact-col:first-child { border-left: none; } */
/* Every cell names its row. Auto-placement is not enough: column three has no
   head, and an auto-placed run starts at row 1, which put its copy in the head
   row. */
.impact-head { grid-row: 1; }
.impact-col > .impact-fill.top { grid-row: 2; }
.impact-col > .impact-col-body { grid-row: 3; }
.impact-col > .impact-fill.bottom { grid-row: 4; }
/* Column two is the stagger, so it stays out of the subgrid and flexes over
   the full height with its own ratio, 270/220. A ratio of free space needs no
   width-dependent correction. */
.impact-col:nth-child(2) {
  display: flex;
  flex-direction: column;
  --fill-top: 270;
  --fill-bottom: 220;
}
.impact-col:nth-child(2) .impact-fill { flex-basis: 0; }
.impact-col:nth-child(2) .impact-fill.top { flex-grow: var(--fill-top); }
.impact-col:nth-child(2) .impact-fill.bottom { flex-grow: var(--fill-bottom); }
.impact-col:nth-child(2) .impact-col-body { flex: 0 0 auto; padding:64px 32px;}
.impact-fill {
  min-height: 90px;
  background-image: var(--hatch-dark-accent);
}
/* Padding 32px and the 24px gap are the Figma values. The heading is Geist
   Mono SemiBold 20px in --accent-dark; the body is Geist 18px/1.6 in
   --paper. */
.impact-head {
  flex: 0 0 auto;
  padding: 32px;
  border-bottom: 1px solid var(--border-dark-accent);
}
.impact-head .section-label {
  color: var(--accent-dark);
  margin-bottom: 4px;
}
.impact-head h2 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 28px;
  color: var(--paper);
  margin: 0;
}
.impact-col-body {
  flex: 0 0 auto;
  padding: 32px;
  border-top: 1px solid var(--border-dark-accent);
  border-bottom: 1px solid var(--border-dark-accent);
}
.impact-col-body h4 {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 20px;
  line-height: 1.3;
  color: var(--accent-dark);
  margin: 0 0 24px;
}
.impact-col-body p {
  font-size: 18px;
  line-height: 1.6;
  color: var(--paper);
  margin: 0;
}

@media (max-width: 1200px) {
  /* Still a floor, just a lower one. Dropping it to 0 here let both fills in
       column one hit their 90px minimum, which flattened the stagger and left
       the section noticeably squatter than the sections around it. */
  .impact-grid { min-height: 600px; }
  .impact-head,
  .impact-col-body { padding: 24px; }
  .impact-col-body h4 { font-size: 17px; margin-bottom: 18px; }
  .impact-col-body p { font-size: 16px; }
}

@media (max-width: 900px) {
  /* Stacked, the staggered hatch loses its job: it exists to offset three
       columns against each other, and there is only one column now. Each fill
       drops to a flat 20px band so the section does not become a screen of
       stripes between paragraphs, and the bottom fill of every column but the
       last is dropped so two bands never meet back to back. */
  /* Stacked, every hatch band is the same 20px, so the gap between one content
       cell and the next is identical down the whole section. The cells
       themselves are held to one height by equalizeImpactCells, which together
       make the rhythm regular: cell, 20, cell, 20, cell.
       Flexible fills would defeat that -- each column would absorb a different
       amount of slack and the gaps would all differ. */
  .impact-grid { grid-template-columns: 1fr; grid-template-rows: none; min-height: 0; }
  /* Stacked, each column is its own flex block again: the shared rows only
       mean anything while the three sit side by side. */
  .impact-col {
      grid-row: auto;
      display: flex;
      flex-direction: column;
      border-left: none;
    }
  .impact-fill,
  /* Same specificity as the column-two rules above, which would otherwise keep
     their flex-basis 0 here and collapse that column's band to nothing. */
  .impact-col:nth-child(2) .impact-fill { flex: 0 0 20px; min-height: 0; }
  .impact-col:not(:last-child) .impact-fill.bottom { display: none; }
  .impact-col-body { padding: 48px 20px; }
  .impact-col:nth-child(2) .impact-col-body{ padding: 48px 20px; }
  .impact-head { padding: 28px 20px 24px; }
  .impact-col-body h4 { font-size: 16px; margin-bottom: 14px; }
  .impact-col-body p { font-size: 16px; }
}
