/* ==========================================================================
   OstuGrupp — OSTUKAST (buybox.css)

   WHAT THIS FILE CHANGES, IN ONE SENTENCE
   The buy block stops being a white card with rows stacked inside it and
   becomes a THREE-PART panel: a coloured stock band across the top, a white
   information middle (price, savings, specs), and a shaded purchase zone at
   the bottom that holds the quantity stepper, the running sum and a
   full-width call to action. Old vs new side by side reads as two different
   components, not as the same one with tighter spacing.

   WHAT IT DOES NOT TOUCH
   · The main price. Its size (32px / 27px on phones) and its colours live in
     woocommerce.css:685-691 and were fixed in a separate pass. Nothing here
     names `.price`, `.price ins` or `.price del`.
   · Anything to do with how money leaves the customer. No selector in this
     file names a checkout gateway, a gateway box or a gateway radio row, in
     code or in a comment. The one third-party instalment-calculator line that
     renders between the price and the savings row sits ABOVE the purchase
     zone this file introduces (measured in the live markup) and is never
     matched by any rule below.
   · Delivery wording, and its weight. `.ostu-delivery` (inc/cart-boosters.php)
     is touched by one property, `background`, and set to `transparent` so it
     reads as a plain row in the purchase zone. Its text is untouched, no new
     promise is written anywhere, and — see section 4 — it is deliberately NOT
     lifted into a white card: the shop's delivery window is disputed between
     the product page and the terms of sale, and a disputed claim does not get
     extra prominence from this file.

   ---------------------------------------------------------------------
   SPECIFICITY — arithmetic, written out, because Trap 1 has been paid for
   four times in this repo
   ---------------------------------------------------------------------
   Everything below is anchored on

     .single-product.woocommerce .summary .ostu-buybox        = (0,4,0)

   and grows from there. The numbers it has to beat, read out of the shipped
   sheets, not guessed:

     single.css:60   .single-product .summary .ostu-buybox               (0,3,0)
     single.css:68   .single-product .summary .ostu-buybox > :first-child(0,3,0)
     single.css:71   … .ostu-buybox .ostu-status-row                     (0,4,0)
     single.css:72   … .ostu-status-row .ostu-stock-badge                (0,5,0)
     single.css:74   … .ostu-buybox form.cart                            (0,4,0)
     single.css:166  .ostu-stock-badge                                   (0,1,0)
     single.css:219  .single-product .ostu-status-row                    (0,2,0)
     single.css:457  .ostu-stock-badge  (inside @media)                  (0,1,0)
     product-polish.css:248 .single-product.woocommerce .summary .ostu-buybox (0,4,0)
     woocommerce.css:713  .single-product form.cart:not(.variations_form)
                          :not(.grouped_form)                            (0,4,1)
     woocommerce.css:717  .single-product .quantity input.qty            (0,2,1)
     woocommerce.css:721  .single-product .single_add_to_cart_button     (0,2,0)
     woocommerce.css:1655 same, inside @media                            (0,2,1)
     woocommerce.css:1657 same, inside @media                            (0,2,0)
     WooCommerce core (woocommerce-layout.css)
                     .woocommerce div.product div.summary                (0,3,2)
     WooCommerce core (woocommerce.css)
                     .woocommerce div.product form.cart .button          (0,4,2)
                     .woocommerce div.product form.cart .quantity        (0,4,2)

   A media query adds NOTHING to specificity, so the (0,6,1)…(0,8,2) rules in
   this file beat the mobile blocks in woocommerce.css from outside any query.
   That is deliberate and is why the responsive section here is short.

   ---------------------------------------------------------------------
   WHAT IS PROVEN, AND WHAT IS NOT
   ---------------------------------------------------------------------
   PROVEN: the markup. The served product page was fetched and read
   (http://og.local/pood/…/aiakaru-voolikurulliga-76-m-4-ratast-tugevdatud/),
   and it carries exactly one `.ostu-buybox`, inside `div.product >
   div.summary.entry-summary`, with one `.ostu-buy`, one `form.cart`, one
   `.quantity` holding both stepper buttons, and one `.ostu-bb-total` — all of
   them printed with the `hidden` attribute the JS is supposed to remove. Every
   specificity figure in this file was recomputed selector by selector against
   that markup; three of them were wrong on the first pass and are corrected in
   place (sections 1, 5).

   NOT PROVEN: computed values. No browser measured this file, so nothing here
   states a pixel that was read out of DevTools. The one rule whose outcome
   cannot be derived on paper at all is the sticky block in section 1 — whether
   it has any travel depends on the measured height of `.summary`, which no
   arithmetic here can supply. It is fenced and can be deleted as one block.
   ========================================================================== */


