/* ==========================================================================
   OstuGrupp — Otsingu viimistlus (search UX)
   Owner: inc/search-ux.php. Loads site-wide, because section 1 styles the
   header search dropdown and the header renders on every page.

   ⚠ DO NOT EDIT assets/css/live-search.css from here — that file belongs to
   inc/live-search.php and is left byte-identical. Section 1 below OVERRIDES
   four of its rules on purpose; each override states the specificity pair it
   has to beat, and every one of them is arithmetic on the selectors as
   written, NOT a measurement in a browser. The conductor measures.

   ⚠ There is deliberately NO <img> rule in this file. One existed —
     .ogsx-cat .ogsx-cat__img — and it had never matched a single element:
     curl of the rendered no-results page returns ogsx-cat__glyph six times
     and ogsx-cat__img zero times, because no top-level product_cat in this
     shop carries a term thumbnail. The PHP branch that would have emitted
     that <img> is gone too (inc/search-ux.php), so the rule was removed
     rather than left as a rule nobody can test.
     IF an image is ever put back here, remember what the dead rule was
     guarding against: WooCommerce core ships
       .woocommerce img, .woocommerce-page img { height:auto; max-width:100% }
     at (0,1,1), and BOTH search views carry the woocommerce-page body class
     (verified in the live markup) — so any image rule here that sets height
     must clear (0,1,1). CLAUDE.md trap 1.
   ========================================================================== */


/* ==========================================================================
   1 · HEADER DROPDOWN — the row you are on must be unmistakable
   ==========================================================================
   The dropdown already showed picture + name + price on one row and already
   moved with ↑/↓/Enter/Esc (inc/live-search.js). What it did not do was make
   the CURRENT row obvious: live-search.css:85-89 gives the active row the same
   --muted fill as plain hover plus a 1px inset ring at 30% opacity. On a white
   panel, at arm's length, "highlighted" and "not highlighted" looked the same.

   Specificity, selector by selector:
     row       .og-ls-panel .og-ls-list > .og-ls-item > a          (0,3,1)
               beats live-search.css:76 .og-ls-item a              (0,1,1)
     hover     …> .og-ls-item > a:hover                            (0,4,1)
               beats live-search.css:85 .og-ls-item a:hover        (0,2,1)
     active    …> .og-ls-item.is-active > a                        (0,4,1)
               beats live-search.css:86 .og-ls-item.is-active a    (0,2,1)
     title     …> .og-ls-item.is-active > a .og-ls-title           (0,5,1)
               beats live-search.css:121-122                       (0,3,1)
   Hover and active tie at (0,4,1); active is written second, so on a tie it
   wins. That is the order we want — a keyboard user who also has the mouse
   somewhere over the panel should see where the KEYBOARD is.
   ========================================================================== */

/* Wider panel. live-search.css:17-22 sets width at (0,1,0); this is (0,2,0).
   The panel is anchored right:0 and grows leftwards, and the 100vw cap is
   kept so it can never reach past the viewport edge. */
.og-ls-host .og-ls-panel {
  width: min(520px, calc(100vw - 32px));
}

.og-ls-panel .og-ls-list > .og-ls-item > a {
  /* 14px → 12px. tokens.css defines no --space-14 (4, 8, 12, 16, 20, 24, 32,
     40, 48, 56, 64, 80), so `var(--space-14, 14px)` always fell through to its
     literal — and live-search.css:79, the rule this one overrides, already uses
     var(--space-12, 12px). The override was raising the gap off the scale for
     no stated reason; with this line the name --space-14 no longer appears
     anywhere in assets/css. 2px, desktop only (the header search is
     display:none until 1024px, main.css:220-224). */
  gap: var(--space-12, 12px);
  padding: 10px 12px;
  border-left: 3px solid transparent;
  border-radius: var(--radius, 12px);
}

