/* Storefront cards (owner list 2026-10-27). Loaded after theme.css and the
   voice forms; every rule names its item. The behaviour lives in
   app/card-add.js (the «+», the price line) and app/cart-bar-empty.js (the
   bar). Product cards are .card[data-key]; the product page's purchase box
   (.rich-product-purchase) keeps its own row. */

/* ---- 1. One «+» until the product is in the cart ----
   The stepper's own + alone until the first tap; the − and the number, the
   unit chips and the preparation choices come with it (.in-cart, set by
   syncQty). The clean card's open card (.is-open) shows its whole stepper, as
   before. The gallery keeps its round + on the photo (its rules name #catalog
   and win). «מונה מלא» (theme.productAppearance.addControl "stepper",
   html[data-add-control]) keeps the whole stepper from the start, as before
   #623 (owner 2026-10-27).
   The «+» stays put (owner 2026-10-28): the stepper keeps its whole footprint
   from the start, its − and number invisible and its strip unpainted, so the
   «+» already sits in the slot it keeps after the first tap — same place,
   same size — and the − and the number appear beside it. «כפתור במילים»
   (below, section 9) is a full-width button that turns into the stepper. */
html:not([data-add-control="stepper"]) .card[data-key]:not(.in-cart):not(.is-open):not(.rich-product-purchase) > .qty-row > :not(.plus){visibility:hidden;}
html[data-add-control="words"] .card[data-key]:not(.in-cart):not(.is-open):not(.rich-product-purchase) > .qty-row > :not(.plus){display:none;}
html:not([data-add-control="stepper"]) .card[data-key]:not(.in-cart):not(.is-open):not(.rich-product-purchase) :is(.unit-choice, .prep){display:none;}
html:not([data-add-control="stepper"]) .card[data-key]:not(.in-cart):not(.is-open):not(.rich-product-purchase) > .qty-row{background:transparent;}
html:not([data-add-control="stepper"]) .card[data-key]:not(.in-cart):not(.is-open):not(.rich-product-purchase) > .qty-row > .plus{line-height:1;}
html:not([data-add-control="stepper"]) .card[data-key]:not(.in-cart):not(.is-open):not(.rich-product-purchase) > .qty-row > .plus:disabled{box-shadow:none;}
/* The preparation choices open under the stepper (app/card-add.js moves them there and marks the card
   .prep-under); the card's spare height sits below, where they open, not above the stepper, so a card shorter
   than its row does not lift its «+» when they appear. */
