/* ==========================================================================
   T39 — Popular search terms (/search/term/popular/)

   SCOPED ON `.hrv-page-t39`, A DECLARED CLASS, AND THE NATIVE `search-term-popular` IS ASSERTED
   SEPARATELY RATHER THAN USED AS THE HOOK.
   Both classes are really on <body> — MEASURED on the live page with the render rig before a line
   of this file was written, not reasoned by analogy from `catalogsearch-advanced-index`. Two
   plausible guesses (`catalogsearch-term-popular`, `search-term-popular-index`) are both wrong,
   and a reskin scoped to a GUESSED body class is 100% dead CSS that passes every static review —
   this theme has already lost a stylesheet that way (T14). `hrv-page-t39` is declared by this
   theme's handle; wheat-T39.json asserts BOTH, so a failure names which hook broke instead of
   sending every geometry row red at once.

   THE ROUTE IS `/search/term/popular/`, NOT `/catalogsearch/term/popular/`. The controller lives in
   module-search (frontName `search`), not module-catalog-search. The natural guess returns 404 —
   indistinguishable from a handle that never merged. Measured with a known-200 and a known-404
   control, plus the without-`X-Forwarded-Proto` case in which every route on this store answers
   302.

   THIS IS A RESKIN OF CORE MARKUP, AND NO TEMPLATE IS FORKED.
   `Magento_Search::term.phtml` already does the thing that looks bespoke in the artboard: it sizes
   each term by popularity, emitting `font-size: (ratio*70+75)%` per `li#term-<id>` through
   `renderStyleAsTag`. Everything below is therefore either UNDOING a default or declaring a look —
   never reproducing behaviour core already has. The breadcrumb row the comp draws is added from
   layout via `addCrumb` against core's own site-wide `breadcrumbs` block.

   COMPONENTS THAT ALREADY OWN ELEMENTS ON THIS PAGE — enumerated with the grep the playbook
   mandates, before a line was written, because on T15 six of eight elements were already owned and
   skipping this produced a duplicated card shell and an AA-failing #fff:
     .breadcrumbs      `components/_breadcrumbs.css` owns the whole trail — 12px, muted, flex
                       `.items`, "/" separator, current crumb in `--hrv-text`. THIS FILE DECLARES
                       NOTHING ABOUT IT. The comp draws "›"; the component's docblock records the
                       slash as a deliberate theme-wide decision, and a page task must not fork a
                       component for one glyph.
     .message.notice   `components/_messages.css` owns core's empty-cloud else-branch. Not styled
                       here, and not asserted either — see below.
     h1                `components/_base.css` (32px, 26px under 768). Magento's own page-title
                       block, outside `.hrv-t39`. Untouched.
     .search-terms     OWNED BY NOBODY. `grep -rln search-terms web/css/components/` returns
                       nothing, and a rule walker over the LIVE page's `document.styleSheets`
                       found no author rule matching it either. Stated because "the theme has no
                       rule for X" is exactly the claim the playbook forbids writing without
                       running the grep.
     tokens            `tokens/_derived.css` owns every colour below. No literal colour appears in
                       this file.

   WHAT THE CASCADE ACTUALLY CONTAINS, read from the live page rather than assumed — and one
   correction to my own first reading, recorded because it changed the answer:
     the bullets and the 40px indent come from the USER-AGENT STYLESHEET, not from Blank. A walker
     over `document.styleSheets` found exactly ONE author rule matching `ul.search-terms`:
     `ul, ol { margin-bottom: 2.5rem }` in `styles-m.css` (2.5rem = 25px here, since Magento sets
     the root to 62.5%). "Blank does it" would have sent the next reader to the wrong file.

     for the anchors, my first walker reported `a, .alink { color: rgb(25,121,195) }` at (0,1,1)
     beating `_base.css`'s `a` at (0,0,1) — which would mean the live links were Magento blue. They
     measure `rgb(192,138,45)`. THE INSTRUMENT WAS WRONG, NOT THE PAGE: specificity is per-selector
     within a selector list, so for an `<a>` the matching half is `a` at (0,0,1), a tie that source
     order resolves in `_base.css`'s favour. Written down because the wrong number was nearly
     recorded here as a fact.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. The measure — 900, the comp's own

   REGISTER #98. The artboard's wrapper is `padding: 32px 40px 0; max-width: 900px` on a
   CONTENT-BOX document: 900 of content, 980 of border box. Under Harvest's theme-wide
   `* { box-sizing: border-box }` a literal transcription of BOTH declarations yields 820 of
   content — 80px short — while `rect.width` still reads a reassuring 900. So the horizontal
   padding is NOT transcribed: `.page-main` already supplies the comp's gutter (MEASURED 16 / 24 /
   24 / 24 / 32 / 32 at the six gated widths), and with no inline padding here
   `content.width === rect.width` and the trap has nothing to act on. The gate still asserts
   `content.width` rather than `rect.width`, because that is the property that MOVES if anyone ever
   adds `padding-inline`, and a row that cannot move is not coverage.

   NO `margin-inline: auto`. The comp's cloud is left-aligned against the page gutter, flush with
   the h1 and the breadcrumb above it — not centred.

   MEASURED `.column.main` content: 343 / 720 / 900 / 901 / 960 / 1376 at 375 / 768 / 948 / 949 /
   1024 / 1440. So this cap is satisfied EXACTLY WITHOUT BINDING at 948 and FIRST BINDS at 949 —
   derived (padding is 24 below 1024, so content = W - 48 first exceeds 900 at W = 949) and then
   re-measured at both, because below the binding edge a capped and an uncapped wrapper measure
   identically and a gate that only checked 375/768/1440 would be blind to this rule at most of
   its widths.
   -------------------------------------------------------------------------- */
