
      /* Cookie consent - compact floating card. Inset + rounded so it reads as an
         overlay rather than a wall, and shrinks further on phones. Kept as a real
         stylesheet (not inline styles) so the media query can actually apply. */
      #cookie-banner{display:none;position:fixed;left:12px;right:12px;bottom:12px;z-index:9999;
        max-width:680px;margin:0 auto;background:#141417;color:#eee;
        border:1px solid rgba(255,255,255,0.14);border-radius:15px;padding:12px 16px;
        font-family:var(--font-body),system-ui;font-size:14px;line-height:1.45;
        align-items:center;gap:10px;flex-wrap:nowrap;
        box-shadow:0 10px 30px rgba(0,0,0,.45)}
      #cookie-banner .cb-text{flex:1 1 auto;min-width:0}
      #cookie-banner .cb-actions{display:flex;gap:8px;flex:0 0 auto}
      #cookie-banner .cb-btn{padding:9px 16px;border-radius:10px;cursor:pointer;
        font:inherit;font-weight:600;white-space:nowrap;line-height:1}
      #cookie-banner .cb-reject{background:transparent;color:#eee;border:1px solid rgba(255,255,255,0.14)}
      #cookie-banner .cb-accept{background:var(--accent);color:var(--accent-ink,#fff);border:0;font-weight:700}
      @media (max-width:560px){
        #cookie-banner{left:10px;right:10px;bottom:10px;padding:12px 13px;font-size:13.5px;gap:9px;
          border-radius:14px;flex-wrap:wrap;justify-content:flex-end}
        #cookie-banner .cb-text{flex:1 1 100%}
        #cookie-banner .cb-btn{padding:9px 15px;font-size:13px}
      }
    
        /* --- price reads as primary text (cleaner than the brand accent) ---
           var(--text) is #ffffff on the dark default and #0a0a0b under
           html[data-theme="light"], so this is legible in BOTH themes. A
           literal #fff would disappear on the light theme. Appended rather
           than edited in place because these classes are bundled into large
           grouped accent selectors that also cover nav links / labels. */
        .product-card-price,
.pd-price,
.pd-variant-price,
.hero-bg-card-price,
.hero-search-sug-price,
.bundle-card-price { color: var(--text); }
        html[data-theme="light"] .product-card-price,