html:not([data-add-control="stepper"]) .card[data-key]:not(.rich-product-purchase) > .qty-row + .prep{margin:8px 0 0;}
html:not([data-add-control="stepper"]) .card.prep-under[data-key]:not(.rich-product-purchase) > .qty-row,
html:not([data-add-control="stepper"]) :is(#catalog, #dealsStrip, body) .boutique-card.prep-under[data-key] > .price-tag{margin-top:0;}
/* One stepper (owner 2026-10-27, «צריך להתאים בגודל»): the counter is as tall as the − and + it sits
   between (their painted boxes are equal: theme.css .card .qty-btn, the shape from «כפתורים»), centred.
   A narrow card (≤ 110px) keeps its own wrapped stepper (theme.css). */
.card[data-key]:not(.rich-product-purchase) > .qty-row{align-items:stretch;}
.card[data-key]:not(.rich-product-purchase) > .qty-row > .qty-value{display:flex; flex-direction:column; justify-content:center; align-self:stretch;}
.card[data-key]:not(.rich-product-purchase) > .qty-row > .qty-btn{align-self:center;}
/* The stepper is centred in the card, the counter between − and + (owner 2026-10-27); before the first tap
   too, so its «+» does not move (owner 2026-10-28). */
.card[data-key]:not(.rich-product-purchase) > .qty-row{align-self:center; margin-inline:auto;}
/* The − is outlined where it is painted: the ring sits on the 42px square, not on the padded tap area around it
   (theme.css draws it as an inset shadow of the whole button, 4px larger than the + beside it). */
.card[data-key]:not(.rich-product-purchase):not(.boutique-card) > .qty-row > .qty-btn.minus{position:relative; box-shadow:none;}
.card[data-key]:not(.rich-product-purchase):not(.boutique-card) > .qty-row > .qty-btn.minus::before{
  content:""; position:absolute; inset:2px; border-radius:inherit; pointer-events:none;
  box-shadow:inset 0 0 0 1px var(--ui-qty-minus-border, var(--line));
}
@container shopcard (max-width:109.98px){
  .card[data-key]:not(.rich-product-purchase):not(.boutique-card) > .qty-row > .qty-btn.minus::before{inset:6px 2px;}
}
/* The round card is centred, so are its «+» and its stepper. */
html[data-layout-card-shape="round"] .card[data-key] > .qty-row{align-self:center;}

/* ---- 2. A grid that grows with the screen, readable names and prices ----
   The catalogue and its search are at least 1320px wide from a 1440px
   screen (the builder publishes a fixed 1180px --container; a wider one
   wins, and so do the owner's part widths through store-design.js). On a computer the columns follow a 200px minimum
   card, and the owner's products per row (--prod-cols, shop or category) is
   the most a row holds. The phone keeps its exact count (theme.css). */
@media (min-width:1440px){
  main, .prod-search:not(.is-floating){max-width:max(var(--container), 1320px);}
}
@media (min-width:1100px){
  .product-grid,
  html[data-products-per-row] .product-grid{
    grid-template-columns:repeat(auto-fill, minmax(max(200px, calc((100% - (var(--prod-cols) - 1) * 22px) / var(--prod-cols))), 1fr));
  }
}
.card[data-key] > .card-name{font-size:0.9375rem; line-height:1.35;}
@media (max-width:640px){
  .card[data-key] > .card-name{font-size:0.875rem;}
}
@container shopcard (max-width:109.98px){
  .card[data-key] > .card-name{font-size:clamp(0.625rem, 12cqi, 0.8125rem);}
}
/* The price, moved under the name by card-add.js (a plain price only: an
   offer keeps its sticker on the photo). Bold and larger than the name, in
   the brand ink; the owner's price colours (--ui-price-*) and «תג מחיר»
   recipe still win. Doubled classes outrank the photo-sticker rules
   (theme.css, the «פשוט» card) without !important. data-price-line marks a moved price. */
html :is(#catalog, #dealsStrip, .editorial-featured-grid, .fc) .card.card[data-key] > .price-tag[data-price-line]{
  position:static; transform:none; transform-origin:50% 50%; align-self:center;
  width:auto; max-width:100%; margin:0 0 8px; padding:1px 8px;
  background:var(--ui-price-bg, transparent); color:var(--ui-price-text, var(--accent-deep, var(--primary)));
  box-shadow:none; border-radius:var(--r-chip);
  font-family:var(--font-body), sans-serif; font-size:1.125rem; font-weight:800; line-height:1.25; text-align:center;
}
html :is(#catalog, #dealsStrip, .editorial-featured-grid, .fc) .card.card[data-key] > .price-tag[data-price-line] .price-unit{font-size:0.75em; font-weight:600;}
/* A bundle's regular price (app/offer-chrome.js, owner list 28.10): the same
   line under the name as every other card's price; the bundle stays on the
   photo's sticker. */
.card[data-key] > .offer-regular-price{
  align-self:center; max-width:100%; margin:0 0 8px; padding:1px 8px; text-align:center;
  color:var(--ui-price-text, var(--accent-deep, var(--primary)));
  font-family:var(--font-body), sans-serif; font-size:1.125rem; font-weight:800; line-height:1.25;
  font-variant-numeric:tabular-nums; overflow-wrap:anywhere;
}
@media (max-width:640px){ .card[data-key] > .offer-regular-price{font-size:1rem; margin-bottom:6px;} }
@container shopcard (max-width:109.98px){ .card[data-key] > .offer-regular-price{font-size:clamp(0.6875rem, 14cqi, 0.9375rem); padding-inline:0;} }
@media (max-width:640px){
  html :is(#catalog, #dealsStrip, .editorial-featured-grid, .fc) .card.card[data-key] > .price-tag[data-price-line]{font-size:1rem; margin-bottom:6px;}
}
@container shopcard (max-width:109.98px){
  html :is(#catalog, #dealsStrip, .editorial-featured-grid, .fc) .card.card[data-key] > .price-tag[data-price-line]{font-size:clamp(0.6875rem, 14cqi, 0.9375rem); padding-inline:0;}
}
/* Forms whose name starts at the card's edge put the price there too. */
html:is([data-layout-catalog="mosaic"], [data-layout-cards="plain"]) #catalog .card.card[data-key] > .price-tag[data-price-line]{align-self:flex-start; text-align:start; margin-inline:2px;}
html[data-layout-catalog="mosaic"] #catalog .product-grid:not(.product-carousel) > .card.card[data-key] > .price-tag[data-price-line]{margin-inline:10px;}
html[data-layout-cards="plain"]:not([data-catalog-style="boutique"]) :is(#catalog, #dealsStrip) .card[data-key]:has(> .price-tag) > .card-name{padding-inline-end:0; min-height:0;}
/* The mosaic's big tile has a big name; its price stays the larger line. */
html[data-layout-catalog="mosaic"] #catalog .product-grid:not(.product-carousel) > .card[data-key]:not([data-card-span]):nth-child(6n+1) > .price-tag[data-price-line]{font-size:1.625rem;}
@media (max-width:640px){
  html[data-layout-catalog="mosaic"] #catalog .product-grid:not(.product-carousel) > .card[data-key]:not([data-card-span]):nth-child(6n+1) > .price-tag[data-price-line]{font-size:1.25rem;}
}
/* Boutique draws its own price line under the name (boutique.js); bold, as everywhere. */
html[data-catalog-style="boutique"] .card.boutique-card[data-key] > .price-tag{font-weight:700;}

.card-img > .price-tag{font-weight:800;}
/* The tag on the photo always shows the whole price (owner 2026-10-29: «8. ₪/ק״ג» on a narrow photo —
   «8.90 ₪/ק״ג» was one unbreakable run, so beside the flag it ran past the tag's edge, off its
   background). The amount keeps one line and «₪/ק״ג» goes under it when the room is short (the
   space between them is the only break); the tag is never narrower than its longest piece. An
   offer's tag is the same block. */
.card-img > .price-tag{min-width:min-content;}
.card-img > .price-tag .price-main{white-space:normal;}
.card-img > .price-tag .price-amount{white-space:nowrap;}

/* ---- 3. The sticker is a small corner badge ----
   «מדבקה» (item.card.sticker) inside the photo's top corner, where the price
   used to stand before it moved under the name (#623): physically top-right
   in both directions (the kashrut tab and the flag hold the top-left).
   A deal still hides it (theme.css), so it never meets the offer sticker. */
.card-img > .card-sticker{
  inset-block-end:auto; inset-inline-start:auto; top:6px; bottom:auto; right:6px; left:auto;
  width:48px; height:48px; padding:4px; font-size:0.6875rem; rotate:-6deg;
}
.card-img > .card-sticker::before{inset:3px;}
/* The list's photo is not a positioned box: the badge sits at its top edge. */
html[data-layout-catalog="rows"] #catalog .product-grid:not(.product-carousel) > .card .card-img > .card-sticker{top:var(--row-pad);}
@media (max-width:640px){
  .card-img > .card-sticker{width:38px; height:38px; padding:3px; font-size:0.5rem; top:4px; right:4px;}
}

/* ---- 5. The bottom bar with no basket on it ----
   «לכל המוצרים» when the cart is empty (#cartBar[data-cart-state], set by
   cart-bar-empty.js). The full bar (.cart-inner) is not laid out meanwhile,
   so --cart-bar-h is the pill's height. */
.cart-pill{display:none;}
#cartBar[data-cart-state="all"] .cart-inner{display:none;}
#cartBar[data-cart-state="all"] .cart-all{
  display:inline-flex; align-items:center; justify-content:center; gap:10px; pointer-events:auto;
  min-height:48px; padding:10px 22px; border:0; border-radius:999px; cursor:pointer;
  background:var(--ui-cart-bg, var(--primary)); color:var(--ui-cart-text, var(--paper));
  font-family:var(--font-body), sans-serif; font-size:0.9375rem; font-weight:700; line-height:1.2;
  box-shadow:0 12px 28px -10px rgba(0,0,0,0.45);
}
.cart-all svg{width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:2.4; stroke-linecap:round;}
.cart-pill:focus-visible{outline:var(--focus-ring-width,2px) solid var(--focus-ring,#0B5FFF); outline-offset:2px;}
body.has-cart-pill{padding-bottom:var(--cart-bar-h, 72px);}
@media (prefers-reduced-motion:no-preference){
  html:not([data-a11y-motion="1"]) #cartBar[data-cart-state] .cart-pill{animation:cart-pill-in .3s cubic-bezier(.22,1,.36,1);}
  @keyframes cart-pill-in{from{transform:translateY(40%); opacity:0;}}
}

/* ---- 6. «גדלים ומחירים»: a chip per size, with its price ----
   app/card-type.js sizesHtml, only on a product whose sizes the owner set
   (details.optionTypes ["portion"]). The chosen one is the card's price
   and what the «+» adds; a sold-out size is greyed and disabled.
   One row of equal fixed-height chips, the name over the price (owner list
   26.10, item 9: two rows of different heights doubled the card at 390):
   the chips share the width, never narrower than their words — when they
   do not fit (a narrow phone card, a fourth size) the row scrolls sideways. */
.variant-picker.size-chips{
  flex-direction:row; flex-wrap:nowrap; gap:6px; min-width:0; overflow-x:auto; overscroll-behavior-x:contain;
  scrollbar-width:none; scroll-snap-type:x proximity; padding:3px 0; margin:-3px 0;
}
.variant-picker.size-chips::-webkit-scrollbar{display:none;}
.size-chip{
  position:relative; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1px;
  flex:1 0 auto; min-width:3.5rem; max-width:8rem; height:2.875rem; padding:0 8px; border:1px solid var(--line); border-radius:var(--r-control, 10px);
  background:var(--surface, var(--paper)); color:var(--ink); cursor:pointer; scroll-snap-align:start;
  font-family:var(--font-body), sans-serif; font-size:0.75rem; font-weight:600; line-height:1.2; text-align:center;
}
.size-chip-name{display:block; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.size-chip-sep{display:none;}
.size-chip-price{display:block; font-size:0.8125rem; font-weight:800; white-space:nowrap; font-variant-numeric:tabular-nums;}
.size-chip[aria-pressed="true"]{
  border-color:var(--primary); box-shadow:inset 0 0 0 1px var(--primary);
  background:color-mix(in srgb, var(--primary) 10%, var(--surface, var(--paper))); color:var(--accent-deep, var(--primary));
}
.size-chip:disabled{cursor:not-allowed; opacity:.5; text-decoration:line-through; text-decoration-thickness:1px;}
/* More chips past the end edge (app/card-type.js markMore, owner list 28.10
   item 2): that edge fades out, so the cut chip reads as "scroll for more".
   Physical sides on purpose: the script names the side from the row's own
   direction, so RTL fades the left edge and an LTR translation the right. */
.variant-picker.size-chips[data-more="left"]{
  -webkit-mask-image:linear-gradient(to right, transparent 0, #000 2.75rem);
  mask-image:linear-gradient(to right, transparent 0, #000 2.75rem);
}
.variant-picker.size-chips[data-more="right"]{
  -webkit-mask-image:linear-gradient(to left, transparent 0, #000 2.75rem);
  mask-image:linear-gradient(to left, transparent 0, #000 2.75rem);
}
.size-chip-oos{position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap;}
/* Inside the chip: the one-row scroller would clip a ring outside it. */
.size-chip:focus-visible{outline:var(--focus-ring-width,2px) solid var(--focus-ring,#0B5FFF); outline-offset:-2px;}

/* ---- 7. «כרטיס לבן» (theme.productAppearance.cardGround, owner list
   26.10, item 21): the card on white with a hairline and a soft lift, so it
   stands off a tinted page ground. On the page (html), or on the card
   itself: a category's look and a product's own (app/category-look.js and
   app/card-overrides.js write data-card-ground on the card; before
   2026-10-29 only an ancestor matched, so neither did anything). A card's
   own «כרטיס רגיל» ("default") stays plain inside a white page. An owner's
   «רקע כרטיס מוצר» still wins. */
[data-card-ground="white"] .product-grid > .card:not([data-card-ground="default"]),
html[data-card-ground="white"][data-layout-catalog] #catalog .product-grid:not(.product-carousel) > .card:nth-child(n):not([data-card-ground="default"]),
.product-grid > .card.card[data-card-ground="white"],
html[data-layout-catalog] #catalog .product-grid:not(.product-carousel) > .card:nth-child(n)[data-card-ground="white"]{
  background:var(--ui-card-bg, #fff); border:1px solid var(--line);
  box-shadow:0 1px 2px rgba(20,24,20,0.06), 0 8px 20px -12px rgba(20,24,20,0.22);
}

/* ---- 8. «הצג עוד N» in «מוצרים נבחרים» (app/section-kinds.js, block.show) ---- */
.editorial-featured-grid > .card[hidden]{display:none;}
.featured-more{display:flex; align-items:center; justify-content:center; min-height:44px; margin:16px auto 0; padding:0 20px;
  border:1px solid var(--line); border-radius:var(--r-chip, 999px); background:var(--surface, var(--paper));
  color:var(--primary); font:inherit; font-weight:700; cursor:pointer;}
.featured-more:focus-visible{outline:var(--focus-ring-width,2px) solid var(--focus-ring,#0B5FFF); outline-offset:2px;}

/* ---- 9. Card finish, opt-in (theme.productAppearance, benchmark 2026-10-27;
   a kit may pick them, builder/kits.js `card`; no key = the card as before) ----
   «גודל שם המוצר» «גדול» (nameSize "large"): the name at 18px (16px on a
   phone), the price under it one step larger still (#623: the price leads).
   «צורת התמונה» «ריבוע» (photoRatio "square"): the photo 1:1 in the grid and
   the strip; a form that draws its own photo (rows, the mosaic's big tile,
   a per-product size, boutique) keeps it.
   «הוספה לסל» «כפתור במילים» (addControl "words"): before the first tap the
   «+» is a full-width button that says so; the stepper follows as with «+». */
html[data-name-size="large"] :is(#catalog, #dealsStrip, .editorial-featured-grid, .fc) .card[data-key]:not(.boutique-card):not([data-pl-name-size]) > .card-name{font-size:1.125rem; line-height:1.3;}
html[data-name-size="large"] :is(#catalog, #dealsStrip, .editorial-featured-grid, .fc) .card.card[data-key]:not([data-pl-name-size]) > .price-tag[data-price-line]{font-size:1.25rem;}
@media (max-width:640px){
  html[data-name-size="large"] :is(#catalog, #dealsStrip, .editorial-featured-grid, .fc) .card[data-key]:not(.boutique-card):not([data-pl-name-size]) > .card-name{font-size:1rem;}
  html[data-name-size="large"] :is(#catalog, #dealsStrip, .editorial-featured-grid, .fc) .card.card[data-key]:not([data-pl-name-size]) > .price-tag[data-price-line]{font-size:1.125rem;}
}
@container shopcard (max-width:109.98px){
  html[data-name-size="large"] :is(#catalog, #dealsStrip, .editorial-featured-grid, .fc) .card[data-key]:not(.boutique-card):not([data-pl-name-size]) > .card-name{font-size:clamp(0.6875rem, 13cqi, 0.875rem);}
}
html[data-photo-ratio="square"] .card[data-key]:not(.boutique-card):not([data-card-span]):not(.rich-product-purchase):not([data-pl-shape]) > .card-img{aspect-ratio:1 / 1;}
:root{--add-words:"הוספה לסל";}
html[lang="en"], html.translated-ltr{--add-words:"Add to cart";}
html[lang="fr"]{--add-words:"Ajouter";}
html[lang="ru"]{--add-words:"В корзину";}
html[lang="ar"]{--add-words:"أضف إلى السلة";}
html[data-add-control="words"] .card[data-key]:not(.in-cart):not(.is-open):not(.rich-product-purchase):not(.boutique-card) > .qty-row{align-self:stretch; justify-content:center; margin-inline:0; max-width:none; padding:0;}
html[data-add-control="words"] .card[data-key]:not(.in-cart):not(.is-open):not(.rich-product-purchase):not(.boutique-card) > .qty-row > .plus{
  flex:1 1 auto; width:auto; min-width:0; font-size:0;
}
html[data-add-control="words"] .card[data-key]:not(.in-cart):not(.is-open):not(.rich-product-purchase):not(.boutique-card) > .qty-row > .plus::after{
  content:var(--add-words); font-family:var(--font-body), sans-serif; font-size:0.875rem; font-weight:700; line-height:1.2; white-space:nowrap;
}

/* The «מחיר רגיל» chip with no free spot on the photo (app/card-corners.js)
   reads as a line under the name instead. */
.card[data-key] > .deal-was[data-cc-out]{
  position:static; align-self:center; flex-direction:row; flex-wrap:wrap; justify-content:center; gap:2px 6px;
  margin:0 0 6px; max-width:100%; background:transparent; border:0; box-shadow:none; padding:0;
}

/* The flag and the kashrut tab with no free spot on the photo
   (app/card-corners.js): small, side by side on one line under the name. */
.card[data-key] > .card-corner-line{display:flex; align-items:center; justify-content:center; flex-wrap:wrap; gap:4px 8px; margin:0 0 6px; min-width:0;}
.card[data-key] > .card-corner-line > *{position:static; inset:auto; transform:none; margin:0; max-width:100%;}
.card-corner-line .card-origin-mark{width:1.25rem;}
.card-corner-line .card-origin-name{display:none;}