.hrv-page-t39 .hrv-t39 {
  max-width: 900px;
}

/* --------------------------------------------------------------------------
   2. The cloud — a wrapping row instead of a bulleted list

   `display: flex` and `flex-wrap: wrap` are asserted as SEPARATE gate rows on purpose: flex
   WITHOUT wrap puts 24 terms on one line and shrinks them, which produces horizontal overflow
   rather than a cloud. The two failures look nothing alike and should not share a row.

   THE `<ul>` HAS 48 CHILDREN, NOT 24, AND THAT IS THE LOAD-BEARING FACT IN THIS BLOCK.
   Measured: `LI,SCRIPT,LI,SCRIPT,…`. Core's `term.phtml` emits each term's font-size through
   `renderStyleAsTag`, which under CSP ships a `<script>` as a SIBLING of every `<li>`, INSIDE the
   `<ul>`. Making this element a flex container therefore hands 24 script elements to the flex
   algorithm. They are `display: none` in the UA sheet so they generate no boxes and the layout is
   correct — but that is an assumption borrowed from a stylesheet this theme does not control, and
   it is the same shape as the Luma `::before` clearfix that became a grid item, ate a track and
   threw a card grid diagonally. `scripts-in-the-cloud-generate-no-box` asserts it rather than
   trusting it.

   Every selector here is `li` or `li > a` and never `> *`, for the same reason.

   `gap: 0 2px` IS DERIVED, NOT PICKED. The comp sets `gap: 14px 22px` between BARE TEXT items.
   These anchors carry `padding: 0 10px` of their own, so adjacent terms already have 20px of
   space between their text edges; 2px of column gap makes it the comp's 22px exactly — FOR ANY
   TERM WIDER THAN THE 44px FLOOR, which is most of them. A short term is wider than its text: with
   `min-width: 44px` and `justify-content: center`, `oli` (12px of text) sits in a 44px box with
   ~16px of centring slack per side, so its neighbours are ~34px from its glyphs rather than 22px.
   That is the floor doing its job and it cannot be tuned away without giving up the tap target;
   stated here because the previous version of this paragraph gave the 22px figure as
   unconditional. S1 correctness review. The ROW gap
   is 0 because the 44px floor below already contributes 12–15px of vertical padding above and
   below each term's text — adding the comp's 14px on top would double-count space the comp does
   not have.
   THE ROW PITCH WAS 54px, NOT THE 44 THIS PARAGRAPH ORIGINALLY CLAIMED, AND THE EXTRA 10px WAS
   NOT MINE TO GIVE. S4 asked for the pitch to be measured rather than asserted off a screenshot;
   it read 383 / 437 / 491 at 1440, i.e. 54. The difference is Blank's `ul > li, ol > li
   { margin-bottom: 1rem }` in `styles-m.css` (1rem = 10px here), found with a rule walker — the
   `<ul>` reset above cleared the list's own margin, padding and bullets and never touched the
   ITEMS. So the vertical rhythm of this cloud was being set by an unreset framework default while
   this comment took credit for it. `margin: 0` on the `li` below fixes it and the pitch becomes
   44 — still looser than the comp's ~36, but now a number this file chose. Consequence, stated plainly rather than left to be noticed: the cloud is LESS DENSE
   than the artboard draws it. That is the unavoidable price of register #106 and it is recorded as
   a known divergence in the manifest.

   `list-style: none` and `padding-left: 0` beat the USER-AGENT sheet (see the header note), so
   any author rule wins; `margin` beats `styles-m.css`'s `ul, ol { margin-bottom: 2.5rem }` with
   (0,3,0). That rule's specificity against a `<ul>` is (0,0,1), NOT (0,0,2) as this line first
   said: specificity is computed PER SELECTOR within a list, so only the matching half (`ul`)
   counts. The outcome is unchanged — (0,3,0) wins either way — but the header of this very file
   records nearly shipping the same error for `a, .alink`, and making it twice in one file is worth
   the correction. S1 correctness review.
   -------------------------------------------------------------------------- */
