/* ============================================================
   The Bridge Course Merch Shop — page-specific styles (copied from emmanuel.css)
   Loaded AFTER the shared /style.css (root color/font tokens,
   .wrap, .site-header, body reset live there — .btn-primary and .bubble
   are defined below in THIS file, not in the shared one, matching where
   Valley Creek actually keeps them too).

   PLACEHOLDER BRANDING: currently reusing Jac'D Up's existing color
   tokens (--navy, --sand, --rose-gold, etc. from /style.css) as a
   starting point. Swap in Emmanuel's actual logo/brand colors once
   provided — same pattern Valley Creek followed.
   ============================================================ */

/* Now lives in the dark navy header (matching Valley Creek's placement),
   so this is light-on-navy rather than the old navy-on-eggshell pill
   that suited its previous spot on the page background. */
.countdown-timer {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  color: var(--sand);
  margin-top: 4px;
  display: block;
}

/* ---- Primary button (Add to Cart) — this genuinely lives only in
   valleycreek.css, NOT the shared /style.css as an earlier comment here
   incorrectly claimed. Copied verbatim so Emmanuel's button isn't
   silently unstyled the way the quantity stepper was. ---- */
.btn-primary {
  display: inline-block;
  box-sizing: border-box;
  background: var(--navy);
  color: var(--eggshell);
  border: none;
  padding: 12px 28px;
  border-radius: 8px;
  font-size: 16px;
  font-weight: 500;
  text-decoration: none;
  line-height: normal;
  cursor: pointer;
  margin-top: 16px;
  transition: background-color 0.15s ease, transform 0.1s ease, box-shadow 0.15s ease;
}

.btn-primary:hover:not(:disabled) {
  background: var(--deep-rose);
  box-shadow: 0 2px 8px rgba(31, 46, 70, 0.25);
}

.btn-primary:active:not(:disabled) {
  transform: scale(0.96);
  background: var(--deep-rose);
}

.btn-primary:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Widen the page beyond the shared 1100px default (defined in the
   shared /style.css, loaded before this file) — that cap was leaving a
   lot of unused space on wide screens, and squeezing products-main well
   below its own 900px basis once the cart sidebar's width was
   subtracted. This override only ever takes effect on this page, since
   emmanuel.css is never loaded by Valley Creek or the main store. */
.wrap {
  max-width: 1440px;
}

/* Matches Valley Creek's welcome-banner exactly — same blush background,
   same navy text — keeping the shared Jac'D Up color scheme rather than
   introducing an Emmanuel-specific accent color here. */
.welcome-banner {
  background: var(--blush);
  padding: 20px 24px;
  text-align: center;
}

.welcome-banner p {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  color: var(--navy);
  margin: 0;
}

.products-intro {
  font-size: 16px;
  color: var(--ink);
  margin-bottom: 28px;
  max-width: 640px;
}

.products-layout {
  display: flex;
  align-items: flex-start;
  gap: 32px;
}

.products-main {
  flex: 0 1 1000px;
  min-width: 0;
}

.cart-column {
  position: sticky;
  top: 24px;
  margin-top: -95px;
  flex: 0 0 360px;
  max-height: calc(100vh - 44px);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

@media (max-width: 1280px) {
  .cart-column {
    flex: 0 0 300px;
  }
}

.cart-sidebar {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  background: #fff;
  border: 1px solid var(--sand);
  border-radius: 10px;
  padding: 24px;
  box-shadow: 0 4px 16px rgba(31, 46, 70, 0.12);
}

.cart-sidebar h3 {
  font-family: var(--font-display);
  color: var(--navy);
  font-size: 20px;
}

.cart-empty-msg {
  color: var(--ink);
  opacity: 0.7;
  font-size: 14px;
}

/* ---- Cart line items, discount progress, totals, checkout button ----
   Ported directly from Valley Creek's cart sidebar (valleycreek.css). ---- */
.cart-sidebar-lines {
  margin-bottom: 12px;
}

.cart-sidebar-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 0;
  font-size: 14px;
  border-bottom: 1px solid var(--sand);
}