/* ==========================================================================
   1 · THE PANEL — a fixed inner gutter, and sticky on wide desktops
   ==========================================================================
   THE GUTTER IS LOCKED ON PURPOSE. Sections 2 and 4 pull the top band and the
   purchase zone out to the card's inner edge with a negative margin, so that
   margin has to equal the card's padding EXACTLY or the bands will not line
   up. Today two files set that padding: product-polish.css:248 says 24px on
   every side, single.css:62 says `22px 24px 24px`, and product-polish is
   behind its own owner toggle. Restating 24px here pins the number whichever
   toggles are on. It is the same value product-polish already sets, so this is
   not a fork, and at most it moves the top padding by 2px if the owner ever
   switches product polish off.

   (0,4,0) — FOUR classes. An earlier note here said (0,5,0); that was one
   class too many, and it made the rule sound stronger than it is. Counted
   again, against the numbers it actually meets:
     · single.css:60   (0,3,0)  — beaten on specificity, always.
     · product-polish.css:248   — the IDENTICAL selector, so (0,4,0) against
       (0,4,0) is a TIE, decided by source order, not by arithmetic. This file
       is enqueued at priority 22 against that file's 21, and the served page
       confirms it (product-polish is stylesheet 37, buybox 38). Losing that
       tie would cost nothing anyway: the declaration on the other side is the
       same `padding: 24px`.
   The two custom properties are NOT in that contest. No other sheet in this
   theme declares `--ostu-bb-pad` or `--ostu-bb-inner-radius`, and the cascade
   is settled one property at a time — so even if the padding line ever lost,
   the variables the negative margins in sections 2 and 4 read would still be
   the ones set here. */
.single-product.woocommerce .summary .ostu-buybox {
  padding: var(--space-24, 24px);
  /* The bands in §2/§4 bleed to the card's inner edge. The card border is 1px,
     so the inner corner radius is the outer radius minus that border. */
  --ostu-bb-pad: var(--space-24, 24px);
  --ostu-bb-inner-radius: 15px;
}

/* STICKY — the one rule in this file that cannot be verified on paper.
   The gallery beside this column is already sticky (woocommerce.css:611-630,
   verified live), which proves that no wrapper from `div.product` upwards
   clips a sticky child. The only wrapper that is NEW in this chain is
   `.summary.entry-summary` itself; a scan of the theme sheets and of every
   plugin stylesheet in the local install found no `overflow`, `contain`,
   `filter` or `transform` on it — only on `.woocommerce-review-link`, which
   sits BELOW the sticky element and so cannot clip it.

   z-index IS load-bearing. A sticky element that comes FIRST in source order
   is painted UNDER the siblings that follow it, so once pinned it would have
   the info accordion drawn on top of it. `z-index: 1` puts it above its own
   siblings and nowhere near the header (which sits far higher).

   Fenced to wide AND tall windows: on anything shorter the panel is taller
   than the viewport, sticky never engages, and the rule is dead weight.

   (0,6,1) — six classes plus the `div` element. `.ostu-buybox` is a
   theme-only class; no core or plugin sheet ships a rule for it, so there is
   nothing here to lose to. */
@media (min-width: 1200px) and (min-height: 800px) {
  .single-product.woocommerce div.product .summary.entry-summary .ostu-buybox {
    position: sticky;
    top: 96px;
    z-index: 1;
  }
}


