/* ==========================================================================
   05-PRODUCT-CARD.CSS — Al Aliyah Supermarket implementation kit
   Status: PENDING REVIEW.

   THE REAL PROBLEM THIS FILE SOLVES
   The live catalogue's titles are inconsistent: some are already good
   mixed-case ("AL RAWABI Juice Guava 200ml"), some are short and shouty
   ("THREE COWS WHITE CHEESE LIGHT 500GM"), and some are enormous, run-on
   marketing strings well past 150 characters (a men's beach-shorts listing
   in the live catalogue runs to 168 characters with embedded size codes
   like "L(36)"). In a grid of cards, if title height is allowed to vary
   with content, every row's image/price/button baseline drifts out of
   alignment the moment one card in that row has a long title.

   THE FIX, two independent pieces:
   1. A RESERVED, FIXED title block height (2 lines, via -webkit-line-clamp)
      that is identical for every card regardless of title length. Short
      titles leave visible whitespace below them inside that block; long
      titles truncate with an ellipsis at line 2. Because the block height
      is fixed by `line-height x 2` rather than by content, price/rating/
      add-to-cart controls below it land on the same row across the whole
      grid every time.
   2. A CASE strategy that does NOT blanket-lowercase or title-case the
      string (both would mangle real embedded units/acronyms like "500GM",
      "200ml", "AL RAWABI"). Instead: render the source string unchanged by
      default, and ONLY when the PHP/JS layer detects the title has NO
      lowercase letters at all (a true ALL-CAPS string, e.g. "THREE COWS
      WHITE CHEESE LIGHT 500GM") apply `.aly-title--soften-caps`
      (defined in 02-typography.css), which uses font-variant-caps to make
      the block visually calmer without touching a single character — so a
      genuine acronym or unit is never split, lowercased, or re-cased.
      Detection is a one-line PHP check the theme integrator adds where the
      title is echoed, e.g.:
        $is_shouting = $title === mb_strtoupper( $title, 'UTF-8' );
      That check belongs in the WooCommerce template override, not in this
      CSS file — see README.md's install checklist.
   ========================================================================== */

.aly-card {
  display: flex;
  flex-direction: column;
  background-color: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--elevation-hairline); /* hairline inset per owner spec, not a drop shadow */
  overflow: hidden;
  position: relative;
  transition: box-shadow var(--duration-base) var(--ease-standard),
              transform var(--duration-base) var(--ease-standard);
}

.aly-card:hover {
  box-shadow: var(--elevation-hairline), var(--shadow-md);
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  .aly-card:hover {
    transform: none;
  }
}

.aly-card:focus-within {
  box-shadow: var(--elevation-hairline), 0 0 0 3px var(--focus-ring-tint), 0 0 0 1px var(--color-focus-outline);
}

.aly-card__media {
  position: relative;
  aspect-ratio: 1 / 1;
  background-color: var(--color-surface-sunk);
}

.aly-card__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
  padding: var(--space-3);
}

.aly-card__badges {
  position: absolute;
  inset-block-start: var(--space-2);
  inset-inline-start: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  align-items: flex-start;
}

.aly-card__wishlist {
  position: absolute;
  inset-block-start: var(--space-2);
  inset-inline-end: var(--space-2);
}

.aly-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  flex: 1;
}

.aly-card__category {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* ---- The fixed-height title block (see file header) ---- */
.aly-card__title {
  font-family: var(--font-sans); /* never the display serif on a product title */
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  line-height: var(--lh-snug); /* 1.35 */
  color: var(--color-text);
  /* Reserved height = line-height (1.35) x font-size (0.875rem) x 2 lines,
     fixed regardless of the string behind it. */
  block-size: calc(var(--lh-snug) * var(--fs-sm) * 2);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  text-transform: none; /* see file header — never blanket-transformed */
}

.aly-card__title a {
  color: inherit;
}

.aly-card__title a:hover {
  color: var(--gold-text-on-white);
  text-decoration: underline;
}

/* Fallback for browsers without -webkit-line-clamp support: the fixed
   block-size + overflow:hidden above still caps the visible area even
   without the ellipsis, so grid alignment is never lost even in the
   degraded case. */
@supports not (-webkit-line-clamp: 2) {
  .aly-card__title {
    display: block;
  }
}

.aly-card__rating {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

.aly-card__price-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin-block-start: auto;
  padding-block-start: var(--space-2);
}

.aly-card__footer {
  padding: 0 var(--space-4) var(--space-4);
}

/* --------------------------------------------------------------------------
   Badges — Sale, New, Local, Halal, Organic, Low Stock, Out of Stock
   -------------------------------------------------------------------------- */
.aly-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  line-height: 1;
  padding-inline: var(--space-2);
  padding-block: var(--space-1);
  border-radius: var(--radius-pill);
  white-space: nowrap;
}