.cart-sidebar-item {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}

.cart-sidebar-price {
  color: var(--deep-rose);
  font-weight: 500;
  white-space: nowrap;
}

.cart-sidebar-line .remove-line-btn {
  background: none;
  border: none;
  color: var(--ink);
  opacity: 0.5;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
  transition: opacity 0.15s ease, color 0.15s ease;
}

.cart-sidebar-line .remove-line-btn:hover {
  opacity: 1;
  color: var(--deep-rose);
}

.cart-progress {
  font-size: 13px;
  color: var(--deep-rose);
  background: var(--blush);
  border-radius: 6px;
  padding: 8px 10px;
  margin: 10px 0;
}

.cart-progress-done {
  color: #3f6b47;
  background: #dcead9;
}

.cart-sidebar-totals {
  border-top: 1.5px solid var(--navy);
  padding-top: 10px;
}

.cart-sidebar-row {
  display: flex;
  justify-content: space-between;
  font-size: 15px;
  padding: 4px 0;
}

.cart-sidebar-discount {
  color: #3f6b47;
}

.cart-sidebar-total {
  font-weight: 600;
  font-size: 18px;
  color: var(--navy);
}

.cart-checkout-btn {
  width: 100%;
  margin-top: 16px;
}

/* ---- Delivery notice (sand box above the already-used notice) ---- */
.delivery-notice {
  background: var(--sand);
  color: var(--ink);
  font-size: 14px;
  font-weight: 500;
  text-align: center;
  padding: 12px 16px;
  border-radius: 10px;
}

/* ---- Already-used discount notice ---- */
.already-used-notice {
  background: var(--blush);
  border-radius: 10px;
  padding: 16px;
  text-align: center;
}

.already-used-notice p {
  font-size: 14px;
  color: var(--ink);
  margin-bottom: 12px;
}

.already-used-notice .btn-footer {
  background: var(--navy);
  color: var(--eggshell);
}

.already-used-notice .btn-footer:hover {
  background: var(--deep-rose);
}

.footer-cta-text {
  font-size: 15px;
  margin-bottom: 14px;
  opacity: 0.9;
}

.btn-footer {
  display: inline-block;
  background: var(--eggshell);
  color: var(--navy);
  border: none;
  padding: 10px 24px;
  border-radius: 8px;
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  margin-bottom: 20px;
  transition: background-color 0.15s ease, transform 0.1s ease;
}

.btn-footer:hover {
  background: var(--blush);
}

.btn-footer:active {
  transform: scale(0.96);
}

/* ---- Discount banner (shown above the product grid once verified) ---- */
.discount-banner {
  background: #dcead9;
  color: #3f6b47;
  padding: 12px 16px;
  border-radius: 8px;
  margin-bottom: 24px;
  font-weight: 500;
}

/* ---- Verification steps: name entry, household confirmation, ----
   ---- not-found / lookup-error fallbacks. Ported from Valley ----
   ---- Creek's .vc-main / .vc-step pattern, renamed to em- so ----
   ---- nothing here can collide with valleycreek.css's classes. ---- */
.br-main {
  padding: 48px 0 100px;
  max-width: 640px;
  transition: max-width 0.2s ease;
}

.br-main-wide {
  max-width: 1440px;
  margin-left: 24px;
  margin-right: 24px;
}

@media (max-width: 640px) {
  .br-main {
    padding-left: 12px;
    padding-right: 12px;
  }
}

.br-step h1 {
  font-family: var(--font-display);
  color: var(--navy);
  font-size: 28px;
  margin-bottom: 8px;
}

.br-step p {
  margin-bottom: 24px;
}

#name-form label,
#household-form label {
  display: block;
  margin-bottom: 16px;
  font-weight: 500;
}

#name-form input[type="text"] {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 10px 12px;
  border: 1px solid var(--sand);
  border-radius: 6px;
  font-size: 16px;
  font-family: var(--font-body);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