/* ==========================================================================
   2 · THE STOCK BAND — the first thing the eye lands on
   ==========================================================================
   Was: a small pill floating inside the white card, 13px, with an 8px dot.
   Now: a full-width coloured band across the head of the panel, carrying a
   20px icon and 14px text, with a hairline under it.

   The text is unchanged — it is whatever inc/single-product.php built from
   WooCommerce's own stock state ("Laos", "Laos — viimased N tk", "Otsas").
   Nothing is invented here and no number is written by this file.

   THE TINT NEEDS `:has()`. The state class (`--in` / `--low` / `--out`) sits
   on the CHILD badge, so the band can only colour itself by asking what it
   contains. In a browser without `:has()` the three tint rules AND the
   badge-flattening rule below drop together, while the plain band rule
   survives: the result is a neutral grey band with today's coloured pill
   still sitting in it. Degraded, coherent, and not broken — the colour signal
   is never lost, it just moves back onto the pill.

   (0,5,0) for the band; `:has()` contributes the specificity of its argument,
   so the tinted variants are (0,6,0). Both beat single.css:71 (0,4,0). */
.single-product.woocommerce .summary .ostu-buybox .ostu-status-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8, 8px);
  margin: calc(var(--ostu-bb-pad, 24px) * -1) calc(var(--ostu-bb-pad, 24px) * -1) var(--space-20, 20px);
  padding: var(--space-12, 12px) var(--ostu-bb-pad, 24px);
  min-height: 48px;
  background: var(--surface-muted, #f1f5f9);
  border-bottom: 1px solid var(--border, #e2e8f0);
  border-radius: var(--ostu-bb-inner-radius, 15px) var(--ostu-bb-inner-radius, 15px) 0 0;
}

.single-product.woocommerce .summary .ostu-buybox .ostu-status-row:has(.ostu-stock-badge--in) {
  background: var(--brand-a1, rgb(4 120 87 / .06));
  border-bottom-color: var(--brand-a3, rgb(4 120 87 / .20));
}
.single-product.woocommerce .summary .ostu-buybox .ostu-status-row:has(.ostu-stock-badge--low) {
  background: rgba(245, 158, 11, .12);
  border-bottom-color: rgba(245, 158, 11, .34);
}
.single-product.woocommerce .summary .ostu-buybox .ostu-status-row:has(.ostu-stock-badge--out) {
  background: rgba(185, 28, 28, .09);
  border-bottom-color: rgba(185, 28, 28, .28);
}

/* Inside a tinted band the pill would be a second surface on a surface, so it
   is flattened to plain text. Guarded by the same `:has()` as the tint, so
   the two can never disagree. (0,7,0) vs single.css:72 (0,5,0). */
.single-product.woocommerce .summary .ostu-buybox .ostu-status-row:has(.ostu-stock-badge) .ostu-stock-badge {
  margin: 0;
  padding: 0;
  background: transparent;
  border-color: transparent;
  border-radius: 0;
  font-size: var(--fs-sm, 14px);
  gap: var(--space-8, 8px);
}

/* The 8px dot becomes a real 20px icon. Drawn as a data URI, the same
   technique woocommerce.css:733 already uses for the trust-row ticks — a
   stroke colour cannot be a var() inside a URL, so each state carries its
   literal. (0,7,0) vs single.css:179 (0,1,0). */
.single-product.woocommerce .summary .ostu-buybox .ostu-status-row .ostu-stock-badge .ostu-stock-badge__dot {
  width: 20px;
  height: 20px;
  border-radius: 0;
  background: none;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  box-shadow: none;
}
.single-product.woocommerce .summary .ostu-buybox .ostu-status-row .ostu-stock-badge--in .ostu-stock-badge__dot {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23047857' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='m8 12 3 3 5-6'/%3E%3C/svg%3E");
}
.single-product.woocommerce .summary .ostu-buybox .ostu-status-row .ostu-stock-badge--low .ostu-stock-badge__dot {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b45309' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7.5v5l3 2'/%3E%3C/svg%3E");
}
.single-product.woocommerce .summary .ostu-buybox .ostu-status-row .ostu-stock-badge--out .ostu-stock-badge__dot {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b91c1c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='m9 9 6 6M15 9l-6 6'/%3E%3C/svg%3E");
}


/* ==========================================================================
   3 · THE SAVINGS ROW — a row, not a stray chip
   ==========================================================================
   The figures come from inc/single-product.php, which computes them from
   WooCommerce's own regular price against its own sale price and prints
   nothing at all when there is no real difference. No reference price is
   invented anywhere in this theme and none is invented here — this section
   only changes how that honest number is presented: an inline chip becomes a
   full-width bordered row with the percentage on the left and the euro saving
   on the right.

   (0,5,0) against single.css:78 (0,2,0). */
.single-product.woocommerce .summary .ostu-buybox .ostu-savings {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-12, 12px);
  margin: var(--space-12, 12px) 0 0;
  padding: var(--space-8, 8px) var(--space-12, 12px);
  background: var(--brand-a1, rgb(4 120 87 / .06));
  border: 1px solid var(--brand-a3, rgb(4 120 87 / .20));
  border-radius: var(--radius-12, 12px);
}
.single-product.woocommerce .summary .ostu-buybox .ostu-savings .ostu-savings__pct {
  font-size: var(--fs-sm, 14px);
  padding: var(--space-4, 4px) var(--space-12, 12px);
}
.single-product.woocommerce .summary .ostu-buybox .ostu-savings .ostu-savings__amt {
  font-size: var(--fs-md, 16px);
  font-weight: var(--fw-bold, 700);
}


