/* ============================================================
   THE PRODUCT CARD — "Volt"
   ------------------------------------------------------------
   One component, used on the homepage, category pages, search,
   the brand pages and the accessories block.

   This file REPLACES seventeen patch sections of custom.css
   (v5, v16-v21, v23-v26, v29, v37, v38, v43, v61). Those were
   appended over time and fought each other: the "Novo" badge
   alone was restyled five times — grey outline, then orange
   border, then yellow, then orange again — with only the last
   surviving. Layering Volt on top of that stack would not have
   held, so the stack is gone.

   Loaded AFTER custom.css. Every colour resolves through the
   --ss-* tokens; no literal hex belongs in this file.

   The governing rule, as everywhere in Volt: --ss-primary is a
   FILL. On the card it appears only behind dark ink, on the
   buy button and on the "Novo" flag.
   ============================================================ */

/* ---------- frame ---------------------------------------- */
.product-miniature{
  display:flex;
  background:var(--ss-surface);
  border:1px solid var(--ss-line);
  border-radius:var(--ss-radius);
  overflow:hidden;
  transition:border-color .16s ease, transform .16s ease, box-shadow .16s ease;
}
.product-miniature::after{display:none}          /* parent theme's underline bar */
.product-miniature__inner{
  display:flex;
  flex-direction:column;
  width:100%;
  min-width:0;
}
.product-miniature:hover{
  border-color:var(--ss-fg);
  transform:translateY(-2px);
  box-shadow:0 10px 26px -14px rgba(var(--ss-chrome-rgb),.45);
}
@media (prefers-reduced-motion:reduce){
  .product-miniature,.product-miniature:hover{transition:none;transform:none}
}

/* ---------- media ---------------------------------------- */
/* Cut-outs shot on white, on a white page: no panel, no tint, no
   border. This is the whole reason Volt inverted the ground. */
.product-miniature__top{
  position:relative;
  margin-bottom:0;
  background:var(--ss-media);
}
/* 5:4, not square. A square media box made the card 280px tall before a single
   line of text, and the height bought nothing: the product shots carry their own
   white space, measured across a 23-image sample at anywhere from 0% to 44% of
   the frame vertically. Cropping that away with object-fit:cover is not an
   option for the same reason — at 0% margin the subject touches the frame edge
   and cover would clip it. contain keeps every subject whole and simply renders
   it smaller.

   No padding at all. The shots carry their own margin — 12px each side on the
   261px thumbnail measured, and far more vertically — so CSS padding was
   inset inside inset. With a 5:4 box a square source is height-constrained
   anyway, which means the horizontal padding never touched the rendered photo:
   removing it changes the layout box, not the picture. */
.product-miniature__image,
.product-miniature__top img{
  aspect-ratio:5/4;
  width:100%;
  object-fit:contain;
  padding:0;
  transition:transform .35s ease;
}
.product-miniature__inner:hover .product-miniature__image{transform:scale(1.04)}
@media (prefers-reduced-motion:reduce){
  .product-miniature__image{transition:none}
  .product-miniature__inner:hover .product-miniature__image{transform:none}
}

/* ---------- flags ---------------------------------------- */
/* Skewed slabs, per the direction's signature. "Novo" is an
   invitation so it takes the accent; the discount is a number so
   it takes the sale colour; "Rasprodano" is a state and must not
   borrow either, or an unavailable bike shouts loudest. */
.product-flags{
  position:absolute; top:10px; left:10px; z-index:2;
  display:flex; flex-direction:column; align-items:flex-start; gap:6px;
  margin:0; padding:0; list-style:none;
}
.product-flags .badge,
.product-flags .product-flag{
  display:inline-block;
  font-size:.63rem;
  font-weight:700;
  font-stretch:86%;
  text-transform:uppercase;
  letter-spacing:.08em;
  line-height:1;
  padding:6px 10px;
  border:0;
  border-radius:0;
  clip-path:none;
  font-style:normal;
  transform:skewX(var(--ss-skew));
  background:var(--ss-fg);
  color:var(--ss-ground);
}
/* The plate is skewed; the letters inside must not be. */
.product-flags .badge > span,
.product-flags .product-flag > span{display:inline-block;transform:skewX(9deg)}

/* ---- flag colour: fed, not fought -----------------------
   The compiled parent theme paints every non-discount flag itself:

     .product-flags .badge:not(.discount){
       background-color:RGBA(var(--bs-primary-rgb),…) !important;
       color:#fff !important;
     }

   That rule sits inside a cascade LAYER, and for !important declarations
   layer order is inverted — a layered !important outranks an unlayered
   one no matter how specific the unlayered selector is. Nothing we write
   in this file can beat it, and raising specificity is wasted effort.

   So we supply its input instead: scope --bs-primary-rgb on the flag and
   the parent's own rule paints the colour we want. Its companion
   `color:#fff` is why non-discount flags are dark rather than lime —
   white on lime is 1.27:1, white on ink is 18:1.

   .discount is exempt from the parent's rule, so it is styled directly. */