#name-form input[type="text"]:focus {
  outline: none;
  border-color: var(--rose-gold);
  box-shadow: 0 0 0 3px rgba(201, 112, 127, 0.2);
}

.household-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 6px;
  border-bottom: 1px solid var(--sand);
  border-radius: 6px;
  transition: background-color 0.15s ease;
  cursor: pointer;
}

.household-option:hover {
  background-color: var(--blush);
}

.household-option input {
  width: 18px;
  height: 18px;
}

.btn-select-all {
  background: var(--navy);
  border: 1.5px solid var(--navy);
  color: var(--eggshell);
  border-radius: 20px;
  padding: 6px 16px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  margin-bottom: 14px;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.btn-select-all:hover {
  border-color: var(--rose-gold);
  background: var(--deep-rose);
}

.btn-select-all:active {
  transform: scale(0.96);
}

.not-found-tagline {
  font-size: 14px;
  color: var(--ink);
  opacity: 0.75;
  margin-bottom: 24px;
}

.not-found-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

.not-found-email-row {
  margin-bottom: 20px;
}

.not-found-email-row label {
  display: block;
  font-size: 14px;
  color: var(--navy);
  font-weight: 600;
  margin-bottom: 6px;
}

.not-found-email-row input[type="email"] {
  width: 100%;
  max-width: 360px;
  padding: 10px 12px;
  border: 1.5px solid rgba(0, 0, 0, 0.15);
  border-radius: 8px;
  font-size: 15px;
  transition: border-color 0.2s ease;
}

.not-found-email-row input[type="email"]:focus {
  outline: none;
  border-color: var(--navy);
}

.field-error {
  color: #b3261e;
  font-size: 13px;
  margin-top: 6px;
}

/* ---- Header: dual logo + welcome text/countdown, ported directly ----
   ---- from Valley Creek's header (valleycreek.css) — same layout, ----
   ---- same sizing, just Emmanuel's logo in the left slot instead. ---- */
.header-logos {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.logo-slot {
  display: flex;
  align-items: center;
  height: 82px;
}

/* Emmanuel's logo is a wide horizontal lockup (icon + wordmark side by
   side, ~3:1 aspect ratio) rather than the roughly-square mark this
   height was originally sized for — at the same height as the base
   slot it rendered nearly 4x wider than the Jac'D Up logo on the right,
   unbalancing the header. Sized down so the two sides read as a closer
   match in visual weight. */
.logo-left {
  height: 58px;
}

.logo-slot img {
  height: 100%;
  width: auto;
}

.header-welcome {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 0 16px;
}

.header-welcome-title {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  color: #FFFFFF;
}

/* Product grid — Valley Creek's stylesheet has no equivalent rule for
   this (cards stack full-width there); this is a fresh, deliberate
   responsive grid for Emmanuel rather than a copy of a gap. */
.product-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  align-items: stretch;
}

.product-divider {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 8px 0 4px;
  font-family: var(--font-display);
  color: var(--navy);
  font-size: 20px;
}

.product-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--sand);
}

.product-card {
  cursor: default;
  transition: box-shadow 0.2s ease, transform 0.15s ease;
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--sand);
  border-radius: 8px;
  overflow: hidden;
}

.product-card:hover {
  box-shadow: 0 4px 16px rgba(31, 46, 70, 0.15);
}

.product-card .card-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 16px;
}

.product-card .image-wrap {
  position: relative;
  border-radius: 8px 8px 0 0;
  background: var(--eggshell);
}

.product-card .image-wrap img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

/* ---- Front/back thumbnail strip ---- */
/* Ported directly from Valley Creek's styling. One strip per color group
   here (vs. one per product on Valley Creek) — same visual treatment.
   Magnifier-on-hover (Valley Creek's .img-magnifier-glass) intentionally
   NOT ported yet — flag if you want that too. */
.view-thumb-strip {
  display: flex;
  flex-direction: row;
  justify-content: center;
  gap: 6px;
  padding: 8px 8px 2px;
  overflow-x: auto;
  scrollbar-width: none;
}

