/**
 * Harvest — T7 "Search Results".
 *
 * Scoped to `.hrv-page-search`, the body class the handle sets. Every colour is an --hrv-*
 * token: no hex, so all palettes work with no rebuild (Gate B).
 *
 * Comp: design/store-theme/03-harvest-food/colors/<palette>/pages/"T7 Search Results.dc.html"
 *   - `Results for "olive oil"` as the page title
 *   - a count line with related terms beside it
 *   - `repeat(4, 1fr)` product grid — FOUR up, where T4's category grid is three
 *
 * THE RAIL FIX IS NOT HERE. It comes from `hrv-cols` in the handle, which opts this page into
 * components/_layout-columns.css. That reset already existed and default.xml's own comment
 * named search as a consumer — nothing had ever added the class, so the rail rendered 1649px
 * below the grid. Fixing it in this file would have been a second copy of a reset that was
 * already correct; the bug was the missing opt-in, not the CSS.
 *
 * FOUR COLUMNS, DECLARED PER BREAKPOINT. T6 taught this the expensive way: an
 * `auto-fill minmax()` grid produced five columns where the comp asked for three, because it
 * answers "how many fit" rather than "how many did the designer draw". Explicit counts make
 * each step a decision.
 */

/* THE COMP DOES NOT GIVE SEARCH A RAIL AT ALL, AND THE SENTENCE THAT USED TO SIT HERE SAID IT
   DID: "The comp gives search the same 240px rail as the category page."

   Checked, in both artboards, by search rather than by recollection. `T7 Search Results.dc.html`
   contains ZERO occurrences of `filter`, `refine`, `sidebar`, `aside`, `Sort`, `per page`,
   `View as` or the string `240px`, in the Wheat copy and in the Basil copy alike. The comp draws
   breadcrumb, h1, a count-and-related line, ONE full-bleed `repeat(4, 1fr)` grid, and a pager.
   The instrument was calibrated before the absence was believed: the identical grep over
   `T4 Category Grid.dc.html` returns `240px` x1, `aside` x2, `filter` x1 and `Sort` x1 - so it
   can find every one of those terms, and finds none of them here. A zero count is a claim about
   the search; this one has a positive control behind it.

   240px IS THE CATEGORY COMP'S FIGURE, carried across. That is a deliberate deviation and it is
   row 1 of the ledger at the foot of this file, not an accident: Magento renders layered
   navigation on this route and removing it would cost real filtering on a page where the store's
   own data shows it working (measured: Category group, 5 options, 10/1/1/1/3). The comment is
   the problem, not the rule. A false "the comp says X" is the most expensive kind of comment in
   this theme, because the next reviewer measures against it instead of against the comp - which
   is exactly how the ledger on `_t6.css` had to be corrected three times.

   THE COST OF THE 240px, STATED SO THE DEVIATION IS PRICED: with the rail the four tracks
   measure 265px each at 1440; the comp's rail-less row gives (1360 - 3x16) / 4 = 328px.

   THIS SENTENCE SAID 332px, AND LEDGER ROW 2 AT THE FOOT OF THIS FILE RETRACTS EXACTLY THAT
   NUMBER. (It used to say "313 lines lower". Measured: 317. I took 313 from the S4 report and
   wrote it into the file without re-deriving it - inside the comment that exists to correct a
   number copied without re-deriving it. Copilot caught it and is right that a hardcoded
   distance rots on the next edit above either end, so the reference is now the ROW, which has
   a name, rather than a count, which does not.) 1376 is THIS THEME's content width (row 9); the comp's body rows are
   inset 40px, so its row is 1440 - 80 = 1360. 332.00 is a real quantity - what this theme would
   give at 1376 with the rail removed - but it is not the comp's, and it sat here wearing the
   comp's label as the FIRST thing a reader meets. Caught by the S4 gate. It is the precise
   failure this file's own ledger congratulates itself on catching - correct the CLAIM, not just
   the row that holds it - reproduced in the same commit that wrote the rule down. */
.catalogsearch-result-index.hrv-page-search .columns {
  grid-template-columns: 240px 1fr;
}

.catalogsearch-result-index.hrv-page-search .page-title-wrapper .page-title {
  font-family: var(--hrv-font-display);
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0 0 18px;
}

/* ── Product grid — four up ─────────────────────────────────────────────────── */
.catalogsearch-result-index.hrv-page-search .products-grid .products.list.items {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--hrv-gap);
  margin: 0;
  padding: 0;
  list-style: none;
}
/* Blank floats each item and gives it a percentage width — both must go or the grid tracks
   are ignored. Same reset the category grid needs, and for the same reason. */
.catalogsearch-result-index.hrv-page-search .products-grid .products.list.items > .item.product {
  width: auto;
  margin: 0;
  padding: 0;
  float: none;
}

