/* token-gate: allow --t-h3 */
/* token-gate: allow --t-card-body */
/* token-gate: allow --t-card-meta */
/* token-gate: allow --deep-blue */
/* token-gate: allow --charcoal */
/* token-gate: allow --blue-tint */
/* token-gate: allow --space-12 */
/* token-gate: allow --space-16 */
/* token-gate: allow --space-24 */
/* token-gate: allow --space-32 */
/* token-gate: allow --card-ring-rest */
/* token-gate: allow --card-ring-hover */
/* token-gate: allow --card-shadow-hover */
/* token-gate: allow --card-accent */
/* token-gate: allow --card-accent-w */
/* token-gate: allow --inner-light */
/* token-gate: allow --dur-base */
/* token-gate: allow --ease-card */

/*
  image-cards: ONE card in three styles (points, problems, services) on the shipped .ill-svc-card family.
  The image is the card's background: an img in .ill-svc-card__bg, a pale scrim above it (.ill-svc-card__scrim, its own element,
  because the card's ::before is the masked ring and its ::after the pointer spotlight), then the text (.ill-svc-card__body).
  Tilt, ring, shadow, spotlight, link wipe and arrow nudge come from theme.css; this file adds the background layers,
  the image zoom, the accent edge and the focus parity.
  Load order: this file is linked BEFORE theme.css, so every rule is scoped under .ill-ic (one extra class) to out-rank it.

  Two arrangements of the one card, chosen by viewport (the card width follows from it):
    TALL (a poster): the object sits top right, the text block starts below it, the scrim rises from the bottom.
         Every card below 768px; points and services from 1024px (three columns).
    WIDE: the text takes the left 57 percent, the object shows on the right.
         Problems from 768px (two columns from 1024px); points and services from 768px to 1023px (one column).
  The artwork is 1344 by 768: a small matte object in the upper right, plain pale ground to the left and below.
  The image box is sized from the CARD WIDTH (container units), never from the card height. A card that grows taller
  because its text is long would otherwise scale the artwork up with it and push the object under the text.

  Odd card counts (from 1024px, see "Odd card counts" below): a rule, not a field. The last row's cards take the WIDE arrangement,
  and a card that spans the whole row keeps its artwork at HALF-ROW size (--ic-half), so the artwork never grows with the row.

  Three additions, each scoped so a card or section that does not use them renders exactly as before:
    .ill-svc-card--dlg   a problems card that opens a pop-up (see "Problems that open a pop-up") and .ill-q-dlg, the pop-up itself.
    .ill-ic--frame       a section whose images are whole renders, shown above the text with nothing cropped (see "Frame").
    .ill-svc-card--band  the full-row last card of a frame section when band_source is recent_posts: a band of three pictures across its top (see "Band").
*/

/* ---- Arrangement switches ----
   --ic-cap      the tallest the image box gets (TALL: the card width, WIDE: the card width over 1.75, the artwork's own shape)
   --ic-bg-h     height of the image box (top right, full width): the card height up to the cap
   --ic-body-w   width of the text block        --ic-body-pad  its padding (TALL: the top clearance for the object)
   --ic-body-min its minimum height (WIDE: keeps a short card tall enough for the whole object)
   --ic-scrim    the scrim gradient (the pale colour is --blue-tint, rgb 234 243 250), TALL rising from the bottom, WIDE from the left
   --ic-bg-w     width of the image box (the card width; a card that spans a whole row sets it to half the row)
   --ic-wide-*   the WIDE values under names, so a card can take that arrangement at any width
   --ic-gap      the grid gap from 1024px          --ic-half  half a full row: the width of a two-up card */
.ill-ic {
  --ic-scrim-tall: linear-gradient(180deg, rgba(234, 243, 250, 0) 0, rgba(234, 243, 250, 0) 49cqw, rgba(234, 243, 250, 0.35) 54cqw, rgba(234, 243, 250, 0.8) 60cqw, rgba(234, 243, 250, 0.94) 66cqw, rgba(234, 243, 250, 0.94) 100%);
  --ic-scrim-wide: linear-gradient(90deg, rgba(234, 243, 250, 0.94) 0, rgba(234, 243, 250, 0.94) 46%, rgba(234, 243, 250, 0.6) 54%, rgba(234, 243, 250, 0) 66%);
  --ic-wide-cap: 57.2cqw;
  --ic-wide-body-w: 57%;
  --ic-wide-body-pad: var(--space-32) var(--space-24) var(--space-32) var(--space-32);
  --ic-wide-body-min: 33cqw;
  --ic-cap: 100cqw;
  --ic-bg-w: 100%;
  --ic-body-w: auto;
  --ic-body-pad: calc(50cqw + var(--space-16)) var(--space-24) var(--space-24);
  --ic-body-min: 0px;
  --ic-scrim: var(--ic-scrim-tall);
  --ic-fade: 0.68; /* where the artwork box starts to fade into the card ground, as a share of --ic-cap */
}

@media (min-width: 768px) {
  .ill-ic {
    --ic-cap: var(--ic-wide-cap);
    --ic-body-w: var(--ic-wide-body-w);
    --ic-body-pad: var(--ic-wide-body-pad);
    --ic-body-min: var(--ic-wide-body-min);
    --ic-scrim: var(--ic-scrim-wide);
  }
}

@media (min-width: 1024px) {
  .ill-ic {
    --ic-gap: var(--space-32);
    --ic-half: calc((100cqw - var(--ic-gap)) / 2);
  }

  .ill-ic--points,
  .ill-ic--services {
    --ic-cap: 100cqw;
    --ic-body-w: auto;
    --ic-body-pad: calc(50cqw + var(--space-16)) var(--space-24) var(--space-24);
    --ic-body-min: 0px;
    --ic-scrim: var(--ic-scrim-tall);
  }
}

/* ---- Grids ---- */
.ill-ic .ill-svc-grid {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
}

@media (min-width: 768px) {
  .ill-ic--problems .ill-svc-grid { grid-auto-rows: 1fr; }
}

/* The 3-column styles are built on six columns and each card spans two: the same third of the row as three columns, and the
   last row can then be shared out (see "Odd card counts"). */
