/**
 * Image card — content shape for the neon and panel frames.
 *
 * 🔴 NO DECORATION HERE. No border, radius, shadow, background or padding: the
 * frame owns all of it and this card runs to the frame's edge. Ruled by
 * Caroline Casals. If you are about to add a visual treatment, it belongs on
 * `neon-card` or `panel-card` instead.
 *
 * The 24px gap is provisional. Figma's innermost ring frame declares
 * `gap: 24px`, which cannot render with a single child, so the spacing seen
 * between artwork and copy must belong to this component. Deduced, not
 * measured — confirm against the vertical instance before treating it as fact.
 */

.image-card {
  display: flex;
  flex-direction: column;
  gap: 24px;
  inline-size: 100%;
}

/* Horizontal is a DESKTOP-ONLY arrangement. Below the tablet boundary it stacks,
   because two columns inside a card inside a 580px track leaves neither enough
   room. 1024 matches the boundary `cards-row` already switches its gap on;
   DONI-864 may move it, so it is written once here. */
@media (min-width: 1024px) {
  .image-card--horizontal {
    flex-direction: row;
    align-items: center;
  }

  /* `align: top`. Centre stays the default, so no existing card moves. Scoped to
     the horizontal arrangement because that is the only one with two columns to
     align — in the stacked layout `align-items` controls the cross axis, where
     `flex-start` would left-align the image instead of raising it. */
  .image-card--horizontal.image-card--align-top,
  .image-card--horizontal.image-card-vertical-aligned {
    align-items: flex-start;
  }

  .image-card--horizontal.image-card-vertical-aligned > .image-card__media {
    padding-top: 8px;
  }

  .image-card--horizontal > .image-card__media,
  .image-card--horizontal > .image-card__body {
    min-inline-size: 0;
    flex: 1 1 auto;
  }

  /**
   * 🔴 A width cap is a SIZE for this column, not just a ceiling.
   *
   * Measured on /why-dawnzera: `--image-card-media-max-w: 198px` with a 266×154
   * logo rendered the image at 126px — 72px short of the cap with room to
   * spare. The cap only ever bounded the wrapper, so the outer row shrank this
   * column to 126px on its content, and the image followed it down through
   * `max-inline-size: 100%`. Nothing was overflowing; the space was simply
   * given to the body column.
   *
   * `flex-basis` makes the cap the column's starting width, and the floor stops
   * the row taking it back. Both fall back to today's values when no cap is
   * set — `auto` and `0` — so an uncapped card cannot move.
   *
   * The floor is `min(cap, 100%)`, not the cap, so a container genuinely
   * narrower than the cap still wins and the column shrinks rather than
   * overflowing. It does NOT stretch an image up to the cap: the image keeps
   * `max-inline-size: 100%` and its intrinsic size, so a logo smaller than the
   * cap stays at its own size.
   */
  .image-card--horizontal > .image-card__media {
    flex-basis: var(--image-card-media-max-w, auto);
    min-inline-size: min(var(--image-card-media-max-w, 0px), 100%);
  }

  /* Per-instance opt-in via Image Card → Custom CSS: image-card--btn-align.
     Fills the frame height and pushes the CTA to the card bottom. */
  .image-card--btn-align > .image-card__body {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    height: 100%;
  }
}

/* Let the slotted Image component fill the media column rather than sitting at
   its intrinsic width. */
.image-card__media {
  display: flex;
  flex-direction: column;
}

.image-card__media :is(img, picture) {
  max-inline-size: 100%;
  block-size: auto;
}