.view-thumb-strip::-webkit-scrollbar {
  display: none;
}

.view-thumb-strip[hidden] {
  display: none;
}

.view-thumb-btn {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 2px solid #fff;
  border-radius: 6px;
  overflow: hidden;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}

.view-thumb-btn:hover {
  transform: scale(1.1);
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.35);
}

.view-thumb-btn.is-active {
  border-color: var(--navy);
  box-shadow: 0 0 0 2px rgba(31, 46, 70, 0.25), 0 2px 6px rgba(0, 0, 0, 0.25);
}

.view-thumb-btn:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}

.view-thumb-btn img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  cursor: pointer;
}

/* ---- Quantity stepper (matches Valley Creek's pill exactly) ---- */
.qty-stepper {
  display: flex;
  align-items: center;
  border: 1.5px solid var(--sand);
  border-radius: 20px;
  overflow: hidden;
}

.qty-btn {
  background: var(--eggshell);
  border: none;
  color: var(--navy);
  font-size: 18px;
  font-weight: 600;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease, transform 0.1s ease;
}

.qty-btn:hover {
  background: var(--blush);
}

.qty-btn:active {
  transform: scale(0.9);
}

.qty-stepper .qty-input {
  width: 36px;
  height: 32px;
  padding: 0;
  border: none;
  text-align: center;
  font-size: 15px;
  font-family: var(--font-body);
  background: #fff;
  -moz-appearance: textfield;
}

.qty-stepper .qty-input::-webkit-outer-spin-button,
.qty-stepper .qty-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* ---- Color swatches ---- */
/* Each swatch shows that color's own product photo as its background
   (cropped to a small square) rather than a flat color chip — always
   accurate to what the customer actually sees, no color-name-to-hex
   lookup table to maintain. */
.color-swatch-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin: 10px 0 6px;
}

.color-swatch {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 2px solid var(--sand);
  background-size: cover;
  background-position: center;
  cursor: pointer;
  padding: 0;
  transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

.color-swatch:hover {
  transform: scale(1.1);
}

.color-swatch.is-active {
  border-color: var(--navy);
  box-shadow: 0 0 0 2px rgba(31, 46, 70, 0.2);
}

.color-swatch:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}

/* ---- Quantity row / Add to Cart alignment ---- */
/* margin-top: auto pushes this row to the bottom of the card regardless
   of what's above it (swatches, size bubbles, both, or neither) — this
   is what keeps every Add to Cart button aligned once cards stretch to
   match the tallest card in their grid row. padding-top guarantees a
   minimum gap even when there's no extra space to distribute. */
.product-card .qty-row {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: auto;
  padding-top: 10px;
}

.product-card .qty-row .add-to-cart-btn {
  flex: 1 1 100%;
}

/* ---- Size selection: a real <select>, not a row of pill buttons ----
   A dropdown is exactly one line tall regardless of how many sizes a
   product has (3 sizes or 9) — that fixed height is what actually keeps
   price/color/size labels lined up across cards in the same grid row.
   Custom chevron via background-image since appearance:none removes the
   native one; #2A2722 below is var(--ink)'s literal hex — custom
   properties can't be interpolated inside a data-URI SVG. */
.size-select {
  display: block;
  width: 100%;
  max-width: 200px;
  margin: 8px auto 0;
  padding: 8px 32px 8px 16px;
  border: 1.5px solid var(--sand);
  border-radius: 20px;
  background-color: #fff;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%232A2722' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 11px;
  color: var(--ink);
  font-size: 14px;
  font-family: var(--font-body);
  text-align: center;
  text-align-last: center;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  transition: border-color 0.15s ease;
}

.size-select:hover {
  border-color: var(--rose-gold);
}

.size-select:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}

.size-select option:disabled {
  color: var(--sand);
}

.product-card .price-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}

.product-card .price {
  font-weight: 500;
  color: var(--deep-rose);
  margin: 4px 0;
}