@media (min-width: 1024px) {
  .ill-ic .ill-svc-grid { gap: var(--ic-gap); }
  .ill-ic--problems .ill-svc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ill-ic--points .ill-svc-grid,
  .ill-ic--services .ill-svc-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .ill-ic--points .ill-svc-card,
  .ill-ic--services .ill-svc-card { grid-column: span 2; }
}

/* The Why page's question cards: a problems section that carries pop-ups (.ill-svc-card--dlg). The Knowledge Hub's cards carry none, so that section
   keeps the grid above. Two columns from 768px (the middle range is not one long column), three from 1200px (six cards in two rows, not three).
   Below 768px the grid stays one column. :has needs @supports, as the frame rules below do; without it the section keeps the grid it had. */
@supports selector(:has(*)) {
  @media (min-width: 768px) {
    .ill-ic--problems.ill-ic--frame:has(.ill-svc-card--dlg) .ill-svc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }

  @media (min-width: 1200px) {
    .ill-ic--problems.ill-ic--frame:has(.ill-svc-card--dlg) .ill-svc-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  }
}

/* ---- Odd card counts (from 1024px; below that every style is one column, so there is no short row) ----
   A rule, not a field: nothing for an editor to choose or forget.
   Problems (two columns): a last card that is alone in its row spans the row.
   Points and services (three cards a row): the last row is shared out.
     one card left over  -> it spans the row (all six columns)
     two cards left over -> each takes half the row (three columns each)
   A card wider than a third takes the WIDE arrangement. Its artwork box is HALF A ROW wide whatever the card's own width, top right,
   so the object keeps the size it has in a two-up card; the card height still comes from its text (and, in problems, from the
   equal-height rows), so nothing here is derived from the full row width. A card that spans the row keeps its text column to
   the left half of the row, at most 34rem (70 characters a line at most, measured), so a paragraph never runs the length of the row. Its scrim is
   anchored to the artwork box instead of the card edge and is solid at the box's left edge, so the box leaves no seam on the card. */
@media (min-width: 1024px) {
  .ill-ic--problems .ill-svc-card:last-child:nth-child(odd),
  .ill-ic--points .ill-svc-card:last-child:nth-child(3n + 1),
  .ill-ic--services .ill-svc-card:last-child:nth-child(3n + 1) {
    grid-column: 1 / -1;
    --ic-cap: calc(var(--ic-half) * 0.572);
    --ic-bg-w: var(--ic-half);
    --ic-body-w: min(var(--ic-half), 34rem);
    --ic-body-pad: var(--ic-wide-body-pad);
    --ic-body-min: calc(var(--ic-half) * 0.33);
    --ic-scrim: linear-gradient(90deg, rgb(234, 243, 250) 0, rgb(234, 243, 250) calc(100cqw - var(--ic-half) * 0.54), rgba(234, 243, 250, 0.6) calc(100cqw - var(--ic-half) * 0.46), rgba(234, 243, 250, 0) calc(100cqw - var(--ic-half) * 0.34));
  }

  .ill-ic--points .ill-svc-card:nth-last-child(2):nth-child(3n + 1),
  .ill-ic--points .ill-svc-card:last-child:nth-child(3n + 2),
  .ill-ic--services .ill-svc-card:nth-last-child(2):nth-child(3n + 1),
  .ill-ic--services .ill-svc-card:last-child:nth-child(3n + 2) {
    grid-column: span 3;
    --ic-cap: var(--ic-wide-cap);
    --ic-body-w: var(--ic-wide-body-w);
    --ic-body-pad: var(--ic-wide-body-pad);
    --ic-body-min: var(--ic-wide-body-min);
    --ic-scrim: var(--ic-scrim-wide);
  }
}

/* token-gate: allow --rx */
/* token-gate: allow --ry */
/* A card that spans the row is twice as wide as a two-up card, so the same tilt angle swings its far edge twice as far in depth and it
   reads as a trapezoid. Half the angle gives it the apparent tilt of a two-up card. --rx and --ry are written by gsap-init.js on pointer
   move; theme.css restates the tilt transform at the .is-in-view specificity, so this does too. */
@media (min-width: 1024px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .ill-ic--problems .ill-svc-card:last-child:nth-child(odd)[data-tilt].is-in-view,
  .ill-ic--points .ill-svc-card:last-child:nth-child(3n + 1)[data-tilt].is-in-view,
  .ill-ic--services .ill-svc-card:last-child:nth-child(3n + 1)[data-tilt].is-in-view {
    transform: rotateX(calc(var(--ry, 0deg) * 0.5)) rotateY(calc(var(--rx, 0deg) * 0.5));
  }
}

/* The WIDE cards are two to three times as wide as the 3-up ones, so at theme.css's 1200px perspective the far edge swings
   twice as far in depth and the card reads as a trapezoid. A deeper perspective gives the same apparent tilt. */
@media (min-width: 768px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .ill-ic--problems .ill-svc-grid { perspective: 2000px; }
}

@media (min-width: 768px) and (max-width: 1023px) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .ill-ic--points .ill-svc-grid,
  .ill-ic--services .ill-svc-grid { perspective: 2000px; }
}

/* ---- The card ----
   A container (inline-size) so the layers can be sized from the card's own width. White ground (the --white token; Owner, 2026-10-14: every image card on the Why and Knowledge Hub pages): an image still loading
   shows a white box, as the card itself is white. Overflow is clipped, so the image zoom stays inside the radius.
   isolation: isolate gives the card its OWN stacking context, whatever its transform. The artwork and the scrim sit at z-index -1 inside the
   card, so they paint above the card's ground and below its text; a negative z-index stays inside the card only if the card is a
   stacking context. A container is not one (measured on dev: contain computes to none, and the artwork painted behind the card's ground).
   What made the card one was the tilt rule's transform, and theme.css applies that only with hover: hover, a fine pointer and no
   reduced-motion preference. Under reduced motion and on a touch phone there was no stacking context and no artwork. The card is already
   overflow:hidden, which already flattens transform-style, so this changes neither the tilt nor the ring. */
.ill-ic .ill-svc-card.ill-svc-card--bg {
  padding: 0;
  gap: 0;
  overflow: hidden;
  container-type: inline-size;
  isolation: isolate;
  background: var(--white);
}

/* Points are not links, so no pointer. */
.ill-ic--points .ill-svc-card--bg { cursor: default; }