/* Sale: amber fill, ink label — a promotional but not alarmist colour */
.aly-badge--sale {
  background-color: var(--amber-500);
  color: var(--ink-900);
}

/* New: gold-500 fill, ink label (rule 2 applies to badges too, not just buttons) */
.aly-badge--new {
  background-color: var(--gold-500);
  color: var(--ink-900);
}

/* Local: success-deep fill, white label */
.aly-badge--local {
  background-color: var(--color-success-deep);
  color: #FFFFFF;
}

/* Halal: outlined, ink text — deliberately understated per brand voice
   ("halal clarity should be visible, not asserted") rather than a loud fill */
.aly-badge--halal {
  background-color: var(--color-surface);
  border: var(--border-width) solid var(--ink-900);
  color: var(--ink-900);
}

/* Organic: soft success tint background, success-deep text */
.aly-badge--organic {
  background-color: var(--color-success-bg);
  color: var(--color-success-deep);
}

/* Low Stock: warning tint background, warning-text label */
.aly-badge--low-stock {
  background-color: var(--color-warning-bg);
  color: var(--color-warning-text);
}

/* Out of Stock: neutral/muted — never red, this is a state not an error */
.aly-badge--out-of-stock {
  background-color: var(--color-surface-sunk);
  color: var(--color-text-muted);
}

.aly-card--out-of-stock .aly-card__media img {
  opacity: 0.5;
}

.aly-card--out-of-stock .aly-card__price-row {
  opacity: 0.6;
}

/* --------------------------------------------------------------------------
   Category tile (department/category grid entry point)
   -------------------------------------------------------------------------- */
.aly-category-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  background-color: var(--color-surface);
  box-shadow: var(--elevation-hairline);
  text-align: center;
  transition: box-shadow var(--duration-base) var(--ease-standard),
              transform var(--duration-base) var(--ease-standard);
}

.aly-category-tile:hover {
  box-shadow: var(--elevation-hairline), var(--shadow-md);
  transform: translateY(-2px);
}

.aly-category-tile:focus-visible {
  outline: 2px solid var(--color-focus-outline);
  outline-offset: 3px;
}

.aly-category-tile__icon {
  inline-size: 3rem;
  block-size: 3rem;
  border-radius: 50%;
  background-color: var(--gold-100);
  display: grid;
  place-content: center;
  color: var(--gold-800);
}

.aly-category-tile__label {
  font-family: var(--font-sans);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-sm);
  color: var(--color-text);
}

.aly-category-tile__count {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Product grid — the surface that makes the fixed-title-height contract
   actually matter (equal-height cards regardless of content).
   -------------------------------------------------------------------------- */
.aly-product-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
}

@media (min-width: 768px) {
  .aly-product-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 1024px) {
  .aly-product-grid { grid-template-columns: repeat(4, 1fr); }
}

@media (min-width: 1440px) {
  .aly-product-grid { grid-template-columns: repeat(5, 1fr); }
}

/* --------------------------------------------------------------------------
   Product facts — the per-unit price line and the points-earned chip.

   `06-pages.md` §4 places both directly under the price on the single product
   page; `05-components.md` §Product card lists the same two in the card's
   anatomy, between the title and the add-to-cart control. The markup comes
   from inc/product-facts.php.

   The chip's tokens are the ones §Product card names for it: --gold-100
   background, --gold-800 text. That is the same pairing the signed-in header
   chip uses, which is deliberate — a gold wash with gold-800 on it is this
   system's one "quiet good news" surface, and it clears 6.06:1.
   -------------------------------------------------------------------------- */