@media (max-width: 1279px) {
  .catalogsearch-result-index.hrv-page-search .products-grid .products.list.items {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
@media (max-width: 1023px) {
  .catalogsearch-result-index.hrv-page-search .products-grid .products.list.items {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 479px) {
  .catalogsearch-result-index.hrv-page-search .products-grid .products.list.items {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 767px) {
  /* Magento's related-search-terms block (dl.block > dd.item > a) measured 23x17 to 117x17.
     These are a LIST of tappable links - "oliv", "olival", "Olive oil & vinegar" - not links
     inside a sentence, so the 44px bar applies to them without an argument to make. */
  .search .block .item > a,
  .catalogsearch-result-index .search .item > a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
  }
  /* THIS PAGE MUST RE-DECLARE ITS OWN SINGLE-COLUMN TRACK, and I shipped it without.
     The shared mobile rule in _layout-columns.css is `.hrv-cols .columns` (0,2,0) while this
     page's desktop track is `.catalogsearch-result-index.hrv-page-search .columns` (0,3,0) —
     and A MEDIA QUERY ADDS NO SPECIFICITY, so the shared rule loses and the 240px rail track
     survives on phones.

     Measured at 375 before this block: grid-template-columns "240px 85px" — the main column
     crushed to 85px, sidebar pushed to y=5675. AND THE PAGE DID NOT OVERFLOW, so an
     overflow-only check reports it clean. That is exactly what _category.css's own comment
     predicts, in the file I should have read before writing the desktop track.
     Rule of thumb, inherited verbatim: WHOEVER DECLARES THE TRACKS OWNS EVERY BREAKPOINT.

     Found by reading the sibling page file after the measurement disagreed with it — the same
     lesson as the product card and _t3.css, three times in one session. */
  .catalogsearch-result-index.hrv-page-search .columns {
    grid-template-columns: 1fr;
  }

  /* Second defect, and I had NOT measured this one — it came from the sibling file too.
     Magento_LayeredNavigation hides `.filter-options` below 768px unless `.block.filter`
     carries `.active`, its mobile accordion state. The rail here stacks as plain content with
     no drawer JS, so without this every phone would render an EMPTY filter card. */
  .catalogsearch-result-index.hrv-page-search .block.filter .filter-options,
  .catalogsearch-result-index.hrv-page-search .block.filter .filter-options-content {
    display: block;
  }
}

/* ═════════════  T8 "Search No Results" — the empty-state recovery panel  ═══════
   Renders only when the search returned nothing; the guard is in the template.

   Comp: an icon, "Nothing found for X", a hint line, a search box, four aisle chips, then a
   "Popular right now" grid. The chips are the store's REAL aisles via HarvestAisles — the
   comp's "Olive oil / Flour / Honey / Coffee" read as suggestions but are the store's own
   aisle names, and a hardcoded list would drift from what the shop actually sells.

   ALL SIX ELEMENTS ARE NOW BUILT. This sentence used to list the "Popular right now" grid as
   part of the comp while nothing on the page rendered it — the list was a description of the
   ARTBOARD being read as a description of the PAGE, for four review rounds. basil-T8 built it;
   the section's own rules are further down this file and ledger row D3 carries the measurement.
   If an element is ever listed here again without being built, say so on this line. */
.hrv-page-search .hrv-search-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
  padding: 48px 24px 40px;
  background: var(--hrv-surface);
  border: 1px solid var(--hrv-border);
  border-radius: var(--hrv-radius);
  margin: 0 0 32px;
}
/* THE COMP DRAWS A 72px RING, AND THE PAGE RENDERED A BARE GLYPH. Built by basil-T8.

   The artboard's icon is `width/height: 72px; border-radius: 50%; border: 2px solid
   color-mix(in oklab, var(--tx) 22%, var(--bg)); display: grid; place-items: center;
   font-size: 30px; color: color-mix(in oklab, var(--tx) 45%, var(--bg))`. The rule here
   declared three properties — font-size, line-height, colour — so the ring, its size, its
   border and its centring were ALL absent, and the muted glyph colour was an accent one.
   Measured before the change: 18.7 x 34, no box.

   FOUND BY LOOKING AT A SCREENSHOT, and worth saying because nothing else could have. Every
   numeric check on this element passed: it was present, visible, non-zero, correctly
   positioned in flow, and the contrast sweep scored it happily. "Is there a circle around it"
   is not a property any probe on this page was asking about — the picture is the instrument.

   THE RING IS BUILT. THE COMP'S GLYPH COLOUR IS NOT ADOPTED, AND THAT SPLIT IS THE WHOLE POINT
   OF THIS BLOCK.

   RETRACTED, LOUDLY, BECAUSE IT WAS WRITTEN INTO THIS FILE BEFORE IT WAS MEASURED: "THE GLYPH
   COLOUR CHANGE IS NOT COSMETIC — IT RETIRES THIS ELEMENT FROM AN OPEN REGISTER ROW … the
   failure came from the deviation this rule is fixing." That was a PREDICTION typed as a
   finding, and it is false in the opposite direction. The comp's `color-mix(in oklab, var(--tx)
   45%, var(--bg))` on the panel's `--hrv-surface` measures, on the deployed page:

       wheat 3.34 | basil 3.30 | tomato 3.47 | plum 3.47 | honey 3.37      (need 4.5)

   ALL FIVE FAIL — and basil, the palette under test, was PASSING at 5.04 before the change.
   Adopting the comp's hue would have taken the one palette this task is answerable for from
   pass to fail while the commit message claimed the opposite. The only reason it did not ship
   is that the sweep was re-run rather than the paragraph re-read.

   SO THE HUE STAYS `var(--hrv-accent)` (basil 5.04 PASS, unchanged by this task) and the
   DEVIATION IS DECLARED, as ledger row D5. This is register #172's exact shape — the artboard's
   own value fails AA harder than what ships, so there is no artboard-conformant value that
   passes, and `tokens/_derived.css` has already ruled that darkening an artboard-authoritative
   hue is a DESIGN decision. Routed, not patched. The pre-existing wheat 3.04 / honey 4.39
   failures on this element are untouched and remain registers #14/#16 via ledger row C2.

   WHAT DOES CHANGE IS THE GEOMETRY, which was the actual gap and is not in dispute: the ring,
   its size, its border and its centring. No contrast threshold is involved in any of them.

   LITERAL MIX FOR THE BORDER RATHER THAN A TOKEN, with the nearest named so the choice is
   checkable: none matches — `--hrv-border` is 10% and `--hrv-border-strong` 35% against the
   comp's 22%. It resolves through `var(--hrv-*)`, so this stays palette-driven and adds no
   hardcoded hex. The ring is decoration on an `aria-hidden` presentational span, so WCAG
   1.4.11's 3:1 does not govern it; the comp's value is taken as-is.

   `inline-grid`, NOT THE COMP'S `grid`, and the difference is deliberate and inert. The span is a
   flex item of `.hrv-search-empty`, so an inline-level `display` is blockified to `grid` anyway
   (CSS Display 3 §2.7) and the rendered box is identical — measured 72 x 72 either way. It is
   written `inline-grid` because the element is a `<span>` and the inline form is the honest
   spelling for one; declared here because a ledger row saying "MATCHES" over an undeclared
   property difference is how the next reader stops trusting the ledger. Found by the S1 Magento
   review. */
.hrv-page-search .hrv-search-empty-icon {
  display: inline-grid;
  place-items: center;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  border: 2px solid color-mix(in oklab, var(--hrv-text) 22%, var(--hrv-bg));
  font-size: 30px;
  line-height: 1;
  color: var(--hrv-accent);
}
.hrv-page-search .hrv-search-empty-title {
  margin: 0;
  font-family: var(--hrv-font-display);
  font-size: 28px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--hrv-text);
}
.hrv-page-search .hrv-search-empty-hint {
  margin: 0;
  font-size: 15px;
  color: var(--hrv-text-muted);
  max-width: 46ch;
}

/* The form is a real recovery control, so its target is sized like one. */
.hrv-page-search .hrv-search-empty-form {
  display: flex;
  gap: 8px;
  width: 100%;
  max-width: 460px;
  margin-top: 4px;
}
/* The label is CLIPPED, not removed — an unlabelled search field is a screen-reader dead
   end, and this is the fourth control in this theme to need the pattern. */
.hrv-page-search .hrv-search-empty-label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}
.hrv-page-search .hrv-search-empty-input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  padding: 10px 18px;
  border: 1px solid var(--hrv-border);
  border-radius: var(--hrv-radius-pill);
  background: var(--hrv-bg);
  color: var(--hrv-text);
  font-family: var(--hrv-font-body);
  font-size: 14px;
}
.hrv-page-search .hrv-search-empty-input:focus-visible {
  outline: 2px solid var(--hrv-focus-ring);
  outline-offset: 1px;
}
.hrv-page-search .hrv-search-empty-submit {
  min-height: 44px;
  padding: 10px 22px;
  border: none;
  border-radius: var(--hrv-radius-pill);
  background: var(--hrv-accent);
  color: var(--hrv-accent-text);
  font-family: var(--hrv-font-body);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.hrv-page-search .hrv-search-empty-submit:hover {
  background: var(--hrv-accent-hover);
}

/* Aisle chips. 44px minimum because these are the primary recovery targets on a dead end —
   the same bar N-10 set for the card buttons, not the 24px AA floor. */
.hrv-page-search .hrv-search-empty-chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
}
/* THE LABEL IS `--hrv-text`, WHICH IS WHAT THE COMP SAYS AND ALSO WHAT AA NEEDS. It shipped
   as `var(--hrv-accent)`, and that was wrong on both counts at once:

     comp   `T8 Search No Results.dc.html` draws each chip as
            `color: var(--tx); border: 1px solid color-mix(in oklab, var(--tx) 24%, var(--bg))`
            — a neutral outlined pill. The accent label was never in the artboard.
     AA     accent-on-a-10%-accent-tint, measured on the rendered page under all five palettes
            by scripts/harvest/t7-page-palette-sweep.js at 1440:
                wheat 2.75 | basil 4.41 | tomato 4.40 | plum 6.49 | honey 3.89   (need 4.5)
            FOUR OF FIVE FAIL, AND ONE OF THEM IS BASIL — the palette under test.

            THE BASELINE IN THIS PARAGRAPH WAS WRONG AND IS CORRECTED, because it is the number
            carrying the whole "why this is patched and #14/#16 are not" argument. It read
            "accent on the plain surface measures 4.62, so the 10% ground costs 0.21". 4.62 is
            accent on `--hrv-bg` (#F3F6EF) — which is #14/#16's ground, not this chip's. The
            chip mixes into `--hrv-surface` (#FFFFFF), where basil's accent measures **5.04**;
            `tokens/_derived.css` publishes that figure and this file's own sweep asserts it as
            a cross-check every run. So the tint costs **0.63**, not 0.21. Caught by the S1
            correctness review re-deriving the oklab mixes; every other figure in this block
            reproduced exactly, which is precisely why the one that did not is worth naming.

            The distinction from #14/#16 survives the correction and is in fact sharper:
            those pairings sit on `--hrv-bg` at 4.62 and PASS on basil; this one sits on a
            tinted `--hrv-surface` at 4.41 and does not.

            RETRACTED: "The live rule is **14px/700** (`font-size: 14px` below); the comp's chip
            is 13px and declares no weight." True when wheat-T7 wrote it, false since basil-T8
            reconciled the rule to the comp — the live rule is now 13px/400. The rest of that
            sentence stands and is why the retraction changes no verdict: neither size is WCAG
            large text (the bold cut is 18.66px), so 4.5 applied before the change and applies
            after it.

   FIXED BY MOVING TOWARD THE COMP, not by inventing a darker accent. That distinction is the
   whole reason this one is patched while #14/#16 are not: those need design to rule on a
   brand hue the artboards DO specify as text; this one had an artboard answer all along.

   RETRACTED: "THE TINTED GROUND STAYS, and that IS a deviation from the comp's
   transparent-with-border chip … It is left alone because the chip's full treatment (border,
   8px/16px padding, 13px type) is basil-T8's comp to match … Only the failing declaration
   moved." Correct as written by wheat-T7, and correctly scoped — the deferral names basil-T8,
   and basil-T8 is the task that has now done it. The ground is transparent, the border, the
   8px/16px padding and the 13px type are all in the rule below, and the deviation this
   paragraph declared no longer exists. Ledger row D1 at the foot of this file carries the
   reconciliation and the one deviation that remains (`min-height: 44px`).

   (The parenthetical this replaces is preserved because it is still the useful part: the
   sentence once said "declared in the ledger" while NO SUCH ROW EXISTED, which the S1 Magento
   review caught — a pointer to a row that is not there is worse than no pointer, and it
   appeared in the very commit whose preamble warns about false pointers. D1 was written in
   response; this task has now changed what D1 says rather than leaving a second stale pointer.)

   Post-fix, same instrument, same width, RE-MEASURED rather than predicted — the first
   version of this paragraph carried 15.34/14.75/15.55/15.36/15.50, which are text-on-BG
   figures copied from another row of the same sweep. (That provenance itself was first written
   as "text-on-SURFACE" and was wrong - the S8 gate recomputed all five from the token hexes with
   a self-tested instrument: text-on-SURFACE is 16.52/16.10/17.16/17.11/16.82, text-on-BG is
   15.34/14.75/15.55/15.36/15.50, an exact match for the retracted row. The substantive
   correction below was right; only the label naming where the bad numbers came from was
   transcribed without re-deriving it - the same failure, inside the paragraph written to
   correct it.) The chip's ground was the 10% tint, not
   the surface, so every one of those five numbers was about a pairing that rule did not
   create. Actual, on the tinted ground: wheat 14.99 | basil 14.06 | tomato 15.03 | plum 14.50 |
   honey 14.89.

   SUPERSEDED BY basil-T8, WHICH REMOVED THE TINT. With the ground transparent the chip's label
   sits on the panel's `--hrv-surface`, so the pairing is now text-on-SURFACE and measures
   16.52 / 16.10 / 17.16 / 17.11 / 16.82.

   RETRACTED, and it is the third correction inside a paragraph whose whole subject is a
   mis-transcribed row — which is exactly why it is being spelled out rather than quietly edited.
   This sentence read: "the retracted numbers above have now become the correct ones … the five
   figures ARE 16.52 / 16.10 / 17.16 / 17.11 / 16.82 — THE VERY ROW THE PARAGRAPH ABOVE RETRACTS."
   FALSE. The paragraph above retracts **15.34 / 14.75 / 15.55 / 15.36 / 15.50**, the text-on-BG
   row; it names 16.52/16.10/… as the text-on-SURFACE row, which it explicitly does NOT retract.
   The two rows are the very pair that paragraph exists to keep apart, and the "coincidence worth
   naming" I built on top of the confusion did not exist. Caught by the S1 Magento review.
   The substantive numbers below were right and are unchanged; only the claim about their
   provenance was wrong — the identical failure mode the paragraph above records, committed one
   paragraph later by the person correcting it.

   RE-MEASURED on the deployed image, not inferred from any equality:

       wheat 16.52 | basil 16.10 | tomato 17.16 | plum 17.11 | honey 16.82   (need 4.5)

   Every palette improves, basil by 2.04. The next person to correct a figure here should check
   which ground the rule declares BEFORE assuming a matching row is the transcription error
   again. */