/* ---- Layers: image, then scrim, both behind the text.
   theme.css gives every direct child of the card position:relative and z-index:1 (to sit above the pointer spotlight), so these
   three direct children restate theirs. The card is isolated (above), so it is its own stacking context and z-index -1 stays inside it. ---- */
.ill-ic .ill-svc-card--bg > .ill-svc-card__bg {
  position: absolute;
  top: 0;
  right: 0;
  z-index: -1;
  display: block;
  width: var(--ic-bg-w);
  height: min(100%, var(--ic-cap));
  /* where a tall card leaves the box shorter than the card, the artwork fades into the pale ground over the last third of the cap,
     so there is no seam. A short card (box shorter than two thirds of the cap) is not faded at all: the object keeps every pixel. */
  -webkit-mask-image: linear-gradient(180deg, #000 calc(var(--ic-cap) * var(--ic-fade)), transparent var(--ic-cap));
  mask-image: linear-gradient(180deg, #000 calc(var(--ic-cap) * var(--ic-fade)), transparent var(--ic-cap));
}

.ill-ic .ill-svc-card__bg img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 100% 0;
  transform-origin: 78% 28%; /* the zoom grows around the object, so it never leaves the card edge */
}

.ill-ic .ill-svc-card--bg > .ill-svc-card__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  background: var(--ic-scrim);
  box-shadow: var(--card-ring-rest); /* the resting hairline, drawn above the image (the card's own inset ring sits under it) */
}

/* The accent edge and the hover ring, also above the image: opacity only. */
.ill-ic .ill-svc-card__scrim::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset var(--card-accent-w) 0 0 0 var(--card-accent), var(--card-ring-hover);
  opacity: 0;
}

/* ---- The text block ---- */
.ill-ic .ill-svc-card--bg > .ill-svc-card__body {
  position: static;
  z-index: auto;
  box-sizing: border-box;
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  align-self: flex-start;
  gap: var(--space-12);
  width: var(--ic-body-w);
  min-height: var(--ic-body-min);
  padding: var(--ic-body-pad);
}

/* The children sit above the spotlight. They are flex items, so z-index works without position, and the stretched link
   (below) keeps the card as its containing block. */
.ill-ic .ill-svc-card__body > * {
  z-index: 1;
  margin: 0;
}

/* ---- One type ladder: title --t-h3, body --t-card-body, meta and link --t-card-meta.
   Three classes: theme.css loads after this file and sets .ill-svc-card--module .ill-svc-card__title to 20px with two. ---- */
.ill-ic .ill-svc-card .ill-svc-card__title {
  font-size: var(--t-h3);
  line-height: 1.2;
  color: var(--deep-blue);
  text-wrap: balance;
}

.ill-ic .ill-svc-card .ill-svc-card__desc,
.ill-ic .ill-svc-card .ill-svc-card__handle,
.ill-ic .ill-svc-card .ill-svc-card__covers {
  font-size: var(--t-card-body);
  line-height: 1.55;
  color: var(--charcoal);
  text-wrap: pretty; /* no one-word last line on the narrow cards */
}

/* How we handle it: emphasis by weight and colour, no label. */
.ill-ic .ill-svc-card .ill-svc-card__handle {
  font-weight: 600;
  color: var(--deep-blue);
}

.ill-ic .ill-svc-card__covers b { font-weight: 700; }

/* The route link: meta size, deep blue, at the foot of the text block. A block, not theme.css's inline-flex, with the arrow set inline
   after the last word, so a wrapped label keeps the arrow with its last word. */
.ill-ic .ill-svc-card .ill-svc-card__link {
  display: block;
  align-self: flex-start;
  margin-top: auto;
  padding-top: var(--space-12);
  font-size: var(--t-card-meta);
  line-height: 1.4;
}

.ill-ic .ill-svc-card__link svg {
  display: inline-block;
  vertical-align: -2px;
  margin-left: 6px;
}

/* The last word and the arrow are one unit, so the arrow can never wrap onto a line of its own. */
.ill-ic .ill-svc-card__link-end { white-space: nowrap; }

/* ---- The card is a div; the label link is stretched over it ----
   The link's ::after covers the whole card (the card is position:relative in theme.css and the link is not positioned).
   theme.css a:hover turns a link mid-blue (3.20:1 on a pale ground) and underlines it: the label keeps its deep blue, and only the
   shipped wipe underline shows. */
.ill-ic .ill-svc-card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

.ill-ic .ill-svc-card__link:hover {
  color: var(--deep-blue);
  text-decoration: none;
}

/* ---- Hover (a fine pointer, or any hover-capable device): the accent edge and the ring. A static change, so reduced motion keeps it. ---- */
@media (hover: hover) {
  .ill-ic .ill-svc-card--bg:hover .ill-svc-card__scrim::after { opacity: 1; }
}

/* ---- Motion: transform and opacity only. Reduced motion and touch get none of it. ---- */
@media (prefers-reduced-motion: no-preference) {
  .ill-ic .ill-svc-card__scrim::after { transition: opacity var(--dur-base) ease; }
  .ill-ic .ill-svc-card__bg img { transition: transform var(--dur-base) var(--ease-card); }
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .ill-ic .ill-svc-card--bg:hover .ill-svc-card__bg img { transform: scale(1.06); }
}

/* ---- Keyboard focus ----
   The ring goes round the whole card, and the card takes the same non-motion parts as hover: accent edge, mid-blue ring, shadow, link underline.
   No tilt (the tilt is pointer-driven JS). The image zoom is allowed when motion is.
   Browsers without :has() keep the shipped ring on the link label. */
@supports selector(:has(*)) {
  .ill-ic .ill-svc-card__link:focus-visible { outline: none; }

  .ill-ic .ill-svc-card--bg:has(.ill-svc-card__link:focus-visible) {
    outline: 2px solid var(--deep-blue);
    outline-offset: 3px;
    box-shadow: inset var(--card-accent-w) 0 0 0 var(--card-accent), var(--inner-light), var(--card-ring-hover), var(--card-shadow-hover);
  }

  .ill-ic .ill-svc-card--bg:has(.ill-svc-card__link:focus-visible)::before,
  .ill-ic .ill-svc-card--bg:has(.ill-svc-card__link:focus-visible) .ill-svc-card__scrim::after { opacity: 1; }

  .ill-ic .ill-svc-card--bg:has(.ill-svc-card__link:focus-visible) .ill-svc-card__link { background-size: 100% 2px; }
}