/**
 * Optional size caps — `media_max_width` / `media_max_height`.
 *
 * The props arrive as custom properties on the wrapper. Every rule falls back to
 * `none`, which is the initial value of both properties, so an unset cap resolves
 * to exactly what the browser would do anyway and cannot change an existing card.
 *
 * The cap applies to the wrapper AND its direct children, so it holds for
 * whatever is placed in the slot rather than only for an image. The custom
 * property is repeated rather than referred to as `100%` because the wrapper's
 * height is content-derived, so a percentage on a child resolves against `auto`.
 *
 * No `flex-shrink` guard is needed on this flex column: a child shares its cap
 * with the container, so it can never overflow it and shrinking never triggers.
 *
 * ⚠️ That reasoning covers this wrapper's own children only. The wrapper is
 * itself a flex item of `.image-card--horizontal`, and THAT row was shrinking
 * it below the cap — see the flex-basis rule in the 1024px block above.
 */
.image-card__media {
  max-inline-size: var(--image-card-media-max-w, none);
  max-block-size: var(--image-card-media-max-h, none);

  /* `stretch` is the flex default, so this is inert until a height cap sets the
     property. See the note in the template for why it cannot be unconditional. */
  align-items: var(--image-card-media-align, stretch);
}

.image-card__media > * {
  max-inline-size: var(--image-card-media-max-w, none);
  max-block-size: var(--image-card-media-max-h, none);
}

/* The height cap has to reach the image itself, not only its wrapper. With the
   stretch released above, an image carrying both a max width and a max height is
   scaled by the smaller of the two, so the aspect ratio survives. */
.image-card__media :is(img, picture) {
  max-block-size: var(--image-card-media-max-h, none);
}

@media (max-width: 1023px) {
  .image-card.image-card-layout > .image-card__media,
  .image-card.image-card-layout > .image-card__media > * {
    max-inline-size: none;
  }
}

/**
 * Stand-alone — `standalone` prop, off by default.
 *
 * 🔴 THE ONE EXCEPTION TO "NO DECORATION", AND IT IS NARROW.
 * Normally this card sits inside a neon or panel frame, and the frame supplies
 * the surface: background, radius, padding and clipping. Declaring any of that
 * here would be invisible at best and a double-rounded edge at worst.
 *
 * `standalone` is for the case where the card is placed WITHOUT a frame and has
 * to be its own surface (Figma `10291:36596`). It turns on exactly what a frame
 * would otherwise have provided — a white rounded surface — and nothing else.
 * Ruled by Caroline Casals.
 *
 * `overflow: hidden` is what makes the radius real: without it a full-bleed
 * image keeps its square corners over a rounded box.
 *
 * ⚠️ Still no border, no shadow and no padding. A frame's ring and glow are the
 * frame's identity, and a stand-alone card is not pretending to be one. If a
 * stand-alone card ever needs an inset, that is a measurement, not a default.
 */
.image-card--standalone {
  background: var(--color-white, #fff);
  border-radius: var(--radius-2xl, 24px);
  overflow: hidden;

  /* Fill the grid area rather than shrink-wrapping the copy. Without a frame
     around it the card IS the surface, so two stand-alone cards in one row must
     square off even when one holds more copy than the other. Inside a frame
     this is not wanted -- the frame sets the height and the card follows it. */
  block-size: 100%;
}

/* Copy needs a horizontal inset once the card is its own surface — without a
   frame there is nothing else holding the text off the edge. On the BODY only:
   the artwork is meant to reach the edge and be clipped by the radius, which is
   the whole reason `overflow: hidden` is there. Ruled by Caroline Casals. */
.image-card--standalone > .image-card__body {
  padding-inline: 1.5rem;
}

/* An unfilled slot leaves an empty wrapper — the wrapper cannot be conditional,
   because a filled slot replaces the whole Twig block and would take a wrapper
   written inside it with it. Hiding the empty one keeps it from claiming a share
   of the flex gap. */
.image-card__media:empty,
.image-card__body:empty {
  display: none;
}

@media (max-width: 1023px) {
  .image-card--center-mobile {
    align-items: center;
  }

  /* Per-instance opt-in for horizontal cards: copy above artwork when stacked. */
  .image-card--horizontal.image-card--body-first-mobile > .image-card__body {
    order: -1;
  }
}

.custom-image-card-horizontal {
  flex-direction: row;
  align-items: center;
}
