/* Shared ProductCard styles — 04-component-library.md §ProductCard.
   card_style="dark" (Home/Product/Wishlist/Search) vs "light" (Shop/Collections/Compare).
   Loaded globally via base.html, so .product-grid lives here (not in a
   page-specific stylesheet) — every page that renders a grid of
   ProductCards (home, shop, search, product-detail's related section,
   custom-order, collections, wishlist) needs it, not just one page. */
/* auto-fill, not auto-fit: with few items (e.g. a homepage tab with only
   1-2 bestsellers, or a related-products row with 2 items), auto-fit
   collapses the unused tracks and stretches the lone card(s) to fill the
   entire row — auto-fill leaves the extra space empty instead, which is
   what the shop variant below already did; the base rule just hadn't
   matched it, so pages with fewer results (home, product-detail related,
   search, wishlist) showed grotesquely oversized cards. Identical result
   to auto-fit once there are enough items to fill a full row, so this
   doesn't change how any already-working grid looks. */
/* Min track raised 230px -> 280px (2026-08-31, user-reported live: "the
   product... looking so small" on the shop card) -- the card's own image
   box is already sized correctly for its content (aspect-ratio: 3/2,
   see .product-card__media below), so a bigger overall card is what
   actually makes the product read bigger, not a change to that box's
   shape (which would reintroduce the letterboxing that was just fixed)
   or to the photo itself. */