@supports selector(:has(*)) {
  @media (prefers-reduced-motion: no-preference) {
    .ill-ic .ill-svc-card--bg:has(.ill-svc-card__link:focus-visible) .ill-svc-card__bg img { transform: scale(1.06); }
  }
}

/* token-gate: allow --blue-tint */
/* token-gate: allow --card-ring-rest */
/* token-gate: allow --card-shadow-rest */
/* token-gate: allow --deep-blue */
/* token-gate: allow --font-heading */
/* token-gate: allow --hairline */
/* token-gate: allow --muted */
/* token-gate: allow --radius-md */
/* token-gate: allow --radius-sm */
/* token-gate: allow --space-8 */
/* token-gate: allow --space-12 */
/* token-gate: allow --space-16 */
/* token-gate: allow --space-24 */
/* token-gate: allow --space-40 */
/* token-gate: allow --t-card-body */
/* token-gate: allow --t-card-meta */
/* token-gate: allow --t-h3 */
/* token-gate: allow --white */

/* ---- Frame (art_fit = frame): a section whose images are whole renders ----
   The three service renders are whole scenes (1344 by 768, the subject in the middle, a pale ground of their own), not an object in a corner.
   The corner arrangement crops the box to a square and starts the text under its top half: that would cut the sides of a centred subject and
   put its lower half under the text, and object-position cannot fix either (the image is already as tall as the box). So here the box is exactly
   the render's own shape, nothing is cropped, and the text starts under it, at every width.
   This block comes after the arrangement switches above and has the same specificity, so it wins at 768px and 1024px too.
   The last tenth of the box fades into the card ground, so a render whose floor is darker than the card leaves no seam.
   The text then sits on the plain card ground, so the scrim has no job here. */
.ill-ic--frame {
  --ic-cap: calc(100cqw / 1.75);
  --ic-bg-w: 100%;
  --ic-body-w: auto;
  --ic-body-pad: calc(100cqw / 1.75 + var(--space-12)) var(--space-24) var(--space-24);
  --ic-body-min: 0px;
  --ic-fade: 0.9;
  --ic-scrim: none;
}

/* One column wide enough to run a line the length of the row (768px to 1023px): keep the text to a readable measure. */
@media (min-width: 768px) {
  .ill-ic--frame { --ic-body-w: min(100%, 38rem); }
}

.ill-ic--frame .ill-svc-card__bg img {
  object-position: 50% 50%;
  transform-origin: 50% 50%; /* the zoom grows around the middle, where the subject is */
}

/* A set can mix cards with and without a render (the Knowledge Hub page does), or have none at all (the Why page's summary and problem cards carry no artwork until an
   image is made for each one). Rows are as tall as their own content, not equal: the problems grid makes every row as tall as the tallest, so an imageless card in the
   last row stretched to the height of a card with a render above its text. */
@media (min-width: 768px) {
  .ill-ic--frame .ill-svc-grid { grid-auto-rows: auto; }
}

/* A card with no picture (module.html adds ill-svc-card--noart to it: it prints no picture and no band) reserves nothing for one, at any width and at any card count:
   the text starts at the card's own top padding (--space-32), the body has no minimum height, and no scrim is drawn (the scrim ELEMENT stays: it carries the resting hairline,
   the accent edge and the hover ring). The odd-count rules were written for a card with an object in its corner: left alone they give the last card a minimum height for
   that object, a gradient over nothing, and (when two cards share the last row) a text column of 57 percent with the rest left empty. This rule carries more specificity
   than they do, so source order does not decide it; the class is added by module.html, so it does not depend on :has(). */
.ill-ic.ill-ic--frame .ill-svc-card.ill-svc-card--bg.ill-svc-card--noart {
  --ic-body-w: inherit; /* back to the section's value: the whole card, at most 38rem from 768px */
  --ic-body-pad: var(--ic-wide-body-pad);
  --ic-body-min: 0px;
  --ic-scrim: none;
}

/* The one exception is the measure: a card that spans the whole row (from 1024px) keeps its text column to the left half of the row, at most 34rem, so a paragraph never
   runs the length of the row (70 characters a line at most, as in the odd-count rule). */
@media (min-width: 1024px) {
  .ill-ic.ill-ic--frame.ill-ic--problems .ill-svc-card--noart:last-child:nth-child(odd),
  .ill-ic.ill-ic--frame.ill-ic--points .ill-svc-card--noart:last-child:nth-child(3n + 1),
  .ill-ic.ill-ic--frame.ill-ic--services .ill-svc-card--noart:last-child:nth-child(3n + 1) {
    --ic-body-w: min(var(--ic-half), 34rem);
  }
}

/* token-gate: allow --space-8 */
/* token-gate: allow --space-12 */
/* token-gate: allow --space-24 */
/* ---- Band (band_source = recent_posts): the full-row last card of a frame section ----
   The odd-count rule gives that card the half-row artwork box, top right, with the text to its left: not the frame arrangement, and with nothing to show
   there it keeps the height of its neighbours over a large empty pale area. A band replaces it: the three newest posts' featured images side by side, edge to
   edge across the top of the card (the card's radius and overflow clip the corners), the text and link below, as in the other frame cards.
   Each cell is the render's own 1.75:1 shape, so nothing is cropped and the cells are equal. The band is IN FLOW (the card is a flex column), so the text follows it
   whatever the cell height is, and a blog with fewer than three posts (one or two cells, see module.html) needs no other rule. Below 1024px the card is one column
   like every other card and the three cells stay in one row.
   The zoom, hover edge, focus and reduced-motion rules above select .ill-svc-card__bg img, so they reach the cells; the zoom is per cell because each cell clips its
   own picture. The band is a layer like the single image (z-index -1, under the spotlight and the stretched link), so the whole card is still one link. */