.choice-hint {
  font-size: 12px;
  color: var(--ink);
  opacity: 0.6;
  text-align: center;
  margin: 10px 0 0;
}

/* Reserved-height zones (garment cards only — see the isAccessory check
   in renderCard) so "Choose your color" / "Choose your size" land at
   the same Y across sibling cards in a grid row even when one product
   has a color choice and its neighbor doesn't. Heights are sized to fit
   one eyebrow line plus one row of swatches (42px circles) or the size
   dropdown, so a populated zone never overflows its own reservation. */
.color-choice-zone {
  min-height: 90px;
}

.size-choice-zone {
  min-height: 80px;
}

/* ============================================================
   Mobile overrides — placed at the end deliberately (matches the
   cascade-order convention used in valleycreek.css: later rules here
   must win over the desktop rules above, so keep new additions below
   this block, not mixed in above it).
   ============================================================ */
@media (max-width: 900px) {
  .products-layout {
    flex-direction: column;
  }

  /* Slide-in drawer, ported from Valley Creek — replaces the old
     "stack the cart below the products" mobile behavior. margin-top
     is explicitly reset to 0 here since the desktop -95px alignment
     value (see the base .cart-column rule) has no meaning once the
     column becomes a fixed-position panel. */
  .cart-column {
    position: fixed;
    top: 0;
    right: 0;
    width: min(85vw, 360px);
    height: 100vh;
    max-height: 100vh;
    margin-top: 0;
    background: var(--eggshell);
    padding: 20px;
    box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);
    transform: translateX(100%);
    transition: transform 0.3s ease;
    z-index: 60;
    overflow-y: auto;
  }

  .cart-column.open {
    transform: translateX(0);
  }

  .cart-toggle-btn {
    display: flex !important;
  }

  .cart-overlay {
    display: block !important;
  }

  .cart-overlay.open {
    opacity: 1;
    pointer-events: auto;
  }

  .product-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Floating cart button (mobile only — hidden on desktop, shown via the
   900px media query above) and its dimmed backdrop + close button. */
.cart-toggle-btn {
  display: none;
  position: fixed;
  bottom: 20px;
  right: 20px;
  align-items: center;
  gap: 8px;
  background: var(--sand);
  color: var(--navy);
  border: none;
  border-radius: 30px;
  padding: 14px 20px;
  font-size: 15px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(216, 196, 167, 0.5);
  z-index: 55;
}

.cart-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
  z-index: 50;
}

.cart-close-btn {
  display: none;
  background: none;
  border: none;
  font-size: 24px;
  color: var(--navy);
  position: absolute;
  top: 12px;
  right: 16px;
  cursor: pointer;
}

@media (max-width: 900px) {
  .cart-close-btn {
    display: block;
  }
}

@media (max-width: 640px) {
  .product-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
  }

  /* Titles: the shared min-height:2.6em (from /style.css) under-reserves
     real 2-line height, and at this much narrower 2-column card width,
     several titles were wrapping to 3 lines — both threw card layouts
     out of alignment with each other. This reserves genuine 2-line
     height and hard-clamps anything longer, so every title is exactly
     2 lines, always, regardless of how long the product name is. */
  .product-card h3 {
    min-height: 3.2em;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  /* Swatches: flex-wrap:nowrap GUARANTEES a single row regardless of how
     many colors a product has — this matters more than getting the exact
     pixel math right, since a wrapped second row is what was throwing
     "Choose your size" out of alignment between cards. overflow-x:auto is
     just a safety net for a hypothetical 5+ color product; the sizing
     below keeps the realistic max (4 colors) comfortably on one line
     with room to spare, so it should never actually need to scroll. */
  .color-swatch {
    width: 24px;
    height: 24px;
  }

  .color-swatch-row {
    gap: 4px;
    flex-wrap: nowrap;
    overflow-x: auto;
  }

  .color-choice-zone {
    min-height: 70px;
  }

  /* Header: stack logos above the welcome text on narrow screens,
     ported from Valley Creek's identical mobile reorder. */
  .header-logos {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px 16px;
  }

  .logo-left {
    order: 1;
  }

  .logo-right {
    order: 2;
  }

  .header-welcome {
    order: 3;
    flex: 0 0 100% !important;
  }

  .header-welcome-title {
    font-size: 16px;
  }

  .countdown-timer {
    font-size: 11px;
  }

  .logo-slot {
    height: 44px;
  }

  .logo-left {
    height: 32px;
  }

  .site-header {
    padding: 12px 0;
  }
}