.hrv-page-t39 .search-terms {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 2px;
  list-style: none;
  margin: 0 0 48px;
  padding: 0;
}

.hrv-page-t39 .search-terms li {
  display: flex;
  margin: 0;
}

/* --------------------------------------------------------------------------
   3. The term — where the artboard is corrected rather than transcribed

   THE 44px FLOOR (register #106), AND IT IS AAA RATHER THAN AA — SAID PLAINLY BECAUSE THE ROW IS
   CALLED `every-term-meets-the-44px-tap-target` AND READS LIKE A LEGAL MINIMUM. WCAG 2.2 SC 2.5.8
   Target Size (Minimum) is level AA and asks for 24x24 CSS px with a spacing exception; 44x44 is
   SC 2.5.5 Target Size (Enhanced), level AAA. This theme uses 44 in four other components and
   register #106 is written against 44, so matching the house number is right — but it is a
   deliberate over-delivery, and it is PAID FOR in comp fidelity (see the density note in section
   2), so it should not be presented as a floor somebody else imposed. S3 review.

   THE ALTERNATIVE WAS REAL AND IS REJECTED ON THE RECORD RATHER THAN ASSERTED AWAY — both S1 and
   S4 raised it independently. Expanding only the HIT box with a positioned pseudo-element
   (`a { position: relative } a::after { content:""; position: absolute; inset: -12px }`) keeps the
   comp's 14/22px gaps AND gives >=44px of pressable area. It is rejected because of what it does
   BETWEEN terms: at the comp's 22px column gap, two neighbours each expanding 12px overlap by
   ~2px, so a click in the gap lands on whichever pseudo-element paints last rather than on the
   nearer word. On a page that is nothing but adjacent links, trading a visible-density gain for
   silently mis-targeted clicks is the wrong direction — and the overlap would be invisible to
   `tapTarget`, which reads each box in isolation. Priced, not dismissed.

   The comp draws its terms at 9px–22px as bare inline anchors.
   MEASURED on the live page before this task, the 24 real anchors are 13–24px tall and 12–115px
   wide; the smallest, "oli", is a 12 × 13 hit box. Transcribing the comp here would ship 24
   controls no thumb can hit, on a page whose entire purpose is being tapped.

   `min-width` AS WELL AS `min-height`, and that is the half that is usually forgotten. A tag cloud
   sizes by term LENGTH, so the shortest terms are exactly the ones that fail — and #106's own
   record is of three FAQ summaries that met 44 only because their English copy happened to wrap,
   i.e. the property was never defended and English was doing the work. `oli`, `oil` and `Wine` all
   need the floor; a German or Polish store view would shift which ones do.

   `display: inline-flex` IS NOT COSMETIC — an inline box cannot take a min-height at all, so this
   declaration is what the whole floor depends on. It has its own gate row for that reason: without
   it the failure surfaces as 24 red tap-target rows with no cause named.

   IT COMPUTES TO `flex`, NOT `inline-flex`, AND THE GATE EXPECTS `flex`. The `li` above is a flex
   container, so this anchor is a FLEX ITEM, and CSS blockifies a flex item's display. The first
   version of the gate row expected `inline-flex` and was the single failure in an otherwise green
   run — the expectation was wrong, not the rule. `inline-flex` is kept here rather than changed to
   match the computed value, so this rule still produces an inline box if the `li` rule above is
   ever removed; the two are recorded as coupled instead of silently depending on each other.

   THE FLOOR IS ALSO ASSERTED AS `spread.height === 0`, WHICH IS STRICTLY STRONGER. The 24 anchors
   carry 24 different font sizes (10.5px–20.3px, measured), so `tapTarget >= 44` alone would still
   pass if the floor were reached by 24 separate accidents of text metrics — which is #106's defect
   exactly. A zero spread proves the FLOOR set the height, and that survives a copy change, a
   locale change, or a term with taller glyphs.

   THE COLOUR IS `--hrv-accent-strong`, NOT THE COMP'S ACCENT, AND THIS IS AN AA CORRECTION.
   `_base.css:93` gives every anchor in the theme `color: var(--hrv-accent)` — #C08A2D on #FBF6EC,
   MEASURED 2.82:1 with a self-testing canvas reader (black/white 21, white/white 1, #767676 4.54,
   `oklab(0.6 0 0)` 3.95, garbage rejected). WCAG 2.1 SC 1.4.3 needs 4.5:1 for normal text, and
   this page is 24 links and almost nothing else. `--hrv-accent-strong` is the same hue darkened
   and measures 5.58:1. THE THEME-WIDE INSTANCE IS NOT FIXED HERE: `_base.css:93` affects every
   unstyled link on every page in every palette, and "a fix that reached one page" is an
   anti-pattern this register records five times. Filed instead.

   ONE TIER, NOT THE COMP'S TWO — the one divergence a reviewer will notice first. The artboard
   draws four large terms in the accent and the display face, and eight small ones muted in the
   body face. That split is a function of POPULARITY, which core expresses ONLY as a computed
   font-size; there is no class, no attribute and no ordinal on the `li`, and CSS cannot select on a
   computed font-size. Reproducing it means forking a core template to add a class — a permanent
   drift liability, and the loss of the 2-second hot-sync loop for every future fix on this page,
   since `opcache.validate_timestamps=Off` means a copied .phtml is never executed. The hierarchy
   the comp is actually communicating IS present: core still sizes each term 10.5px–20.3px.
   -------------------------------------------------------------------------- */