/* token-gate: allow --blue-tint */
/* token-gate: allow --space-8 */
.ill-ic .ill-svc-card--bg > .ill-svc-card__bg.ill-svc-card__bg--band {
  position: relative;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: var(--space-8);
  /* The gutter's own ground (Owner, 2026-10-14: "tint the gutter"). The pictures are opaque and edge to edge, so this shows in the gaps only. The card is white and the first
     two renders end in near-white (rgb 253 and 254 at their shared edge), so on a white gutter the gap is 2 RGB units wide of nothing (1.017:1, measured at 1440 and 390 and
     unchanged by gap widths of 16 to 48px); on the tint it is 20 (1.114:1). The card ground is not touched. The band's mask fades this out with the pictures. */
  background: var(--blue-tint);
  width: 100%;
  height: auto;
  -webkit-mask-image: linear-gradient(180deg, #000 90%, transparent);
  mask-image: linear-gradient(180deg, #000 90%, transparent);
}

.ill-ic .ill-svc-card__cell {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 7 / 4;
}

/* More specific than the odd-count rule (which sets the half-row box, the 34rem column and the wide padding) and later in the file: the text starts under the band. */
.ill-ic.ill-ic--frame .ill-svc-card.ill-svc-card--bg.ill-svc-card--band {
  --ic-body-pad: var(--space-12) var(--space-24) var(--space-24);
  --ic-body-min: 0px;
  --ic-scrim: none;
}

/* ---- Odd card counts in a frame section (from 1024px) ----
   The odd-count rules above were written for the corner arrangement: a last-row card puts its text on a scrim over the artwork box. In a frame section that
   cut the render to the card's height (measured on dev: a 592 by 227 box, 2.6 to 1, and 3 to 1 for a points card, where the render is 1.75 to 1), veiled the
   left of the subject with the scrim and ran the text over it. Two rules, scoped under the frame class and to a card that has artwork (:has needs @supports, as above;
   a card with no render keeps the odd-count rule's own arrangement). They carry more specificity than the odd-count rules, so source order does not decide it.
     two cards left over (points, services: half a row each): the frame arrangement, the whole render across the top at the card's own width, the text beneath.
       Each variable is taken back from the section (inherit), which holds the frame values.
     one card left over (it spans the row): the render at HALF A ROW, 1.75 to 1, top right, the text column to its left (the odd-count rule's own geometry), no scrim,
       and the card at least as tall as the render, so the box is never cut shorter than the render.
   A card with a band (.ill-svc-card--band) is left to the band rule. */
@media (min-width: 1024px) {
  @supports selector(:has(*)) {
    .ill-ic--frame.ill-ic--points .ill-svc-card:nth-last-child(2):nth-child(3n + 1):has(> .ill-svc-card__bg),
    .ill-ic--frame.ill-ic--points .ill-svc-card:last-child:nth-child(3n + 2):has(> .ill-svc-card__bg),
    .ill-ic--frame.ill-ic--services .ill-svc-card:nth-last-child(2):nth-child(3n + 1):has(> .ill-svc-card__bg),
    .ill-ic--frame.ill-ic--services .ill-svc-card:last-child:nth-child(3n + 2):has(> .ill-svc-card__bg) {
      --ic-cap: inherit;
      --ic-bg-w: inherit;
      --ic-body-w: inherit;
      --ic-body-pad: inherit;
      --ic-body-min: inherit;
      --ic-scrim: inherit;
    }

    .ill-ic--frame.ill-ic--problems .ill-svc-card:last-child:nth-child(odd):not(.ill-svc-card--band):has(> .ill-svc-card__bg),
    .ill-ic--frame.ill-ic--points .ill-svc-card:last-child:nth-child(3n + 1):not(.ill-svc-card--band):has(> .ill-svc-card__bg),
    .ill-ic--frame.ill-ic--services .ill-svc-card:last-child:nth-child(3n + 1):not(.ill-svc-card--band):has(> .ill-svc-card__bg) {
      --ic-cap: calc(var(--ic-half) / 1.75);
      --ic-body-min: calc(var(--ic-half) / 1.75);
      --ic-scrim: none;
    }
  }
}

/* ---- Problems that open a pop-up (.ill-svc-card--dlg) ----
   The whole card is the opener of its pop-up: the stretched link is the cue ("How we solve it" and a chevron). It points to #SLUG-detail and carries
   no data-route and no data-problem: opening a dialog is not a route. The route lives on the dialog's primary action. js/diff-dialog.js opens the
   dialog on click and on Enter; without script the link still goes to #SLUG-detail and theme.css shows that dialog (:target).
   The chevron points down and nudges down; the arrow of a link to another page points right and nudges right. */
.ill-ic .ill-svc-card--dlg .ill-svc-card__link { touch-action: manipulation; }

.ill-ic .ill-svc-card--dlg:hover .ill-svc-card__link svg { transform: none; }

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .ill-ic .ill-svc-card--dlg:hover .ill-svc-card__link svg { transform: translateY(3px); }
}

/* ---- The pop-up (.ill-q-dlg) ----
   One dialog per problem card, rendered after the section; js/diff-dialog.js moves it to the body, sets role="dialog" and aria-modal, and drives it.
   Text only: the card carries the artwork. The shipped detail dialog in theme.css (.ill-quote-modal--detail, .ill-pkg-modal__*, .ill-pkg__*) is shared with
   the Packages pages and is not touched; every override below is scoped under .ill-q-dlg and carries one more class than the shipped rule it replaces
   (this file loads before theme.css, so a tie would lose).
   Layout, top to bottom in three bands. Top bar: the question the reader clicked, the Close chip, one hairline under it. Body (the part that scrolls, the
   region the script focuses): the answer heading, the three steps, what changes, an optional proof line. Foot: the primary action (the route to the service)
   and Previous and Next, one hairline above, never scrolled away.
   From 900px the panel is 960px wide and the body is two columns with a 40px gutter and one vertical hairline: on the left (5 of 12) the heading, what changes
   and the proof strip at the foot of the column; on the right (7 of 12) the steps, one row each, ruled apart. From 600px to 899px it is one column in a
   640px panel. Under 600px it is a sheet: one column, the primary action across the width, Previous and Next on one row under it.
   The shipped text rule caps a step at 32em, which left a dead strip on the right of the panel; that cap is lifted here, so a step uses its whole column. */
.ill-q-dlg {
  --q-pad: var(--space-24);   /* the dialog's side padding */
  --q-chip: 72px;             /* the Close chip's width */
  --q-edge: var(--space-16);  /* the Close chip's distance from the panel's right edge: 16px on the sheet, where the question needs the width */
}

/* token-gate: allow --space-16 */
/* token-gate: allow --space-40 */
@media (min-width: 600px) {
  .ill-q-dlg { --q-edge: var(--q-pad); }  /* from 600px the chip sits on the content edge */
}

@media (min-width: 768px) {
  .ill-q-dlg { --q-pad: var(--space-40); }
}

/* The shipped root pads 24px and the shipped panel is 16px shorter than the viewport on a phone, so the pair overflows; 8px each side makes them agree. */
@media (max-width: 767px) {
  .ill-q-dlg.ill-quote-modal { padding: var(--space-8); }
}

.ill-q-dlg.ill-quote-modal--detail .ill-quote-modal__panel { max-width: 640px; padding: 0; }

@media (min-width: 900px) {
  .ill-q-dlg.ill-quote-modal--detail .ill-quote-modal__panel { max-width: 960px; }
}

/* One panel height for all six pop-ups, so the footer and the panel do not move when Next steps from one question to the next (the panel was as tall as its own content and the pop-up is centred, so the panel
   height varied by up to 94px and the foot jumped by up to 47px). The height of a band is that of the TALLEST pop-up in it, rounded up to a whole pixel; a shorter pop-up keeps the spare height as
   space above the foot, and the shipped max-height still caps the panel to the window. If the copy grows past it the body scrolls (it is already a scrolling, focusable region), so nothing is cut;
   raise the number for that band and run tests\why-cards\panel.cjs again (its bodyScroll column must read "no"). The tallest is pop-up 2 at every width measured: the only one with a proof line.
   Measured on dev on 2026-10-27: the natural height of each pop-up (panel height auto, window 1200px high, Chromium with a 15px page scrollbar) at 50 widths from 320px to 1920px. The heading type is
   fluid up to about 1200px (--t-h2, --t-h3), so a pop-up grows as the window widens, and the tallest point of a band is not always where the band starts:
     600 to 639px    710px   709.03 at 600 (688.73 from 605 to 635, 663.94 from 639): the panel is under 640px wide here
     640 to 899px    669px   668.95 at 899 (663.94 from 640 to 720, 665.27 at 800)
     900 to 939px    552px   550.78 at 939 (547.84 at 900): the earlier value, which still clears it by 1.2px, so it stays
     940px and up    569px   568.56 from 1199px up (550.84 at 940, 557.12 at 1024, 566.56 at 1150)
   Phones (under 600px) take the window height up to 826px: with the phone spacing below, the tallest pop-up is 825.09px at 390 and at 412 (889.09px before the spacing), 775.72 at 430, 874.69 at 375,
   919.78 at 360 and 1011.27 at 320. So a 390 by 844 window holds all six (the panel is 826px of the 828px it could be), and on a narrower phone the longest pop-up scrolls its body, as it does on
   any phone window shorter than it, except that under 842px high the tight spacing below applies: a 375 by 812 window then holds all six, and 375 by 667, 360 by 740 and 360 by 800 still scroll
   pop-up 2 (by 135, 86 and 26px, measured on dev on 2026-10-28 with this stylesheet served).
   Short windows: from 768px the shipped max-height is 92% of the window (662.4px at 720px high) and under 768px it is the window less 16px (704px at 720px high), so at 720px high pop-up 2 still
   scrolls its body by 1px at 768px wide, 2px at 800px, 6px at 899px, and by 5px at 600, 601 and 603px; from 728px high up it does not at 768 to 899px. */
.ill-q-dlg { --q-panel-h: min(826px, calc(100dvh - 16px)); }

@media (min-width: 600px) {
  .ill-q-dlg { --q-panel-h: 710px; }
}

@media (min-width: 640px) {
  .ill-q-dlg { --q-panel-h: 669px; }
}

@media (min-width: 900px) {
  .ill-q-dlg { --q-panel-h: 552px; }
}

@media (min-width: 940px) {
  .ill-q-dlg { --q-panel-h: 569px; }
}

.ill-q-dlg.ill-quote-modal--detail .ill-quote-modal__panel { height: var(--q-panel-h); }

/* Close: a solid white chip with a fixed width, so the question beside it can clear it exactly. Plain deep blue on white, a blue tint on hover.
   From 600px its right edge sits on the content edge (the side padding), so it lines up with the right edge of the body; on the sheet it is 16px from the panel edge. */
.ill-q-dlg .ill-quote-modal__close {
  z-index: 2;
  right: var(--q-edge);
  width: var(--q-chip);
  padding: 0;
  background-color: var(--white);
  border-radius: var(--radius-md);
  box-shadow: var(--card-ring-rest), var(--card-shadow-rest);
  font-size: var(--t-card-meta);
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
}

.ill-q-dlg .ill-quote-modal__close:hover { background-color: var(--blue-tint); color: var(--deep-blue); }

/* Top bar: the question the reader clicked, beside the Close chip, with one hairline under the pair. */
/* token-gate: allow --space-16 */
/* token-gate: allow --space-12 */
/* token-gate: allow --space-24 */
/* token-gate: allow --hairline */
/* token-gate: allow --t-card-body */
/* token-gate: allow --muted */
.ill-q-dlg .ill-pkg-modal__head { display: block; flex: 0 0 auto; padding: var(--space-16) var(--q-pad); border-bottom: 1px solid var(--hairline); }

/* token-gate: allow --space-12 */
.ill-q-kicker {
  display: flex;
  align-items: center;
  min-height: 44px;
  text-wrap: pretty;
  margin: 0 calc(var(--q-edge) + var(--q-chip) + var(--space-12) - var(--q-pad)) 0 0;
  font-size: var(--t-card-body);
  line-height: 1.35;
  color: var(--muted);
}

/* The body scrolls, so every band of it carries its own padding. The heading is the first thing in it, and it labels the region. */
.ill-q-dlg.ill-quote-modal--detail .ill-pkg-modal__body { padding: var(--space-24) var(--q-pad); }

.ill-q-dlg.ill-quote-modal--detail .ill-quote-modal__title { margin: 0 0 var(--space-24); }

/* Blocks: one column. The shipped hairline above each block and the shipped top padding go; the spacing between blocks is the row gap. */
.ill-q-dlg.ill-quote-modal--detail .ill-pkg__blocks { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-24); }

