/* ==========================================================================
   FORM SYSTEM — assets/css/form-system.css
   One form language for the forms WooCommerce, the plugins and the theme
   never agreed on. Loaded by inc/form-system.php at wp_enqueue_scripts 26.

   ==========================================================================
   1 · WHAT THIS FILE IS FOR, AND WHAT IT DELIBERATELY LEAVES ALONE
   ==========================================================================
   assets/css/controls-d1-d2.css already owns the WooCommerce `.form-row`
   family off the gateway screens, and its own header names the forms it chose
   NOT to reach: "Those are a migration to propose, not a side effect of this
   file."

   This file is that migration, restricted to places where a shopper meets a
   field that nobody styles today. Measured on http://og.local, 14.08.2026, by
   fetching the real pages and grepping the real stylesheets:

     SURFACE                     WHO OWNS THE FIELD BEFORE THIS FILE
     ------------------------------------------------------------------
     account sign-in/register    controls-d1-d2.css  (52px, --border-strong)
     the till                    checkout-fields.css (fenced out here)
     cart coupon                 cart-ultra.css:425
     shop sort / sidebar select  archive-polish.css:296, pages.css:346
     shop filter tick box        filters.css:179  (.ostu-filter-cb)
     cookie-consent switches     the consent plugin (.oga-cc-toggle)
     footer newsletter           footer.css:134
     ------------------------------------------------------------------
     THE REVIEW FORM on every    pages.css:410, and only for text inputs and
     product page, and the       textarea: 1px --border #e2e8f0, 12px/14px
     comment form on every       padding, NO min-height. Every tick box is
     post and page               matched by no theme rule at all and renders
                                 as a browser-default square.

   So one shopper sees a 52px field with a #cbd5e1 border in the account, and
   a ~46px field with a #e2e8f0 border and 13px tick squares in the review
   form. That mixture is what this file removes.

   CORRECTION, 15.08.2026 — the survey above was run with
   `grep -rn "#respond" assets/css/`, i.e. over the THEME folder only, and two
   controls were declared "styled by nobody" that are in fact owned by
   WooCommerce itself. Both were wrong in the same direction, and both were
   named as this module's most visible wins:

     the submit button   owned by plugins/woocommerce/assets/css/woocommerce.css
                         at `#respond input#submit` — TWO ids. See block I.
     the rating select   owned by plugins/woocommerce/assets/js/frontend/
                         single-product.js:118, which calls jQuery .hide() on
                         `#rating` and inserts `p.stars` in front of it. The
                         select is display:none on every page view where JS
                         runs. See the note where block B used to be.

   The lesson is one line long: a survey of "who owns this control" that reads
   the theme folder only will always find the theme's own gaps and never the
   plugin that fills them. Grep the plugins too, then read the rendered page.

   THE VALUES BELOW ARE NOT NEW. 52px, 16px type, 12px/16px padding, 1px
   --border-strong, --radius-12 and --focus-ring are copied from
   controls-d1-d2.css:431-447 (which copied checkout-fields.css:89-107) on
   purpose. A second, prettier field shape would have made the split WORSE
   while looking like an improvement in the diff.

   ==========================================================================
   2 · THE FENCE — how this file is kept away from the protected block
   ==========================================================================
   CLAUDE.md invariant 1 puts one block of markup out of bounds, and the
   markup around it is not safely distant: on the till, WooCommerce renders
   the terms tick box INSIDE the same container as the gateway list. A rule
   named `.woocommerce form .form-row input[type="checkbox"]` therefore reaches
   the protected area while naming nothing an auditor would grep for. That is
   the trap this file has to solve, and it solves it with structure.

   EVERY selector here begins with `body.ofs-forms`.

   `ofs-forms` is a body class that inc/form-system.php adds only on views it
   has positively cleared. It is decided per request by PHP, not baked into
   any file, so:

     - if a caching plugin combines this stylesheet into a bundle that is also
       served on a gateway screen, NOTHING in it can match, because the class
       is not on that page's <body>;
     - the gate in PHP is an ALLOW-list, not a block-list. A gateway-related
       account screen that WooCommerce adds in some future version is excluded
       by default, without anyone having to remember to add it here.

   That is the whole fence, and it needs no selector naming the protected area
   — which also means nothing in this file can be mistaken for styling it.

   Second, independent guard: inc/form-system.php does not enqueue this file
   on those views either. That is a byte saving, never a safety net.

   ==========================================================================
   3 · SPECIFICITY — the arithmetic, written down (CLAUDE.md trap 1)
   ==========================================================================
   PREFIX  body.ofs-forms  =  body (0,0,1) + .ofs-forms (0,1,0)  =  (0,1,1)

   That is a small number on purpose: it must not out-rank the per-surface
   owners listed in section 1. It is raised, where it has to be, by real
   structure that exists in the live markup — never by an id and never by
   !important. The three rules this file has to beat, and the result:

     pages.css:410   body:not(.single-post) .comment-form input[type="text"]
                     (0,3,2)  <  PREFIX + .comment-respond + .comment-form
                                 + input[type=…]  =  (0,4,2)          WINS
     pages.css:407   body:not(.single-post) .comment-form p
                     (0,2,2)  <  PREFIX + .comment-form + p.<class>
                                 = (0,3,2)                            WINS
     blog.css:270    .comment-respond input[type="text"]
                     (0,2,1)  <  (0,4,2)                              WINS
     a11y.css:204    .a11y-ready .woocommerce form .form-row
                     input[type="checkbox"]
                     (0,4,2)  <  PREFIX + .woocommerce form .form-row
                                 input[type="checkbox"] = (0,4,3)     WINS

   And the one this file got wrong until 15.08.2026, because the list of
   opponents was drawn from the theme folder alone (plugins/woocommerce/
   assets/css/woocommerce.css, WC 11.0.1, printed as `woocommerce-general-css`
   BEFORE every theme sheet on the rendered page):

     woocommerce.css .woocommerce:where(body:not(
                       .woocommerce-block-theme-has-button-styles))
                     #respond input#submit
                     (2,1,1)  — :where() weighs nothing, but `#respond` and
                                `input#submit` are TWO ids, and two ids beat
                                any number of classes. Block I used to be
                                (0,5,2) and lost every property it declared.
                                It is now (2,3,2). Arithmetic in block I.

   `.comment-respond` is not padding: `<div id="respond" class="comment-respond">`
   wraps the form in both the WooCommerce review block and the WordPress
   comment form. Both were read out of live markup before this was written.

   Source order agrees with every line above (priority 26 prints after
   pages.css and blog.css at 10 and a11y.css at 10), so neither channel is
   load-bearing on its own. NOTHING here is marked !important, and nothing
   needs to be: the one !important nearby is woocommerce.css:1209, scoped to
   `.woocommerce form .form-row` fields — a family this file sets no border on.

   HONEST LABEL: the numbers above are specificity ARITHMETIC read off four
   stylesheets. They are not computed-style readings from a browser. Nothing
   here may be called "applied" until the lead has read getComputedStyle on a
   real page — CLAUDE.md trap 1, which has now cost this shop four times.

   ==========================================================================
   4 · TOKENS
   ==========================================================================
   Every var() carries a literal fallback. An unresolvable custom property
   voids the WHOLE declaration, so `border-color: var(--border-strong)` with
   no fallback is a field with no border, not a field with a default one.
   ========================================================================== */