/* ==========================================================================
   4 · THE PURCHASE ZONE — the panel's second half
   ==========================================================================
   `<div class="ostu-buy">` is opened at summary priority 24 and closed at 32
   by inc/buybox.php, so it contains everything about GETTING the product:
   the stock-urgency line, the delivery line, the add-to-cart form, the trust
   row and the wishlist link. Both ends come from the same action, so the
   element can never be left unbalanced.

   It is pulled out to the card's inner edge on three sides and given the
   card's own bottom corners, so the panel visibly splits into an information
   half and a purchase half.

   (0,5,0). `.ostu-buy` is new in this pass — nothing else in the theme, in
   WooCommerce or in any plugin sheet ships a rule for that class. */
.single-product.woocommerce .summary .ostu-buybox .ostu-buy {
  margin: var(--space-24, 24px) calc(var(--ostu-bb-pad, 24px) * -1) calc(var(--ostu-bb-pad, 24px) * -1);
  padding: var(--space-20, 20px) var(--ostu-bb-pad, 24px) var(--ostu-bb-pad, 24px);
  background: var(--surface-muted, #f1f5f9);
  border-top: 1px solid var(--border, #e2e8f0);
  border-radius: 0 0 var(--ostu-bb-inner-radius, 15px) var(--ostu-bb-inner-radius, 15px);
}
/* Nothing to render (a product with no urgency line, no delivery line and no
   form) must not leave a shaded stripe with nothing in it. */
.single-product.woocommerce .summary .ostu-buybox .ostu-buy:empty {
  display: none;
}
.single-product.woocommerce .summary .ostu-buybox .ostu-buy > :first-child { margin-top: 0; }
.single-product.woocommerce .summary .ostu-buybox .ostu-buy > :last-child { margin-bottom: 0; }

/* The delivery line ships `background: var(--muted)` (boosters.css:136), and
   `--muted` is defined as `var(--surface-muted, #f1f5f9)` (main.css:44) — the
   exact grey this zone is painted in. Its box therefore dissolves and only its
   1px border remains.

   An earlier pass here answered that by painting it WHITE, which lifted it
   into a raised card standing immediately above the buy button — the loudest
   place on the page. The sentence it carries is the one claim on this page the
   shop has not settled with itself: the product page states one delivery
   window and the terms of sale state a wider one. This module writes no
   delivery wording anywhere, and it will not put extra weight behind wording
   that is still in dispute either. Transparent leaves the row plainly readable
   — its text is --slate-dark on #f1f5f9, the same contrast it had on white —
   and adds nothing to it. One property, one value: the owner who settles the
   wording can turn it back into a card by changing this line alone.
   (0,6,0) vs boosters.css:136 (0,1,0). */
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .ostu-delivery {
  background: transparent;
  margin: 0 0 var(--space-16, 16px);
}

/* The trust row that closes the zone has the same background problem in a
   different place: its separator line was picked to read on white, and on this
   shaded field it all but disappears. One step darker brings it back. No
   surface is added here either — only the line between two rows. */
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .product-trust {
  margin-top: var(--space-20, 20px);
  padding-top: var(--space-16, 16px);
  border-top-color: var(--border-strong, #cbd5e1);
}


/* ==========================================================================
   5 · THE ACTION LAYOUT — quantity on its own line, CTA full width under it
   ==========================================================================
   Was: quantity and button side by side on one line, the button taking the
   leftover width. Now: line one is the quantity stepper with the running sum
   pushed to the right, line two is the call to action at full width. This is
   the change that is visible from two metres.

   NO WRAPPER ELEMENT, ON PURPOSE. The obvious way to build this row is to
   open a div on `woocommerce_before_add_to_cart_quantity` and close it on
   `woocommerce_after_add_to_cart_quantity` — but a template that fires only
   one of that pair (a gift-card or bundle form that draws its own controls)
   would then emit an unbalanced div into the page. The form is already a flex
   container (woocommerce.css:713), so the same layout falls out of
   `flex-basis` alone, with nothing to leave open.

   NO `order` PROPERTY, ON PURPOSE either. Any plugin that renders into
   `woocommerce_after_add_to_cart_button` would default to order 0 and be
   yanked in front of the quantity. Source order already puts the pieces in
   the right sequence; only the widths are set.

   Both product shapes are covered: `form.cart` for a simple product, and
   `.woocommerce-variation-add-to-cart` for a variable one, which is the
   element the theme flexes there (woocommerce.css:707-715). Grouped products
   are excluded in PHP — their quantities live in a table, and Trap 11 is not
   a thing to go near for a cosmetic gain.

   form.cart      = (0,8,1): 5 anchor classes + `.cart` + two `:not()` class
                    arguments + the `form` element. Beats woocommerce.css:713
                    (0,4,1) and core's (0,4,2).
   variation form = (0,6,0). */
.single-product.woocommerce .summary .ostu-buybox .ostu-buy form.cart:not(.variations_form):not(.grouped_form),
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .woocommerce-variation-add-to-cart {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-12, 12px);
}

/* The form's own margin, for EVERY product shape — the simple form, the
   variations form and the grouped form all carry `margin: 22px 0` from
   woocommerce.css:713/716, which was measured for a form standing on white,
   not for one sitting inside a padded zone. (0,6,1) vs (0,4,1)/(0,3,0). */
.single-product.woocommerce .summary .ostu-buybox .ostu-buy form.cart {
  margin: 0;
}
/* Inside a variations form the picker sits above, so the button row keeps a
   gap of its own. (0,6,0). */
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .woocommerce-variation-add-to-cart {
  margin: var(--space-16, 16px) 0 0;
}

/* ---- The stepper ---------------------------------------------------------
   `.quantity` is turned into one bordered pill holding [ − ][ input ][ + ].
   The buttons are printed with the `hidden` attribute by inc/buybox.php and
   are un-hidden by assets/js/buybox.js, which also adds `.ostu-qty` to this
   wrapper. Without JavaScript neither the class nor the buttons appear and
   the shopper gets exactly today's number field — no dead controls.

   TOUCH TARGET: 48px wide buttons on a 56px tall pill, 46 x 52 below 600px.
   Both axes clear the 44px minimum at every width. Measured off the numbers
   set here, not off a screen.

   (0,8,1) for the wrapper and (0,9,2) for the input. An earlier note here said
   (0,7,1) and (0,8,2) — one class short in both cases, because `.quantity` and
   `.ostu-qty` on the same compound are two classes, not one. Recounted for the
   wrapper: single-product, woocommerce, summary, ostu-buybox, ostu-buy, cart,
   quantity, ostu-qty = 8 classes, plus the `form` element. The variation-form
   twins carry the same classes without `form`, so they are (0,8,0) and
   (0,9,1). All four clear what they have to clear: woocommerce.css:717
   (0,2,1), its @media twins (0,2,1), and core's
   `.woocommerce div.product form.cart .quantity` (0,4,2). */
.single-product.woocommerce .summary .ostu-buybox .ostu-buy form.cart .quantity.ostu-qty,
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .woocommerce-variation-add-to-cart .quantity.ostu-qty {
  display: inline-flex;
  align-items: stretch;
  flex: 0 0 auto;
  float: none;
  margin: 0;
  background: var(--surface, #fff);
  border: 1px solid var(--border-strong, #cbd5e1);
  border-radius: var(--radius-12, 12px);
  /* NO `overflow: hidden` here, however tempting. The two buttons are focusable
     and a11y.css draws their focus ring OUTSIDE their box; clipping the wrapper
     would cut that ring in half. The end buttons carry the matching corner radii
     instead (11px = the wrapper's 12px minus its 1px border), which rounds the
     pill without clipping anything. */
}
.single-product.woocommerce .summary .ostu-buybox .ostu-buy form.cart .quantity.ostu-qty input.qty,
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .woocommerce-variation-add-to-cart .quantity.ostu-qty input.qty {
  width: 56px;
  height: 56px;
  margin: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  font-size: var(--fs-md, 16px);
  font-weight: var(--fw-bold, 700);
  font-variant-numeric: tabular-nums;
  color: var(--text, #0f172a);
}

.single-product.woocommerce .summary .ostu-buybox .ostu-buy .quantity.ostu-qty .ostu-qty__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 48px;
  min-height: 56px;
  padding: 0;
  border: 0;
  background: var(--surface, #fff);
  color: var(--text-muted, #475569);
  cursor: pointer;
  transition: background .16s ease, color .16s ease;
}
/* The same user-agent lesson, stated for the two buttons as well. They are
   printed with `hidden` too, and the rule above is another author `display`.
   Today nothing goes wrong, for one reason only: assets/js/buybox.js removes
   the attribute from both buttons BEFORE it adds `.ostu-qty` to the wrapper,
   so the rule above can never match a still-hidden button. That is a guarantee
   held by the order of two lines in a JavaScript file. This states it in CSS,
   where it cannot be reordered away, and it also keeps `hidden` usable as a
   real control if a later pass ever wants to take a stepper button away.
   (0,9,0) — eight classes plus `[hidden]`, against the (0,8,0) above. */
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .quantity.ostu-qty .ostu-qty__btn[hidden] {
  display: none;
}
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .quantity.ostu-qty .ostu-qty__btn:hover {
  background: var(--surface-muted, #f1f5f9);
  color: var(--brand, #047857);
}
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .quantity.ostu-qty .ostu-qty__btn:disabled {
  color: var(--border-strong, #cbd5e1);
  cursor: default;
  background: var(--surface, #fff);
}
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .quantity.ostu-qty .ostu-qty__btn--dec {
  border-radius: 11px 0 0 11px;
}
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .quantity.ostu-qty .ostu-qty__btn--inc {
  border-radius: 0 11px 11px 0;
}
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .quantity.ostu-qty .ostu-qty__btn svg {
  width: 18px;
  height: 18px;
  display: block;
}

/* ---- The running sum -----------------------------------------------------
   Printed by inc/buybox.php with the `hidden` attribute and revealed by JS
   only from a quantity of two upwards, because at one it would repeat the
   price standing 100px above it. The number is the displayed unit price times
   the chosen quantity — arithmetic on a figure WooCommerce already printed,
   not a second source of truth, and it is never shown for a variable product
   where the unit price depends on a choice that has not been made yet. */
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .ostu-bb-total {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-2, 2px);
  flex: 1 1 auto;
  min-width: 0;
  text-align: right;
}

/* REQUIRED, not defensive. This is the fourth time this repo writes this line
   down — home-proof.css:404, info-density.css:108, cart-sticky-bar.css:61 —
   and the first three all say the same thing: `[hidden] { display: none }`
   lives in the USER AGENT stylesheet, and ANY author `display` beats a
   user-agent declaration outright, because the cascade sorts by ORIGIN before
   it ever looks at specificity. The `display: flex` directly above is such a
   declaration, so without this rule the `hidden` attribute on this element
   does nothing at all.

   What that costs, precisely, on a live product page: inc/buybox.php prints
   the block hidden and empty, and assets/js/buybox.js only fills it from a
   quantity of two upwards. So at the default quantity of 1 — every first view
   of every simple product that can be bought more than once — the word "KOKKU"
   would stand next to the quantity field with nothing under it. And because
   the same script re-hides the block when the quantity drops back below two,
   a shopper who went 1 -> 2 -> 1 would be left looking at the two-item sum
   beside a field reading 1. A wrong number next to a buy button is not a
   cosmetic defect.

   (0,7,0) — six classes plus `[hidden]`, and an attribute selector counts in
   the SAME column as a class, never as an element. It must beat the (0,6,0)
   rule above it, which it does. The short form `.ostu-bb-total[hidden]`
   (0,2,0) would have lost to it and left the bug in place. */
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .ostu-bb-total[hidden] {
  display: none;
}
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .ostu-bb-total__label {
  font-size: var(--fs-2xs, 12px);
  font-weight: var(--fw-semibold, 600);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-muted, #475569);
}
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .ostu-bb-total__value {
  font-size: var(--fs-lg, 18px);
  font-weight: var(--fw-bold, 700);
  font-variant-numeric: tabular-nums;
  line-height: var(--lh-md, 24px);
  color: var(--text, #0f172a);
}

/* ---- The call to action --------------------------------------------------
   Full width, 60px tall, with a bag mark drawn as a data URI. The button is
   already `display:inline-flex` with an 8px gap (woocommerce.css:721), so the
   pseudo-element joins as a flex item and the gap spaces it for free.
   `float: none` is not decoration: core ships
   `.woocommerce div.product form.cart .button { float: left }` at (0,4,2).

   (0,7,1) — beats woocommerce.css:721 (0,2,0), :1655 (0,2,1), :1657 (0,2,0)
   and core's (0,4,2), from outside any media query. */
.single-product.woocommerce .summary .ostu-buybox .ostu-buy form.cart .single_add_to_cart_button,
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .woocommerce-variation-add-to-cart .single_add_to_cart_button {
  flex: 1 1 100%;
  width: 100%;
  float: none;
  min-height: 60px;
  padding: 0 var(--space-24, 24px);
  border-radius: var(--radius-12, 12px);
  font-size: var(--fs-lg, 18px);
  letter-spacing: .01em;
}
.single-product.woocommerce .summary .ostu-buybox .ostu-buy form.cart .single_add_to_cart_button::before,
.single-product.woocommerce .summary .ostu-buybox .ostu-buy .woocommerce-variation-add-to-cart .single_add_to_cart_button::before {
  content: "";
  width: 20px;
  height: 20px;
  flex: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 7h12l-1.2 13H7.2z'/%3E%3Cpath d='M9 7V5.5a3 3 0 0 1 6 0V7'/%3E%3C/svg%3E") center / contain no-repeat;
}


/* ==========================================================================
   6 · NARROW WIDTHS
   ==========================================================================
   The panel keeps its structure on a phone — that is the point of it — but
   the gutter narrows so the bands do not eat the screen, and the controls
   shrink to the tallest size that still clears 44px. */
@media (max-width: 600px) {
  .single-product.woocommerce .summary .ostu-buybox {
    padding: var(--space-16, 16px);
    --ostu-bb-pad: var(--space-16, 16px);
  }
  .single-product.woocommerce .summary .ostu-buybox .ostu-status-row {
    margin-bottom: var(--space-16, 16px);
  }
  .single-product.woocommerce .summary .ostu-buybox .ostu-buy {
    padding-top: var(--space-16, 16px);
    margin-top: var(--space-20, 20px);
  }
  .single-product.woocommerce .summary .ostu-buybox .ostu-buy form.cart .quantity.ostu-qty input.qty,
  .single-product.woocommerce .summary .ostu-buybox .ostu-buy .woocommerce-variation-add-to-cart .quantity.ostu-qty input.qty {
    width: 52px;
    height: 52px;
  }
  .single-product.woocommerce .summary .ostu-buybox .ostu-buy .quantity.ostu-qty .ostu-qty__btn {
    width: 46px;
    min-height: 52px;
  }
  .single-product.woocommerce .summary .ostu-buybox .ostu-buy form.cart .single_add_to_cart_button,
  .single-product.woocommerce .summary .ostu-buybox .ostu-buy .woocommerce-variation-add-to-cart .single_add_to_cart_button {
    min-height: 56px;
    font-size: var(--fs-md, 16px);
  }
}


/* ==========================================================================
   7 · REDUCED MOTION
   ==========================================================================
   The only movement this file introduces is the stepper button's hover fade.
   It is switched off for anyone who asked the system for less motion. */
@media (prefers-reduced-motion: reduce) {
  .single-product.woocommerce .summary .ostu-buybox .ostu-buy .quantity.ostu-qty .ostu-qty__btn {
    transition: none;
  }
}