.product-miniature .product-flags .badge,
.product-miniature .product-flags .product-flag{
  --bs-primary-rgb:20,23,15;              /* --ss-fg */
}
.product-flags .badge.discount,
.product-flags .product-flag.discount{
  background-color:var(--ss-sale) !important;
  color:var(--ss-ground) !important;
}
/* "Na rasprodaji" duplicates the discount percentage next to it. */
.product-flags .badge.on-sale,
.product-flags .product-flag.on-sale{display:none}

/* ---------- body ----------------------------------------- */
.product-miniature__bottom{
  display:flex;
  flex:1;
  /* Top padding is 2px, not 12px: the media box above already ends in the
     photo's own white margin, so a gap here read as a second one. */
  padding:2px 13px 14px;
}
.product-miniature__infos{
  display:flex;
  flex-direction:column;
  gap:5px;
  flex:1;
  min-width:0;
}

.product-miniature__brand{
  display:block;
  font-size:.66rem;
  font-weight:700;
  font-stretch:88%;
  letter-spacing:.1em;
  text-transform:uppercase;
  color:var(--ss-fg-muted);
  text-decoration:none;
  margin:0;
}
.product-miniature__brand:hover{color:var(--ss-fg)}

.product-miniature__title,
.product-miniature__title a{
  font-size:.9rem;
  font-weight:600;
  line-height:1.3;
  color:var(--ss-fg);
  text-decoration:none;
}
.product-miniature__title{
  display:-webkit-box;
  -webkit-line-clamp:2;
  -webkit-box-orient:vertical;
  overflow:hidden;
  /* Still clamped at two lines, but no longer reserving both. A one-line title
     now takes one line and the card is shorter for it — at the cost of the
     price and button no longer sitting at the same height across a row. */
  min-height:1em;
}
.product-miniature__title:hover{
  color:var(--ss-fg);
  box-shadow:inset 0 -2px 0 0 var(--ss-primary);
}

/* ---------- availability --------------------------------- */
.product-miniature__stock{
  display:inline-flex;
  align-items:center;
  gap:5px;
  font-size:.72rem;
  font-weight:600;
  color:var(--ss-ok);
  margin-top:auto;
  padding-top:4px;
}
.product-miniature__stock .material-icons{font-size:14px;line-height:1}
.product-miniature__stock--order{color:var(--ss-fg-muted)}

/* ---------- price + buy ---------------------------------- */
.product-miniature__pricerow{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:10px;
  flex-wrap:wrap;
  margin-top:8px;
}
.product-miniature__prices{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:1px;
  margin:0;
  flex:1 1 auto;
  min-width:0;
  font-variant-numeric:tabular-nums;
}
.product-miniature__price{
  font-style:italic;
  font-weight:800;
  font-stretch:80%;
  font-size:1.18rem;
  line-height:1.1;
  letter-spacing:-.01em;
  color:var(--ss-fg);
}
/* Red only when there is something to compare against. A permanently
   red price stops meaning "reduced". */
.product-miniature__prices:has(.product-miniature__regular-price) .product-miniature__price{
  color:var(--ss-sale);
}
.product-miniature__discount-price{margin:0}
.product-miniature__regular-price{
  font-size:.72rem;
  color:var(--ss-fg-muted);
  text-decoration:line-through;
}

.product-miniature__actions{flex:0 0 auto;margin:0}
/* The stepper belongs on the product page, not on a grid tile. */
.product-miniature .quantity-button,
.product-miniature .js-quantity-button{display:none}

.product-miniature__add,
.product-miniature__add.btn-primary{
  display:inline-flex;
  align-items:center;
  gap:6px;
  font-size:.68rem;
  line-height:1;
  padding:11px 14px;
  border:0;
  border-radius:var(--ss-radius);
  background:var(--ss-primary);
  color:var(--ss-primary-ink);
  transform:skewX(var(--ss-skew));
  --bs-btn-bg:var(--ss-primary);
  --bs-btn-color:var(--ss-primary-ink);
  --bs-btn-border-color:var(--ss-primary);
  --bs-btn-hover-bg:var(--ss-primary-dk);
  --bs-btn-hover-color:var(--ss-primary-ink);
  --bs-btn-hover-border-color:var(--ss-primary-dk);
  --bs-btn-active-bg:var(--ss-primary-dk);
  --bs-btn-active-color:var(--ss-primary-ink);
  --bs-btn-active-border-color:var(--ss-primary-dk);
}
.product-miniature__add > *{display:inline-block;transform:skewX(9deg)}
.product-miniature__add:hover,
.product-miniature__add:active{
  background:var(--ss-primary-dk);
  color:var(--ss-primary-ink);
}
.product-miniature__add .material-icons{font-size:16px;line-height:1}
.product-miniature__add-text{white-space:nowrap}