.product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 22px; margin-top: 36px; }
.product-grid--shop { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
/* Switched 2-col -> 1-col on mobile (2026-08-31, user-reported live:
   "the picture is looking soo small" -- a 2-column card was only
   ~162px wide, and every real product photo here is a full multi-panel
   marketing collage (hero + detail shot + a filmstrip of smaller shots)
   that reads as cluttered/tiny squeezed into that width, no padding or
   sizing tweak fixes that; it needs real width). Real, deliberate
   tradeoff: browsing is now more scrolling (one product per row instead
   of two) on every page that uses .product-grid (Home Featured
   Products, Shop, Search, Wishlist, PDP related, Collections, Custom
   Order) -- accepted in exchange for the product actually being legible
   at a glance. Card internals below were tuned for the old ~150px
   width; left as-is for now (still legible, just conservative) rather
   than re-tuning everything for the new ~330px width in the same pass. */
@media (max-width: 639px) {
  .product-grid, .product-grid--shop { grid-template-columns: 1fr; gap: 16px; margin-top: 24px; }
  .product-card__body { padding: 12px 12px 4px; }
  /* Real bug found and fixed: real product names vary in length (this
     session's own earlier color-based renames, e.g. "Clutches — Emerald
     & Orange" vs "Mini Cross Body"), wrapping to 1-3 lines. CSS Grid's
     default row-stretch only equalizes cards WITHIN the same row, so
     cards in different rows kept their own natural height -- confirmed
     live: two cards with an identical 2-line name measured 357.2px and
     336.4px (a full line-height apart) depending only on which row they
     landed in. Clamped to 2 lines with ellipsis and reserved that exact
     height so every card is the same height regardless of row position,
     instead of leaving it to grid-stretch happenstance. */
  .product-card__name {
    font-size: 13.5px; margin-bottom: 4px;
    min-height: 2.6em; line-height: 1.3;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .product-card__descriptor { font-size: 11px; margin-bottom: 6px; }
  .product-card__rating { font-size: 11px; margin-bottom: 6px; }
  .product-card__stock { font-size: 10.5px; margin-bottom: 6px; }
  .product-card__swatches { margin-bottom: 6px; min-height: 13px; }
  .product-card__swatch { width: 13px; height: 13px; }
  .product-card__price .price { font-size: 13.5px; }
  .product-card__price .price-old { font-size: 11px; }
  .product-card__cta { margin: 8px 12px 12px; padding: 10px; font-size: 10.5px; width: calc(100% - 24px); }
}

/* Real bug fix: a handful of items (e.g. "You May Also Like", 2-4
   products) inside a `1fr` grid stretched each card to fill the row --
   with only 2 related products on a wide screen, cards ballooned to
   ~700px each. A horizontal slider keeps cards a fixed, normal size
   regardless of item count, and lets more items be browsed by
   scrolling instead of being crushed into (or stretched across) a
   fixed-width row. */
.product-slider-wrap { position: relative; margin-top: 24px; }
.product-slider {
  display: flex; gap: 18px; overflow-x: auto; scroll-snap-type: x proximity;
  padding-bottom: 10px; scroll-behavior: smooth;
  -ms-overflow-style: none; scrollbar-width: thin;
}
.product-slider .product-card { flex: 0 0 210px; scroll-snap-align: start; }
.product-slider-nav {
  position: absolute; top: 40%; transform: translateY(-50%);
  width: 34px; height: 34px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--color-charcoal-primary); color: var(--color-beige-light);
  display: flex; align-items: center; justify-content: center; box-shadow: var(--shadow-dropdown);
  z-index: 2;
}
.product-slider-nav--prev { left: -14px; }
.product-slider-nav--next { right: -14px; }
@media (max-width: 640px) { .product-slider-nav { display: none; } }

.product-card {
  position: relative;
  border-radius: var(--radius-card);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  /* Grid items default to min-width: auto too -- same fix as the nested
     flex chain below, at the level where the card is itself a
     .product-grid item. */
  min-width: 0;
}
.product-card--light { background: var(--color-white); box-shadow: var(--shadow-card-resting-light); }
.product-card--light:hover { box-shadow: var(--shadow-card-hover-light); transform: translateY(-6px); }
.product-card--dark { background: var(--color-charcoal-secondary); border: 1px solid rgba(255,255,255,.06); }
.product-card--dark:hover { box-shadow: var(--shadow-card-hover-dark); transform: translateY(-6px); }
.product-card { transition: transform .3s ease, box-shadow .3s ease; }
/* Touch feedback for devices with no real :hover (mobile motion overhaul,
   2026-08-21) -- scoped to `(hover: none)` specifically so it doesn't
   fight with the desktop hover-lift transform above on a mouse click. */
@media (hover: none) {
  .product-card:active { transform: scale(.985); transition: transform var(--motion-fast) var(--ease-premium); }
}

/* object-fit: contain, not cover -- these are studio/cutout product
   shots (a wallet, bag, belt photographed whole against a backdrop), not
   lifestyle photography where cropping into the frame is fine. `cover`
   would zoom into the product until part of it goes off-frame -- exactly
   what a shopper needs to NOT happen when deciding whether to buy a
   physical object. Real neutral backdrop (matches the site's own cream
   token) instead of a flat grey placeholder color, with padding so the
   product doesn't touch the card edges. */
/* aspect-ratio 3/2, not 1/1 (2026-08-31, user-reported live: "so much
   white space", then confirmed "all the pictures will be same size" --
   every real product photo here is a fixed 1536x1024, a real 3:2 frame).
   A square box could never match that without letterboxing under
   object-fit: contain, no matter how small the img's own padding got --
   see .pdp-gallery__main's identical fix/reasoning in product-detail.css.
   Matching the box's aspect to the real photo aspect removes the
   structural white bars; only the small deliberate padding remains.
   Changes the card's own shape sitewide (shop/home/search/wishlist/
   related/collections) from square to a wider rectangle -- a real,
   visible layout change, not just an internal padding tweak. */
.product-card__media { position: relative; aspect-ratio: 3/2; overflow: hidden; background: var(--color-beige-light); }
/* Real bug found and fixed (2026-08-31, user-reported live: pictures
   looking small with a lot of white area, worse on mobile): this
   padding used to be a flat 14px regardless of card size. On the
   2-column mobile grid (~150-170px cards) that same 14px eats a far
   bigger share of the square than it does on a ~280px desktop card, so
   the product read as noticeably smaller on mobile even before
   accounting for apps/catalog/services/media.py's own new whitespace-
   trim fix on the source photo itself. Scaled to the card's own size
   instead of a fixed px value, with a sane floor/ceiling. */
.product-card__media img { width: 100%; height: 100%; object-fit: contain; padding: clamp(6px, 4%, 14px); box-sizing: border-box; transition: transform .4s ease; }
.product-card:hover .product-card__media img { transform: scale(1.05); }
/* Real bug fix: this was a flat diagonal-hatch pattern -- reads as a
   broken/missing image, not a premium placeholder. 41 of 42 real
   published products have no photo uploaded yet (a real content gap,
   not a design choice -- see FRONTEND_CHANGELOG.md), so this fallback is
   what most of the catalog actually shows; it needed to look intentional.
   Matches the same dark-gradient + faint gold "AK" monogram treatment
   already used for .category-tile/.craft-split__media's own no-image
   fallback, so an unphotographed product reads as "on-brand, photo
   coming soon" rather than "something is broken". */
.product-card__media-placeholder {
  width: 100%; height: 100%; position: relative;
  background: linear-gradient(160deg, var(--color-charcoal-surface) 0%, var(--color-charcoal-secondary) 100%);
  display: flex; align-items: center; justify-content: center;
}
.product-card__media-placeholder::before {
  content: "AK";
  font-family: var(--font-serif);
  font-size: 48px;
  color: var(--color-gold-accent);
  opacity: .16;
}
.product-card--oos .product-card__media img { opacity: .5; }
.product-card__badge { position: absolute; top: 12px; left: 12px; }

.product-card__wishlist {
  position: absolute; top: 10px; right: 10px;
  width: 32px; height: 32px; border-radius: 50%;
  border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.85); color: var(--color-charcoal-primary);
  z-index: 2;
}
.product-card--dark .product-card__wishlist { background: rgba(15,15,15,.6); color: var(--color-beige-light); }
.product-card__wishlist.is-active { color: var(--color-gold-accent); }
/* Real bug found and fixed (2026-08-22 final QA pass): this override
   used to live inside the earlier combined mobile block above (line
   ~25), BEFORE this base rule in source order -- with equal selector
   specificity, the later, unconditioned base rule always won the
   cascade regardless of viewport, so the mobile size never actually
   applied at any width; confirmed live (31x31px measured, matching the
   32px base size, not the documented mobile value). Moved to directly
   after its own base rule, matching the correct pattern already used
   for .product-card__quick-view in quick-view.css. Bumped to the
   spec's real 44px touch-target minimum while fixing the ordering --
   absolutely-positioned overlay, costs no card layout space. */