.ill-q-dlg .ill-pkg__block { padding-top: 0; border-top: 0; }

/* Labels in sentence case, 14px and 600: --muted on white is 5.55:1. */
.ill-q-dlg .ill-pkg__label {
  margin-bottom: var(--space-8);
  font-size: var(--t-card-meta);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
}

/* token-gate: allow --t-card-body */
/* max-width: none lifts the shipped 32em cap (512px at 16px), which stopped the text 128px short of the panel's right padding. text-wrap: pretty keeps a last line from being one word. */
.ill-q-dlg .ill-pkg__text { max-width: none; font-size: var(--t-card-body); line-height: 1.55; text-wrap: pretty; }

/* The three steps are a real sequence, so they are numbered. The shipped list resets list-style, so the number is drawn here (Oswald, deep blue).
   One hairline between one row and the next, none above the first: the shipped rule is kept for the rows after the first and its first-row reset is repeated one class stronger.
   The numeral is a DISPLAY numeral (Owner, 2026-10-14, option B) hung from the CAP LINE of the first line of its step, not set on its baseline: it is baseline-aligned in the grid, so
   it follows the first line of the text whatever the length of the step, and is then dropped by whole pixels so that the top of the digit meets the cap line of the 16px text. The
   numeral therefore overhangs the text baseline by that drop (4px at 390 up to 8px at 1440); that overhang is the design.
   Whole pixels, because both baselines snap to the pixel grid and a fractional drop makes them snap apart by a pixel in some rows. The drop is the digit height at --t-h3 less the cap
   height of the text (Oswald 600 digit 0.8203125em, the mean of the flat 1, 4, 7 at 0.8125 and the round digits at 0.828125; DM Sans cap 0.703125em), rounded to a pixel; the font size is then
   the one for which that drop is exact, (drop + cap) / digit, which is within 0.6px of --t-h3 at every width. line-height: 0 keeps the larger numeral out of the row height and out
   of the shared baseline. A browser without round() drops the two declarations that use it and shows the numeral at the body size on the shared baseline.
   Measured by tests\why-cards\steps.cjs: the numeral top and the cap line of the first capital agree within one device pixel (0.33px) in all six dialogs at 1440, 1024, 768 and 390. */