.hrv-page-t39 .search-terms li a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  padding: 0 10px;
  line-height: 1.15;
  color: var(--hrv-accent-strong);
  font-family: var(--hrv-font-display);
  border-radius: var(--hrv-radius-pill);
}

/* Hover is a filled pill rather than a colour change: at these sizes a hue shift on a 10px word is
   nearly invisible, and the 44px box already exists to be filled. `--hrv-accent-tint` is the
   theme's existing wash; `--hrv-text` on it measures well clear of AA. */
.hrv-page-t39 .search-terms li a:hover {
  background: var(--hrv-accent-tint);
  color: var(--hrv-text);
}

/* --------------------------------------------------------------------------
   4. Focus — the page stops shipping an indicator nobody can see

   `--hrv-focus-ring` resolves to `color-mix(in oklab, #C08A2D 60%, #FBF6EC)` and MEASURES 1.8:1
   against this page's background, where WCAG 2.2 SC 1.4.11 requires 3:1. It fails at every site
   that uses it. That is a TOKEN decision with an open ticket (869ejk6zm / register #90, which also
   records that no single colour can fix it) and NOT a thing to settle inside a page task — so the
   token is left alone and this page declares its own ring, exactly as T38 did for its inputs and
   submit and T37 did for its CTAs. `--hrv-text` measures 15.34:1 here.
   DECLARED DIVERGENCE: this page's ring is a different colour from the theme's other focus sites
   until that ticket lands. That is deliberate and is the same divergence T37 and T38 already carry.

   `:focus-visible` AND NOT `:focus`, WHICH IS THE OPPOSITE OF T38'S CHOICE AND CORRECT FOR BOTH.
   T38's controls are TEXT INPUTS, where a caret target is wanted on every focus regardless of
   modality. These are ANCHORS, where `:focus-visible` is what suppresses a ring on a mouse click —
   T37 made the same call for the same reason.

   THE SELECTOR QUOTED BELOW IS THE ONE THIS FILE SHIPS. An earlier version of this paragraph
   quoted `.hrv-page-t39 .hrv-t39 .search-terms li a:focus-visible` while the rule read
   `li > a:focus-visible`, and the scope has since dropped `.hrv-t39` as well — in a file whose
   whole value is that its comments are measured, quoting a selector it does not ship is the
   cheapest possible way to lose that. S3 review.

   REGISTER #105 — SPECIFICITY, AND WHY THE OBVIOUS RULE WOULD LOSE.
   Luma's `styles-m.css` ships `._keyfocus *:focus` at (0,2,0), and Magento adds `_keyfocus` to
   <body> only on the first TRUSTED Tab — so the resting cascade is not the keyboard cascade, and a
   scripted `.focus()` measures a state the keyboard user never has. `_base.css:95`'s
   `a:focus-visible` is (0,1,1), i.e. OUTRANKED by Luma's rule wherever the two declare the same
   property. Stated carefully because the first version of this paragraph asserted flatly that it
   "LOSES", which is an inference: a rule is only overridden by one declaring the same property,
   and Luma's `_keyfocus` rule declares `box-shadow` while the `outline: 0` reset is a separate
   `*:focus` at (0,1,0). The arithmetic is right, the conflict was assumed. It does not change what
   this page does — the rule below wins on either reading — and the outcome was MEASURED rather
   than argued: a trusted Tab (14 real key events through CDP) landed on a term anchor with
   `_keyfocus` on <body> and computed `outline: 2px solid rgb(36,30,20)`, which is `--hrv-text`,
   i.e. this rule. This selector is
   `.hrv-page-t39 .search-terms li a:focus-visible` = FOUR class-level components
   (three classes plus the pseudo-class) and two type selectors, (0,4,2), which beats (0,2,0)
   comfortably. The gate reads this with `_keyfocus` FORCED onto <body> for that reason, and a real
   Tab is driven through CDP separately, because "Magento adds the class on a trusted key" is not
   something a scripted run can prove about itself.
   -------------------------------------------------------------------------- */