@media (max-width: 639px) {
  .product-card__wishlist { width: 44px; height: 44px; top: 6px; right: 6px; }
}

/* Real bug found and fixed (2026-08-22, reported live): CTA buttons
   across cards in the same row weren't level -- confirmed root cause:
   .product-card is a real flex column and .product-card__body genuinely
   has flex:1, but .product-card__body is nested a level deeper inside
   <a class="product-card__body-link">, which is the ACTUAL direct flex
   child of .product-card and had no sizing rule of its own at all. A
   flex:1 on a non-flex-item does nothing, so the link only ever took
   its natural content height -- varying with each product's real name/
   description length -- and the CTA button (a sibling right after it)
   landed wherever that content happened to end, not at a consistent
   card-bottom position. Grid still stretches every card in a row to the
   same total height regardless, so the CTA visibly floated at a
   different height per card even though the cards themselves matched. */
/* Real bug found and fixed (2026-08-31, user-reported live: the
   descriptor line running off the edge of the card): both of these are
   flex containers, and a flex item's default min-width is `auto`, not
   0 -- meaning the browser sizes it to fit its content's intrinsic
   width. .product-card__descriptor below has white-space: nowrap
   specifically so text-overflow: ellipsis can clip it to one line, but
   that same nowrap text IS the "intrinsic width" the flex algorithm
   measures, so without min-width: 0 breaking that default, the item
   (and the whole nested flex chain up through the card) was sized to
   fit the full unwrapped sentence instead of the card's real width --
   the ellipsis rule never got a chance to apply because nothing was
   actually constraining the box it lives in. */
