/* ══════════════════════════════════════════════════════════════════════════════════════════
   AUTHOR / VENDOR PROFILE — LISTINGS GRID
   RC1 UI POLISH — Author Profile Listings Grid

   Scope: the listings grid rendered by author.php ONLY. Page-specific layout overrides for the
   legacy `.ail-search-grid` / `.ail-search-card` / `.ail-sc-*` markup.

   This file deliberately contains NO shared Listing Card styles. Everything to do with badges
   (.lbai-badges, .lbai-badge, .lbai-badge__icon, .lbai-tick, .lbai-badges__more,
   .lbai-badges__panel) stays in assets/css/listing-card.css, which is the single source for the
   shared component and is now enqueued on is_author() as this stylesheet's dependency. The badge
   popup continues to be driven by listing-card.css + assets/js/badges.js — nothing here
   re-implements or overrides that behaviour.

   Presentation only. No business logic, no query, no badge eligibility/priority, no permission
   and no data path is touched by this file.

   ── WHY THESE SELECTORS CARRY AN EXTRA CLASS ────────────────────────────────────────────────
   author.php has an inline <style> block that appears AFTER the markup it styles, so at equal
   specificity it wins over anything loaded in <head>. author.php is not modified by this task,
   so the two declarations that genuinely conflict with it are written with one additional class
   (`.ail-card-wrap`) to raise specificity from 2 classes to 3. That makes the outcome
   independent of document order. Each such rule says so at the point of use.

   ── WHAT WAS BROKEN ─────────────────────────────────────────────────────────────────────────
   1. No stylesheet anywhere defined .ail-search-grid, .ail-search-card, .ail-sc-meta,
      .ail-sc-rating or .ail-sc-location, so the card had no chrome, no padding and no internal
      spacing, and its content column could not distribute vertically.
   2. The image rule was `height: auto` with no aspect-ratio, which made the accompanying
      `object-fit: cover` a no-op: every image resolved to its own intrinsic ratio, so card
      heights were ragged and left large whitespace under the shorter cards in each row.
   3. Badge CSS was absent entirely (fixed by the enqueue change, not by this file).
   ══════════════════════════════════════════════════════════════════════════════════════════ */


/* ── 1. GRID ────────────────────────────────────────────────────────────────────────────────
   Declared here, in <head>, with values IDENTICAL to author.php's inline block (1 / 2 @640 /
   3 @1024 / 4 @1280, gap 16px). Two reasons:
     a) first paint is already correct, so the grid no longer forms as a stack of 240px-wide
        blocks (core.css `.ail-card-wrap { flex: 0 0 240px; width: 240px }`) and then reflow
        into a grid when the late inline block arrives — that reflow is a layout shift;
     b) because the values match exactly, the inline block re-asserting them later produces no
        second shift.
   Column counts and breakpoints are unchanged from the existing design, so no width reflows
   differently than it did before. */
.ail-search-grid {
    display: grid;
    grid-template-columns: repeat(1, 1fr);
    gap: 16px;
    width: 100%;
    align-items: stretch;   /* every item fills its row: the basis of equal heights */
}

@media (min-width: 640px) {
    .ail-search-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1024px) {
    .ail-search-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 1280px) {
    .ail-search-grid { grid-template-columns: repeat(4, 1fr); }
}


/* ── 2. EQUAL CARD HEIGHTS ──────────────────────────────────────────────────────────────────
   A three-level flex chain, no JavaScript and no fixed heights anywhere:

     .ail-card-wrap        grid item, stretched to the row height by align-items:stretch
       a.ail-search-card   flex column that fills the wrap
         img               fixed ratio, never shrinks
         .ail-sc-info      flex column that absorbs the remaining space
           h3.ail-sc-title title + ticks + badge cluster (top-aligned)
           .ail-sc-meta    margin-top:auto -> pinned to the card floor

   The `margin-top: auto` on the meta block is what makes rating/location sit on the same
   baseline across every card in a row regardless of how long each title is. That is the
   "vertically aligned / consistent structure" requirement, achieved purely by layout. */

/* Grid item. core.css sets `flex: 0 0 240px; width: 240px` for the homepage horizontal rail;
   inside this grid the item must be full-width. Declared here too (2 classes beats core.css's
   1 class) so first paint is correct rather than 240px-then-reflow. */
.ail-search-grid .ail-card-wrap {
    display: flex;
    width: 100%;
    min-width: 0;           /* a grid/flex child may not shrink below content width unless told it may */
}

/* SPECIFICITY NOTE: overrides `display: block` from author.php's inline
   `.ail-search-grid .ail-search-card` (2 classes). The extra `.ail-card-wrap` makes this
   3 classes, so it wins irrespective of source order. This is the only genuine conflict. */