html[data-theme="light"] .pd-price,
html[data-theme="light"] .pd-variant-price,
html[data-theme="light"] .hero-bg-card-price,
html[data-theme="light"] .hero-search-sug-price,
html[data-theme="light"] .bundle-card-price { color: var(--text); }

        /* --- hero ticker card is a WHITE surface ---
           `.hero-bg-card { background:#ffffff !important }` (the fleet-wide
           white-product-surface rule) makes the WHOLE card white, info area
           included - not just the image. So the name and price printed on it must
           be DARK in both themes: --text is #ffffff on the dark default and would
           render white-on-white. The name was already invisible this way; the price
           became invisible when prices moved from the accent to --text. Fixed value,
           not a variable, because the surface is fixed regardless of theme. */
        .hero-bg-card-info,
        .hero-bg-card-name,
        .hero-bg-card-price,
        html[data-theme="light"] .hero-bg-card-name,
        html[data-theme="light"] .hero-bg-card-price { color: #0a0a0b; }

    
        /* ---- FTC affiliate disclosure -------------------------------------
           Required near the links and before the click, not just in the policy.
           No `color` on purpose: inheriting body text guarantees it has the same
           contrast as the site's own copy on whatever ground it lands. */
        .aff-notice {
            margin: 0;
            padding: 9px 18px;
            font-size: 12px;
            line-height: 1.45;
            text-align: center;
            background: rgba(127, 127, 127, 0.10);
            border-bottom: 1px solid var(--border-subtle, rgba(127, 127, 127, 0.18));
        }
        .aff-notice a { text-decoration: underline; }
        /* The standalone notice sat at y=51 under a fixed 61px header and a fixed
           55px tool strip: 4px of 69 was visible. It now lives in the footer,
           and the sentence that matters is on the buy row itself, where the FTC
           wants it - next to the link, before the click. */
        .aff-inline { margin: 8px 0 0; font-size: 11.5px; line-height: 1.45; color: var(--text-muted); text-align: center; }
        .footer .aff-notice { position: static; margin: 0 0 14px; }
        @media (max-width: 600px) { .aff-notice { font-size: 12px; padding: 8px 14px; } }
    
        /* ---- 44px touch-target floor (v2) (touch only) ---------------------------
           CLAUDE.md requires a 44px minimum and this audience is on phones.
           Scoped to coarse pointers / narrow viewports so desktop keeps its
           tighter sizing. Declared last so it also beats page-level CSS from
           the extra_css block, which is where .filter-tab lives.
           HEIGHT_ONLY selectors deliberately do not set `display`: some are
           hidden at a breakpoint and forcing a display value un-hides them. */
        @media (max-width: 900px), (pointer: coarse) {
            .popup-close,
            .nav-hamburger,
            .product-card-wish,
            .product-card-agents,
            .side-btn,
            .conv-btn,
            .nav-mob-wish,
            .mobile-close,
            .pd-close {
                min-width: 44px; min-height: 44px;
                display: inline-flex; align-items: center; justify-content: center;
            }

            .filter-tab,
            .cat-tab,
            .spread-cat,
            .filters-btn,
            .mob-lang-btn,
            .currency-btn,
            .signup-other,
            .hero-search-go,
            .tut-link,
            .pagination a {
                min-height: 44px;
                display: inline-flex; align-items: center; justify-content: center;
            }

            /* .back-top, #btt and .page-back are HEIGHT-ONLY on purpose. They
               were in the groups above, which set display: inline-flex - and
               that beat `.back-top { display: none }` and shop.html's
               `.page-back { display: none }`, so the back-to-top button was
               pinned to every phone screen from the first paint (measured
               sitting on a product card's own action pill) and the floating
               BACK pill came back on /shop, over the category row. */
            .back-top, #btt, .page-back { min-width: 44px; min-height: 44px; }
            /* Recent-search remove (x) and Clear all, in the hero dropdown and
               the nav dropdown: 24px and ~16px tall. min-* wins over their
               width/height at any specificity; display is left alone. */
            .hero-search-recent-x, .hero-search-recent-clear,
            .rs-x, .rs-clear { min-width: 44px; min-height: 44px; }
            .back-top.vis, #btt.vis { display: inline-flex; align-items: center; justify-content: center; }
            /* The rows of the sign-up popup read logo-then-name from the left;
               the tap-target rule above centred the pair mid-row on phones. */
            .signup-other { display: flex; justify-content: flex-start; }

            .footer-col a,
            .footer-bottom a,
            .filter-row a,
            .sec-link {
                min-height: 44px;
                display: inline-flex; align-items: center;
            }

            .nav-cta,
            .shop-sort,
            .nav-brand {
                min-height: 44px;
            }

        }
    
        /* ---- touch targets, second pass ------------------------------
           Named from a real 375px probe: footer column links were 44 tall but as
           narrow as 22px, pagination and the search row sat at 39-42px, and the
           popup's soft dismiss was 21px. Inline fine-print links inside a
           sentence are deliberately left alone. */
        @media (max-width: 900px), (pointer: coarse) {
            .footer-col a,
            .footer-links a,
            .legal a,
            .pager a,
            .pagination a,
            .shop-pager a,
            /* kai's pager anchors carry no class and are styled inline, so they
               are reachable only by href. Inline styles set padding, not height,
               so a stylesheet min-height still wins. */
            a[href*="?page="],
            a[href*="&page="],
            .cat-filter,
            .cmd-bar a,
            .cmd-bar button {
                min-width: 44px; min-height: 44px;
                display: inline-flex; align-items: center; justify-content: center;
            }
            .btn,
            .btn-outline,
            .btn-primary { min-height: 44px; }
            .search-wrap input,
            .search-wrap button,
            .shop-tools input,
            .shop-tools button { min-height: 44px; }
            .popup-dismiss {
                min-height: 44px;
                display: inline-flex; align-items: center; justify-content: center;
            }
        }
    
        /* ---- footer columns: restore the phone stack --------------------
           .footer-col a is display:block further up, but the two 44px
           touch-target blocks re-declare it inline-flex, so on a phone the
           nine column links flowed as text - three run-on lines of touching
           tap targets. A flex column puts the inline-flex children back on
           their own rows, and padding:0 keeps each one at exactly the
           inherited 44px instead of 44+22. */
        @media (max-width: 900px), (pointer: coarse) {
            .footer-col { display: flex; flex-direction: column; align-items: stretch; }
            .footer-col a { padding: 0; justify-content: flex-start; }
        }

        /* ---- card controls, re-ranked -------------------------------------
           .product-card-buy is a <span> inside the card's own <a href=
           "/product/...">: it cannot buy anything, it repeats the link the
           card already is. It was 64x44 of solid accent - the loudest element
           on the card - while save and agent, the two controls that do
           something of their own, were 34px and 32px discs at 0.32 alpha over
           white product cut-outs. The label now says what it does, the accent
           is spent on hover/focus, and the two real controls get 44px hit
           areas without growing: background-clip paints the disc only, so the
           padding ring stays transparent and tappable. */
        .product-card-buy { background: transparent; color: var(--accent-text, var(--accent));
            border: 1px solid currentColor; box-shadow: none; }
        .product-card:hover .product-card-buy, .product-card:focus-within .product-card-buy,
        .product-card-buy:hover { background: var(--accent); color: var(--accent-ink, #fff); border-color: var(--accent); }
        .product-card-wish, .product-card-agents {
            width: 44px; height: 44px; padding: 7px; box-sizing: border-box;
            background-clip: content-box; border: 0; box-shadow: none; }
        .product-card-wish { bottom: 2px; left: 2px; background-color: rgba(0,0,0,0.62); }
        .product-card-agents { top: 2px; right: 2px; background-color: rgba(0,0,0,0.62); opacity: 1;
            backdrop-filter: none; -webkit-backdrop-filter: none; }
        .product-card-wish:hover { background-color: rgba(0,0,0,0.78); color: #ff5a7a; transform: none; }
        .product-card-wish.on { background-color: #e0245e; color: #fff; }
        .product-card-agents:hover { background-color: var(--accent); }
        .product-card.out-of-stock .product-card-buy { background: transparent; color: var(--text-muted);
            border-color: var(--text-muted); }

        /* Below 340 the heart goes too: at (0,2,0) this has to sit after the
           .nav-mobile-actions .nav-mob-wish rule that gives it display:flex,
           or it loses on source order. It is the one control in the cluster
           the hamburger menu already carries as its own tile. */
        @media (max-width: 339px) {
            .nav-mobile-actions .nav-mob-wish { display: none; }
        }

        /* ---- states the captures never showed --------------------------------
           Light theme: the popup is a hard-dark glass panel. Re-scoping --text
           to white does not reach an element that sets no colour of its own -
           it inherits body's already-computed dark value - so the headline
           rendered #0a0a0b on rgba(18,18,18,.95), 1.06:1. Setting the colour on
           the overlay itself fixes everything that inherits. */
        html[data-theme="light"] .popup-overlay {
            --surface: #161616; --surface-2: #1e1e1e; --surface-3: #282828;
            --text: #ffffff; --text-secondary: rgba(255,255,255,0.65); --text-muted: rgba(255,255,255,0.5);
            --border-subtle: rgba(255,255,255,0.09); --accent-text: var(--accent);
            color: #ffffff;
        }
        /* accent printed as TEXT on the light surfaces was 3.2-3.3:1 */
        html[data-theme="light"] .nav-tool.active { color: var(--accent-text); }
        /* the last controls under 44px between 320 and 768 */
        .hero-products-btn { min-height: 44px; box-sizing: border-box; }
        .signup-other { min-height: 44px; }
        #cookie-banner .cb-btn { min-height: 44px; }
        /* the consent banner stays on top of everything, but lifts above the
           product page's sticky Buy bar while that bar is showing, so both can
           be reached - with both up, a tap on Buy used to land on the banner */
        @media (max-width: 860px) {
            body:has(#ppSticky.past:not([hidden])) #cookie-banner { bottom: 88px; }
        }
        /* ---- keyboard focus ------------------------------------------------
           No page had a :focus-visible rule, so a keyboard user tabbing through
           the header, the cards and the product page saw no sign of where focus
           was. :focus-visible matches keyboard focus, not a mouse click on a link
           or button. Text fields keep their own accent-border focus style (they
           set outline:none at higher specificity). --accent-text is the accent
           tuned for the active theme; the ategoat family defines it only in the
           light theme, hence the fallback. Top level, outside every @media. */
        :focus-visible { outline: 2px solid var(--accent-text, var(--accent)); outline-offset: 2px; }
        /* cards sit in scroll rows whose overflow would clip a ring drawn outside */
        .product-card:focus-visible { outline-offset: -2px; }
        /* the card's agent button is opacity:0 until hover on a mouse desktop */
        .product-card-agents:focus-visible { opacity: 1; }