.og-ls-panel .og-ls-list > .og-ls-item > a:hover {
  background: var(--muted, #f1f5f9);
  border-left-color: transparent;
  box-shadow: none;
}

/* The active row: a solid green wash, a 3px green edge and a ring. Three
   signals instead of one, so it survives a bright screen and a bad angle. */
.og-ls-panel .og-ls-list > .og-ls-item.is-active > a {
  background: rgb(4 120 87 / .10);
  border-left-color: var(--green, #047857);
  box-shadow: inset 0 0 0 1px rgb(4 120 87 / .35);
}

.og-ls-panel .og-ls-list > .og-ls-item.is-active > a .og-ls-title {
  color: var(--green-dark, #035e43);
}

/* Bigger picture. live-search.css:91-102 sets 52px at (0,1,0); this is
   (0,2,0). The skeleton box is bumped in the same breath — they are the same
   row a tenth of a second apart, and a size change between them is a jump. */
.og-ls-panel .og-ls-thumb,
.og-ls-panel .og-ls-skeleton-thumb {
  width: 62px;
  height: 62px;
}

/* Price is the second thing a shopper reads and it was the same size as the
   name. live-search.css:125-130 is (0,1,0); this is (0,2,0). */
.og-ls-panel .og-ls-price {
  font-size: 16px;
  color: var(--slate-dark, #1e293b);
}

/* "Vaata kõiki tulemusi (N)" was a quiet text link at the bottom of a list of
   pictures. It is the row that takes you to the whole result set, so it gets
   the weight of a control. live-search.css:150-161 is (0,1,0) → (0,2,0). */
.og-ls-panel .og-ls-all {
  min-height: 46px;
  background: var(--muted, #f1f5f9);
  font-size: 15px;
}

.og-ls-panel .og-ls-all:hover,
.og-ls-panel .og-ls-all.is-active {
  background: var(--green, #047857);
  color: #fff;
}


/* ==========================================================================
   2 · RESULTS PAGE — how many, said once and said large
   ==========================================================================
   Printed by inc/search-ux.php on woocommerce_archive_description, i.e. inside
   <header class="woocommerce-products-header">, straight after the h1.

   Nothing in the theme styles that header beyond margin-bottom
   (archive-polish.css:208 and woocommerce.css:70), and this block sets no
   margin — so there is no rule to outrank here and none of the .ogsx- class
   names exist anywhere else in the theme. The h1's own type is left exactly
   where type-rhythm.css:108-112 put it; heading rhythm is that file's job.  */

/* ⚠️ MOBILE OVERFLOW — the h1 above this band prints whatever the shopper
   typed, and nothing was allowed to break it.
   The heading is `Otsingutulemused: "<term>"`, and type-rhythm.css gives it
   var(--h1) = clamp(28px, 4.4vw, 44px) with `text-wrap: balance` and NO
   overflow-wrap. balance only rebalances lines at existing break opportunities;
   a part number has none. ARITHMETIC at 375px: the container is 375 − 2×24 =
   327px, and a 39-character term like "BOSCH-GSR-12V-15-PROFESSIONAL-06019H8020"
   at 28px Space Grotesk Bold (~0,56em ≈ 15,7px a character) is ~610px — nearly
   twice the width it has. main.css:124 sets `overflow-x: clip` on body, so it
   would not even show as a scrollbar: the end of the shopper's own search term
   is simply cut off the side of the phone.
   Scoped to the `search` body class (present on both search views — verified in
   the curl) so no archive title is touched, and it sets a property nothing else
   in the theme sets on this element, so there is no cascade to win: (0,2,0)
   against type-rhythm's (0,1,1)/(0,2,1) either way. */
.search .woocommerce-products-header__title {
  overflow-wrap: anywhere;
}

.ogsx-band {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-16, 16px);
  margin-top: var(--space-16, 16px);
  padding: var(--space-16, 16px) var(--space-20, 20px);
  background: rgb(4 120 87 / .06);
  border: 1px solid rgb(4 120 87 / .18);
  border-radius: var(--radius-16, 16px);
}

.ogsx-band__lead {
  display: flex;
  align-items: baseline;
  gap: var(--space-12, 12px);
  flex: 1 1 260px;
  margin: 0;
}

.ogsx-band__num {
  font-family: var(--font-display, "Space Grotesk", "DM Sans", system-ui, sans-serif);
  font-weight: var(--fw-bold, 700);
  font-size: clamp(32px, 5vw, 46px);
  line-height: var(--lh-flat, 1);
  color: var(--green, #047857);
  font-variant-numeric: tabular-nums;
}

.ogsx-band__words {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.ogsx-band__unit {
  font-size: var(--fs-xs, 13px);
  font-weight: var(--fw-medium, 500);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-muted, #475569);
}

.ogsx-band__term {
  font-size: 19px;
  font-weight: var(--fw-bold, 700);
  color: var(--slate-dark, #1e293b);
  overflow-wrap: anywhere;
}

.ogsx-band__reset {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--space-16, 16px);
  border: 1px solid var(--border-strong, #cbd5e1);
  border-radius: var(--radius-pill, 999px);
  background: var(--surface, #ffffff);
  font-size: 14px;
  font-weight: var(--fw-semibold, 600);
  color: var(--slate-dark, #1e293b);
  transition: border-color .18s ease, color .18s ease;
}

.ogsx-band__reset:hover {
  border-color: var(--green, #047857);
  color: var(--green, #047857);
}


/* ==========================================================================
   3 · NO RESULTS — the page that used to be one grey box
   ==========================================================================
   .ogsx-zero replaces .ostu-empty-shop on this ONE view (the swap is done in
   PHP, see inc/search-ux.php). archive-polish.css:424-501 keeps owning
   .ostu-empty-shop everywhere else and none of its selectors can reach these
   class names, so the two cannot fight.

   The drawing is assets/img/illustrations/search-empty.svg — the same file
   archive-polish.css:466 uses for the panel this replaces, so the shop does
   not gain a second picture that means the same thing. It is decorative (the
   heading says it in words) and therefore a background on an aria-hidden
   span, which is also the only way it can be used: a background SVG cannot
   inherit currentColor, and this file carries its own hex.                  */

/* ⚠️ VISIBLE ON DESKTOP — a width cap this section never had.
   ARITHMETIC (not measured): main.css:106 --container:1440px and main.css:151
   .container padding-inline:24px, and the rendered no-results page puts this
   section straight inside `<div class="container section-y woo-content">` with
   NO sidebar (verified in the curl of /?s=zzzqqqnothing&post_type=product). So
   at a 1280px viewport the content box is 1280 − 48 = 1232px, and §4's
   three-column grid dealt each tile (1232 − 2×16)/3 = 400px. A 400px tile with
   aspect-ratio 4/3 media is a 300px-tall grey panel around a 68px glyph — the
   grid was the widest thing on the page and the emptiest.
   880px → (880 − 32)/3 = 282,7px per tile, 212px of media. That is one step
   above the measured product card (215px @1280) which is the right order of
   size for a "six doors out" grid.
   The `0` left/right margin became `auto` in the same line; without it a
   max-width here would have pinned the block to the left edge. */
.ogsx-zero {
  max-width: 880px;
  margin: var(--space-24, 24px) auto var(--space-40, 40px);
}

/* 560px is the measure the other empty states in this shop already share —
   empty cart and empty wishlist (empty-states.css, `.og-empty--cart` card and
   `.ostu-wl-page__empty:has(.og-empty__art)`) and empty category
   (archive-polish.css `.woo-content .ostu-empty-shop`). Referenced by selector
   rather than by line: CLAUDE.md invariant 1 records what happens to a line
   number in this repo after a few releases.
   This panel was the one with no cap at all, so on a
   laptop it was a 1232px box holding a 128px drawing, two centred lines and a
   520px form. Same panel, same measure, and it now sits on the same centre
   axis as the tile grid below it.
   Padding follows the same family: 40/24 on a phone, 48/32 from 768px. */
.ogsx-zero__head {
  max-width: 560px;
  margin-inline: auto;
  text-align: center;
  padding: var(--space-40, 40px) var(--space-24, 24px);
  background: var(--surface, #ffffff);
  border: 1px solid var(--border, #e2e8f0);
  border-radius: var(--radius-16, 16px);
  /* The pack's level-1 elevation written as a literal pair, byte-identical to
     archive-polish.css:437-439. The --shadow-card token is deliberately NOT
     used: main.css:98 redefines that name to a lighter recipe and wins on load
     order, so the panel would sit at a different height from its neighbours. */
  box-shadow:
    0 1px 2px var(--ink-a1, rgba(15, 23, 42, .04)),
    0 2px 8px var(--ink-a2, rgba(15, 23, 42, .08));
}

/* clamp(104px, 26vw, 136px), not 96/22vw/128: the SAME drawing is printed at
   104–136px by every other empty state in the shop — empty-states.css
   (`.og-empty__art` for cart + wishlist, `.search-empty__inner::before` for the
   general search, `.error-404__inner::before` for the 404) and
   archive-polish.css (`.ostu-empty-shop__icon`). This file was the only one
   at 96–128, i.e. one picture at two sizes depending on which of the two
   no-results pages you landed on. At 375px both clamps hit their floor
   (26vw = 97,5px < 104px), so the phone gains 8px; at 1280px 136 vs 128. */
.ogsx-zero__art {
  display: block;
  width: clamp(104px, 26vw, 136px);
  height: clamp(104px, 26vw, 136px);
  margin: 0 auto var(--space-20, 20px);
  background: transparent url("../img/illustrations/search-empty.svg") center / contain no-repeat;
}

/* An <h2>. type-rhythm.css writes the default heading scale on the BARE
   element at (0,0,1); this is (0,1,0) and takes this one heading out of that
   default on purpose — it is the loudest sentence on the page and has to
   carry the word the shopper typed.
   3.4vw→3vw and the 32px cap→26px: the SAME failed search renders two
   different pages depending on post_type — /?s=x lands on search.php
   (.search-empty__title) and /?s=x&post_type=product lands here — and the two
   headings were 24px flat vs 22–32px. Both are now clamp(22px, 3vw, 26px),
   which is also where the empty cart sits (woocommerce.css:1105,
   clamp(20px,3vw,26px)). Arithmetic: 375px → 22px (unchanged), 1280px → 26px
   (3vw = 38,4px, capped) where it used to be 32px. */
.ogsx-zero__title {
  margin: 0 0 var(--space-8, 8px);
  font-family: var(--font-display, "Space Grotesk", "DM Sans", system-ui, sans-serif);
  font-weight: var(--fw-bold, 700);
  font-size: clamp(22px, 3vw, 26px);
  line-height: 1.18;
  letter-spacing: -.02em;
  color: var(--slate-dark, #1e293b);
  overflow-wrap: anywhere;
  text-wrap: balance;
}

.ogsx-zero__lead {
  max-width: 54ch;
  margin: 0 auto var(--space-24, 24px);
  font-size: 16px;
  line-height: 1.55;
  color: var(--text-muted, #475569);
}


/* ---- The search field, offered again --------------------------------------
   16px on the input is not a taste call: below 16px iOS Safari zooms the page
   on focus, and a zoomed page is a page the shopper now has to pinch back.
   52px tall clears the 44px touch minimum with room for the border.         */

.ogsx-form {
  display: flex;
  max-width: 520px;
  margin: 0 auto;
  background: var(--surface, #ffffff);
  border: 1px solid var(--border-strong, #cbd5e1);
  border-radius: var(--radius, 12px);
  overflow: hidden;
}

.ogsx-form:focus-within {
  outline: 2px solid var(--green, #047857);
  outline-offset: 2px;
}

.ogsx-form__input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 52px;
  padding: 0 var(--space-16, 16px);
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 16px;
  color: var(--fg, #0f172a);
  outline: none;
}

.ogsx-form__submit {
  flex: 0 0 auto;
  min-height: 52px;
  padding: 0 var(--space-20, 20px);
  border: 0;
  background: var(--green, #047857);
  color: #ffffff;
  font-family: inherit;
  font-size: 15px;
  font-weight: var(--fw-bold, 700);
  cursor: pointer;
  transition: background .18s ease;
}

.ogsx-form__submit:hover {
  background: var(--green-dark, #035e43);
}


/* ==========================================================================
   4 · CATEGORY TILES — six real doors instead of one
   ==========================================================================
   Two columns on a phone, three from 700px. Six tiles therefore land as 3×2
   on a laptop and 2×3 on a phone, and never as a lonely orphan row.
   ========================================================================== */

.ogsx-cats {
  margin-top: var(--space-32, 32px);
}

.ogsx-cats__title {
  margin: 0 0 var(--space-16, 16px);
  text-align: center;
  font-size: 13px;
  font-weight: var(--fw-bold, 700);
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--text-muted, #475569);
}

/* grid-auto-rows:1fr makes all six tiles ONE height, not one height per row.
   The six category names this shop actually returns are (curl of the rendered
   page): Sporditarbed · Aiakaubad · Tööriistad, remont, sanitaartehnika ·
   Kodukaubad · Sõidukid ja varuosad · Tööriistad — one of them is 35
   characters and the shortest is 9, so with `auto` rows the three grid rows
   were three different heights and the block read as ragged. With every row
   the same 1fr the tallest tile sets the height and the other five match it. */
.ogsx-cats__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: 1fr;
  gap: var(--space-16, 16px);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The <li> is a grid item and stretches to the row height by default; making
   it a grid container too means the <a> inside fills it without depending on
   a percentage height resolving. `height:100%` on .ogsx-cat stays as the
   belt-and-braces half of the same job. */
.ogsx-cats__cell {
  display: grid;
  margin: 0;
}

/* ⚠️ THE ROW-STRETCH TRAP — why `grid-template-rows` and `align-items` below
   are load-bearing, and what was actually wrong here.
   The tile is a grid with TWO implicit rows (media, then name+arrow) and both
   were `auto`. `align-content` was never set, and on a grid container
   `align-content: normal` behaves as **stretch**, which grows every auto-sized
   TRACK equally when the container is taller than its content. The container
   IS taller than its content in five tiles out of six, because `height:100%`
   ties each tile to the tallest tile in its row. So the leftover height was
   split 50/50 between the media row and the name row, and `align-items:center`
   then floated the grey media panel in the middle of its oversized track —
   i.e. every short-named tile had a band of white ABOVE its grey panel, a
   different band in every tile, and the six icons sat at six different heights.
   That is exactly the "kas nende sees on tekst ühel kõrgusel" this pass was
   sent to find, and it is invisible in the stylesheet: the rules all "apply".
   Fix, both halves needed:
     • `auto 1fr` — the media track is content-sized (its aspect-ratio decides
       it and all six tiles are the same width, so all six panels are the same
       height, flush at the top), and ALL the leftover height goes to the name
       track, which is where empty space is meant to live.
     • `align-items: start` instead of `center` — the name and the arrow sit at
       the TOP of that track, so the first line of every name is on the same
       baseline across the row no matter how many lines it wraps to. With
       `center` a one-line name floated to the middle of a three-line track. */
.ogsx-cat {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: auto 1fr;
  align-items: start;
  height: 100%;
  background: var(--surface, #ffffff);
  border: 1px solid var(--border, #e2e8f0);
  border-radius: var(--radius-16, 16px);
  overflow: hidden;
  color: var(--slate-dark, #1e293b);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}

.ogsx-cat:hover {
  transform: translateY(-3px);
  border-color: var(--green, #047857);
  box-shadow:
    0 1px 2px var(--ink-a1, rgba(15, 23, 42, .04)),
    0 10px 24px var(--ink-a2, rgba(15, 23, 42, .08));
}

.ogsx-cat:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring, 0 0 0 2px #ffffff, 0 0 0 5px #047857);
}

.ogsx-cat__media {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  grid-column: 1 / -1;
  aspect-ratio: 4 / 3;
  padding: var(--space-8, 8px);
  background: var(--muted, #f1f5f9);
}

/* The glyph branch. (0,2,0) so it outranks anything written on the bare
   element or on a single utility class, and so the width/height ATTRIBUTES the
   icon helper prints (20/40/48) never decide the size — presentation
   attributes lose to any real CSS rule. Square on purpose: every icon in the
   pack is drawn on a square viewBox. */
.ogsx-cat .ogsx-cat__glyph {
  width: clamp(44px, 30%, 68px);
  height: clamp(44px, 30%, 68px);
  color: var(--green, #047857);
}

/* The name and the arrow MUST carry the same top padding — they are two grid
   items in the same row and `align-items:start` now puts both at the track top,
   so an unequal top padding is a visible misalignment between the first line of
   the name and the arrow beside it. Both were 14px, written as
   var(--space-14, 14px); tokens.css has no --space-14 (the scale is 4, 8, 12,
   16, 20, 24, 32, 40, 48, 56, 64, 80), so that var() always fell through to the
   literal and the number was off the scale in fact as well as in name. Both are
   now 12px — the scale step below it — so the tile loses 4px of height and the
   two items still start on the same line. */
.ogsx-cat__name {
  padding: var(--space-12, 12px) var(--space-8, 8px) var(--space-12, 12px) var(--space-16, 16px);
  font-family: var(--font-display, "Space Grotesk", "DM Sans", system-ui, sans-serif);
  font-weight: var(--fw-bold, 700);
  font-size: 16px;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

/* Same 12px top as the name above — see the note there — and the same 1.25
   leading, which it did not have.
   ARITHMETIC: `align-items:start` puts both items at the top of the row, so the
   arrow's line BOX and the name's first line BOX both start at y = 12px, and
   the glyph inside each is centred in its own box. The arrow inherited
   line-height 1.6 from body (main.css:121) → an 18 × 1.6 = 28,8px box against
   the name's 16 × 1.25 = 20px, i.e. the arrow's centre sat (28,8 − 20)/2 =
   4,4px below the first line of the name it points at. At 1.25 the box is
   22,5px and the gap closes to 1,25px (0,6px at ≥700px, where the name grows to
   17px). Under a pixel and a half, and both numbers now come from the same
   leading value instead of two different ones. */
.ogsx-cat__go {
  padding: var(--space-12, 12px) var(--space-16, 16px) var(--space-12, 12px) var(--space-8, 8px);
  font-size: 18px;
  line-height: 1.25;
  font-weight: var(--fw-bold, 700);
  color: var(--green, #047857);
  transition: transform .18s ease;
}

.ogsx-cat:hover .ogsx-cat__go {
  transform: translateX(3px);
}

/* No :has() rule guards the empty case, because there is no empty case: PHP
   omits the whole .ogsx-cat__media span when the glyph does not resolve, so
   the browser is never asked to hide a box it has already laid out. One fewer
   feature this file depends on. */


/* ==========================================================================
   5 · WIDTHS
   ========================================================================== */

@media (min-width: 700px) {
  .ogsx-cats__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .ogsx-cat__name {
    font-size: 17px;
  }
}

/* Second half of the panel padding step. 40/24 below, 48/32 here — the same
   pair empty-states.css gives the empty-cart card in its own (min-width:768px)
   block, so the two panels breathe identically at every width. The old
   (max-width:560px) override that put this panel at 32/16 on a phone is gone
   for the same reason: the cart card is 40/24 there and these two are the same
   component wearing two names. */
@media (min-width: 768px) {
  .ogsx-zero__head {
    padding: var(--space-48, 48px) var(--space-32, 32px);
  }
}

@media (max-width: 560px) {
  /* 14px was the only hand-picked number in this file's spacing, and it was
     written as var(--space-14, 14px) — a token that does not exist
     (tokens.css:213-223 goes 4, 8, 12, 16, 20, 24, 32, 40, 48, 56, 64, 80), so
     it always resolved to the literal anyway. 16px is the scale value next to
     it and matches the horizontal padding on the same line. */
  .ogsx-band {
    padding: var(--space-16, 16px);
  }

  .ogsx-band__reset {
    flex: 1 1 100%;
    justify-content: center;
  }

  /* ⚠️ THE PHONE FIX — the arrow was eating the name.
     ARITHMETIC at 375px (not measured): .container is 375 − 2×24 = 327px, the
     grid is two columns with a 16px gap, so each tile is (327 − 16)/2 =
     155,5px. Inside the tile the second column held the "→": its own padding
     is 8px left + 16px right and the glyph is ~18px at font-size 18 → ~42px.
     The name column therefore got 155,5 − 42 = 113,5px, and its own 16px+8px
     padding left ~89px of TEXT. The longest real category name in this shop is
     "Tööriistad, remont, sanitaartehnika", and "sanitaartehnika" alone needs
     ~118px at 14px (15 characters × ~7,8px, Space Grotesk Bold ≈ 0,56em) — so
     `overflow-wrap: anywhere` did what it was told and cut a word in half on
     the phone, which is the single most-visible sloppiness on this page.
     Dropping the arrow (it is aria-hidden="true" and decorative; the tile is
     already a card-shaped link with hover, focus ring and border) and using
     symmetric 12px padding gives the name 155,5 − 24 = 131,5px. Every one of
     the six real names now fits its longest word: sanitaartehnika ~118px,
     Sporditarbed ~94px, Kodukaubad ~78px, varuosad ~63px. ~14px of slack on
     the worst case, so a wider font fallback still does not break a word.
     14px is --fs-sm; this is a tile label, not body copy, and the 16px floor
     the brief sets is a rule about INPUTS (iOS zoom), which this is not. */
  .ogsx-cat {
    grid-template-columns: minmax(0, 1fr);
  }

  .ogsx-cat__go {
    display: none;
  }

  .ogsx-cat__name {
    padding: var(--space-12, 12px);
    font-size: var(--fs-sm, 14px);
  }

  .ogsx-form {
    flex-wrap: wrap;
  }

  .ogsx-form__input {
    flex: 1 1 100%;
  }

  .ogsx-form__submit {
    flex: 1 1 100%;
  }
}


/* ==========================================================================
   6 · REDUCED MOTION
   --------------------------------------------------------------------------
   Every transform in this file is decoration on top of a colour change that
   says the same thing, so removing the movement loses no information.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .ogsx-cat,
  .ogsx-cat__go,
  .ogsx-band__reset,
  .ogsx-form__submit {
    transition: none;
  }

  .ogsx-cat:hover {
    transform: none;
  }

  .ogsx-cat:hover .ogsx-cat__go {
    transform: none;
  }
}