/* ============================================================
   Bridge-only additions (kept at the end so they win the cascade).
   ============================================================ */

/* The Bridge logo is a script lockup (~1.9:1) with a long descender, so
   it gets a bit more height than Emmanuel's wide wordmark to read at a
   similar weight to the Jac'D Up mark on the right. */
.logo-left {
  height: 72px;
}

/* Show the whole garment. The product photos are 4:5 portraits on white;
   the shared rule above crops them to fill a square (object-fit: cover),
   which clipped the hem and neckline. Fit the full photo inside the
   square on a matching white ground, with a little extra margin so the
   garment sits slightly zoomed out. Main photo only; thumbnails keep
   their crop. */
.product-card .image-wrap img.main-product-image {
  object-fit: contain;
  background: #fff;
  padding: 4%;
  box-sizing: border-box;
}

/* ============================================================
   UNIFORM TILES — standing rule for every shop: tiles must line up.
   Every card has the same stack, top to bottom, at fixed heights:
     photo (square) → thumbnail row (always 54px, blank if no extra
     views) → title (as tall as the tallest title, never cut off) → price → [color row, only when
     some product offers colors] → size picker zone → qty pill → button.
   The size/qty/button group (.card-actions) is pinned to the bottom of
   the card, so even if something above grows, the pickers and buttons
   still line up across the row. Kept last so it wins the cascade at
   every screen width.
   ============================================================ */
.product-card .image-wrap .view-thumb-strip {
  height: 54px;
  box-sizing: border-box;
  align-items: center;
  padding-top: 4px;
  padding-bottom: 4px;
}

/* The spacer only shows when the card has no real thumbnail row. */
.product-card .image-wrap:has(.view-thumb-strip:not([hidden]):not(.thumb-strip-spacer)) .thumb-strip-spacer {
  display: none;
}

/* Titles are never cut off. app.js measures the tallest title on the
   page (equalizeTitleHeights) and sets --title-h so every title box is
   that tall; re-measured whenever the window size changes. */
.product-card h3 {
  line-height: 1.3;
  height: var(--title-h, auto);
  min-height: 2.6em;
  display: block;
  overflow: visible;
}

.product-card .price-row {
  height: 1.6em;
  align-items: center;
}

.product-grid:not(.has-color-choices) .color-choice-zone {
  min-height: 0;
}

.product-card .card-actions {
  margin-top: auto;
  display: flex;
  flex-direction: column;
}

/* Size zone: fixed height, contents stacked from the bottom so the picker
   always ends at the same line. Its old margins made the contents taller
   than the box, so the picker spilled down onto the quantity pill. Here
   the hint and picker have no outside margins; spacing is set only by the
   gap and by the 14px above the quantity pill. */
.product-card .size-choice-zone {
  height: 64px;
  min-height: 64px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
}

.product-card .size-choice-zone .choice-hint,
.product-card .size-choice-zone .size-select {
  margin: 0;
}

.product-card .card-actions .qty-row {
  margin-top: 0;
  padding-top: 14px;
}

/* Phones: the button label stays on one line. (Title height is handled
   by --title-h at every width.) */
@media (max-width: 640px) {
  .product-card h3 {
    height: var(--title-h, auto);
    min-height: 2.6em;
    display: block;
    -webkit-line-clamp: unset;
  }

  .product-card .add-to-cart-btn {
    white-space: nowrap;
    padding-left: 8px;
    padding-right: 8px;
    font-size: 15px;
  }
}