.ill-q-dlg .ill-q-steps { counter-reset: q-step; }

/* token-gate: allow --space-12 */
/* token-gate: allow --hairline */
.ill-q-dlg .ill-q-steps li {
  counter-increment: q-step;
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  align-items: baseline;
  padding: var(--space-12) 0;
  border-top: 1px solid var(--hairline);
}

.ill-q-dlg .ill-q-steps li:first-child { padding-top: 0; border-top: 0; }

.ill-q-dlg .ill-q-steps li::before {
  --q-drop: round(0.8203125 * var(--t-h3) - 0.703125 * var(--t-card-body), 1px);
  content: counter(q-step);
  position: relative;
  top: var(--q-drop);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: calc((var(--q-drop) + 0.703125 * var(--t-card-body)) / 0.8203125);
  line-height: 0;
  font-variant-numeric: tabular-nums;
  color: var(--deep-blue);
}

/* The proof line: a tinted strip, deep blue on the tint (7.85:1, computed from the token values). Only printed when the field is filled. */
.ill-q-dlg .ill-q-proof {
  margin: var(--space-24) 0 0;
  padding: var(--space-12) var(--space-16);
  border-radius: var(--radius-sm);
  background-color: var(--blue-tint);
  font-size: var(--t-card-meta);
  font-weight: 600;
  line-height: 1.45;
  color: var(--deep-blue);
  text-wrap: pretty;
}

/* Primary action and Previous and Next: one white band under the scrolling body, one hairline above it. */
.ill-q-dlg__actions {
  display: flex;
  flex: 0 0 auto;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-16) var(--q-pad) var(--space-8);
  border-top: 1px solid var(--hairline);
  background: var(--white);
}

.ill-q-dlg .ill-q-dlg__actions .ill-btn { gap: var(--space-8); }

.ill-q-dlg.ill-quote-modal--detail .ill-pkg-modal__foot { padding: 0 var(--q-pad) var(--space-8); border-top: 0; }

/* On the sheet (under 600px) Previous is at the left edge of the row and Next at the right, and a lone Next (the first dialog) still goes right. */
.ill-q-dlg .ill-pkg-modal__nav { width: 100%; justify-content: space-between; }

.ill-q-dlg .ill-pkg-modal__step[aria-label^="Next"] { margin-left: auto; justify-content: flex-end; }

/* The shipped step link is a 44px-tall box with its label at the top; centre the label so it lines up with the button beside it. The shipped 4px side padding is
   dropped so the label itself sits on the content edge (Previous on the left edge, Next on the right), and a 44px minimum width keeps the target 44 by 44 (Next's label alone is 28px wide). */
.ill-q-dlg .ill-pkg-modal__step { display: inline-flex; align-items: center; min-width: 44px; padding: 0; }

/* token-gate: allow --deep-blue */
/* token-gate: allow --hairline */
/* token-gate: allow --space-12 */
/* token-gate: allow --space-16 */
/* The shipped a:hover recolours every link mid blue (2.85:1 on the Close tint, 3.20:1 on white): Previous and Next keep deep blue, the underline is the cue. */
.ill-q-dlg .ill-pkg-modal__step:hover { color: var(--deep-blue); }

/* On a phone the primary action takes the width, so it is an easy target, and Previous and Next sit under it. The sheet also spends less on space, so that all six pop-ups
   fit a 390 by 844 screen without a scroll: groups sit 16px apart (the body's top and bottom padding, the gap under the heading, the gap between the blocks, the margin above
   the proof strip), a step row has 8px above and below its hairline, the proof strip 8px of padding above and below, and the primary action 12px under its hairline.
   Those were, in that order, 24px (the bottom padding; the top was already 16px), 24, 24, 24, 12, 12 and 16px. Type, alignment and the 44px targets are untouched, and from 600px the old values stand. */