/* RECONCILED TO THE COMP BY basil-T8, WHICH LEDGER ROW D1 ASSIGNED IT. D1 recorded that only
   the LABEL COLOUR had moved (wheat-T7 changed it to fix an AA failure) and that "the ground,
   border, padding and type size are basil-T8's to reconcile". They are reconciled here: the
   ground goes transparent, the comp's 1px border arrives, padding becomes 8px/16px and the type
   13px — `T8 Search No Results.dc.html`'s own values, all four.

   THE ONE DECLARATION THAT DOES NOT FOLLOW THE COMP IS `min-height: 44px`, AND IT IS KEPT
   DELIBERATELY. The comp's chip computes to roughly 33px tall (13px type, 8px padding, 1px
   border). These are the primary recovery targets on a dead end, and WCAG 2.5.8 sets 44px — the
   same bar N-10 already enforces on the card buttons and `_home.css:434` on the hero CTAs, so
   this is the theme's existing answer rather than a new standard invented here. Declared as
   ledger row D1 rather than silently followed in either direction, per the playbook's rule for
   a comp/accessibility disagreement.

   THE BOUNDARY CONTRAST WAS MEASURED BEFORE THIS CHANGE, NOT ASSUMED, because "the comp's
   border is too faint" is the obvious objection and it needed a number. Measured on the
   deployed page under basil with a self-tested canvas instrument (21 / 1 / 4.54 on the known
   pairs, and it rejects a garbage colour):

       comp border  color-mix(in oklab, #1C231A 24%, #F3F6EF) -> rgb(185,190,182)  1.89 : 1
       old ground   color-mix(in oklab, #4C7A3F 10%, #FFFFFF) -> rgb(236,241,235)  1.14 : 1

   NEITHER reaches the 3:1 of WCAG 1.4.11 — so this change does not introduce a boundary
   problem, it improves one, and 1.4.11 is satisfied here regardless: these are links carrying
   visible text labels, so the LABEL is what identifies the component, and the pill is
   decoration. The label pairing is the one that must clear 4.5, and it gets BETTER, because
   `--hrv-text` now sits on the panel's own `--hrv-surface` instead of a tint of it:

       basil label, before (text on 10% accent tint)   14.06 : 1
       basil label, after  (text on --hrv-surface)     16.10 : 1

   FONT-WEIGHT IS DECLARED 400 EVEN THOUGH THE COMP DECLARES NOTHING. The comp's chip is a bare
   `<a>`, which RENDERS at 400; declaring it pins the rendered value so an ancestor weight
   change cannot silently move it, which is the same reason this file names tokens rather than
   resolved values elsewhere. The old 700 was not in the artboard.

   THE TINT IS NOT DELETED, IT MOVES TO :hover — the resting treatment becomes the hover
   treatment, so the control still has a ground on pointer-over and the accent still appears on
   the chip, one state later. Focus is NOT declared here: `components/_base.css:95` styles
   `a:focus-visible` globally and this is an `<a>`, so a rule here would duplicate it. */