.hrv-page-t39 .search-terms li a:focus-visible {
  outline: 2px solid var(--hrv-text);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   5. Mobile

   Only the bottom margin moves. The cloud is already fluid — it wraps by construction, the cap
   never binds below 949, and the 44px floor is a floor at every width, not a desktop affordance.
   Deliberately NO font-size media query: the sizes are core's, computed per term from popularity,
   and overriding them here would flatten the one piece of hierarchy the artboard is actually
   communicating.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {
  .hrv-page-t39 .search-terms {
    margin-bottom: 32px;
  }
}

/* --------------------------------------------------------------------------
   6. The EMPTY state — the other rendering of this page, and it failed AA

   S3 FOUND THIS AND THE HEADER OF THIS FILE HAD EXPLICITLY DECLINED TO LOOK AT IT ("not styled
   here, and not asserted either"). Core `term.phtml` has an else-branch rendering
   `<div class="message notice">` when the collection is empty — the DEFAULT state of any fresh
   tenant, and of any store where every query has num_results = 0. `components/_messages.css`
   colours `.message.notice` with `var(--hrv-accent)` on `var(--hrv-accent-tint)`, which is the
   SAME 2.82:1 pair section 3 exists to fix. The page raised its links to AA in five palettes and
   left its other half at the number it was complaining about.

   MEASURED, not computed from token hex, and measuring changed the answer. The review predicted
   all five palettes would fail; building core's markup and reading it in each gives
   wheat 2.82, basil 4.54, tomato 4.50, plum 6.74, honey 3.98 — TWO fail (wheat and honey) and
   tomato passes by 0.00. The review flagged its own figure as an expectation rather than a
   reading, which is the only reason the difference is visible instead of inherited.

   Same remedy as the links, for the same reason: page-scoped here, theme-wide filed. This does NOT
   fork `_messages.css` — it overrides one property for one page, at (0,3,0) against that file's
   (0,2,0), and the component keeps owning the border, the background and the layout.
   -------------------------------------------------------------------------- */
.hrv-page-t39 .message.notice {
  color: var(--hrv-accent-strong);
}