/* Only the order-only action is secondary. "Izaberi opciju" keeps the
   accent fill: it is the primary thing to do on a card whose product
   happens to have sizes, which here is nearly all of them. */
/* Two classes deep so it outranks `.product-miniature__add.btn-primary`
   above, which is where the accent fill comes from. */
.product-miniature__add.product-miniature__add--secondary{
  background:transparent;
  color:var(--ss-fg);
  box-shadow:inset 0 0 0 1.5px var(--ss-fg);
  --bs-btn-bg:transparent;
  --bs-btn-color:var(--ss-fg);
}
.product-miniature__add.product-miniature__add--secondary:hover{
  background:var(--ss-fg);
  color:var(--ss-ground);
}
/* Both link variants are wider than "U korpu" and would wrap the row,
   so they drop to their own line under the price. */
.product-miniature__pricerow:has(.product-miniature__details){
  flex-direction:column;
  align-items:stretch;
}
.product-miniature__pricerow:has(.product-miniature__details) .product-miniature__details{
  justify-content:center;
}

/* Narrow tiles: keep the price, drop the button label to its icon. */
@media (max-width:520px){
  .product-miniature__add .product-miniature__add-text{display:none}
  .product-miniature__details .product-miniature__add-text{display:inline}
}

/* ---------- brand row (spartanbrandrow) ------------------ */
/* A scroll-snap track rather than a JS carousel: it works with a swipe, a
   trackpad and the keyboard before any script runs, and the arrows are an
   enhancement layered on top. */
.ss-brandrow{margin:0 0 var(--ss-gap-sect, 44px)}
.ss-brandrow__frame{position:relative}
.ss-brandrow__track{
  display:flex;
  gap:14px;
  overflow-x:auto;
  scroll-snap-type:x proximity;
  scroll-behavior:smooth;
  /* Room for the card's hover lift, which would otherwise be clipped by the
     scroll container. */
  padding:4px 2px 10px;
  scrollbar-width:none;
}
.ss-brandrow__track::-webkit-scrollbar{display:none}
.ss-brandrow__track:focus-visible{outline:2px solid var(--ss-primary);outline-offset:3px}
.ss-brandrow__cell{
  flex:0 0 auto;
  /* Five across: the track shows n cards and (n-1) gaps, so the subtrahend is
     4 x the 14px gap. Change both numbers together or the last card clips. */
  width:calc((100% - 56px) / 5);
  min-width:0;
  scroll-snap-align:start;
}
@media (max-width:1199px){ .ss-brandrow__cell{width:calc((100% - 42px) / 4)} }
@media (max-width:991px){ .ss-brandrow__cell{width:calc((100% - 14px) / 2)} }
/* One and a half on a phone: a full card plus half of the next, so the row
   visibly continues past the edge. That half card is the only scroll
   affordance a phone gets — the arrows are hidden on touch.

   The divisor is the number of cards in view. For n cards there are (n-1)
   whole gaps before the partial one, which at n=1.5 is a single gap, hence
   (100% - gap) / 1.5. Cards come out ~213px on a 360px screen, wider than the
   ~160px they had at two-up. */
@media (max-width:575px){
  .ss-brandrow__track{gap:10px}
  .ss-brandrow__cell{width:calc((100% - 10px) / 1.5)}
}

.ss-brandrow__arw{
  position:absolute; top:calc(50% - 22px); z-index:3;
  display:flex; align-items:center; justify-content:center;
  width:44px; height:44px; padding:0;
  border:1px solid var(--ss-line);
  border-radius:50%;
  background:var(--ss-surface);
  color:var(--ss-fg);
  box-shadow:0 6px 18px -8px rgba(var(--ss-chrome-rgb),.5);
  cursor:pointer;
  transition:background .14s ease, color .14s ease, transform .14s ease;
}
.ss-brandrow__arw svg{width:20px;height:20px}
.ss-brandrow__arw--prev{left:-10px}
.ss-brandrow__arw--next{right:-10px}
.ss-brandrow__arw:hover{background:var(--ss-primary);color:var(--ss-primary-ink);transform:scale(1.06)}
.ss-brandrow__arw:focus-visible{outline:2px solid var(--ss-fg);outline-offset:2px}
.ss-brandrow__arw[hidden]{display:none}
@media (prefers-reduced-motion:reduce){
  .ss-brandrow__track{scroll-behavior:auto}
  .ss-brandrow__arw:hover{transform:none}
}
/* Touch devices get the native swipe; a hover-driven arrow is meaningless
   there and only steals space from the cards. */
@media (hover:none){ .ss-brandrow__arw{display:none} }