.hrv-page-search .hrv-search-empty-chip {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 16px;
  border: 1px solid color-mix(in oklab, var(--hrv-text) 24%, var(--hrv-bg));
  border-radius: var(--hrv-radius-pill);
  background: transparent;
  color: var(--hrv-text);
  font-size: 13px;
  font-weight: 400;
  text-decoration: none;
}
.hrv-page-search .hrv-search-empty-chip:hover {
  background: color-mix(in oklab, var(--hrv-accent) 10%, var(--hrv-surface));
  border-color: var(--hrv-accent);
}

@media (max-width: 599px) {
  .hrv-page-search .hrv-search-empty { padding: 32px 16px; }
  .hrv-page-search .hrv-search-empty-title { font-size: 22px; }
  /* The form stacks rather than shrinking the input below a usable width. */
  .hrv-page-search .hrv-search-empty-form { flex-direction: column; }
}

/* ---------------------------------------------------------------------------
   T8 "POPULAR RIGHT NOW" — the comp's four-card row beneath the recovery panel.
   Block, collection and guard are wired in `catalogsearch_result_index.xml`; read that
   docblock for why `Bestsellers` and why it hangs off the panel rather than off `content`.

   THE CARD AND THE GRID ARE NOT RE-DECLARED HERE, matching what `_cart.css` does for the
   identical markup on T17. `components/_product-card.css` owns the card shell and now carries
   `.hrv-page-search .widget-product-grid` on its shared grid helper, so the 4-column desktop
   step and the 4->2 tablet step have exactly ONE definition across both consumers and cannot
   drift. What is left below is only what that component cannot supply — the heading type and
   the row's measure — because every `.hrv-home-*` rule in `_home.css` is scoped
   `.cms-index-index.hrv-page-home` and therefore matches nothing here.

   The block renders nothing on a store with no order history, so the HEADING is either fully
   present or fully absent — there is no state where it appears over an empty grid; that is the
   block's own guard, and it is the claim this sentence is entitled to make.

   IT IS NOT A CLAIM ABOUT THE CARD COUNT, and an earlier version of this sentence read as though
   it were. `Bestsellers::getBestsellerProductIds()` applies `setPageSize(limit)` to the sales
   AGGREGATE and only then filters `status = 1` / `visibility IN (2,4)`, so anything the filter
   drops is not backfilled: the row can legitimately render 1-3 cards, which under
   `repeat(4, 1fr)` pack left beneath a centred heading. On this tenant the aggregate holds
   exactly 4 rows, so disabling one product is enough to produce it. The collection also applies
   no stock filter, so an out-of-stock bestseller renders an "Out of stock" card inside "Popular
   right now". Both are properties of the shared block (three consumers: Home, T17 cart, this
   page), not of these rules, and both are recorded rather than fixed from a page task that is
   not measuring the other two. Found by the S1 correctness review.
   --------------------------------------------------------------------------- */
.hrv-page-search .hrv-home-headrow {
  margin: 0 0 20px;
  text-align: center;
}

.hrv-page-search .hrv-home-title {
  font-family: var(--hrv-font-display);
  font-size: 22px;
  font-weight: 700;
  line-height: 1.12;
  margin: 0;
}