.ail-search-grid .ail-card-wrap .ail-search-card {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
    background: var(--card-bg, #fff);
    box-shadow: 0 2px 12px rgba(15, 23, 42, .06);
    transition: box-shadow .2s ease;
    /* No padding here: the image must sit flush against the card edges. Padding lives on
       .ail-sc-info. Corner rounding + clipping already come from core.css .ail-card-wrap. */
}

.ail-search-grid .ail-card-wrap .ail-search-card:hover {
    box-shadow: 0 10px 26px rgba(15, 23, 42, .10);
}

/* Content column: absorbs the leftover height so the meta block can be pushed to the bottom.
   The single `gap` is the whole vertical rhythm — title, badge row and meta are spaced by one
   value, so every card is identically spaced by construction rather than by per-element
   margins. author.php's inline rule only sets width/box-sizing, so there is no conflict. */
.ail-search-grid .ail-sc-info {
    display: flex;
    flex-direction: column;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
    padding: 12px;
}


/* ── 3. IMAGE: FIXED ASPECT RATIO ───────────────────────────────────────────────────────────
   4:3 with object-fit:cover. The source is get_the_post_thumbnail_url( $id, 'medium' ), so the
   uploaded ratio varies per listing; a fixed ratio is what makes every card's media band the
   same height, which in turn is what removes the ragged heights and the whitespace beneath
   shorter cards. 4:3 is preferred over 16:9 here because it crops portrait uploads less
   severely. One ratio at every breakpoint, so the image ratio is consistent site-wide on this
   surface. Nothing is stretched: width/height stay 100%/auto and cover does the cropping.

   `aspect-ratio` is not declared by author.php's inline image rule, so this does not conflict
   with it — but the extra `.ail-card-wrap` class is kept for consistency with the rule above
   and to keep the ratio safe if that inline block is ever extended.

   In-repo precedent for this exact pattern: home.css `.lbai-blog-card__cover img`. */
.ail-search-grid .ail-card-wrap .ail-search-card img {
    width: 100%;
    aspect-ratio: 4 / 3;
    height: auto;
    object-fit: cover;
    display: block;
    flex: 0 0 auto;         /* the media band never shrinks when the content column grows */
    background: #e2e8f0;    /* placeholder tone while the lazy image decodes — no white flash */
}


/* ── 4. TITLE ───────────────────────────────────────────────────────────────────────────────
   The flex/wrap title row itself is already defined in core.css
   (`.ail-sc-info .ail-sc-title`), which is where the green/blue ticks are kept inline beside
   the title text and the business badge cluster is allowed to wrap onto its own line. It is NOT
   restated here. Only the typographic reset the card needs is set, since no stylesheet
   previously gave .ail-sc-title a size or margin at all. */
.ail-search-grid .ail-sc-title {
    margin: 0;
    font-size: 15px;
    font-weight: 800;
    line-height: 1.3;
    color: var(--text-primary, #0f172a);
}


/* ── 5. BADGES: CONTAINMENT ONLY ────────────────────────────────────────────────────────────
   All badge presentation comes from listing-card.css. `.lbai-badges { flex: 0 0 100% }` there
   is what puts the business cluster on its own row directly beneath the title, producing
   Image -> Title -> Badges -> Rating -> Location with no markup change. `flex-wrap: wrap` there
   is what wraps multiple badges.

   The only thing added here is containment: cap the cluster to the content width so a long
   label can never push past the card edge inside this narrower grid. These are page-specific
   overrides, not copies of the component rules. */
.ail-search-grid .ail-sc-title .lbai-badges {
    max-width: 100%;
    min-width: 0;
}

/* The popup panel is position:fixed (listing-card.css) and badges.js portals it to <body>, so
   core.css's `.ail-card-wrap { overflow: hidden }` cannot clip it. Nothing to override. */


/* ── 6. META: RATING THEN LOCATION ──────────────────────────────────────────────────────────
   Pinned to the bottom of the card by margin-top:auto, and stacked into one row each so the
   required structure (… -> Rating -> Location) is identical on every card. No stylesheet
   defined .ail-sc-meta / .ail-sc-rating / .ail-sc-location before, so all of this is new
   rather than a change to existing values. */
.ail-search-grid .ail-sc-meta {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: auto;       /* equal-height alignment: meta sits on the card floor */
    min-width: 0;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--text-secondary, #64748b);
}

.ail-search-grid .ail-sc-rating {
    display: block;
    color: var(--accent-color, #f59e0b);
    white-space: nowrap;
}

/* Location can be long; it is allowed one line and truncates rather than pushing the card
   wider. The text is already shortened server-side with wp_trim_words(), so this is a safety
   net for long single words, not the primary shortening mechanism. */
.ail-search-grid .ail-sc-location {
    display: block;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}


/* ── 7. NARROW PHONES 320–412px ─────────────────────────────────────────────────────────────
   Single column at these widths, so the card is wide and only the internal spacing needs to
   tighten. No layout or column change — purely spacing and type scale. */
@media (max-width: 412px) {
    .ail-search-grid .ail-sc-info { padding: 10px; gap: 6px; }
    .ail-search-grid .ail-sc-title { font-size: 14px; }
}

/* ── 8. 320px FLOOR ─────────────────────────────────────────────────────────────────────────
   Smallest supported viewport: trim once more so the content keeps clear of the card edge. */
@media (max-width: 360px) {
    .ail-search-grid .ail-sc-info { padding: 9px; }
    .ail-search-grid .ail-sc-meta { font-size: 11.5px; }
}


/* ── 9. REDUCED MOTION ──────────────────────────────────────────────────────────────────────
   The only transition introduced above is the hover shadow. */
@media (prefers-reduced-motion: reduce) {
    .ail-search-grid .ail-card-wrap .ail-search-card { transition: none; }
}
/* ═══════════════════════ END AUTHOR / VENDOR PROFILE — LISTINGS GRID ══════════════════════ */