.product-card__body-link { flex: 1; display: flex; min-width: 0; }
.product-card__body { padding: 16px 16px 18px; flex: 1; display: flex; flex-direction: column; min-width: 0; }
.product-card__name { font-family: var(--font-serif); font-size: 15.5px; margin-bottom: 6px; }
.product-card--light .product-card__name { color: var(--color-text-dark); }
/* Real gap fix: Product.short_description is real and populated for
   every product but had no card slot -- single-line clamp (not
   unbounded) so a longer real description can't reintroduce the same
   row-stretch card-height inconsistency already fixed for the name. */
.product-card__descriptor {
  font-size: 12px; line-height: 1.4; margin-bottom: 8px; min-height: 1.4em;
  color: var(--color-text-grey-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.product-card--light .product-card__descriptor { color: var(--color-text-dark-dim-2); }
.product-card__rating { display: flex; align-items: center; gap: 4px; margin-bottom: 8px; font-size: 12px; color: var(--color-text-grey-dim); }
.product-card--light .product-card__rating { color: var(--color-text-dark-dim-2); }
.product-card__stock { font-size: 11.5px; margin-bottom: 8px; }
/* Real color data (every variant has one) -- small swatch row, only
   rendered when a product genuinely has more than one real color. */
/* min-height reserves the row even when empty (single-color products) --
   see the template comment: this is what actually keeps card heights
   consistent, not the conditional content inside it. */
.product-card__swatches { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; min-height: 15px; }
.product-card__swatch {
  width: 15px; height: 15px; border-radius: 50%; flex-shrink: 0;
  border: 1px solid rgba(255,255,255,.25);
}
.product-card--light .product-card__swatch { border-color: rgba(0,0,0,.15); }
.product-card__swatch-more { font-size: 10.5px; color: var(--color-text-grey-dim); }
.product-card--light .product-card__swatch-more { color: var(--color-text-dark-dim-2); }
.product-card__price { display: flex; align-items: baseline; gap: 8px; }
.product-card__price .price { font-size: 15px; font-weight: 700; color: var(--color-gold-accent); }
.product-card--light .product-card__price .price { color: var(--color-brown-leather); }
.product-card__price .price-old { font-size: 12.5px; color: #6a6a6a; text-decoration: line-through; }

.product-card__cta {
  margin: 0 16px 16px;
  background: transparent;
  border: 1px solid rgba(245,242,236,.3);
  color: var(--color-beige-light);
  padding: 11px; font-size: 11.5px; font-weight: 700; letter-spacing: .06em;
  border-radius: var(--radius-button);
  cursor: pointer; width: calc(100% - 32px);
  /* Real bug found and fixed: .btn (base.css) sets white-space: nowrap
     sitewide, which is right for short button labels but confirmed live
     to push "NOTIFY WHEN AVAILABLE" (this component's longest real CTA
     string, vs. "ADD TO CART"/"SOLD OUT") past the button's own right
     edge and out of the card entirely at the 2-column mobile width.
     Scoped to just this button, not the global .btn, so every other
     short CTA sitewide stays single-line as intended. Grid rows already
     auto-stretch to the tallest card (see .product-card__name's own
     2-line-clamp fix a few lines up for the same reasoning), so a
     2-line CTA on one card just evens out with its row-mates instead
     of breaking anything. */
  white-space: normal; line-height: 1.3; text-align: center;
}
.product-card--dark .product-card__cta:hover { background: var(--color-gold-accent); border-color: var(--color-gold-accent); color: var(--color-charcoal-primary); }
.product-card--light .product-card__cta { background: var(--color-charcoal-primary); border-color: var(--color-charcoal-primary); }
.product-card--light .product-card__cta:hover { background: var(--color-gold-accent); border-color: var(--color-gold-accent); color: var(--color-charcoal-primary); }

.empty-state { grid-column: 1/-1; text-align: center; padding: 60px 0; color: var(--color-text-grey-dim); font-size: 14px; }