.aly-product-facts {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  margin-block-start: var(--space-2);
}

.aly-product-facts .aly-price--per-unit {
  margin: 0;
}

/* wc_price() wraps the amount in WooCommerce's own markup, which inherits the
   page's price styling. Inside the per-unit line it must read as the quiet
   secondary figure it is, not as a second price competing with the first. */
.aly-price--per-unit .woocommerce-Price-amount {
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
}

/* BIDI. `.aly-price` in 02-typography.css sets `unicode-bidi: plaintext`, which
   takes the paragraph's direction from its first strong character. That is
   right for a bare price — it keeps "AED 12.50" reading LTR inside an Arabic
   sentence — and wrong here, because this store's currency symbol is "د.إ",
   itself strongly RTL. The first strong character in "100.00 د.إ / kg" is
   therefore Arabic, the whole line flips, and it rendered as "kg / 100.00 د.إ"
   — the unit before the amount, which reads as a different claim.

   `isolate` takes the direction from the element instead, i.e. from the page,
   so the line reads LTR on the English site and RTL on the Arabic one, while
   the amount stays a self-contained run either way. */
.aly-price--per-unit {
  unicode-bidi: isolate;
}

.aly-price--per-unit .woocommerce-Price-amount {
  unicode-bidi: isolate;
}

.aly-points-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
  padding: 0.15rem var(--space-2);
  border-radius: var(--radius-xs);
  background-color: var(--gold-100);
  color: var(--gold-text-on-cream);
  box-shadow: inset 0 0 0 var(--border-width) var(--gold-200);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  line-height: 1.5;
  white-space: nowrap;
}

.aly-points-chip svg {
  inline-size: 0.75rem;
  block-size: 0.75rem;
  flex: none;
  display: block;
}

/* ---- 2026-09 revision: badge, price row, points chip, stepper ----
   Reuses/appends to the .aly-card__* BEM names already declared above
   (.aly-card__price-row existed but had no live markup pointing at it yet —
   see 05-components.md §Product card / task-10-report.md self-review); the
   two overlapping declarations here (display, align-items) are the ones this
   revision intentionally changes, the rest of the earlier rule still applies. */
.aly-card__badge { position: absolute; inset-block-start: var(--space-2); inset-inline-start: var(--space-2); z-index: 2; font-size: 10.5px; font-weight: var(--fw-bold); letter-spacing: 0.06em; text-transform: uppercase; padding: 3px 7px; border-radius: var(--radius-badge); }
.aly-card__badge--fresh { background: var(--palm-wash); color: var(--palm); }
.aly-card__badge--sale  { background: var(--clay); color: var(--surface-white); }
.aly-card__badge--new   { background: var(--gold-500); color: var(--ink-900); }
.aly-card__price-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); flex-wrap: wrap; margin-block-start: 0; padding-block-start: 0; }
.aly-card__points { font-size: 11px; font-weight: var(--fw-semibold); color: var(--gold-text-on-cream); background: var(--gold-wash); padding: 2px 7px; border-radius: var(--radius-chip); white-space: nowrap; }
/* Touch targets: --touch-target-min (44px, see 00-tokens.css) drives both the
   stepper's overall height and each button's grid track, per this project's
   hard 44px rule for interactive controls — the brief's own 34px/40px figures
   were under that floor, so this widens the control rather than using them. */
.aly-stepper--card { display: inline-grid; grid-template-columns: var(--touch-target-min) 1fr var(--touch-target-min); align-items: center; inline-size: 128px; block-size: var(--touch-target-min); border-radius: var(--radius-sm); background: var(--gold-500); color: var(--ink-900); font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; text-align: center; }
.aly-stepper--card .aly-stepper__btn { block-size: 100%; inline-size: 100%; border: 0; background: transparent; color: inherit; font-size: 18px; cursor: pointer; border-radius: var(--radius-sm); }
.aly-stepper--card .aly-stepper__btn:hover { background: var(--gold-400); }
.aly-stepper--card .aly-stepper__btn:focus-visible { outline: 2px solid var(--color-focus-outline); outline-offset: -2px; }
.aly-stepper--card.is-busy { opacity: 0.6; pointer-events: none; }
