/* Closo Direct — the buyer realm's ONE stylesheet (storefront · PDP · checkout ·
   claim/order-ref). Its `?v=` is the CRC32 of these bytes (DirectAssetPin), so
   an edit moves the pin by itself: nothing to bump, nothing to forget.
   Every "why" — the §-clauses, the measured
   contrast ratios, the type scale and why this is a file and not an inline
   <style> — is in that layout's docblock, where a PHP comment costs the buyer
   nothing. Contract: tests/standalone/DirectStorefrontCssContractTest.php. */
/* mockup-v2 tokens — roles/numbers in the layout docblock */
/* Latin-subset fonts (R-16, 745271B->140136B) — recipe: tools/fonts/subset-storefront-fonts.sh */
@font-face{font-family:"Inter";src:url("/fonts/Inter-Regular-latin.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;unicode-range:U+0000-00FF,U+0100-024F,U+0259,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-2027,U+2030-205E,U+2074,U+20AC,U+2113,U+2122,U+2190-2193,U+2212,U+2215,U+2605,U+FEFF,U+FFFD}
@font-face{font-family:"Inter";src:url("/fonts/Inter-Medium-latin.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+0000-00FF,U+0100-024F,U+0259,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-2027,U+2030-205E,U+2074,U+20AC,U+2113,U+2122,U+2190-2193,U+2212,U+2215,U+2605,U+FEFF,U+FFFD}
@font-face{font-family:"Inter";src:url("/fonts/Inter-SemiBold-latin.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+0000-00FF,U+0100-024F,U+0259,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-2027,U+2030-205E,U+2074,U+20AC,U+2113,U+2122,U+2190-2193,U+2212,U+2215,U+2605,U+FEFF,U+FFFD}
@font-face{font-family:"Inter";src:url("/fonts/Inter-Bold-latin.woff2") format("woff2");font-weight:700;font-style:normal;font-display:swap;unicode-range:U+0000-00FF,U+0100-024F,U+0259,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-2027,U+2030-205E,U+2074,U+20AC,U+2113,U+2122,U+2190-2193,U+2212,U+2215,U+2605,U+FEFF,U+FFFD}
@font-face{font-family:"JetBrains Mono";src:url("/fonts/JetBrainsMono-Regular-latin.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;unicode-range:U+0020-007E,U+00A0,U+00B7,U+2013-2014,U+2018-2019,U+201C-201D,U+2026,U+2212,U+20AC,U+FEFF,U+FFFD}
@font-face{font-family:"JetBrains Mono";src:url("/fonts/JetBrainsMono-SemiBold-latin.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+0020-007E,U+00A0,U+00B7,U+2013-2014,U+2018-2019,U+201C-201D,U+2026,U+2212,U+20AC,U+FEFF,U+FFFD}
@font-face{font-family:"JetBrains Mono";src:url("/fonts/JetBrainsMono-Bold-latin.woff2") format("woff2");font-weight:700;font-style:normal;font-display:swap;unicode-range:U+0020-007E,U+00A0,U+00B7,U+2013-2014,U+2018-2019,U+201C-201D,U+2026,U+2212,U+20AC,U+FEFF,U+FFFD}
:root{--bg:#fff;--fg:#1A202C;--muted:#556070;--line:#E4E2EE;--edge:#7A7290;--focus:#1D4ED8;
  --accent:#452B90;--accent-ink:#fff;--card:#FAFAFC;--tint:#EDE8F8;--ok:#186A3B;--ok-tint:#E8F5EC;
  --err:#B0202A;--err-tint:#FBECEC;--warn:#8A5A00;--warn-tint:#FDF3E0;
  --shadow:0 1px 2px rgba(26,32,44,.06),0 8px 24px rgba(26,32,44,.07);
  --fm:"JetBrains Mono",ui-monospace,"SF Mono",Menlo,monospace;color-scheme:light;
  /* §34 pairs (band + §28 badge) — contrast pinned by the CSS-contract suite */
  --rose-tint:#FBE3EE;--rose:#B02E68;--ocean-tint:#DCEAFB;--ocean:#1D5FBF;
  --teal-tint:#D2F4EC;--teal:#0D7462;--sand-tint:#F3EADC;--sand:#8A5A2B;
  /* type scale — six steps, docblock §17. Nothing new may be added. */
  --f1:11px;--f2:12.5px;--f3:13.5px;--f4:15px;--f5:18px;--f6:24px}
/* ТЗ §38: LIGHT ONLY — dark block removed (operator 2026-08-09); rollback =
   git revert. `color-scheme:light` keeps UA controls light. Cabinet unaffected. */
*{box-sizing:border-box}
/* docblock §18 — the lock used to reflow `.wrap` by 7-8px. */
html{scrollbar-gutter:stable}
body{margin:0;background:var(--bg);color:var(--fg);
  font:16px/1.5 "Inter",system-ui,-apple-system,"Segoe UI",sans-serif;
  -webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none}
img{max-width:100%;display:block}
/* Controls do not inherit `font`; without this they render in Arial. */
input,button,select,textarea{font-family:inherit}
/* INLINE longhands only — see docblock §1. Second pair = safe-area ladder. */
.wrap{max-width:1280px;margin:0 auto;
  padding-left:16px;padding-right:16px;
  padding-left:max(16px,env(safe-area-inset-left));
  padding-right:max(16px,env(safe-area-inset-right))}

/* interaction states — docblock §3, §29 */
a:focus-visible,button:focus-visible,summary:focus-visible,input:focus-visible,
[tabindex]:focus-visible{outline:3px solid var(--focus);outline-offset:2px}
/* docblock §19 — allowed only because every one of these grows an `:active`. */
a,button,summary,label,input,.chip,.card{-webkit-tap-highlight-color:transparent}
.card,.chip,.btn,.iconbtn,.loadmore,.msgbtn,.acc-row,.ss-visit,
.st-back,.asklink,.desk-side .row,.side-more>summary,details.facet>summary,
.chip-x .x{transition:box-shadow .15s ease,border-color .15s ease,opacity .15s ease,
  background-color .15s ease,color .15s ease}
.cta,.followbtn{transition:background-color .12s,border-color .12s,color .12s}
@media (hover:hover){
  .card:hover{box-shadow:var(--shadow);border-color:var(--fg)}
  .card:hover .card-t{text-decoration:underline}
  .chip:hover,.btn:hover,.searchrow input:hover,.pricerow input:hover,.field-i:hover{border-color:var(--fg)}
  .btn-primary:hover{opacity:.88}
  .back:hover,.direct-order-ref__shop a:hover,.revlink:hover{text-decoration:underline}
  .iconbtn:hover,.loadmore:hover,.msgbtn:hover{border-color:var(--fg);background:var(--card)}
  .followbtn:hover{background:#f6f4fb;border-color:#cfc9df}
  .followbtn--on:hover{background:#efebf7;border-color:transparent}
  .cta:not([aria-disabled=true]):hover{background:#3a2478}
  .cta--ghost:not([aria-disabled=true]):hover{background:#f6f4fb;border-color:var(--accent);color:var(--accent)}
  .desk-side .row:hover{color:var(--fg);background:var(--card)}
  .side-more>summary:hover{color:var(--fg)}
  .desk-side .row.on:hover{background:var(--tint)}
  .desk-side .row.on:hover{color:var(--accent);text-decoration:underline}
  .acc-row:hover,details.facet>summary:hover{color:var(--accent)}
  .ss-visit:hover,.asklink:hover,.reset:hover{text-decoration:underline}
  .st-back:hover{color:var(--fg);background:var(--tint)}
  .chip.on:hover{opacity:.85}
  .chip-x:hover .x{opacity:1}
}
.chip:active,.btn:active,.followbtn:active,.iconbtn:active,.loadmore:active,
.msgbtn:active,.acc-row:active,details.facet>summary:active{background:var(--tint)}
.btn-primary:active{opacity:.8}
.cta:not([aria-disabled=true]):active{background:#2f1d63}
.cta--ghost:not([aria-disabled=true]):active{background:#efebf7}
.chip.on:active{background:var(--fg);opacity:.85}
.card:active{border-color:var(--edge)}

/* motion — docblock §20 */
@media (prefers-reduced-motion:no-preference){
  @keyframes sheet-up{from{transform:translateY(14%);opacity:.6}to{transform:none;opacity:1}}
  @keyframes sheet-dim{from{opacity:0}to{opacity:1}}
  @keyframes fade-in{from{opacity:0}to{opacity:1}}
  /* A6-06: the body used to shove the strip down 42.14px in one frame. Opacity
     + 4px, never height — docblock §23. */
  @keyframes acc-in{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
  .sheet-d[open]>.sheet-b{animation:sheet-up .22s cubic-bezier(.2,.7,.3,1)}
  .sheet-d[open]>.sh-dim,.drop[open]>.sh-dim{animation:sheet-dim .2s ease}
  .flashtip{animation:fade-in .15s ease}
  .acc[open] .acc-body{animation:acc-in .15s ease}
}
@media (prefers-reduced-motion:no-preference) and (max-width:1023px){
  /* only where the panel IS a sheet. */
  details.drop[open]>.drop-p{animation:sheet-up .22s cubic-bezier(.2,.7,.3,1)}
}
/* ≥1024 the sheet is a CENTRED DIALOG, and `sheet-up` ends on `transform:none`
   — which would un-centre it for the whole animation. Docblock §23. */
@media (prefers-reduced-motion:no-preference) and (min-width:1024px){
  @keyframes dlg-in{from{transform:translate(-50%,-46%);opacity:0}
    to{transform:translate(-50%,-50%);opacity:1}}
  .sheet-d[open]>.sheet-b{animation:dlg-in .18s cubic-bezier(.2,.7,.3,1)}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important}
}

/* shop header: banner + avatar + name (mockup storefront-m/-d) */
/* 96→128 / 140→220, ТЗ §7.4c. Budget + visible-crop arithmetic: docblock §24.
   The cropper frame reads THESE two heights, not 4:1 (§7.4c.3). */
.sf-banner{height:128px;position:relative;overflow:hidden;background-size:cover;background-position:50% 50%;
  background-image:
  repeating-linear-gradient(115deg,rgba(255,255,255,.07) 0 16px,transparent 16px 32px),
  linear-gradient(115deg,#4A3468,#7A6396 46%,#C0A98A)}
.sf-b-preset2{background-image:linear-gradient(115deg,#123B47,#2E7D6E 52%,#D6C39A)}
.sf-b-preset3{background-image:linear-gradient(115deg,#3B1F2B,#8A4257 50%,#E0A87E)}
.sf-b-preset4{background-image:linear-gradient(115deg,#1D2440,#4B5B8C 50%,#B9C6E0)}
/* §34.2 — presets 5-8, same 115deg family (why: layout docblock §26) */
.sf-b-preset5{background-image:linear-gradient(115deg,#5C2340,#A34D74 50%,#E8C2D2)}
.sf-b-preset6{background-image:linear-gradient(115deg,#16324F,#3D6DA8 50%,#BFD5EE)}
.sf-b-preset7{background-image:linear-gradient(115deg,#5A431F,#8A5A2B 50%,#EBD9BC)}
.sf-b-preset8{background-image:linear-gradient(115deg,#23222B,#4B4956 50%,#C9C7D4)}
/* The tagline rides the CONTENT column, not the screen edge (finding A1-10). */
.sf-banner .tagwrap{position:absolute;left:0;right:0;bottom:10px}
/* Two lines, not one ellipsis at 44 characters — ТЗ §7.4c.1, docblock §24. */
.sf-banner .tag{margin:0;color:#fff;font-size:var(--f2);line-height:1.35;
  font-weight:600;text-shadow:0 1px 6px rgba(0,0,0,.55);overflow:hidden;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.shop-head{padding-bottom:12px}
.sf-idrow{display:flex;align-items:center;gap:12px}
.sf-idtext{min-width:0;flex:1}
/* Positioned, or the painted banner covers the top ~40% of it (finding A1-03). */
.sf-ava{flex:0 0 auto;width:56px;height:56px;margin-top:-26px;border-radius:50%;
  position:relative;z-index:2;
  background:var(--accent);color:var(--accent-ink);border:3px solid var(--bg);
  display:flex;align-items:center;justify-content:center;font-size:21px;font-weight:700}
.sf-ava-img{object-fit:cover;background:var(--card)}
/* Two lines, not an ellipsis at 19 characters (finding A4-17). */
.shop-name{font-size:20px;font-weight:700;margin:0;letter-spacing:-.01em;
  padding-top:6px;overflow:hidden;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.25}
.sf-handle{font-size:var(--f2);color:var(--muted);margin:1px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sf-acts{flex:0 0 auto;display:flex;gap:8px;align-items:center;margin-left:auto}
.followbtn{display:inline-flex;align-items:center;gap:6px;min-height:36px;padding:0 13px;
  border:1px solid var(--line);border-radius:9px;background:var(--bg);color:var(--fg);
  font-size:13px;font-weight:600;letter-spacing:-.004em;cursor:pointer;white-space:nowrap;list-style:none}
.followbtn::-webkit-details-marker{display:none}
.followbtn--on{background:var(--tint);border-color:transparent;
  color:var(--accent);font-weight:700}
.iconbtn{width:44px;height:44px;flex:0 0 auto;border:1px solid var(--edge);border-radius:22px;
  display:flex;align-items:center;justify-content:center;color:var(--fg);background:var(--bg)}
.iconbtn svg{width:17px;height:17px}
.repline{font-size:13px;margin:8px 0 0;display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.repline b{font-family:var(--fm);font-size:14px}
.repline .cnt{color:var(--muted)}
/* The last two sub-44px targets on the first screen (finding A2-19): padded to
   44 and pulled back, so the type sits where it did and the thumb gets its box. */
.vbadge{display:inline-flex;align-items:center;min-height:44px;margin:-5px 0;color:var(--accent);font-weight:700;
  font-size:var(--f2);cursor:pointer;list-style:none}
.vbadge::-webkit-details-marker{display:none}
.behav{font-size:var(--f2);color:var(--muted);margin:5px 0 0}
.behav .lnk{color:var(--accent);font-weight:600;cursor:pointer;list-style:none;
  display:inline-flex;align-items:center;min-height:44px;margin:-10px 0;white-space:nowrap}
.behav .lnk::-webkit-details-marker{display:none}
.shop-trust{font-size:13px;color:var(--muted);margin:6px 0 0;display:flex;flex-wrap:wrap;gap:4px 8px}
.shop-trust span{white-space:nowrap}
/* §1.7 — statically true, so it carries no number and needs no data. Its text
   rides the content column (`.wrap`), not the screen edge — finding A1-10. */
@media (min-width:700px){
  .sf-banner{height:220px}   /* ТЗ §7.4c — see the note at `.sf-banner` above */
  .sf-ava{width:76px;height:76px;font-size:27px;margin-top:-36px}
  .shop-name{font-size:24px}
}

/* bottom sheets, from <details> alone (docblock §11) */
.sheet-d{display:inline-block}
.behav .sheet-d{display:inline}
.sheet-d>summary{cursor:pointer;list-style:none}
.sheet-d>summary::-webkit-details-marker{display:none}
.sh-dim{display:none}
.sheet-d[open]>.sh-dim,.drop[open]>.sh-dim{display:block;position:fixed;inset:0;z-index:40;
  background:rgba(12,8,20,.5)}
.sheet-b{position:fixed;left:0;right:0;bottom:0;z-index:41;display:flex;flex-direction:column;
  max-height:min(82vh,620px);background:var(--bg);border-top:1px solid var(--line);
  border-radius:18px 18px 0 0;box-shadow:0 -8px 30px rgba(0,0,0,.3);text-align:left}
/* A bottom sheet is a phone pattern; 1280px of one is not a dialog (A3-08).
   The same breakpoint split `.drop-p` has. Docblock §23. */
@media (min-width:1024px){
  .sheet-b{left:50%;right:auto;bottom:auto;top:50%;transform:translate(-50%,-50%);
    width:480px;max-width:calc(100vw - 32px);border:1px solid var(--line);border-radius:18px;
    box-shadow:0 18px 50px rgba(0,0,0,.28),var(--shadow)}
}
.grab{width:36px;height:4px;border-radius:3px;background:var(--edge);margin:9px auto 2px;flex:0 0 auto}
.sh-head{display:flex;justify-content:space-between;align-items:center;gap:12px;
  padding:8px 16px 10px;border-bottom:1px solid var(--line);font-size:15px}
/* `contain`: the gesture used to fall through to the page (finding A2-14). */
.sh-scroll{overflow-y:auto;overscroll-behavior:contain;padding:4px 16px 12px;flex:1 1 auto}
.sh-foot{padding:12px 16px 20px;padding-bottom:max(20px,env(safe-area-inset-bottom));
  border-top:1px solid var(--line);flex:0 0 auto}
.sh-cta{display:block;width:100%}
.sh-p,.sh-bio,.sh-note,.sh-goal{font-size:13px;color:var(--muted);margin:10px 0 0;line-height:1.55}
/* ТЗ §18 — the goal line: quiet weight, italic = quoted, no colour of its own. */
.sh-goal{font-style:italic}
.sh-bio{color:var(--fg);white-space:pre-wrap}
.reset{color:var(--accent);font-weight:600;font-size:13px;display:inline-flex;align-items:center;min-height:44px}
.trow{display:flex;justify-content:space-between;gap:12px;padding:10px 0;font-size:13px;
  border-bottom:1px solid var(--line)}
.trow:last-child{border-bottom:0}
.trow span{color:var(--muted);text-align:right}
.srctable{width:100%;border-collapse:collapse;margin-top:10px;font-size:13px}
.srctable th{text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted);padding:6px 0;border-bottom:1px solid var(--line)}
.srctable td{padding:9px 0;border-bottom:1px solid var(--line);color:var(--muted)}
.srctable td:first-child{color:var(--fg)}
.srctable .num{font-family:var(--fm);color:var(--fg)}
.followform{margin-top:12px}
.followform .btn{width:100%;margin-top:12px}
/* The trap: out of sight, out of the tab order, never display:none — some bots
   fill only what is rendered, and the point is that they fill it. */


/* controls */
.controls{padding:14px 0}
.controls>.wrap::after{content:"";display:block;height:1px;background:var(--line);margin-top:14px}
/* ONE ROW FOR SEARCH AND SORT — operator directive A0-01, docblock §21.
   Composed with `order`, so the DOM (and the screen reader) keeps its order. */
.toolbar{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-top:0;position:relative}
/* `min-width:0` IS the row — measured arithmetic (300px min-content; 150+142+8): git history, commit 5dbecf0df's parent carries the full block. */
.toolbar .searchrow{order:1;flex:1 1 150px;min-width:0}
.toolbar .drop-sort{order:2}
.toolbar .drop-filters{order:3}
.toolbar .count{order:4}
/* Capped: a 1248px-wide search field is not a search field. */
.searchrow{display:flex;gap:8px;max-width:560px;position:relative}
/* Enter submits either way; below 1024 the button costs the 85px Sort needs. */
@media (max-width:1023px){.searchrow .searchgo{display:none}}
.searchrow-i{position:absolute;left:15px;top:50%;transform:translateY(-50%);color:var(--muted);
  pointer-events:none;line-height:0}
.searchrow-i svg{width:15px;height:15px}
/* 44px min-height on every control — docblock §5 carries the before/after. */
.searchrow input[type=search]{flex:1;min-width:0;padding:11px 14px 11px 38px;font-size:16px;min-height:44px;
  border:1px solid var(--edge);border-radius:999px;background:var(--card);color:var(--fg)}
/* joined search pill — submit inside, ≥1024 only */
@media (min-width:1024px){
  .searchrow input[type=search]{padding-right:104px}
  .searchrow .searchgo{position:absolute;right:5px;top:50%;transform:translateY(-50%);
    min-height:34px;padding:7px 18px;border-radius:999px;font-size:var(--f2)}
}
.toolbar .btn{border-radius:999px}
.toolbar .drop-t{border-radius:10px}
.drop-t .chev{width:12px;height:12px;flex:0 0 auto;margin-left:2px;opacity:.7;
  transition:transform .15s ease}
.drop[open]>.drop-t .chev{transform:rotate(180deg)}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:44px;
  padding:11px 15px;border:1px solid var(--edge);border-radius:10px;background:var(--bg);
  color:var(--fg);font-size:13.5px;font-weight:600;cursor:pointer;white-space:nowrap}
.btn-primary{background:var(--accent);color:var(--accent-ink);border-color:var(--accent);font-weight:700}
.facet{margin:12px 0}
.facet-label{font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;
  color:var(--muted);margin-bottom:8px}
.chips{display:flex;flex-wrap:wrap;gap:10px}
.chip{display:inline-flex;align-items:center;justify-content:center;min-height:44px;min-width:44px;
  padding:10px 14px;border:1px solid var(--edge);border-radius:999px;
  font-size:13px;background:var(--bg);color:var(--fg)}
/* Selected = ink-filled, as in the mockup; the CTA keeps brand purple. */
.chip.on{background:var(--fg);color:var(--bg);border-color:var(--fg);font-weight:600}
.chip .n{opacity:.65;font-size:12px;margin-left:4px}
/* Was an 18px grey caption. `display` untouched: it keeps the triangle. */
details.facet>summary{font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;
  color:var(--fg);cursor:pointer;margin-bottom:8px;list-style:revert;min-height:44px;padding:13px 0}
.count{font-size:13px;color:var(--muted);margin-left:auto}
.pricerow{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.pricerow input{width:90px;padding:11px 10px;min-height:44px;font-size:16px;border:1px solid var(--edge);
  border-radius:10px;background:var(--card);color:var(--fg);font-family:var(--fm)}

/* Filters · Sort toolbar (docblock §8) */
/* A `<summary>` styled as a button: any display other than list-item drops the
   disclosure triangle, which is the intent here — `.drop-t` IS the control. */
.drop-t{list-style:none}
.drop-t::-webkit-details-marker{display:none}
.drop[open]>.drop-t{border-color:var(--fg)}
.drop-t .v{font-weight:500;color:var(--muted);margin-left:5px}
/* Applied-count badge on the Filters trigger — the mockup's brand pill. */
.drop-t .n{background:var(--accent);color:var(--accent-ink);border-radius:9px;min-width:18px;
  height:18px;display:inline-flex;align-items:center;justify-content:center;
  font-size:11px;font-weight:700;padding:0 5px}
/* The panel FLOATS, anchored to the TOOLBAR (not its trigger) — else it pushes
   the grid 339px / opens off-edge at 360 (measured left=-68.7). */
.drop-p{position:absolute;z-index:20;top:calc(100% + 6px);left:0;
  min-width:min(320px,calc(100vw - 32px));max-width:min(400px,calc(100vw - 32px));
  max-height:min(60vh,440px);overflow:auto;
  padding:12px 16px;border:1px solid var(--line);border-radius:14px;
  background:var(--bg);box-shadow:0 10px 30px rgba(0,0,0,.18),var(--shadow)}
.drop-p .facet:first-child{margin-top:0}
.drop-t .ic{width:14px;height:14px;flex:0 0 auto}
.sortlist{flex-direction:column;align-items:stretch}
.sortlist .chip{justify-content:flex-start}
/* The SAME panel, dressed as the mockup's sheet on a phone. Nothing is
   duplicated and nothing is script-created — docblock §11. */
@media (max-width:1023px){
  .drop-p{position:fixed;inset:auto 0 0 0;z-index:41;max-width:none;max-height:min(82vh,620px);
    display:flex;flex-direction:column;overflow:visible;padding:0;
    border:0;border-top:1px solid var(--line);border-radius:18px 18px 0 0;
    box-shadow:0 -8px 30px rgba(0,0,0,.3)}
  .drop-p .sh-scroll{padding-left:16px;padding-right:16px}
}
/* Desktop dropdown hangs off ITS OWN trigger; below 1024 the panel is fixed. */
@media (min-width:1024px){
  details.drop{position:relative}
  .drop-p{left:auto;right:0}
}
/* Applied filters live OUTSIDE the collapsed panel: a filter you cannot see is
   worse than a filter that costs a row. */
.applied{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-top:12px}
.chip-x .x{margin-left:7px;font-size:15px;line-height:1;opacity:.75}

/* grid: 2-up on phones, the shape a bio link needs */
/* Column count follows the window above 600 — docblock §7. The phone rule
   stays a fixed pair: auto-fill at 360px resolves to ONE column. */
.grid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;padding-top:12px}
@media (min-width:600px){.grid{grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}}
/* Automatic minimum is content: one long token would tear the row. */
.grid>*{min-width:0}
/* Bordered card, image bleeding to its edges — mockup .pcard. The tile is
   delimited by its BORDER, not its fill: dark `--card` on `--bg` is 1.06:1 and
   lifting the fill costs §4's 3:1. Arithmetic in the docblock §4. */
.card{display:block;background:var(--bg);border:1px solid var(--edge);border-radius:14px;
  overflow:hidden;padding-bottom:10px}
.card-img{aspect-ratio:1/1;background:var(--card);border-bottom:1px solid var(--line);
  overflow:hidden;position:relative}
/* Two or more PHOTOGRAPHS (frames, not image rows) — see views/shop/_card.php. */
.card-img .multi{position:absolute;left:7px;top:7px;display:flex;align-items:center;gap:4px;
  padding:3px 7px;border-radius:6px;background:var(--fg);color:var(--bg);
  font-size:11px;font-weight:700;font-family:var(--fm)}
.card-img .multi svg{width:11px;height:11px}
/* A broken image used to PAINT its alt — a scrape title over the tile (A4-03).
   Kept for the screen reader, off the screen; the frame degrades to `--card`. */
.card-img img{width:100%;height:100%;object-fit:cover;font-size:0;color:transparent}
/* hover scrub — ТЗ §10.3, docblock §25. Both boxes are created by script and
   exist only while a fine pointer is on the tile. */
.card-scrub{position:absolute;inset:0;z-index:1;opacity:0}
@media (prefers-reduced-motion:no-preference){
  .card-scrub{transition:opacity .16s ease}
  @media (hover:hover){.card-img img,.card-scrub{transition:opacity .16s ease,transform .18s ease}
    .card:hover .card-img img,.card:hover .card-scrub{transform:scale(1.05)}}
}
.scrub-dots{position:absolute;left:0;right:0;bottom:6px;z-index:2;
  display:flex;justify-content:center;gap:4px;pointer-events:none}
.scrub-dots i{width:5px;height:5px;border-radius:50%;background:rgba(255,255,255,.5);
  box-shadow:0 0 2px rgba(12,8,20,.6)}
.scrub-dots i.on{background:#fff}
.card-b{font-size:11px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;
  color:var(--fg);margin:9px 10px 0}
.card-t{font-size:var(--f3);margin:2px 10px 0;line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.card-p{font-size:var(--f4);font-weight:700;margin:5px 10px 0}
.card-p-na,.price-na{color:var(--muted);font-weight:600}
.card-s,.card-meta{font-size:12px;color:var(--muted);margin:2px 10px 0}

/* desktop facet rail (docblock §12) */
.desk-side{display:none}
.sec-h{font-size:15px;font-weight:700;margin:18px 0 2px}
.sec-note{font-size:12.5px;color:var(--muted);margin:0 0 8px}
@media (min-width:1024px){
  .shop-body{display:grid;grid-template-columns:220px minmax(0,1fr);gap:24px;align-items:start}
  /* 936.5px of rail in an 800px window had a bottom nobody could reach
     (finding A1-06). Its own scroll port, contained. */
  .desk-side{display:block;position:sticky;top:14px;padding-top:18px;
    max-height:calc(100vh - 28px);overflow-y:auto;overscroll-behavior:contain}
  .desk-side h4{font-size:10.5px;text-transform:uppercase;letter-spacing:.09em;color:var(--muted);
    margin:16px 0 6px}
  .desk-side h4:first-child{margin-top:0}
  .desk-side .row{display:flex;justify-content:space-between;gap:10px;align-items:center;
    min-height:34px;padding:5px 8px;margin:0 -8px;border-radius:8px;font-size:13px;color:var(--muted)}
  .desk-side .row.on{color:var(--accent);font-weight:700}
  .desk-side .row .n{font-family:var(--fm);font-size:12px}
  .side-more>summary{font-size:13px;color:var(--accent);font-weight:600;cursor:pointer;
    min-height:34px;padding:6px 0}
  /* The rail replaces the Filters sheet; Sort and the count stay. */
  .toolbar>.drop:first-of-type{display:none}
  /* A dropdown is not a sheet (A1-01 P0): no `.sh-dim` over the desktop panel. */
  .drop[open]>.sh-dim{display:none}
  /* Search · count · Sort, the mockup's desk-tools order (:1992-2000). */
  .toolbar .count{order:2;margin-left:auto}
  .toolbar .drop-sort{order:3;margin-left:0}
  /* Floor raised WITH the rail, not instead of it — §12 has the arithmetic. */
  .grid{grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}
}

/* states */
.empty{padding:48px 16px 24px;text-align:center;color:var(--muted)}
.empty h2{color:var(--fg);font-size:17px;font-weight:700;margin:0 0 6px}
.empty p{margin:0 0 16px;font-size:13.5px}
.empty-why{color:var(--muted)}
.empty-acts{display:flex;gap:10px;flex-wrap:wrap;justify-content:center}
.pager{display:flex;gap:10px;justify-content:center;padding:8px 0 40px;
  padding-bottom:max(40px,env(safe-area-inset-bottom));align-items:center;flex-direction:column}
.pager .pos{font-size:13px;color:var(--muted)}
/* "Next →" is the only route to items 25-63; it read as body text. */
.pager .btn{font-weight:600}
.pager-alt{display:flex;gap:10px;align-items:center;justify-content:center;flex-wrap:wrap}
/* mockup П-31: one button instead of a numbered ladder. */
.loadmore{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;max-width:360px;
  min-height:48px;padding:13px;border:1px solid var(--edge);border-radius:11px;
  font-size:14px;font-weight:700;background:var(--bg);color:var(--fg)}
.loadmore .lm-n{font-family:var(--fm);font-size:12px;font-weight:600;color:var(--muted)}

/* product page */
/* BLOCK AXIS ONLY — the inline axis belongs to `.wrap` (docblock §1). */
.pdp{padding-top:18px;padding-bottom:40px;padding-bottom:max(40px,env(safe-area-inset-bottom))}
/* Two classes beat one: the grid may run to 1280, prose may not. */
.wrap.pdp{max-width:960px}
/* PHONE: one snap track (docblock §10); 88% basis leaves the next-photo sliver. */
.pdp-gallery{display:flex;gap:8px;overflow-x:auto;scroll-snap-type:x mandatory;
  -webkit-overflow-scrolling:touch}
.pdp-gallery>img{flex:0 0 88%;scroll-snap-align:center;
  /* a flex item's automatic minimum is its content, and `width:100%` below
     makes that the FULL track — without this the 88% basis is floored away. */
  min-width:0}
.pdp-gallery>img:only-child{flex-basis:100%}
/* R-58 — the checkout is NOT two-column: `.co` cancels the grid, caps 560px.
   Measured why (448px floor): git history — the full comment rode this rule until the C-08b budget squeeze, commit 5dbecf0df. */
.wrap.pdp.co{max-width:560px}
@media (min-width:700px){
  .pdp{display:grid;grid-template-columns:1fr 1fr;gap:32px;align-items:start}
  .pdp.co{display:block}
  .pdp-gallery{display:grid;gap:10px;grid-template-columns:minmax(0,1fr);overflow:visible}
  .pdp-gallery>img{flex:none}
  /* Buy column travels with the photos (A3-07); max-height pair §12; docblock §23. */
  .pdp-buy{position:sticky;top:64px;max-height:calc(100vh - 78px);overflow-y:auto}
}
/* width:100% alone let height="640" stretch the frame — docblock §2. */
.pdp-gallery img,.pdp-info>img{width:100%;height:auto;aspect-ratio:4/5;object-fit:contain;
  border-radius:14px;background:var(--card);border:1px solid var(--line)}
.pdp-info>img{max-width:320px}
.pdp .card-b{margin:14px 0 0}
.pdp h1{font-size:18px;line-height:1.3;margin:4px 0 8px;font-weight:700;letter-spacing:-.01em}
.pdp .price{font-family:var(--fm);font-size:24px;font-weight:700;margin:0 0 12px}
/* Size / condition as bordered fact chips — mockup .facts/.fact. */
.pdp .attrs{list-style:none;padding:0;margin:0 0 16px;display:flex;flex-wrap:wrap;gap:6px}
.pdp .attrs li{display:inline-flex;gap:6px;align-items:center;padding:7px 11px;font-size:13px;
  border:1px solid var(--line);border-radius:8px}
.pdp .attrs .k{color:var(--muted)}
.pdp .attrs li span+span{font-weight:600}
.pdp .desc{font-size:14px;line-height:1.6;white-space:pre-wrap;word-break:break-word;margin:0 0 20px}
/* `cursor:pointer` — A6-10; the sold-out <span> keeps the arrow on purpose. */
.cta{display:block;width:100%;text-align:center;padding:14px;border-radius:11px;min-height:48px;
  background:var(--accent);color:var(--accent-ink);font-weight:700;font-size:15px;border:0;margin:0 0 10px;
  cursor:pointer}
.cta[aria-disabled=true]{background:var(--card);color:var(--muted);border:1px solid var(--edge);
  cursor:default}
.note{font-size:12.5px;color:var(--muted);margin:0 0 14px}
/* product page re-skin (docblock §14) */
.stickytop{position:sticky;top:0;z-index:30;background:var(--bg);border-bottom:1px solid var(--line)}
.stickytop-in{display:flex;align-items:center;gap:9px;min-height:48px;padding-top:4px;padding-bottom:4px}
.st-back{display:flex;align-items:center;justify-content:center;width:44px;height:44px;
  margin-left:-12px;font-size:22px;line-height:1;color:var(--muted);flex:0 0 auto;border-radius:50%}
/* 44px of thumb without 44px of ink (A3-15: 38×38 and 36×44). The overlay is
   part of the link's hit area; padding would have grown the circle. §23. */
.st-back,.st-share{position:relative}
.st-back::after,.st-share::after{content:"";position:absolute;left:50%;top:50%;
  width:44px;height:44px;transform:translate(-50%,-50%)}
.st-ava{width:30px;height:30px;font-size:13px;margin-top:0;border-width:0}
.st-id{min-width:0;flex:1}
.st-name{display:block;font-size:13px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.st-rev{font-size:11.5px;color:var(--muted)}
.st-share{width:38px;height:38px}
.galwrap{position:relative;min-width:0}
/* The 12% is §10's sliver of the NEXT photo: `right:12px` hung the counter
   over it (A3-16). Dots stay centred — §23 says why. */
.galcount{position:absolute;top:10px;right:calc(12% + 12px);padding:3px 9px;border-radius:10px;
  background:rgba(12,8,20,.68);color:#fff;font-family:var(--fm);font-size:11px;font-weight:700}
.galdots{position:absolute;left:0;right:0;bottom:10px;display:flex;gap:5px;justify-content:center}
.galdots i{width:6px;height:6px;border-radius:50%;background:#fff;opacity:.5;box-shadow:0 0 2px rgba(0,0,0,.5)}
.galdots i.on{opacity:1}
@media (min-width:700px){.galcount,.galdots{display:none}}
.pdp .price .pn{font-family:"Inter",system-ui,sans-serif;font-size:12.5px;font-weight:500;
  color:var(--muted);margin-left:6px;white-space:normal}
.pdp-from,.factnote{font-size:12px;color:var(--muted);margin:0 0 10px;line-height:1.5}
.factnote{margin:-8px 0 12px}
.checkline{display:flex;gap:8px;align-items:center;font-size:12.5px;color:var(--ok);
  font-weight:600;margin:0 0 10px}
.checkline svg{width:14px;height:14px;flex:0 0 auto}
/* the accordion: native <details>, so it opens with scripting off */
.accordion{border-top:1px solid var(--line);margin-top:14px}
.acc{border-bottom:1px solid var(--line)}
.acc-row{display:flex;justify-content:space-between;gap:12px;align-items:center;
  min-height:48px;padding:12px 2px;font-size:13.5px;font-weight:700;cursor:pointer;list-style:none}
.acc-row::-webkit-details-marker{display:none}
.acc-row span{color:var(--muted);font-size:12.5px;font-weight:500;text-align:right}
.acc-row .ok-s{color:var(--ok);font-weight:600}
.chev{display:inline-block;margin-left:4px;transition:transform .15s ease}
.acc[open] .chev{transform:rotate(90deg)}
.acc-body{padding:0 2px 14px;font-size:13px;line-height:1.55}
.acc-body p{margin:0 0 8px}
.acc-n{color:var(--muted);font-size:12.5px}
.asklink{color:var(--accent);font-weight:700;text-decoration:underline;text-underline-offset:2px}
.sellerstrip{display:flex;gap:10px;align-items:center;margin-top:16px;padding:11px;
  border:1px solid var(--line);border-radius:12px}
.ss-ava{width:38px;height:38px;font-size:15px;margin-top:0;border-width:0}
.ss-id{min-width:0;flex:1}
.ss-name{font-size:13.5px;font-weight:700}
.ss-rep{font-size:12px;color:var(--muted);margin-top:1px}
.ss-visit{color:var(--accent);font-weight:700;font-size:13px;min-height:44px;
  display:inline-flex;align-items:center;padding-left:8px}
.msg-d{display:block}
.msgbtn{display:flex;align-items:center;justify-content:center;gap:8px;min-height:48px;
  margin-top:10px;padding:12px;border:1px solid var(--edge);border-radius:11px;
  font-size:13.5px;font-weight:600;cursor:pointer;list-style:none}
.msgbtn::-webkit-details-marker{display:none}
.msgbtn svg{width:16px;height:16px}
.msgform .field-l{margin-top:12px}
.msg-t{min-height:96px;resize:vertical;line-height:1.5}
.msgform .btn{width:100%;margin-top:14px}
/* §4.8: server-rendered, `hidden`, revealed by the script. No script ⇒ no bar.
   It SLIDES (A6-07): parked below the edge, `.sb-on` at rest. `visibility` and
   not a transform alone — a parked bar is otherwise still tabbable. §23. */
.stickybuy{position:fixed;left:0;right:0;bottom:0;z-index:30;background:var(--bg);
  border-top:1px solid var(--line);box-shadow:0 -4px 14px rgba(12,8,20,.14);
  visibility:hidden;transform:translateY(110%);
  transition:transform .22s cubic-bezier(.2,.7,.3,1),visibility .22s}
.stickybuy.sb-on{visibility:visible;transform:none}
.sb-in{display:flex;gap:10px;align-items:center;padding-top:9px;padding-bottom:9px;
  padding-bottom:max(9px,env(safe-area-inset-bottom))}
.sb-p{font-family:var(--fm);font-size:17px;font-weight:700;flex:0 0 auto}
.sb-cta{flex:1;margin:0;padding:12px;min-height:44px}
/* And it is a PHONE bar (A3-06: a 1,163px Buy button at 1280). The mockup
   draws it for the phone only; above 700 the buy column is sticky. §23. */
@media (min-width:700px){.stickybuy{display:none}}
/* checkout form (docblock §9) */
/* Order summary card — mockup checkout-m. Rows RE-DISPLAY server values,
   the total included; nothing is added up here (buy.php's pricing note). */
.paybox{border:1px solid var(--line);border-radius:12px;background:var(--card);
  padding:10px 14px;margin:0 0 16px}
.sumline{display:flex;justify-content:space-between;gap:12px;font-size:13.5px;
  color:var(--muted);padding:4px 0}
.sumline .amt{font-family:var(--fm);color:var(--fg);font-weight:600}
.paybox-n{font-size:12px;color:var(--muted);margin:6px 0 2px;border-top:1px solid var(--line);padding-top:8px}
.co-hint{font-size:12.5px;color:var(--muted);margin:-4px 0 12px}
/* R-56 — 56x70 thumbnail, `cover` not `contain` (A3-18); NOT `.pdp-info>img`.
   Why: docblock §15/§16. */
.co-item{display:flex;gap:10px;align-items:center;margin:-4px 0 12px}
.co-item .co-hint{margin:0}
.co-thumb{width:56px;height:70px;flex:0 0 auto;object-fit:cover;
  border-radius:8px;border:1px solid var(--line);background:var(--card)}
/* checkout re-skin §5.1/§5.5/§5.7/§5.9 — see docblock §15/§16 */
.sumline.total{border-top:1px solid var(--line);margin-top:4px;padding-top:9px;
  color:var(--fg);font-weight:700}
.sumline.total .amt{font-size:16px}
.amt-off{color:var(--ok)}
/* R-10 — marks lead with CLOSO's promise; glyph pinned to the first line. */
.guards{border-top:1px solid var(--line);margin:14px 0 12px;padding-top:10px;
  font-size:12px;color:var(--muted);line-height:1.6}
.guards p{margin:0;display:flex;gap:7px;align-items:flex-start}
.guards svg{width:14px;height:14px;flex:0 0 auto;margin-top:2px}
.guards .g-ok{color:var(--ok);font-weight:600}
.guards .g-ok b{font-weight:700}
/* ТЗ §18 — the seller's own line, between the marks and the button. Quieter
   than a mark (no glyph, no `--ok`, italic = quoted) because it is not a
   promise Closo makes; `--f2` is the existing type step, no new size. */
.paygoal{font-size:var(--f2);color:var(--muted);font-style:italic;line-height:1.55;
  margin:0 0 12px;text-align:center}
.errbox{border:1px solid var(--err);border-radius:11px;background:var(--err-tint);
  color:var(--err);padding:10px 12px;margin:0 0 14px;font-size:13px;font-weight:700}
.errbox span{display:block;font-weight:400;color:var(--fg);margin-top:3px;font-size:12.5px}
.consents{border-top:1px solid var(--line);margin-top:14px;padding-top:10px}
.cons-t{font-size:12px;color:var(--muted);margin:0 0 6px;line-height:1.5}
.cons{display:flex;gap:10px;align-items:center;min-height:44px;font-size:12.5px;cursor:pointer}
.cons input{width:20px;height:20px;flex:0 0 auto;accent-color:var(--accent)}
.okhero{text-align:center;padding:18px 0 10px}
.okhero h1,.okhero h2{font-size:19px;font-weight:700;margin:0 0 6px}
.okhero p{font-size:13px;color:var(--muted);margin:0 0 4px;line-height:1.55}
.okhero .ok-num{font-family:var(--fm);color:var(--fg);font-weight:700;font-size:13.5px}
.okhero .ring{width:52px;height:52px;margin:0 auto 12px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;background:var(--ok-tint);color:var(--ok)}
.okhero .ring svg{width:26px;height:26px}
.okhero.warn .ring{background:var(--warn-tint);color:var(--warn)}
.okbtns{display:flex;gap:8px;margin-top:14px}
.okbtns .btn{flex:1;justify-content:center;text-align:center}
.gonebox{border-top:1px solid var(--line);margin-top:14px;padding-top:6px}
.gonebox .sec-h{margin-top:10px}
.gonebox .followform{margin-top:6px}
.gonebox .followform .btn{width:100%;justify-content:center;margin-top:10px}
.payform .field{margin:0 0 16px}
.field-l{display:block;font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--muted);margin:0 0 6px}
.field-i{width:100%;min-height:44px;padding:12px;font-size:16px;
  border:1px solid var(--edge);border-radius:10px;background:var(--card);color:var(--fg)}
/* The payment form mounts into `.mount`; unmounted, it must leave no dead gap.
   (Comment ships inside the page — never name the processor here, §3.2а.) */
.payform .mount:not(:empty){margin:0 0 16px}
.back{font-size:14px;color:var(--muted);padding:16px 0;display:inline-block}
/* shop policies + footer (ТЗ §3; one data source, two layouts) */
.polwrap{padding:6px 0 4px}
.polbox{border:1px solid var(--line);border-radius:13px;overflow:hidden;margin-top:8px}
.polrow{display:flex;gap:11px;padding:12px 13px;border-bottom:1px solid var(--line);align-items:flex-start}
.polrow:last-child{border-bottom:0}
.polrow svg{width:17px;height:17px;color:var(--muted);flex:0 0 auto;margin-top:1px}
.polrow .pt{font-size:12.5px;font-weight:700}
.polrow .pdsc{font-size:12.5px;color:var(--muted);margin-top:2px;line-height:1.5}
.polrow.protect{background:var(--ok-tint)}
.polrow.protect svg,.polrow.protect .pt{color:var(--ok)}
@media (min-width:900px){
  .polbox{display:grid;grid-template-columns:repeat(4,1fr)}
  .polrow{border-bottom:0;border-right:1px solid var(--line)}
  .polrow:last-child{border-right:0}
}
.sf-foot{border-top:1px solid var(--line);margin-top:18px;padding:16px 0 36px;
  padding-bottom:max(36px,env(safe-area-inset-bottom));font-size:12.5px;color:var(--muted)}
.sf-foot .wrap{display:flex;flex-wrap:wrap;gap:10px 16px;align-items:center}
.sf-foot a{min-height:34px;display:inline-flex;align-items:center}
.sf-foot a:hover{text-decoration:underline;text-underline-offset:2px}
footer{border-top:1px solid var(--line);padding:22px 0 40px;
  padding-bottom:max(40px,env(safe-area-inset-bottom));font-size:12.5px;color:var(--muted)}
.sr,.hp{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* 35 tab stops to the first item (finding A1-11); shows itself when focused. */
.skipl{position:absolute;left:-9999px;top:8px;z-index:60;background:var(--bg);color:var(--fg);
  border:1px solid var(--edge);border-radius:10px;padding:11px 15px;font-size:var(--f3);font-weight:700}
.skipl:focus{left:8px}
/* Share's copy confirmation. Script-created, so it is styled but never shipped
   as markup — a no-JS page has no element with this class. */
.flashtip{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);z-index:50;
  background:var(--fg);color:var(--bg);border-radius:999px;padding:9px 16px;font-size:13px;font-weight:600}

/* buyer half: claim page + public order reference */
/* Plain, narrow, no chrome. These pages carry four values at most. */
.direct-claim,.direct-order-ref{max-width:560px;margin:0 auto;padding:32px 16px;
  padding-left:max(16px,env(safe-area-inset-left));
  padding-right:max(16px,env(safe-area-inset-right));
  padding-bottom:max(32px,env(safe-area-inset-bottom))}
.direct-claim h1,.direct-order-ref__item{font-size:20px;font-weight:600;margin:0 0 12px;line-height:1.35}
.direct-claim__state,.direct-order-ref__state{font-size:14px;color:var(--muted);margin:0 0 12px}
.direct-claim__tracking{font-size:14px;margin:0 0 18px;word-break:break-all}
.direct-order-ref__shop{font-size:14px;color:var(--muted);margin:0 0 6px}
.direct-order-ref__shop a{text-decoration:underline}
.direct-claim__disavow{margin-top:28px;padding-top:18px;border-top:1px solid var(--line)}
.direct-claim__disavow button{padding:11px 14px;min-height:44px;border:1px solid var(--edge);
  border-radius:10px;background:var(--card);color:var(--muted);font-size:14px;cursor:pointer}
.direct-claim--missing p,.direct-order-ref--missing p{color:var(--muted);font-size:15px}

/* A0-05/07 brand row */
.sf-brandrow{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:14px;
  padding-top:14px;border-top:1px solid var(--line);font-size:13px;color:var(--muted)}
.sf-closo{display:inline-flex;align-items:center;gap:7px;font-weight:700;font-size:14px;
  color:var(--fg);text-decoration:none;letter-spacing:-.02em}
.sf-closo-mark{width:18px;height:18px;border-radius:5px;
  background:linear-gradient(135deg,#6C40B5,#452B90);display:inline-block}
.sf-closo-line{color:var(--muted)}
.sf-closo-cta{color:var(--muted);text-decoration:none;margin-left:auto;min-height:44px;
  display:inline-flex;align-items:center}
.sf-closo-cta:hover,.sf-closo-cta:focus-visible{color:var(--accent);text-decoration:underline;text-underline-offset:3px}
@media(max-width:700px){.sf-closo-cta{margin-left:0}}

/* operator round 2026-08-08 — see commit 454820ca6 */
.sf-badges{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-top:12px}
.sf-badge{display:inline-flex;align-items:center;gap:6px;min-height:28px;padding:4px 12px;
  border:1px solid var(--line);border-radius:999px;background:var(--card);
  font-size:var(--f2);font-weight:500;color:var(--muted)}
.sf-badge svg{width:13px;height:13px;flex:0 0 auto}
.sf-badge b{font-weight:600}
.sf-badge.ok{background:var(--ok-tint);border-color:transparent;color:var(--ok)}
.sf-banner .tag{margin-left:66px}
@media(min-width:1024px){.sf-banner .tag{margin-left:92px}}
.sortlist{flex-direction:column;gap:2px;align-items:stretch}
.sortlist .chip{width:100%;justify-content:space-between;border-color:transparent;
  background:none;border-radius:8px;min-height:44px;font-weight:500}
.sortlist .chip:hover{background:var(--card);border-color:transparent}
.sortlist .chip.on{background:var(--tint);color:var(--fg);border-color:transparent;font-weight:600}
.sortlist .chip.on::after,.followbtn--on::before{content:"";width:7px;height:11px;flex:0 0 auto;
  border-right:2px solid var(--accent);border-bottom:2px solid var(--accent);
  transform:rotate(45deg) translateY(-2px)}
.sortlist .chip.on::after{margin-left:10px}
.applied{gap:8px}
.applied .chip-x{font-size:var(--f2);min-height:34px;padding:4px 12px;
  background:var(--tint);border-color:transparent;color:var(--fg);font-weight:500}
.applied .chip-x .x{margin-left:8px;width:18px;height:18px;display:inline-flex;
  align-items:center;justify-content:center;border-radius:50%;font-size:var(--f2);opacity:.8}
.applied .chip-x:hover .x{background:var(--card);opacity:1}
.applied .clear-all{min-height:34px;padding:4px 6px;border:0;background:none;
  color:var(--muted);font-size:var(--f2);text-decoration:underline;text-underline-offset:3px}
.applied .clear-all:hover{color:var(--accent)}
.foot-shop{display:inline-flex;align-items:center;gap:8px;color:var(--muted);font-weight:500;margin-left:auto}
.foot-ava{width:20px;height:20px;border-radius:50%;object-fit:cover;flex:0 0 auto}
.foot-ava-i{display:inline-flex;align-items:center;justify-content:center;
  background:var(--accent);color:var(--accent-ink);font-size:var(--f1);font-weight:700}

/* vstats — aggregate only, no marketplace names (operator 08-08) */
.vstats{display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr));gap:10px;margin-top:12px}
.vstat{background:var(--card);border:1px solid var(--line);border-radius:12px;
  padding:12px 14px;display:flex;flex-direction:column;gap:2px}
.vstat b{font-size:var(--f5);font-weight:700;letter-spacing:-.02em}
.vstat span{font-size:var(--f2);color:var(--muted)}
.searchrow input::placeholder{text-overflow:ellipsis}
@media (max-width:400px){
  .toolbar{gap:8px 10px}
  .drop-t{padding-left:12px;padding-right:12px}
}
/* the grab handle is a swipe affordance — phones only (operator 08-08) */
@media (min-width:1024px){.grab{display:none}}
@media (max-width:1023px){
  .toolbar{flex-wrap:nowrap}
  .toolbar .count{display:none}
  .drop-t .colon,.drop-sort .drop-t .v{display:none}
  .drop-filters .drop-t .lbl{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
  .drop-filters .drop-t{min-width:44px;justify-content:center;padding-left:12px;padding-right:12px}
}
.desc.clamped{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.desc-toggle{background:none;border:0;padding:6px 0;min-height:44px;color:var(--accent);
  font-size:var(--f3);font-weight:600;cursor:pointer;text-underline-offset:3px}
.desc-toggle:hover{text-decoration:underline}
.trow b{display:inline-flex;align-items:center;gap:8px}
.trow-ic{width:14px;height:14px;flex:0 0 auto;color:var(--muted)}
.sumline.sale .amt{color:var(--ok);font-weight:600}

/* ── PROMO STRIP (ТЗ §19) — the shop's live offers, over the grid ───────────
   A band, not a sticker; one icon per offer kind, so it is a flex list.
   Spacing 14 above, 2 + the grid's own 12 below = 14, both carried by the
   strip so a shop with no offers leaves the grid where it was.
   Four named pairs, all TOKENS ⇒ both themes follow with no second rule. */
.promo-strip{margin:14px 0 2px;padding:10px 14px;border-radius:12px;
  background:var(--tint);color:var(--accent);
  font-size:var(--f3);font-weight:600;letter-spacing:-.01em;
  display:flex;flex-wrap:wrap;align-items:center;gap:2px 9px}
.promo-part{display:inline-flex;align-items:center;gap:6px}
.promo-ic{width:15px;height:15px;flex:0 0 auto}
.promo-sep{opacity:.45}
.promo-strip--brand{background:var(--tint);color:var(--accent)}
.promo-strip--green{background:var(--ok-tint);color:var(--ok)}
.promo-strip--amber{background:var(--warn-tint);color:var(--warn)}
.promo-strip--ink{background:var(--fg);color:var(--bg)}
.promo-strip--rose{background:var(--rose-tint);color:var(--rose)}
.promo-strip--ocean{background:var(--ocean-tint);color:var(--ocean)}
.promo-strip--teal{background:var(--teal-tint);color:var(--teal)}
.promo-strip--sand{background:var(--sand-tint);color:var(--sand)}

/* ── GIVEAWAY BAND (E2 ТЗ §37) — one partial (_giveaway_band.php); a link,
   promo-strip spacing, card ground so it reads as a door, not an offer. */
.gwband{display:flex;align-items:center;gap:9px;margin:14px 0 2px;padding:11px 14px;
  border:1px solid var(--edge);border-radius:12px;background:var(--card);
  font-size:var(--f3);letter-spacing:-.01em}
.gwband-ic{width:17px;height:17px;flex:0 0 auto;color:var(--accent)}
.gwband-t{font-weight:700;color:var(--fg);white-space:nowrap}
.gwband-meta{color:var(--muted);min-width:0}
.gwband-cta{margin-left:auto;color:var(--accent);font-weight:700;white-space:nowrap}
@media (hover:hover){.gwband:hover{border-color:var(--fg)}
  .gwband:hover .gwband-cta{text-decoration:underline}}

/* ── SALE BADGE (ТЗ §28) — `.multi`'s geometry, top-RIGHT; colours = the band's
   eight pairs, no class = brand; inline in the PDP price row. Why: layout
   docblock §27. */
.sbadge{display:inline-block;padding:4px 8px;border-radius:9px;
  font-size:11px;font-weight:700;line-height:1.35;
  letter-spacing:.02em;background:var(--rose);color:#fff;white-space:nowrap}
.card-img .sbadge{position:absolute;right:7px;top:7px;box-shadow:var(--shadow)}
.price .sbadge{margin-left:7px;vertical-align:3px}
.sbadge--brand{background:var(--tint);color:var(--accent)}
.sbadge--green{background:var(--ok-tint);color:var(--ok)}
.sbadge--amber{background:var(--warn-tint);color:var(--warn)}
.sbadge--ink{background:var(--fg);color:var(--bg)}
.sbadge--rose{background:var(--rose-tint);color:var(--rose)}
.sbadge--ocean{background:var(--ocean-tint);color:var(--ocean)}
.sbadge--teal{background:var(--teal-tint);color:var(--teal)}
.sbadge--sand{background:var(--sand-tint);color:var(--sand)}
.sh-goal,.sh-bio{display:flex;gap:8px;align-items:flex-start}
.sh-ic{width:14px;height:14px;flex:0 0 auto;margin-top:3px;color:var(--muted)}
.card-p .was,.price .was{font-size:var(--f2);color:var(--muted);font-weight:400;margin-left:6px}

/* ── E1 «Make an offer» (ТЗ §39; mockup screen 8) ─────────────────────────
   The sheet + link-action pages reuse the storefront system whole; these are
   the only additions. `.cta--ghost` is the secondary CTA beside Buy now —
   outlined, same hit target. `.note--warn` is the §33.7 refusal color (the
   floor phrase after a low amount); `.note--fine` the smaller print under the
   card step; `.visually-hidden` the standard SR-only label utility. */
.cta--ghost{background:var(--card);color:var(--fg);border:1px solid var(--edge);margin-top:8px}
.note--warn{color:var(--warn)}
.note--fine{font-size:11.5px}
.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
#offer-sheet .chips{margin:0 0 12px}
#offer-sheet section{margin-top:6px}
#offer-sheet .btn,#offer-act .btn{margin-top:10px}
#offer-card-element{margin:10px 0}

/* §36 L1 welcome popup + passive lines — existing tokens only */
.lg-dim{position:fixed;inset:0;background:rgba(26,32,44,.45);z-index:60}
.lg-pop{position:fixed;left:16px;right:16px;bottom:16px;z-index:61;background:var(--bg);
  border:1px solid var(--edge);border-radius:14px;padding:18px 16px;box-shadow:var(--shadow)}
@media (min-width:700px){.lg-pop{left:50%;right:auto;bottom:auto;top:50%;
  transform:translate(-50%,-50%);width:400px;max-width:calc(100vw - 32px)}}
.lg-x{position:absolute;right:6px;top:6px;background:none;border:0;font-size:20px;
  color:var(--muted);width:44px;height:44px;cursor:pointer}
.lg-pop h5{margin:0 28px 4px 0;font-size:17px}
.lg-pop p{margin:0 0 10px;font-size:var(--f2);color:var(--muted)}
.lg-pop .field-i{width:100%;margin:0 0 8px}
.lg-cta{width:100%}
.lg-code{font-family:var(--fm);font-weight:700;font-size:var(--f6);letter-spacing:2px;
  text-align:center;border:1px dashed var(--edge);border-radius:10px;background:var(--tint);
  padding:10px;margin:0 0 10px}
.lg-no{background:none;border:0;color:var(--muted);font-size:var(--f2);cursor:pointer;
  min-height:44px;width:100%;text-decoration:underline}
.lg-field{margin:0 0 10px}
.lg-line{padding:10px 16px;margin:0;font-size:var(--f3);color:var(--muted)}
.lg-line a{color:var(--accent);font-weight:600}
.lg-line--foot{padding:10px 0 0}

/* ── SKELETON ENTRANCE (2026-08-16, operator: same as the liquidator
   storefront). Copied from `modules/shop/views/shop/windex.php` .skel — one
   shimmer pass over the tiles and the shop name while the page settles, then
   a staggered fade-in. Applied and removed by `shop-storefront.js` §23; the
   server HTML is untouched (the load-more suites count `<a class="card"`
   literally and see the same string). `--card` is this sheet's soft surface
   (windex uses its own --soft); the literal #EEF1F4 is used because --card here is near-white and would be invisible on the white page. */
.skel{position:relative;overflow:hidden;color:transparent!important;pointer-events:none;user-select:none}
.skel *{visibility:hidden}
.skel::before{content:"";position:absolute;inset:0;background:#EEF1F4;border-radius:inherit;z-index:2}
.skel::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent,rgba(255,255,255,.6),transparent);transform:translateX(-100%);animation:sf-shm 1.1s infinite;z-index:3}
@keyframes sf-shm{to{transform:translateX(100%)}}
.unskel{animation:sf-skf .3s ease}
@keyframes sf-skf{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.skel::after,.unskel{animation:none!important}}