/* token-gate: allow --space-8 */
/* token-gate: allow --space-12 */
/* token-gate: allow --space-16 */
@media (max-width: 599px) {
  .ill-q-dlg .ill-q-dlg__actions .ill-btn { width: 100%; }
  .ill-q-dlg.ill-quote-modal--detail .ill-pkg-modal__body { padding-top: var(--space-16); padding-bottom: var(--space-16); }
  .ill-q-dlg.ill-quote-modal--detail .ill-quote-modal__title { margin-bottom: var(--space-16); }
  .ill-q-dlg.ill-quote-modal--detail .ill-pkg__blocks { row-gap: var(--space-16); }
  .ill-q-dlg .ill-q-steps li { padding: var(--space-8) 0; }
  .ill-q-dlg .ill-q-proof { margin-top: var(--space-16); padding: var(--space-8) var(--space-16); }
  .ill-q-dlg .ill-q-dlg__actions { padding-top: var(--space-12); }
}

/* A phone window shorter than the 826px panel. Under 842px high the panel is the window less 16px (796px on a 375 by 812 screen), and pop-up 2, the tallest, wants 874.69px at 375px wide, so its
   body scrolled by 79px and the proof strip ran under the foot. On exactly those windows the spacing goes one step further down the ladder: the side padding 24px to 16px (the Close chip's own
   edge distance, so the chip, the hairlines and the button share one edge, and the wider column takes a line off step 2 and off What changes), each 16px gap to 12px, the step rows' 8px to 4px.
   Type, copy, colours and the 44px targets are untouched. A window of 842px or more, and any width from 600px, keep the values above. */
/* token-gate: allow --space-4 */
/* token-gate: allow --space-12 */
/* token-gate: allow --space-16 */
@media (max-width: 599px) and (max-height: 841px) {
  .ill-q-dlg { --q-pad: var(--space-16); }
  .ill-q-dlg.ill-quote-modal--detail .ill-pkg-modal__body { padding-top: var(--space-12); padding-bottom: var(--space-12); }
  .ill-q-dlg.ill-quote-modal--detail .ill-quote-modal__title { margin-bottom: var(--space-12); }
  .ill-q-dlg.ill-quote-modal--detail .ill-pkg__blocks { row-gap: var(--space-12); }
  .ill-q-dlg .ill-q-steps li { padding: var(--space-4) 0; }
  .ill-q-dlg .ill-q-proof { margin-top: var(--space-12); }
}

/* token-gate: allow --space-12 */
/* token-gate: allow --space-16 */
/* token-gate: allow --space-24 */
/* token-gate: allow --space-32 */
/* token-gate: allow --space-40 */
/* token-gate: allow --hairline */
/* From 600px the primary action and Previous and Next share one row under the body, with one hairline across both: the primary action at the left, the two links
   together at the right, centred on the button. The panel is a grid for that (the body row is minmax(0, 1fr), so it is the part that scrolls; the shipped max-height is what bounds the panel). */
@media (min-width: 600px) {
  .ill-q-dlg.ill-quote-modal--detail .ill-quote-modal__panel {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto minmax(0, 1fr) auto;
    grid-template-areas: "head head" "body body" "actions foot";
  }

  .ill-q-dlg .ill-pkg-modal__head { grid-area: head; }
  .ill-q-dlg.ill-quote-modal--detail .ill-pkg-modal__body { grid-area: body; }
  .ill-q-dlg__actions { grid-area: actions; padding: var(--space-16) var(--space-12) var(--space-16) var(--q-pad); }

  .ill-q-dlg.ill-quote-modal--detail .ill-pkg-modal__foot {
    grid-area: foot;
    padding: var(--space-16) var(--q-pad) var(--space-16) var(--space-12);
    border-top: 1px solid var(--hairline);
  }

  .ill-q-dlg .ill-pkg-modal__nav { width: auto; margin-left: auto; }
}

/* From 900px the body is two columns inside the scrolling region. Five tracks: the side padding, the left column (5 of 12), a 40px gutter, the right column (7 of 12), the side padding.
   The vertical hairline is drawn in the middle of the gutter and runs the full height of the body, so it meets the hairline under the top bar and the one over the foot.
   The list of blocks is taken out of the box tree (display: contents) so that its two blocks can be placed in the body's grid: the steps in the right column over every row,
   what changes under the heading in the left column. The proof strip takes the last row of the left column and sits at its foot. */
@media (min-width: 900px) {
  .ill-q-dlg.ill-quote-modal--detail .ill-pkg-modal__body {
    display: grid;
    grid-template-columns: var(--q-pad) minmax(0, 5fr) var(--space-40) minmax(0, 7fr) var(--q-pad);
    grid-template-rows: auto auto 1fr;
    padding: 0;
  }

  .ill-q-dlg.ill-quote-modal--detail .ill-pkg-modal__body::before {
    content: "";
    grid-area: 1 / 3 / -1 / 4;
    justify-self: center;
    width: 1px;
    background-color: var(--hairline);
  }

  .ill-q-dlg.ill-quote-modal--detail .ill-pkg__blocks { display: contents; }

  .ill-q-dlg.ill-quote-modal--detail .ill-quote-modal__title { grid-area: 1 / 2; margin: 0; padding-top: var(--space-32); }

  .ill-q-dlg .ill-pkg__block:first-child { grid-area: 1 / 4 / 4 / 5; padding: var(--space-32) 0; }

  .ill-q-dlg .ill-pkg__block + .ill-pkg__block { grid-area: 2 / 2; padding-top: var(--space-24); }

  .ill-q-dlg .ill-q-proof { grid-area: 3 / 2; align-self: end; margin: var(--space-24) 0 var(--space-32); }

  /* A pop-up with no proof strip closes its left column with the "What changes" block, 32px above the foot of the body, where the proof strip sits in the pop-up that has one, so the
     column ends on the same line in all six and the space left by a shorter pop-up opens between the heading and that block rather than under it. */
  .ill-q-dlg .ill-pkg-modal__body:not(:has(.ill-q-proof)) .ill-pkg__block + .ill-pkg__block { grid-area: 3 / 2; align-self: end; margin-bottom: var(--space-32); }

  .ill-q-dlg .ill-q-steps li { padding: var(--space-16) 0; }
}

/* The page scrollbar would vanish under the scroll lock and shift the page: reserve it, as the Packages pages do. */
html:has(.ill-svc-card--dlg) { scrollbar-gutter: stable; }