/* 64px, AND IT IS NOT A SUM. THE FIRST VERSION OF THIS RULE SHIPPED 32px WITH ARITHMETIC THAT
   DOES NOT APPLY, AND THE RENDERED GAP WAS HALF THE COMP'S.

   RETRACTED: "THE 32px IS ARITHMETIC, NOT A CHOSEN FIGURE … the comp puts 64px between the panel
   and this heading, `.hrv-search-empty` above already contributes `margin: 0 0 32px`, so this
   supplies the remaining 32px." Adjacent in-flow block siblings do not ADD their facing margins,
   they COLLAPSE to the larger of the two (CSS 2.1 §8.3.1). `.hrv-search-empty` and
   `.hrv-home-section` are exactly that — adjacent siblings, nothing between them, parent
   `.column.main` is `display: block` and is only ever a grid ITEM in this theme
   (`components/_layout-columns.css:74`), never a grid CONTAINER, so nothing suppresses collapsing.
   32 and 32 collapsed to 32.

   MEASURED ON THE BUILT IMAGE, not reasoned — the S1 Magento review named the mechanism and said
   explicitly that it had not put a browser on it, which is the right way to hand over a
   deterministic-but-unmeasured claim:

       0.1.243-local (margin-top: 32px)   panelBottom 766.45  sectionTop 798.45  gap 32.00
       0.1.244-local (margin-top: 64px)   see below

   64px on this side collapses with the panel's 32px to max(32, 64) = 64 — the comp's figure.
   Putting the full gap on `.hrv-search-empty`'s `margin-bottom` (what `_cart.css` does for its
   own copy) was rejected: that margin ALSO separates the panel from the footer on a store with no
   order history, where this section does not render at all, and it would move that page too. */
.hrv-page-search .hrv-home-section {
  margin-top: 64px;
}

/* The comp caps the row at 1180px and centres it. No bottom margin: the footer's own top
   margin already provides the comp's trailing space, and a figure added here for symmetry
   would be an invented one — the exact correction `_cart.css` had to make. */