/* ==========================================================================
   BLOCK A · THE FIELD — one resting shape
   Scope: `.comment-respond .comment-form`, which is the form element of BOTH
   the WooCommerce product review form and the WordPress comment form.

   min-height 52px matches controls-d1-d2.css:435. The tap-target minimum is
   44px; 52px is the theme's field height and clears it.
   font-size 16px: under 16px, iOS Safari zooms the page on focus and leaves
   the shopper scrolled sideways in the middle of a form. That is the reason
   for the value — it is not a typographic choice and must not be "tidied"
   down to 15px.
   ========================================================================== */

body.ofs-forms .comment-respond .comment-form input[type="text"],
body.ofs-forms .comment-respond .comment-form input[type="email"],
body.ofs-forms .comment-respond .comment-form input[type="url"],
body.ofs-forms .comment-respond .comment-form input[type="tel"],
body.ofs-forms .comment-respond .comment-form input[type="number"],
body.ofs-forms .comment-respond .comment-form input[type="password"],
body.ofs-forms .comment-respond .comment-form textarea,
body.ofs-forms .comment-respond .comment-form select {
  box-sizing: border-box;
  display: block;
  width: 100%;
  max-width: 100%;
  min-height: 52px;
  margin: 0;
  padding: var(--space-12, 12px) var(--space-16, 16px);
  font-family: var(--font-text, 'DM Sans', 'Segoe UI', sans-serif);
  font-size: 16px;
  line-height: var(--lh-md, 24px);
  color: var(--text, #0f172a);
  background-color: var(--surface, #ffffff);
  border: 1px solid var(--border-strong, #cbd5e1);
  border-radius: var(--radius-12, 12px);
  box-shadow: none;
  transition-property: border-color, background-color, box-shadow;
  transition-duration: var(--dur, 200ms);
  transition-timing-function: var(--ease, cubic-bezier(.2, .6, .3, 1));
}

/* Multi-line. WordPress ships `rows="8"` but no minimum height, and pages.css
   sets none either, so the box ends up at whatever the browser feels like.
   Dragging stays ON, vertically only — a horizontally resizable textarea
   breaks the column it sits in. */
body.ofs-forms .comment-respond .comment-form textarea {
  min-height: 140px;
  height: auto;
  resize: vertical;
}

body.ofs-forms .comment-respond .comment-form input::placeholder,
body.ofs-forms .comment-respond .comment-form textarea::placeholder {
  color: var(--text-subtle, #64748b);
  opacity: 1;
}

/* The label above the field. pages.css:408 already makes it 600 weight; this
   restates it so the look survives if that file is ever scoped down, and adds
   the 8px gap the theme uses between a label and its control.

   THE TWO :not() ARE LOAD-BEARING, not tidiness. A tick-box row is also a
   direct `<p>` child of this form, so the bare `> p > label` this rule used to
   carry matched the consent row and the newsletter row as well — at (0,3,3),
   which beats block H's own `p.mc4wp-checkbox > label` (0,2,3) and
   `p.comment-form-cookies-consent > label` (0,2,3). The result, measured
   against the rendered forms, was that the SAME newsletter row rendered
   `display:block` / 600 / 14px inside a review form and `display:flex` / 400 /
   16px in the account — this file producing, by itself, exactly the split it
   was written to remove. It also reversed blog.css:285
   (`.comment-respond .comment-form-cookies-consent label`, (0,2,1)), which had
   deliberately set that one label back to 400.

   Excluding the two wrappers is better than out-specifying them: a label that
   sits INSIDE a card must not be styled by the rule for labels that sit ABOVE
   a field. Rating label kept on its own line — `.comment-form-rating` is a
   div, not a p, and its label stays visible even though the select does not
   (see the note where block B used to be). */
body.ofs-forms .comment-respond .comment-form > p:not(.mc4wp-checkbox):not(.comment-form-cookies-consent) > label,
body.ofs-forms .comment-respond .comment-form .comment-form-rating > label {
  display: block;
  margin-bottom: var(--space-8, 8px);
  font-family: var(--font-text, 'DM Sans', 'Segoe UI', sans-serif);
  font-size: var(--fs-sm, 14px);
  font-weight: var(--fw-semibold, 600);
  line-height: var(--lh-sm, 20px);
  color: var(--text, #0f172a);
}

/* The required star is a MARKER, not an error, so it takes --brand rather
   than the one red. A red star on a form nobody has filled in yet reads as
   "you already got this wrong". */
body.ofs-forms .comment-respond .comment-form .required {
  color: var(--brand, #047857);
  font-weight: var(--fw-bold, 700);
  text-decoration: none;
}


/* ==========================================================================
   BLOCK B WAS HERE, AND IS DELETED — the rating dropdown is not on the screen
   ==========================================================================
   This block used to give `select#rating` an appearance:none reset, 44px of
   right padding and a brand chevron, and the handover called it the module's
   most visible change. It never drew a pixel. WooCommerce does this on every
   product page, plugins/woocommerce/assets/js/frontend/single-product.js:118
   and :199:

       .on( 'init', '#rating', function() {
         $( this ).hide().before( '<p class="stars"> … five <a> … </p>' );
       } )
       …
       $( '.wc-tabs-wrapper, .woocommerce-tabs, #rating' ).trigger( 'init' );

   jQuery .hide() writes an INLINE `style="display:none"`, which no stylesheet
   beats without !important — and this file carries none, correctly. The
   control the shopper actually clicks is `p.stars`, and the theme has owned it
   since before this module existed: reviews.css:320 already gives
   `#review_form p.stars a` a 44px square. There was nothing here to fix.

   Verified in the live minified bundle as well, so this is not a local-only
   condition. The select survives only with JavaScript switched off, and for
   that case block A's resting shape is enough — height, border, radius, 16px
   type. It gets no appearance:none, because stripping the platform arrow off
   a control in a no-JS fallback removes the only affordance it has left.

   The `select` still named in blocks A, C, E and K is that fallback and
   nothing more. It is NOT a visible change and must not be reported as one:
   getComputedStyle answers 52px on a display:none element just as happily as
   on a drawn one, which is how this went unnoticed in the first place.
   ========================================================================== */


/* ==========================================================================
   BLOCK C · FOCUS — one ring, on every control in scope
   --focus-ring is tokens.css:246: a 2px surface-coloured gap and a 5px brand
   ring, 5.00:1 on white.

   `outline: 2px solid transparent` is not a leftover. Windows High Contrast
   discards box-shadow entirely; a transparent outline is re-coloured by the
   operating system and becomes the visible indicator there. Block J states
   that outcome explicitly rather than relying on it.

   Nothing in this file ever sets `outline: none` without putting something
   visible in its place.
   ========================================================================== */

body.ofs-forms .comment-respond .comment-form input[type="text"]:focus,
body.ofs-forms .comment-respond .comment-form input[type="email"]:focus,
body.ofs-forms .comment-respond .comment-form input[type="url"]:focus,
body.ofs-forms .comment-respond .comment-form input[type="tel"]:focus,
body.ofs-forms .comment-respond .comment-form input[type="number"]:focus,
body.ofs-forms .comment-respond .comment-form input[type="password"]:focus,
body.ofs-forms .comment-respond .comment-form textarea:focus,
body.ofs-forms .comment-respond .comment-form select:focus {
  outline: 2px solid transparent;
  outline-offset: 2px;
  border-color: var(--brand, #047857);
  box-shadow: var(--focus-ring, 0 0 0 2px #ffffff, 0 0 0 5px #047857);
}


/* ==========================================================================
   BLOCK D · ERROR — border AND glyph AND sentence. Never colour alone.
   WCAG 1.4.1: a state may not be carried by colour alone. The three channels
   are a red border, a warning glyph inside the box, and a sentence under the
   field. The sentence is written by assets/js/form-system.js as a real
   element with role="alert", wired to the control with aria-describedby — a
   CSS ::after would have been silent in several screen readers.

   `.woocommerce-invalid` is deliberately NOT used. It is added by
   WooCommerce's till script and by nothing else, so on these forms it never
   appears. The two signals that do appear:
     [aria-invalid="true"]  set by our script, on blur and on the invalid event
     :user-invalid          native; matches only AFTER the shopper has left a
                            field wrong (`:invalid` fires on an untouched empty
                            required field and would paint a fresh form red)

   THE TWO ARE IN SEPARATE RULE BLOCKS ON PURPOSE. An engine that does not
   know `:user-invalid` discards the ENTIRE selector list the unknown
   pseudo-class appears in, so grouping them would take the attribute selector
   down with it and leave older browsers with no error state at all.

   `:not([type="checkbox"]):not([type="radio"])` mirrors FIELD_SELECTOR in
   assets/js/form-system.js. A 20px warning glyph does not fit in a 22px tick
   box, and block G cannot cancel it: block G's box rule is (0,3,2) and these
   are (0,6,2). Excluding the two types here is the only version of that
   promise the cascade actually keeps — see the note in block G.
   ========================================================================== */

body.ofs-forms .comment-respond .comment-form input[aria-invalid="true"]:not([type="checkbox"]):not([type="radio"]),
body.ofs-forms .comment-respond .comment-form textarea[aria-invalid="true"],
body.ofs-forms .comment-respond .comment-form select[aria-invalid="true"] {
  border-color: var(--state-error, #b91c1c);
  background-color: var(--danger-a1, rgb(185 28 28 / .06));
  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='10'/%3E%3Cline x1='12' y1='8' x2='12' y2='13'/%3E%3Cline x1='12' y1='16.5' x2='12.01' y2='16.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-16, 16px) center;
  background-size: 20px 20px;
  padding-right: 46px;
}

body.ofs-forms .comment-respond .comment-form input:user-invalid:not([type="checkbox"]):not([type="radio"]),
body.ofs-forms .comment-respond .comment-form textarea:user-invalid,
body.ofs-forms .comment-respond .comment-form select:user-invalid {
  border-color: var(--state-error, #b91c1c);
  background-color: var(--danger-a1, rgb(185 28 28 / .06));
  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='10'/%3E%3Cline x1='12' y1='8' x2='12' y2='13'/%3E%3Cline x1='12' y1='16.5' x2='12.01' y2='16.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-16, 16px) center;
  background-size: 20px 20px;
  padding-right: 46px;
}

/* A field in error keeps a RED ring while focused. A brand-green ring on a
   red field reads as "fixed" before it is. Two blocks again, same reason. */
body.ofs-forms .comment-respond .comment-form input[aria-invalid="true"]:focus:not([type="checkbox"]):not([type="radio"]),
body.ofs-forms .comment-respond .comment-form textarea[aria-invalid="true"]:focus,
body.ofs-forms .comment-respond .comment-form select[aria-invalid="true"]:focus {
  border-color: var(--state-error, #b91c1c);
  box-shadow: 0 0 0 2px var(--surface, #ffffff), 0 0 0 5px var(--state-error, #b91c1c);
}

body.ofs-forms .comment-respond .comment-form input:user-invalid:focus:not([type="checkbox"]):not([type="radio"]),
body.ofs-forms .comment-respond .comment-form textarea:user-invalid:focus,
body.ofs-forms .comment-respond .comment-form select:user-invalid:focus {
  border-color: var(--state-error, #b91c1c);
  box-shadow: 0 0 0 2px var(--surface, #ffffff), 0 0 0 5px var(--state-error, #b91c1c);
}

/* The sentence under the field. Written by the script; styled here so it can
   never appear unstyled if the script runs before this sheet is parsed. The
   glyph is a pseudo-element, so a reader announces the sentence once. */
body.ofs-forms .ofs-msg {
  display: flex;
  align-items: flex-start;
  gap: var(--space-8, 8px);
  margin-top: var(--space-8, 8px);
  font-family: var(--font-text, 'DM Sans', 'Segoe UI', sans-serif);
  font-size: var(--fs-sm, 14px);
  font-weight: var(--fw-medium, 500);
  line-height: var(--lh-sm, 20px);
  color: var(--state-error, #b91c1c);
}

body.ofs-forms .ofs-msg::before {
  content: "";
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  background-color: var(--state-error, #b91c1c);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='8' x2='12' y2='13'/%3E%3Cline x1='12' y1='16.5' x2='12.01' y2='16.5'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cline x1='12' y1='8' x2='12' y2='13'/%3E%3Cline x1='12' y1='16.5' x2='12.01' y2='16.5'/%3E%3C/svg%3E");
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: 18px 18px;
  mask-size: 18px 18px;
}


/* ==========================================================================
   BLOCK E · SUCCESS — the third distinct look
   Restricted to REQUIRED fields. `:user-valid` matches an optional empty
   field the moment the shopper tabs through it, so an unrestricted rule would
   tick fields nobody filled in. Green border plus a tick glyph, so the state
   does not rest on colour either.
   ========================================================================== */

body.ofs-forms .comment-respond .comment-form input:required:user-valid:not([type="checkbox"]):not([type="radio"]),
body.ofs-forms .comment-respond .comment-form textarea:required:user-valid {
  border-color: var(--brand, #047857);
  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.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-16, 16px) center;
  background-size: 20px 20px;
  padding-right: 46px;
}

/* Border only, no tick glyph: with block B gone the select keeps the browser's
   own arrow, and a second image would be drawn underneath it. This rule can
   only ever be seen with JavaScript off — with JS the rating select is
   display:none and `p.stars` is the control (see the note where block B was).
   The green border is not the sole channel there either: a filled select
   shows the chosen word. */
body.ofs-forms .comment-respond .comment-form select:required:user-valid {
  border-color: var(--brand, #047857);
}


/* ==========================================================================
   BLOCK F · OFF and READ-ONLY — two more looks, told apart without colour
   off        : muted fill, faint border, muted text, not-allowed cursor.
   read-only  : normal fill and normal text (it must stay readable and
                copyable) with a DASHED border. The dash is the channel that
                needs no colour at all.
   ========================================================================== */

body.ofs-forms .comment-respond .comment-form input:disabled,
body.ofs-forms .comment-respond .comment-form textarea:disabled,
body.ofs-forms .comment-respond .comment-form select:disabled {
  background-color: var(--surface-muted, #f1f5f9);
  border-color: var(--border, #e2e8f0);
  border-style: solid;
  color: var(--text-subtle, #64748b);
  cursor: not-allowed;
  box-shadow: none;
}

body.ofs-forms .comment-respond .comment-form input[readonly],
body.ofs-forms .comment-respond .comment-form textarea[readonly] {
  background-color: var(--surface, #ffffff);
  border-color: var(--border-strong, #cbd5e1);
  border-style: dashed;
  color: var(--text, #0f172a);
  cursor: default;
}


/* ==========================================================================
   BLOCK G · TICK BOXES AND CHOICE DOTS
   ==========================================================================
   THE SCOPE HERE IS A LIST, NOT `input[type="checkbox"]`, AND THAT IS THE
   POINT. A site-wide tick-box rule is how a visually hidden checkbox driving
   a custom control becomes a visible 22px square. Two live examples were
   found on this shop before the list was written:

     .ostu-filter-cb        filters.css:179 already draws its own box
     .oga-cc-toggle input   the cookie-consent plugin's switches, which the
                            owner has ruled out of bounds entirely

   Neither is in the list below and neither can be reached by it. Every
   context that IS listed was read out of live markup on 14.08.2026:

     .woocommerce-form__input-checkbox   account sign-in "Jäta mind meelde",
                                         account register newsletter opt-in
     .mc4wp-checkbox input               register form AND review/comment form
     .comment-form input[type=checkbox]  "Jäta mu nimi ja e-post meelde"
     .woocommerce .form-row input        any other WooCommerce option row on a
                                         cleared view

   Before: three different browser-default 13px squares on ONE page (the
   account), two more in the review form. After: one 22px box.

   `:not(.shipping_method)` on the dot rule removes the cart's delivery-method
   list from reach. Those are drawn by a delivery plugin beside its own carrier
   logos, and a plugin's own control is not this file's to restyle. The class
   is WooCommerce core's, and it sits on the input itself.

   TAP TARGET: the box is 22px, under the 44px minimum. The 44px is delivered
   by the row in Block H, which is what a finger actually hits. Where a listed
   context has no row — none was found in live markup — the box alone would be
   under the minimum; that is written into the handover as an unverified case
   rather than hidden here.
   ========================================================================== */

body.ofs-forms .woocommerce-form__input-checkbox,
body.ofs-forms .mc4wp-checkbox input[type="checkbox"],
body.ofs-forms .comment-form input[type="checkbox"],
body.ofs-forms .woocommerce form .form-row input[type="checkbox"],
body.ofs-forms .woocommerce form .form-row input[type="radio"]:not(.shipping_method) {
  box-sizing: border-box;
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin: 0;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  display: inline-grid;
  place-content: center;
  vertical-align: middle;
  background-color: var(--surface, #ffffff);
  /* NOT a cancellation of blocks D and E — this rule is (0,3,2) and those are
     (0,6,2), so it would lose that argument outright. It is a plain reset for
     browsers that ship a background on a checked box. Blocks D and E are kept
     off a tick box where that is actually decidable: in their own selectors,
     with :not([type="checkbox"]):not([type="radio"]). */
  background-image: none;
  border: 2px solid var(--border-strong, #cbd5e1);
  border-radius: var(--radius-8, 8px);
  cursor: pointer;
  transition-property: background-color, border-color, box-shadow;
  transition-duration: var(--dur, 200ms);
  transition-timing-function: var(--ease, cubic-bezier(.2, .6, .3, 1));
}

body.ofs-forms .woocommerce form .form-row input[type="radio"]:not(.shipping_method) {
  border-radius: var(--radius-circle, 50%);
}

/* The mark. clip-path rather than a background image, so the glyph inherits
   nothing and cannot be knocked out by a later `background` shorthand — the
   failure controls-d1-d2.css:464 documents for the select arrow. Same
   technique filters.css:186 already uses for the filter box. */
body.ofs-forms .woocommerce-form__input-checkbox::before,
body.ofs-forms .mc4wp-checkbox input[type="checkbox"]::before,
body.ofs-forms .comment-form input[type="checkbox"]::before,
body.ofs-forms .woocommerce form .form-row input[type="checkbox"]::before,
body.ofs-forms .woocommerce form .form-row input[type="radio"]:not(.shipping_method)::before {
  content: "";
  width: 12px;
  height: 12px;
  transform: scale(0);
  background-color: var(--text-on-brand, #ffffff);
  clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
  transition-property: transform;
  transition-duration: var(--dur-fast, 120ms);
  transition-timing-function: var(--ease, cubic-bezier(.2, .6, .3, 1));
}

/* A choice dot's mark is a dot, not a tick. */
body.ofs-forms .woocommerce form .form-row input[type="radio"]:not(.shipping_method)::before {
  width: 10px;
  height: 10px;
  border-radius: var(--radius-circle, 50%);
  clip-path: none;
}

body.ofs-forms .woocommerce-form__input-checkbox:checked,
body.ofs-forms .mc4wp-checkbox input[type="checkbox"]:checked,
body.ofs-forms .comment-form input[type="checkbox"]:checked,
body.ofs-forms .woocommerce form .form-row input[type="checkbox"]:checked,
body.ofs-forms .woocommerce form .form-row input[type="radio"]:not(.shipping_method):checked {
  background-color: var(--brand, #047857);
  border-color: var(--brand, #047857);
}

body.ofs-forms .woocommerce-form__input-checkbox:checked::before,
body.ofs-forms .mc4wp-checkbox input[type="checkbox"]:checked::before,
body.ofs-forms .comment-form input[type="checkbox"]:checked::before,
body.ofs-forms .woocommerce form .form-row input[type="checkbox"]:checked::before,
body.ofs-forms .woocommerce form .form-row input[type="radio"]:not(.shipping_method):checked::before {
  transform: scale(1);
}

body.ofs-forms .woocommerce-form__input-checkbox:hover,
body.ofs-forms .mc4wp-checkbox input[type="checkbox"]:hover,
body.ofs-forms .comment-form input[type="checkbox"]:hover,
body.ofs-forms .woocommerce form .form-row input[type="checkbox"]:hover,
body.ofs-forms .woocommerce form .form-row input[type="radio"]:not(.shipping_method):hover {
  border-color: var(--brand, #047857);
}

body.ofs-forms .woocommerce-form__input-checkbox:focus-visible,
body.ofs-forms .mc4wp-checkbox input[type="checkbox"]:focus-visible,
body.ofs-forms .comment-form input[type="checkbox"]:focus-visible,
body.ofs-forms .woocommerce form .form-row input[type="checkbox"]:focus-visible,
body.ofs-forms .woocommerce form .form-row input[type="radio"]:not(.shipping_method):focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: var(--focus-ring, 0 0 0 2px #ffffff, 0 0 0 5px #047857);
}

body.ofs-forms .woocommerce-form__input-checkbox:disabled,
body.ofs-forms .comment-form input[type="checkbox"]:disabled,
body.ofs-forms .woocommerce form .form-row input[type="checkbox"]:disabled {
  background-color: var(--surface-muted, #f1f5f9);
  border-color: var(--border, #e2e8f0);
  cursor: not-allowed;
}


/* ==========================================================================
   BLOCK H · THE CHOICE ROW — the structural change
   ==========================================================================
   Today a consent line is a naked 13px square with a sentence beside it, and
   the shopper has to hit the square. Three of them sit on the account page,
   each drawn by a different author (WooCommerce, the mail plugin, WordPress),
   so they do not even line up with one another.

   After this block each one is a full-width bordered row: 52px tall, 12px
   radius, the whole row clickable, and the row itself turns brand-tinted with
   a brand border when it is ticked. A line of text becomes a card, and the
   ticked state is readable from across the room instead of from a 13px glyph.

   The three wrappers are the three real ones in live markup:
     label.woocommerce-form__label-for-checkbox   the label IS the wrapper
     p.mc4wp-checkbox                             wrapper holds a label
     p.comment-form-cookies-consent               input and label are SIBLINGS

   The two `p` wrappers are listed twice: once bare, and once behind
   `.comment-form`, because pages.css:407 sets `body:not(.single-post)
   .comment-form p { margin: 0 }` at (0,2,2) and a bare `p.<class>` also
   computes to (0,2,2). A tie decided by source order is the kind of thing
   that breaks the day someone reorders an enqueue, so the scoped copy takes
   it to (0,3,2) and settles it on specificity instead.

   `:has()` carries the ticked state. If an engine does not support it, the
   selector is dropped and the row still renders as a card in its resting
   look — and the box inside it (Block G) still turns brand green, so no state
   becomes invisible. Degradation, not breakage.

   LAYOUT NOTE, because it is a visible side effect and not an accident: on
   the sign-in form WooCommerce puts "Jäta mind meelde" and the submit button
   inside the SAME `<p class="form-row">`. Making the label a full-width row
   pushes the button onto its own line beneath it. Deliberate and accepted —
   flagged in the handover so the owner is not surprised.
   ========================================================================== */

body.ofs-forms label.woocommerce-form__label-for-checkbox,
body.ofs-forms p.mc4wp-checkbox,
body.ofs-forms p.comment-form-cookies-consent,
body.ofs-forms .comment-form p.mc4wp-checkbox,
body.ofs-forms .comment-form p.comment-form-cookies-consent {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: var(--space-12, 12px);
  width: 100%;
  min-height: 52px;
  margin: 0 0 var(--space-12, 12px);
  padding: var(--space-12, 12px) var(--space-16, 16px);
  background-color: var(--surface, #ffffff);
  border: 1px solid var(--border, #e2e8f0);
  border-radius: var(--radius-12, 12px);
  font-family: var(--font-text, 'DM Sans', 'Segoe UI', sans-serif);
  font-size: var(--fs-md, 16px);
  font-weight: var(--fw-regular, 400);
  line-height: var(--lh-md, 24px);
  color: var(--text, #0f172a);
  cursor: pointer;
  transition-property: background-color, border-color, box-shadow;
  transition-duration: var(--dur, 200ms);
  transition-timing-function: var(--ease, cubic-bezier(.2, .6, .3, 1));
}

/* The mail plugin nests a label inside the row; flatten it so the row's own
   flex layout is what positions the box and the sentence. */
body.ofs-forms p.mc4wp-checkbox > label {
  display: flex;
  align-items: center;
  gap: var(--space-12, 12px);
  width: 100%;
  margin: 0;
  font-weight: var(--fw-regular, 400);
  cursor: pointer;
}

/* The cookie-consent row's label is a SIBLING of the input, so it carries its
   own pointer; the row stays clickable through the `for` attribute. */
body.ofs-forms p.comment-form-cookies-consent > label {
  margin: 0;
  font-weight: var(--fw-regular, 400);
  font-size: var(--fs-md, 16px);
  line-height: var(--lh-md, 24px);
  cursor: pointer;
}

body.ofs-forms label.woocommerce-form__label-for-checkbox:hover,
body.ofs-forms p.mc4wp-checkbox:hover,
body.ofs-forms p.comment-form-cookies-consent:hover {
  border-color: var(--border-strong, #cbd5e1);
  background-color: var(--brand-a1, rgb(4 120 87 / .06));
}

/* Ticked: a brand border doubled by an inset ring, so the row reads as 2px
   without the 1px layout shift a real border-width change would cause. */
body.ofs-forms label.woocommerce-form__label-for-checkbox:has(input:checked),
body.ofs-forms p.mc4wp-checkbox:has(input:checked),
body.ofs-forms p.comment-form-cookies-consent:has(input:checked) {
  border-color: var(--brand, #047857);
  background-color: var(--brand-a1, rgb(4 120 87 / .06));
  box-shadow: inset 0 0 0 1px var(--brand, #047857);
}

/* Keyboard: the ring belongs on the ROW, because the row is what the shopper
   sees. The box keeps its own ring from Block G for the case where this
   selector was dropped by an older engine. */
body.ofs-forms label.woocommerce-form__label-for-checkbox:has(input:focus-visible),
body.ofs-forms p.mc4wp-checkbox:has(input:focus-visible),
body.ofs-forms p.comment-form-cookies-consent:has(input:focus-visible) {
  outline: 2px solid transparent;
  outline-offset: 2px;
  border-color: var(--brand, #047857);
  box-shadow: var(--focus-ring, 0 0 0 2px #ffffff, 0 0 0 5px #047857);
}


/* ==========================================================================
   BLOCK I · THE SUBMIT BUTTON OF THE REVIEW AND COMMENT FORMS
   ==========================================================================
   Rendered markup, read off a real product page on 15.08.2026:
     <div id="respond" class="comment-respond">
       <form class="comment-form"> …
         <p class="form-submit">
           <input name="submit" type="submit" id="submit" class="submit"
                  value="Saada">

   NO THEME STYLESHEET MATCHES IT — that part was true (pages.css:436 sets
   `cursor: pointer` and stops). WOOCOMMERCE DOES, and that was missed, because
   the survey grepped `assets/css/` in the theme and stopped there.
   plugins/woocommerce/assets/css/woocommerce.css (11.0.1), printed on the page
   as `woocommerce-general-css`:

     .woocommerce:where(body:not(.woocommerce-block-theme-has-button-styles))
     #respond input#submit { padding:.618em 1em; font-weight:700;
       border-radius:3px; color:#515151; background-color:#e9e6ed;
       display:inline-block; box-shadow:none; … }

   The body of a product page carries `woocommerce` and does NOT carry
   `woocommerce-block-theme-has-button-styles` (both checked in the rendered
   HTML), so it matches, at:

     ids 2 (#respond, #submit) · classes 1 (.woocommerce) · elements 1 (input)
     = (2,1,1)              — `:where()` contributes nothing, by definition.

   The selector this block used to carry was
     body.ofs-forms .comment-respond .comment-form .form-submit
     input[type="submit"]
     ids 0 · classes 5 (.ofs-forms .comment-respond .comment-form .form-submit
     [type="submit"]) · elements 2  =  (0,5,2)

   and ZERO ids lose to TWO ids however many classes are stacked behind them.
   Every declared property went to WooCommerce: grey #e9e6ed fill, #515151
   label, 3px radius, inline-block. Only `min-height:48px` and
   `min-width:160px` got through — and because `display` stayed inline-block,
   `align-items:center` had nothing to centre and the label sat at the top of a
   48px box. The button did not turn green; it got taller and worse.

   Worse than that, and not in any earlier note: WooCommerce's base rule also
   declares `box-shadow:none`. It outranked the focus ring in this block too,
   while the `outline: 2px solid transparent` here — which WooCommerce does not
   declare, so it applied — replaced the browser's own focus ring with an
   invisible one. Keyboard focus on the send-review button had NO indicator at
   all. That is WCAG 2.4.7, introduced by this file.

   THE FIX IS TWO IDS OF OUR OWN, and it is the one place in this file that
   uses an id. The alternative was !important, which is worse: it cannot be
   out-ranked by a later fix, and this shop has been burned by exactly this
   trap three times (CLAUDE.md trap 1).

     body.ofs-forms #respond .comment-form .form-submit input#submit
     ids 2 (#respond #submit) · classes 3 (.ofs-forms .comment-form
     .form-submit) · elements 2 (body input)      =  (2,3,2)   >  (2,1,1)

   The ids are not decoration: `#respond` and `#submit` are the ids WordPress
   itself puts in the markup (comment_form() defaults), and they are the same
   two WooCommerce is leaning on. The hover rule below reaches (2,4,2) against
   WooCommerce's own hover at (2,2,1) — `.woocommerce` plus `:hover` is two
   classes, still one short.

   The two selectors WITHOUT the id stay in each list for markup where
   comment_form() was given a different `id_submit`, and for a `<button>`. They
   are (1,4,2), so on the default markup WooCommerce still outranks them —
   they carry identical declarations to the id selector, so nothing about the
   result depends on which of them matches.

   Styled here rather than given a class: adding a class would mean a template
   override or a filter on comment_form(), and the theme has a standing rule
   that only two WooCommerce templates may be overridden.

   The values are main.css's `.btn-primary` ladder as restated by
   controls-d1-d2.css:187 — 48px, 12px radius, brand fill, white label. No
   `:active` transform: motion.css owns press feedback site-wide and prints
   after this file.

   STILL ARITHMETIC, NOT A MEASUREMENT. Two ids beating one id plus a class is
   not in dispute, but the rendered result is: read background-color on
   `#respond input#submit` in a browser before calling this done.
   ========================================================================== */

body.ofs-forms #respond .comment-form .form-submit input#submit,
body.ofs-forms #respond .comment-form .form-submit input[type="submit"],
body.ofs-forms #respond .comment-form .form-submit button[type="submit"] {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  min-width: 160px;
  padding: 0 var(--space-24, 24px);
  font-family: var(--font-text, 'DM Sans', 'Segoe UI', sans-serif);
  font-size: var(--fs-md, 16px);
  font-weight: var(--fw-semibold, 600);
  line-height: var(--lh-md, 24px);
  color: var(--text-on-brand, #ffffff);
  background-color: var(--brand, #047857);
  border: 0;
  border-radius: var(--radius-12, 12px);
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  transition-property: background-color, box-shadow;
  transition-duration: var(--dur, 200ms);
  transition-timing-function: var(--ease, cubic-bezier(.2, .6, .3, 1));
}

body.ofs-forms #respond .comment-form .form-submit input#submit:hover,
body.ofs-forms #respond .comment-form .form-submit input[type="submit"]:hover,
body.ofs-forms #respond .comment-form .form-submit button[type="submit"]:hover {
  background-color: var(--brand-hover, #035e43);
}

/* (2,4,2) on the first selector. It has to clear WooCommerce's base
   `box-shadow:none` at (2,1,1) — not just its hover rule — or the ring is
   simply not drawn, which is the state this button was in. */
body.ofs-forms #respond .comment-form .form-submit input#submit:focus-visible,
body.ofs-forms #respond .comment-form .form-submit input[type="submit"]:focus-visible,
body.ofs-forms #respond .comment-form .form-submit button[type="submit"]:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: var(--focus-ring, 0 0 0 2px #ffffff, 0 0 0 5px #047857);
}

body.ofs-forms #respond .comment-form .form-submit input#submit:disabled,
body.ofs-forms #respond .comment-form .form-submit input[type="submit"]:disabled,
body.ofs-forms #respond .comment-form .form-submit button[type="submit"]:disabled {
  background-color: var(--surface-muted, #f1f5f9);
  color: var(--text-subtle, #64748b);
  cursor: not-allowed;
}

/* The rating row needs air under it: pages.css:406 gives the comment form a
   16px flex gap, but `.comment-form-rating` is a div that sits outside that
   flow on the product template. */
body.ofs-forms .comment-respond .comment-form .comment-form-rating {
  margin-bottom: var(--space-16, 16px);
}


/* ==========================================================================
   BLOCK J · MOTION AND HIGH CONTRAST
   Every transition declared above is named here, so a shopper who asked the
   operating system for less motion gets none of it. The states do not change
   — only the time they take.
   ========================================================================== */

/* The submit selector here MIRRORS block I's, ids included. A media query adds
   no weight of its own: at (0,5,2) this rule would have lost to block I's own
   (2,3,2) transition and the button would have kept animating for a shopper
   who asked the operating system for no motion. */
@media (prefers-reduced-motion: reduce) {
  body.ofs-forms .comment-respond .comment-form input,
  body.ofs-forms .comment-respond .comment-form textarea,
  body.ofs-forms .comment-respond .comment-form select,
  body.ofs-forms #respond .comment-form .form-submit input#submit,
  body.ofs-forms #respond .comment-form .form-submit input[type="submit"],
  body.ofs-forms #respond .comment-form .form-submit button[type="submit"],
  body.ofs-forms .woocommerce-form__input-checkbox,
  body.ofs-forms .mc4wp-checkbox input[type="checkbox"],
  body.ofs-forms .woocommerce form .form-row input[type="checkbox"],
  body.ofs-forms label.woocommerce-form__label-for-checkbox,
  body.ofs-forms p.mc4wp-checkbox,
  body.ofs-forms p.comment-form-cookies-consent {
    transition-duration: 1ms;
  }
  body.ofs-forms .woocommerce-form__input-checkbox::before,
  body.ofs-forms .mc4wp-checkbox input[type="checkbox"]::before,
  body.ofs-forms .comment-form input[type="checkbox"]::before,
  body.ofs-forms .woocommerce form .form-row input[type="checkbox"]::before {
    transition-duration: 1ms;
  }
}

/* Windows High Contrast discards box-shadow and author colours. The
   transparent outlines above are re-coloured by the operating system and
   become the focus indicator; the tick box needs a real border there, because
   its ticked state was being carried by a background colour. */
@media (forced-colors: active) {
  body.ofs-forms .comment-respond .comment-form input:focus,
  body.ofs-forms .comment-respond .comment-form textarea:focus,
  body.ofs-forms .comment-respond .comment-form select:focus {
    outline: 3px solid Highlight;
    outline-offset: 2px;
  }
  body.ofs-forms .woocommerce-form__input-checkbox,
  body.ofs-forms .mc4wp-checkbox input[type="checkbox"],
  body.ofs-forms .comment-form input[type="checkbox"],
  body.ofs-forms .woocommerce form .form-row input[type="checkbox"] {
    border-color: CanvasText;
  }
  body.ofs-forms .woocommerce-form__input-checkbox:checked::before,
  body.ofs-forms .mc4wp-checkbox input[type="checkbox"]:checked::before,
  body.ofs-forms .comment-form input[type="checkbox"]:checked::before,
  body.ofs-forms .woocommerce form .form-row input[type="checkbox"]:checked::before {
    background-color: CanvasText;
  }
}


/* ==========================================================================
   BLOCK K · NARROW SCREENS
   Nothing shrinks below 16px type and nothing drops under 44px of height. The
   only change is horizontal padding, so a 52px field does not eat the whole
   width of a 360px phone.
   ========================================================================== */

@media (max-width: 480px) {
  body.ofs-forms .comment-respond .comment-form input[type="text"],
  body.ofs-forms .comment-respond .comment-form input[type="email"],
  body.ofs-forms .comment-respond .comment-form input[type="url"],
  body.ofs-forms .comment-respond .comment-form input[type="tel"],
  body.ofs-forms .comment-respond .comment-form textarea,
  body.ofs-forms .comment-respond .comment-form select {
    padding-left: var(--space-12, 12px);
    padding-right: var(--space-12, 12px);
    font-size: 16px;
  }
  body.ofs-forms label.woocommerce-form__label-for-checkbox,
  body.ofs-forms p.mc4wp-checkbox,
  body.ofs-forms p.comment-form-cookies-consent {
    align-items: flex-start;
    padding: var(--space-12, 12px);
  }
  body.ofs-forms #respond .comment-form .form-submit input#submit,
  body.ofs-forms #respond .comment-form .form-submit input[type="submit"],
  body.ofs-forms #respond .comment-form .form-submit button[type="submit"] {
    width: 100%;
  }
}