.hrv-page-search .widget-product-grid {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

/* Magento's own "Your search returned no results." notice renders IN ADDITION to the panel
   above, so the page said the same thing twice — mine with a recovery flow, Magento's as a
   bare strip beneath it. The comp has one message.

   Suppressed only WHEN THE PANEL IS PRESENT, via :has(), rather than hiding the notice
   outright: on any other empty-ish state where the panel does not render, that notice is the
   only thing telling the shopper what happened, and blanket-hiding a core message is how a
   page ends up silently saying nothing. (:has() is already relied on in
   components/_layout-columns.css for the same reason — it is supported by every browser this
   theme targets.)

   Caught by LOOKING at the rendered page. Every measurement passed: the panel was present,
   the guard was correct, both states behaved. Duplication is not a property any of my probes
   were asking about. */
/* ...BUT ONLY WHEN THE NOTICE ADDS NOTHING, AND THE FIRST VERSION OF THIS RULE DID NOT CHECK.
   Found by following an S1 review question rather than by any probe: "the panel is the first
   thing visible" was measured on `?q=zzzqqqxxx`, a query with NO spell suggestion. Asked what a
   zero-result query WITH one looks like, and measured it:

     ?q=zzzqqqxxx    notice contains one sentence and nothing else
     ?q=olivve+oill  notice contains that sentence AND
                     `<dl class="block"><dt>Did you mean</dt><dd><a href="...?q=olive+oil">`
                     - a live link to a query returning 16 real products

   Core renders "Did you mean" INSIDE `.message.notice`, so the blanket `display:none` above was
   hiding the store's own spelling correction ON THE PAGE WHOSE ENTIRE PURPOSE IS RECOVERY, while
   the panel three lines below advised "Check the spelling". Measured before the fix: notice
   `display:none`, `.search.results dl` absent from the rendered document, the suggestion
   unreachable by any gesture.

   The original rule's stated reason was that the page "said the same thing twice". That is true
   only when the notice is JUST the sentence. `:not(:has(dl))` keeps the de-duplication for that
   case and stops the suppression the moment the notice carries content of its own - which is a
   refinement of the original intent, not a reversal of it.

   Four zero-result queries were checked, not one, because a single example is how the first
   version shipped: `olivve+oill`, `honeyy+jarr`, `chesse+charcuteriee`, `expresso+beanz` all
   emit the `dl`; `zzzqqqxxx` does not. Specificity is unchanged apart from the `dl` type
   selector `:not(:has(dl))` contributes, so nothing else in the cascade moves. */
.hrv-page-search .column.main:has(.hrv-search-empty) .message.notice:not(:has(dl)) {
  display: none;
}


/* ═══════════════════════════════════════════════════════════════════════════════════════════
   DEVIATION LEDGER - T7 "Search Results", Basil, measured at 1440 on harvest-demo (local kind)
   image 0.1.238-local + this file hot-synced, `?q=olive+oil` (16 matches, 12 per page).

   READ THE OWNERSHIP COLUMN BEFORE ACTING ON A ROW. It is the column that has been wrong three
   times on this theme's other ledger, always in the same direction - claiming this file owns a
   value that actually resolves through a shared component, which hides a theme-wide blast
   radius and sends whoever trusts it to a rule site that does not exist.

       HERE     the declaration is in this file
       SPLIT    the property is named in this file, the VALUE comes from the named component
       NOT HERE this file declares nothing about it; the named file does

   The denominators below are mine and were produced by the probes named beside them. Where a
   figure is quoted from another artefact rather than re-derived, the row says so.

   ── A. Deviations from the T7 comp ────────────────────────────────────────────────────────
   #   what                         comp                     live                    ownership
   1   filter rail                  ABSENT                   240px, 5 options        HERE
                                    ^ see the block above the `.columns` rule. Kept on purpose.
   2   grid track width             328.00 derived           265.00 measured         HERE
                                    ^ arithmetic consequence of row 1, not a separate decision.
                                      THE COMP FIGURE HERE WAS 332.00 AND THAT WAS THIS THEME'S
                                      NUMBER WEARING THE COMP'S LABEL: (1376 - 3x16) / 4 uses
                                      1376, which is the width row 9 records as OURS. The comp's
                                      body rows are inset 40px, so its own row is 1440 - 80 =
                                      1360 and its track is (1360 - 3x16) / 4 = 328.00. The S1
                                      correctness review found the contradiction by reading row 9
                                      against row 2 - two rows of the same table disagreeing
                                      about the same artboard. 332.00 is still a real quantity
                                      and is kept, correctly labelled: it is what THIS theme
                                      would give at 1376 if the rail were removed.
   3   toolbar (View as / Sort By   ABSENT                   2 toolbars, 6 controls  NOT HERE
       / Show N per page)                                                            (core markup,
                                                                                      styled by
                                                                                      components/
                                                                                      _toolbar.css)
                                    ^ core's `product_list_toolbar`. THE SIX, NAMED, because
                                      "6 controls" was not reconstructible from the four the
                                      previous note listed: #sorter, #limiter,
                                      [data-role="direction-switcher"], and the mode switcher's
                                      TWO anchors (`.mode-grid`, `.mode-list`) - five - plus the
                                      pager's page links as the sixth family. Each of the five
                                      widget-bound ones was driven through a prototype shim that
                                      captures `changeUrl(paramName, paramValue)`, and the
                                      resulting URL was then loaded and asserted BY PRODUCT ID,
                                      so this deviation is a working one and not merely a
                                      present one. (The mangled cell that used to sit here - the
                                      ownership text split across three lines and landing in the
                                      middle column - was an S1 finding in its own right.)
   4   h1 string                    Results for "olive oil"  Search results for:      NOT HERE
                                                             'olive oil'             (core string;
                                    ^ i18n IS the mechanism, but the source string is
                                      `Search results for: '%1'` in module-catalog-search, shared
                                      with no other page - so a CSV row is viable and cheap. NOT
                                      done here: it is a copy change on a page whose comp is
                                      Basil-invariant, and it belongs with the theme's i18n pass
                                      (en_US/de_DE/pl_PL all need the row, not just en_US).
                                      Declared, not silently skipped.
   5   count + related, one line    `14 products - Related:  `Items 1-12 of 16`       NOT HERE
       under the h1                 extra virgin, ...`       at x=435 y=410.86 INSIDE
                                                             the toolbar; related terms
                                                             in a separate stacked
                                                             `.search.results dl` block
                                    ^ two comp elements collapsed into one live element in the
                                      wrong place plus one core block. Not rebuilt: the count is
                                      core's `.toolbar-amount` and the related list is core's
                                      spell-suggest, so this is a template task, not a CSS one.
   6   `margin-top: auto` on the    present                  0px                     NOT HERE
       card's price row                                                              (register #2,
                                    ^ theme-wide open item, every card surface.      open)
   7   "New" / "Sale" pill          3 of 8 cards             0                       NOT HERE
                                    (2 "New", 1 "Sale")
                                    ^ counted, not remembered: grep over the Basil T7 artboard
                                      returns 2 and 1. The row said 2 of 8.
   8   unit-price line              8 of 8 cards             0                       NOT HERE
                                    ^ rows 7 and 8 are register #8, declared: both need template
                                      AND data work, and the unit price is a claim about real
                                      merchandise that will not be fabricated.
   10  card secondary actions       ABSENT                   2 per card x 12 = 24    NOT HERE
       (wishlist / compare)                                                          (components/
                                                                                      _product-card
                                                                                      .css:241/253
                                                                                      /373)
                                    ^ THE LEDGER'S live->comp DIRECTION MISSED THESE. It carried
                                      rows for the mirror case - comp-only pills, comp-only unit
                                      price - and none for controls the live page renders that the
                                      comp does not draw. Measured at 1440: 12 `.action.towishlist`
                                      + 12 `.action.tocompare`; the comp contains neither word. No
                                      hidden blast radius, since both are declared and styled in
                                      the component - but "both directions" has to be checkable,
                                      and one direction was thinner than the other.

   9   horizontal page inset        40px on the body rows    32px                    NOT HERE
                                    (32px on the header row)                         (`--hrv-container:
                                    ^ THE ARTBOARD USES TWO INSETS and the theme applies one.     1440px`,
                                      `components/_base.css:53` calls 32px "the artboards' 1376px content",  components/_base.css:53)
                                      which is exactly right for the comp's HEADER row
                                      (1440-64=1376) and 16px wide for its body rows
                                      (1440-80=1360). Left alone: it is a theme-wide container
                                      decision on a token every closed page renders through, and
                                      changing it from a search task would move 40-odd pages.

   ── B. Comp properties that MATCH, so the ledger is a comparison and not a complaint list ──
   Measured, not assumed; ownership still stated because "it matches" is where a wrong owner
   does the most damage - it looks settled.

       h1 30px / 700 / Bricolage Grotesque / text-wrap: balance   HERE (font-size, weight)
                                                                  + SPLIT (`--hrv-font-display`,
                                                                    `text-wrap: balance` from
                                                                    _base.css:85, headings only)
       h1 line-height  comp 1.12 -> 33.60   live 34.50 (1.15)     NOT HERE - the 0.90px gap is
                                                                  inherited, not declared
       grid  repeat(4, ...) at >=1280                             HERE
       grid gap 16px                                              SPLIT - named here,
                                                                  `--hrv-gap: 16px`, components/_base.css:27
       card  #FFF surface / 1px border / 18px radius / 14px pad /  NOT HERE - every one of these
             flex column / gap 10px / position relative            is components/_product-card.css
                                                                   (rule head :43); 18px resolves
                                                                   through `--hrv-radius`,
                                                                   components/_base.css:21
       media 1/1 aspect, 14px radius                               NOT HERE - _product-card.css
                                                                   rule head :138, border-radius
                                                                   :142, aspect-ratio :145;
                                                                   `--hrv-radius-md`,
                                                                   components/_base.css:22
                 ^ :141 was cited for both, and :141 is `position: relative`. Line citations
                   rot; a rule head plus the declaration's own line is what survives an edit
                   above it.
       name 14.5px / 700                                           NOT HERE - _product-card.css
       price 17px / 700 / Bricolage                                NOT HERE - _product-card.css
       add button 36x36, border-radius 50%, accent fill            NOT HERE - _product-card.css
       pager  gap 8px, centred, current 9px/14px pad, 14px radius,  NOT HERE - components/_toolbar.css
              bg `--hrv-text`, colour `--hrv-band-text`; other page  (:223-262). This file declares
              1px border, 14px radius                                NOTHING about `.pages`.
                 ^ the colour token is named as DECLARED, not as resolved. `_toolbar.css` rule
                   head :252, declaration :259 - the row cited :255, which is `min-width: 40px`,
                   four lines under this file's own warning that a rule head plus the
                   declaration's own line is what survives an edit above it. `pages/_t41.css:546`
                   cites :175 for the same declaration and is also wrong; corrected in the same
                   pass so the two citations cannot disagree. It sets `--hrv-band-text`, which
                   `tokens/_derived.css:61` currently defines as
                   `var(--hrv-bg)` - so the rendered value is identical and an earlier row said
                   `--hrv-bg`. `pages/_t41.css:547` already records that exact substitution as a
                   defect: naming the resolved value hides which token a future change would move.

   ── C. Measured on this page, NOT a T7 defect, filed elsewhere ────────────────────────────
   Each of these was run through the counterfactual in both directions before being left here.

   C1  `.hrv-cols .block.filter .filter-options-content .count` fails AA on ALL FIVE palettes:
       wheat 3.86 | basil 3.82 | tomato 4.02 | plum 4.06 | honey 3.91, need 4.5 at 13px, ground
       `--hrv-surface` (measured `rgb(255,255,255)`, walked live). The declaration is
       `components/_filter-rail.css:169` `color: var(--hrv-text-subtle)`, a SHARED component that
       every category page renders too. NOT PATCHED HERE, and the reason is this theme's own
       written policy rather than reluctance: the T4 artboard specifies
       `color-mix(in oklab, var(--tx) 45%, var(--sf))` for that number - LIGHTER than the 50% the
       theme already uses - so there is no artboard-conformant value that passes, and
       `tokens/_derived.css` has already ruled that "darkening an artboard-authoritative hue ...
       is a DESIGN decision", routing the identical shape to design rather than patching it.
       `--hrv-text-muted` would clear it at 6.00-6.46 on all five. Filed as a theme-wide register
       row with that option attached. Blast-radius UPPER BOUND, stated as a bound because it was
       not re-measured per site: `--hrv-text-subtle` has 17 declarations across 14 files; only
       this one has been measured failing.

   C2  ACCENT AS SMALL TEXT - registers #14/#16, unchanged and awaiting a design ruling.
       `.search.results dl dd a` and `.page-footer a`: wheat 2.82 / honey 4.05, basil 4.62 PASS.
       `.hrv-search-empty-icon`: wheat 3.04 / honey 4.39, basil 5.04 PASS. Accent used AS the
       text colour, over `--hrv-surface` or `--hrv-bg`.

   C2b THE EMPTY-STATE SUBMIT IS THE INVERSE PAIR, AND C2 USED TO SWALLOW IT UNDER A WHEAT FIGURE
       IT DOES NOT PRODUCE. `.hrv-search-empty-submit` is `color: var(--hrv-accent-text)` over
       `background: var(--hrv-accent)` - accent-text ON accent, this theme's primary-CTA pair.
       Measured on the deployed page, five palettes:

           wheat 5.44 PASS | basil 5.04 PASS | tomato 5.02 PASS | plum 7.66 PASS | honey 4.39 FAIL

       Wheat PASSES because `tokens/_derived.css:99/203` deliberately flips `--hrv-accent-text` to
       `--hrv-text` for wheat, under the heading "AA fix - on-accent label colour for Wheat". So
       the old row (a) quoted 3.04 for an element that measures 5.44, (b) filed it under #14/#16
       when this theme's registers #38, #67 and #129 already own `accent-text on accent` with the
       identical five figures, and (c) listed as unresolved the one palette that already has a
       shipped fix. Corroborated by this task's own sweep, which reports `honey/t7-tocart:4.39`
       and NO wheat failure for the same pairing.

       Both counterfactuals still hold for every row above: BASIL PASSES all of them, and fixing
       them would not change basil's verdict, so they neither block nor belong to this task.

   C3  The recovery panel's aisle chips render the tenant's leftover sample-data categories -
       "Electronics, Jewelry, Kitchen, Sports" on a food store. `HarvestAisles` derives them from
       the catalogue, so this is register #12 (sample-data categories in the nav) reaching a
       second surface, not a defect in this file. Tenant data, not theme code.

   C4  `/catalogsearch/advanced/result/` renders the same orphaned `.sidebar-additional` this
       handle now removes (229.33 x 199.56 at y=1475.66). It is T38's page and is filed with the
       same two lines as its fix, rather than changed from a task that is not verifying it.

       AMENDED by basil-T11: "the same two lines" is two of THREE. The removal is inherited by
       three further handles across five vendor files, so the remedy is the two `remove="true"`
       lines plus a `remove="false"` on every handle that must keep its column - otherwise the
       fix silently strips the sidebar from `review_product_list`, which belongs to T41 and
       whose own CSS records a decision to KEEP it. Found by basil-T11's review as a RED against
       its own scope claim. Original wording kept: it was correct about this file's fix and
       wrong only about how far that fix travels.

   ── D. The T8 recovery panel, which this handle renders in the zero-result state ───────────
   The panel's comp is `T8 Search No Results.dc.html` and belongs to basil-T8. Only what THIS
   task changed or measured is listed; the rest of the panel is deliberately untouched.

   D1  aisle chip                    comp: transparent ground,   live: MATCHES, except
                                     1px solid mix(tx 24%, bg),  min-height: 44px
                                     999px radius, 13px, tx      HERE
                                     ^ RECONCILED BY basil-T8. wheat-T7 moved only the label
                                       colour (accent -> `--hrv-text`), because basil FAILED AA
                                       at 4.41 and the comp already specified the value that
                                       fixes it, and it DEFERRED the ground, border, padding and
                                       type size to basil-T8 by name. basil-T8 has now done all
                                       four: transparent ground, the comp's 1px border, 8px/16px
                                       padding, 13px/400 type. Label contrast improved with it,
                                       14.06 -> 16.10 on basil (all five palettes, and the rule
                                       block above carries the row).

                                       THE ONE REMAINING DEVIATION IS `min-height: 44px` against
                                       the comp's ~33px, kept on WCAG 2.5.8: these are the
                                       primary recovery targets on a dead end. Declared rather
                                       than silently followed in either direction, per the
                                       playbook's comp-vs-accessibility rule.

                                       NOT A CONTRAST REGRESSION IN THE OTHER DIRECTION, asked
                                       because removing a ground is the obvious way to cause
                                       one: the comp's border measures 1.89:1 on basil and the
                                       tint it replaces measured 1.14:1, so NEITHER reaches
                                       WCAG 1.4.11's 3:1 and the change improves that number
                                       without being answerable to it — these chips are links
                                       with visible text labels, so the label identifies the
                                       component and the pill is decoration.

   D2  zero-result notice            comp: one message           live: shown when it carries a
                                                                 `dl`, hidden when it does not
                                                                                         HERE
                                     ^ a REFINEMENT of the previous blanket `display:none`, not
                                       a reversal - see the rule's own block above. Core renders
                                       "Did you mean" INSIDE `.message.notice`, so the blanket
                                       rule was hiding a live spelling correction on the recovery
                                       page itself. Measured on ?q=olivve+oill: notice at
                                       y=382.86 carrying two links, panel below at y=507.23; the
                                       "olive oil" link followed for real returns HTTP 200 with
                                       12 cards, ids 49,53,47,46...
                                       AND IT EXPOSED A SHARED DEFECT, fixed in the component
                                       rather than here: `components/_messages.css`'s
                                       `.message a { color: inherit }` is (0,1,1) while Blank
                                       declares `#1979c3` for EIGHT message-link selectors
                                       across SEVEN rule blocks - two GROUPED on one line - at
                                       (0,2,1), and (0,3,1) for the three `.global` ones, so
                                       EVERY message link in this theme rendered Luma blue.
                                       (This sentence read "at (0,2,1) for all seven" until the
                                       S8 gate re-derived it: false on both counts. The S4
                                       loopback had already corrected the identical claim in
                                       `components/_messages.css` - the correction reached one
                                       of its two homes. Search for the CLAIM, not the syntax.) Two live instances measured - these two links,
                                       and `.message.error a` "Modify your search." on
                                       /catalogsearch/advanced/result/, which owed nothing to
                                       this change and was blue on the storefront already.
                                       Post-fix both take their message's own colour: 4.54 and
                                       4.50 against their own grounds, both AA.

   D3  "Popular right now"           comp: heading + 4-card row  live: MATCHES (built by
                                     under the panel               basil-T8)          HERE + a
                                                                   selector on
                                                                   _product-card.css
                                     ^ IT WAS ABSENT ENTIRELY, on a page whose own header comment
                                       twelve screens above already listed it as part of what the
                                       comp draws. Described, never built — the failure mode that
                                       header warns about in the opposite direction ("a comment
                                       naming a page as a consumer is not the page consuming it").

                                       MEASURED BEFORE BUILDING, with the probe calibrated on a
                                       known-PRESENT case in the SAME run so the zero could not
                                       be the instrument's: /checkout/cart/ rendered
                                       `.hrv-home-section` "Popular right now" with 4 cards at
                                       y=658.19 while this page rendered 0 sections, 0 grids and
                                       0 `.product-item`. After: 4 cards at y=760.45 on
                                       ?q=zzzqqqxxx and y=884.83 on ?q=olivve+oill (lower by the
                                       height of the spell-suggestion notice, which is correct).

                                       GUARD PROVEN BOTH WAYS on 0.1.243-local, which is the
                                       property that actually matters here — a "popular" row
                                       leaking onto the populated results page would be a worse
                                       defect than its absence: ?q=olive+oil renders 0 sections
                                       and its 12 result cards, unchanged. It is a CHILD of the
                                       panel block, so it inherits the panel's single
                                       `hasNoResults()` condition instead of adding a second one
                                       that could disagree with it (register #148).

                                       PAGINATION RE-GATED AFTER THE CHANGE, because this handle's
                                       one historical defect was block ordering:
                                       `t7-pagination-check.js` PASS post-`cache:flush`, page 1
                                       ids 49,53,47,46,55,51,117,52,48,121,91,120 / "Items 1-12
                                       of 16", page 2 ids 105,76,54,50 / "Items 13-16 of 16",
                                       0 shared. `Bestsellers` reads the sales aggregate, not the
                                       fulltext collection, and renders inside a block that is
                                       itself `after="search.result"`.

   D4  ...AND IT CARRIES A KNOWN FAILURE ONTO A NEW SURFACE, which is this task's cost and is
       recorded as a cost rather than left for the next sweep to discover. Adding four product
       cards to this state adds a fourth instance of `--hrv-accent-text` on `--hrv-accent`, the
       theme's primary-CTA pair, which FAILS AA on honey at **4.39**. Registers #38/#67/#129 and
       row C2b above already own that pairing with the identical figure; this task creates no new
       pairing and moves no number. `t7-page-palette-sweep.js` now scores it as
       `t8-popular-tocart` — the row was added in the same change, so the new surface is measured
       from its first render rather than from whenever someone next looks.
       Both counterfactuals: basil measures **5.04** and PASSES, so it does not block this task;
       and fixing honey would not change basil's verdict, so it does not belong to it.

   D5  empty-state icon              comp: 72x72 ring, 50%       live: ring MATCHES;
                                     radius, 2px mix(tx 22%,bg),  glyph stays var(--hrv-accent)
                                     glyph 30px mix(tx 45%, bg)                        HERE
                                     ^ THE RING WAS ABSENT AND UNDECLARED. The rule carried three
                                       properties — font-size, line-height, colour — so the box,
                                       the radius, the border and the centring were all missing
                                       and nothing in this file said so. Measured before:
                                       18.7 x 34, no box. basil-T8 built it.

                                       FOUND BY LOOKING AT A SCREENSHOT. Every numeric check
                                       passed — present, visible, non-zero, correctly placed in
                                       flow, and the contrast sweep scored it without complaint.
                                       "Is there a circle around it" was not a property any probe
                                       on this page asked.

                                       THE GLYPH HUE IS THE DEVIATION, AND IT IS DECLARED RATHER
                                       THAN TAKEN. Measured on the deployed page, the comp's
                                       `mix(tx 45%, bg)` over the panel's `--hrv-surface`:
                                       wheat 3.34 | basil 3.30 | tomato 3.47 | plum 3.47 |
                                       honey 3.37, against 4.5. ALL FIVE FAIL, and basil — this
                                       task's own palette — measures 5.04 PASS on the shipped
                                       `var(--hrv-accent)`. So the artboard's own value fails
                                       harder than what ships: register #172's exact shape, and
                                       `tokens/_derived.css`'s standing ruling that darkening an
                                       artboard-authoritative hue is a DESIGN decision applies.
                                       Routed to design; the hue is unchanged by this task.

                                       A CLAIM WAS RETRACTED HERE, and the retraction is the
                                       useful part. This row's first draft asserted that adopting
                                       the comp's hue would RETIRE this element from registers
                                       #14/#16. That was written from the reasoning "the comp
                                       never said accent, so accent is the bug" — plausible, and
                                       false: the comp's hue is worse on every palette. It was
                                       caught only because the sweep was re-run instead of the
                                       paragraph re-read. The wheat 3.04 / honey 4.39 rows in C2
                                       stand, untouched.

   ── E. One thing this file relies on and does not declare ─────────────────────────────
   The desktop `.columns` track above hard-codes `240px 1fr` for a `sidebar-main` that CORE
   supplies, and core does not always supply it. The safety net is
   `components/_layout-columns.css:79`, `.hrv-cols .columns:not(:has(.sidebar-main:not(:empty)))`
   at (0,4,0), which outranks this file's (0,3,0) and collapses the grid to `1fr` when the rail
   is empty or absent - which is exactly what the zero-result state does. Recorded because it is
   invisible from here: reading only this file, the 240px track looks unconditional.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */
