/* ==========================================================================
   Homepage
   ========================================================================== */

/* ==========================================================================
   Homepage hero
   A crossfading gallery. The frame owns the geometry and every slide is
   cover-cropped into it, so photos of any dimension — portrait, square,
   panoramic, 6000px wide — all render correctly and none of them can push
   the page out of shape.
   ========================================================================== */

/* Spacing comes from the section rhythm; the hero itself only frames a photo. */
.ca-hero__frame {
  position: relative;
  isolation: isolate;
  border-radius: var(--ca-r-2xl);
  overflow: hidden;
  box-shadow: var(--ca-shadow-xl);
  background: var(--ca-sand);

  /*
   * Height is driven by the frame, never by the image. aspect-ratio sets the
   * shape; max-height stops a wide viewport turning the hero into a wall you
   * have to scroll past; min-height keeps the overlaid copy readable on very
   * short screens.
   */
  aspect-ratio: 16 / 10;
  max-height: min(78vh, 720px);
  min-height: 340px;
  width: 100%;
}

/* Portrait phones get a squarer crop so the headline still has room. */
@media (max-width: 700px) {
  .ca-hero__frame {
    aspect-ratio: 4 / 5;
    max-height: 72vh;
    min-height: 420px;
  }
}

.ca-hero__slides {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.ca-hero__slides--empty {
  background:
    radial-gradient(circle at 30% 30%, rgba(14,156,147,0.25), transparent 60%),
    radial-gradient(circle at 70% 70%, rgba(242,103,43,0.25), transparent 60%),
    var(--ca-sand);
}

/*
 * All slides stack on top of each other. object-fit does the heavy lifting:
 * whatever the source dimensions, the visible area is exactly the frame.
 */
.ca-hero__slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  opacity: 0;
  transition: opacity 1.2s var(--ca-ease);
  will-change: opacity;
}

.ca-hero__slide.is-active { opacity: 1; }

/*
 * Without JavaScript no slide ever gets .is-active added, but the first one
 * ships with it, so the hero is a static photo rather than an empty box.
 */

@media (prefers-reduced-motion: reduce) {
  .ca-hero__slide { transition: none; }
}

.ca-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    0deg,
    rgba(20, 25, 43, 0.80) 0%,
    rgba(20, 25, 43, 0.35) 42%,
    rgba(20, 25, 43, 0.05) 70%
  );
}

.ca-hero__copy {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  padding: clamp(22px, 4vw, 48px);
  padding-bottom: clamp(40px, 6vw, 64px);
  text-align: center;
}

.ca-hero__title {
  font-size: var(--ca-text-hero);
  line-height: 1.02;
  color: var(--ca-white);
  max-width: 18ch;
  margin: 0 auto;
  text-wrap: balance;
  text-shadow: 0 2px 18px rgba(20, 25, 43, 0.45);
}
.ca-hero__title em { font-style: normal; color: var(--ca-amber); }

.ca-hero__lede {
  max-width: 48ch;
  margin: 14px auto 0;
  color: rgba(255, 255, 255, 0.92);
  font-size: clamp(14px, 1.8vw, 18px);
  line-height: 1.5;
  text-wrap: balance;
}

.ca-hero__actions { margin: 22px 0 0; }

/* --- Feature band ------------------------------------------------------ */

.ca-features { background: var(--ca-sky); }
.ca-features__inner { text-align: center; }
.ca-features h2 { max-width: 20ch; margin: 0 auto 34px; }

.ca-feature { text-align: left; }
.ca-feature h3 { font-size: 20px; margin-bottom: 8px; }
.ca-feature p { color: var(--ca-muted); font-size: 14px; margin: 0; }

/* --- Events & specials rail --------------------------------------------- */

.ca-promos {
  background: var(--ca-cream-warm);
}

.ca-promos__inner {
  padding-block: var(--ca-section-pad);
  padding-inline: 0;
}

.ca-promos__head {
  padding-inline: var(--ca-gutter);
  margin-bottom: 26px;
  text-align: center;
}
.ca-promos__head .ca-eyebrow { margin-bottom: 12px; }

.ca-promos__title {
  font-family: var(--ca-font-display);
  font-weight: 700;
  font-size: clamp(26px, 4.4vw, 44px);
  letter-spacing: var(--ca-tracking-tighter);
  color: var(--ca-ink);
  margin: 0;
}

/*
 * The viewport clips the track and carries the edge fade; the track itself is
 * twice the content wide and slides by half, which loops seamlessly.
 */
.ca-promos__viewport {
  overflow: hidden;
}

.ca-promos__track {
  display: flex;
  width: 100%;
  gap: 18px;
  padding-inline: var(--ca-gutter);
  justify-content: center;
}
.ca-promos:hover .ca-promos__track,
.ca-promos:focus-within .ca-promos__track { animation-play-state: paused; }
/*
 * The card itself. This rule went missing during an edit, and without a width
 * a flex item inside a `width: max-content` track sizes to its image — which
 * is why the cards ballooned to the full 600px of the source photo.
 *
 * 420px is the width matched to the review strip.
 */
.ca-promo {
  flex: none;
  /*
   * Wider than the review cards, because these carry artwork and those carry
   * text. 84vw on a phone keeps a sliver of the next card visible, which is
   * what tells you the row scrolls.
   */
  width: min(520px, 86vw);
  background: var(--ca-white);
  border: 1px solid var(--ca-hairline);
  border-radius: 18px;
  overflow: hidden;
  box-shadow: var(--ca-shadow-md);
  text-decoration: none;
  color: inherit;
}

/*
 * 16:9 — wider and shorter than the old 4:3, so a landscape flyer keeps its
 * sides. `object-fit: cover` still crops, but now from the top and bottom
 * where there is usually margin, rather than from the edges where the text is.
 */
.ca-promo img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
}
.ca-promo__body { padding: 16px 18px; }
.ca-promo__kicker {
  font-family: var(--ca-font-mono);
  font-size: var(--ca-text-xs);
  letter-spacing: var(--ca-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--ca-orange-dark);
}
.ca-promo__title {
  font-family: var(--ca-font-display);
  font-weight: 700;
  font-size: 16px;
  color: var(--ca-ink);
  margin: 6px 0 0;
}

/* Anyone who prefers less motion gets a swipeable rail instead. */
@media (prefers-reduced-motion: reduce) {
  .ca-promos__track {
    animation: none;
    width: 100%;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
  }
  .ca-promo { scroll-snap-align: start; }
}

/* --- Hero strapline & mascot -------------------------------------------- */

/*
 * Status pill, borrowed from the location pages and centred.
 * One treatment on both the homepage and the store pages.
 */
/* ==========================================================================
   Hero eyebrow

   The prototype's pill — mono, uppercase, teal on a teal tint with a teal
   hairline, fully rounded, with a pulsing dot — placed in the top-left corner
   of the hero frame.

   It sits *over* the photo, at the same inset as the mascot in the opposite
   corner, so the two corners of the frame agree. That means it needs to be
   absolutely positioned and raised above the slides: they are absolutely
   positioned and fill the frame, so anything in normal flow inside the frame
   is painted underneath them and simply never appears.
   ========================================================================== */

/*
 * The base pill is in normal flow.
 *
 * It used to be `position: absolute` by default, which only works inside a
 * positioned frame. Anywhere else — a pattern-built page where the pill is a
 * sibling of the banner rather than a child — it positioned itself against
 * some distant ancestor and ended up off-screen or behind the artwork.
 *
 * So the default is safe anywhere, and the corner placement is added by the
 * three containers that can actually be a corner. A pill in the wrong place is
 * a layout nit; a pill nobody can see is a bug.
 */
.ca-hero__eyebrow {
  display: flex;
  align-items: center;
  gap: 9px;
  width: fit-content;
  max-width: 100%;
  margin: 0 auto 14px var(--ca-corner-inset);
  padding: 7px 14px;

  border: 1px solid var(--ca-teal-line);
  border-radius: var(--ca-r-pill);

  /*
   * Opaque rather than the prototype's 8% tint: over a photograph a
   * translucent pill is unreadable wherever the image happens to be light.
   */
  background: var(--ca-cream);
  box-shadow: var(--ca-shadow-sm);

  color: var(--ca-teal);
  font-family: var(--ca-font-mono);
  font-size: var(--ca-text-pill);
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: var(--ca-tracking-label);
  text-transform: uppercase;
  text-align: left;
}

/*
 * Corner placement, only where there is a corner to sit in. Each of these
 * three sets `position: relative`, so the pill has something to anchor to.
 */
.ca-hero__frame > .ca-hero__eyebrow,
.ca-loc-gallery > .ca-hero__eyebrow,
.ca-page-hero__banner > .ca-hero__eyebrow {
  position: absolute;
  top: var(--ca-corner-inset);
  left: var(--ca-corner-inset);
  z-index: 3;
  margin: 0;
  max-width: calc(100% - (var(--ca-corner-inset) * 2));
}

.ca-hero__eyebrow-dot {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  animation: ca-twinkle 1.6s ease-in-out infinite;
}

/* Store pages trade colour for state; the dot and border follow currentColor. */
.ca-hero__eyebrow[data-state="soon"]   { color: var(--ca-orange-dark); border-color: var(--ca-orange-line); }
.ca-hero__eyebrow[data-state="closed"] { color: var(--ca-faint); border-color: var(--ca-hairline-str); }

/* Nothing configured: no pill, rather than a pill asserting "open". */
.ca-hero__eyebrow[data-state="unknown"] { display: none; }

@media (max-width: 520px) {
  .ca-hero__eyebrow {
    font-size: 10px;
    letter-spacing: 0.12em;
    padding: 5px 11px;
    gap: 7px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ca-hero__eyebrow-dot { animation: none; }
}

.ca-hero__mascot {
  position: absolute;
  top: clamp(6px, 2vw, 18px);
  right: clamp(6px, 2vw, 18px);
  z-index: 3;
  width: clamp(78px, 11vw, 150px);
  height: auto;
  pointer-events: none;
  filter: drop-shadow(0 10px 14px rgba(20, 25, 43, 0.28));
}

@media (max-width: 520px) {
  .ca-hero__mascot { width: 64px; }
}
@media (max-width: 520px) {
  .ca-hero__mascot { width: 64px; }
}

/* --- Feature card badge -------------------------------------------------- */

.ca-mk-feature { position: relative; }

/*
 * Solid pill over the top-left of each photo, one brand colour per card,
 * exactly as the prototype had it. The colour is a modifier rather than a
 * nth-child rule so reordering or removing a card cannot shuffle the palette.
 */
.ca-mk-feature__badge {
  position: absolute;
  top: 14px; left: 14px;
  z-index: 2;
  margin: 0;
  padding: 5px 11px;
  border-radius: var(--ca-r-pill);
  background: var(--ca-ink);
  color: var(--ca-cream);
  font-family: var(--ca-font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
}

.ca-mk-feature__badge--purple { background: var(--ca-purple); }
.ca-mk-feature__badge--teal   { background: var(--ca-teal); }
.ca-mk-feature__badge--orange { background: var(--ca-orange); }
.ca-mk-feature__badge--yellow { background: var(--ca-yellow); color: var(--ca-ink); }
.ca-mk-feature__badge--ink    { background: var(--ca-ink); }

/* --- Short hero for marketing pages -------------------------------------- */

/* With no photo behind it there is nothing to darken. */

/* A photo, if one is set, tints the panel rather than filling it. */

/* ==========================================================================
   Marketing page hero

   The prototype's shape: a full-width banner at the page measure, then the
   label, heading and lede centred beneath it. The artwork keeps its own
   proportions — these images have text in them, so cropping to a fixed ratio
   would cut words off.
   ========================================================================== */

/*
 * No padding of its own. The hero has no background, so its own padding was
 * just extra space stacked on top of the section gap — which is what made the
 * frame look bigger than the picture inside it. Spacing comes from the section
 * rhythm like everything else.
 */
.ca-page-hero {
  padding-block: 0;
}

/* Core centres constrained children; the banner should span the measure. */
.ca-page-hero > /* --- Page hero copy --------------------------------------------------------

   These rules were lost in an earlier edit that replaced a block of this file
   by position rather than by name — which is why the side-page headings had no
   size of their own and fell back to the base h1.
   -------------------------------------------------------------------------- */

/* The homepage hero centres its own contents; the eyebrow opts out. */
/*
 * Core's constrained layout caps every child of the hero group at the content
 * width. The banner is meant to span the whole measure, so it opts out.
 */
.ca-page-hero > .ca-page-hero__banner { max-width: none; }

.ca-hero { text-align: center; }

.ca-page-hero__copy { text-align: center; }

.ca-page-hero__title {
  font-family: var(--ca-font-display);
  font-size: clamp(30px, 5.6vw, 54px);
  font-weight: 800;
  letter-spacing: var(--ca-tracking-tighter);
  line-height: 1.02;
  color: var(--ca-ink);
  max-width: 20ch;
  margin: 0 auto;
  text-wrap: balance;
}
.ca-page-hero__title em { font-style: normal; color: var(--ca-orange-dark); }

.ca-page-hero__lede {
  max-width: 60ch;
  margin: 14px auto 0;
  color: var(--ca-muted);
  font-size: clamp(15px, 1.8vw, 18px);
  line-height: 1.55;
  text-wrap: balance;
}

/*
 * The banner is exactly its image, and nothing more.
 *
 * It was carrying a sand background and a minimum height so an empty banner
 * would not collapse in the editor — but both stayed once an image was added,
 * which is why the frame ran past the picture along the bottom. Those belong
 * only to the empty state, so they now live there.
 *
 * `display: flow-root` rather than the old `line-height: 0`: it contains the
 * figure's margins outright instead of relying on a text-sizing trick to hide
 * them, which is what left a sliver below the image.
 */
.ca-page-hero__banner {
  position: relative;
  isolation: isolate;
  display: flow-root;
  margin: 0 0 28px;
  border-radius: 26px;
  overflow: hidden;
  box-shadow: 0 20px 50px rgba(20, 25, 43, 0.14);
  font-size: 0;
}

/*
 * Zeroing every child's margin, at a specificity that beats core's block
 * layout — which puts a margin on each child after the first, and the image
 * is the second child once the pill is in there with it.
 */
.wp-block-group.ca-page-hero__banner > *,
.ca-page-hero__banner > .wp-block-image,
.ca-page-hero__banner > figure {
  margin-block: 0;
  margin-inline: 0;
}

/* The pill's own text must not inherit the zeroed font-size above. */
.ca-page-hero__banner > .ca-hero__eyebrow {
  font-size: var(--ca-text-pill);
  line-height: 1.4;
}

/* Kept so existing markup using it still resolves; the base already does this. */
.ca-hero__eyebrow--inline { position: static; }

/*
 * Pages saved before the banner became a wrapper have the pill as a sibling of
 * the image rather than a child. It cannot sit in a corner from there, so it
 * leads the copy instead — visible and correctly styled, just not overlaid.
 * Re-inserting the hero pattern moves it into the corner.
 */
/*
 * The pill in flow — before the script moves it, or where there is no image to
 * move it into. Even spacing on both axes, so it never looks half-placed.
 */
.ca-page-hero > .ca-hero__eyebrow {
  margin: 0 auto var(--ca-corner-inset) var(--ca-corner-inset);
}

/*
 * Core's image block inside the banner: the group is the frame, so the figure
 * should fill it rather than adding margins of its own.
 */
.ca-page-hero__banner > .wp-block-image,
.ca-page-hero__banner > figure { margin: 0; }.ca-page-hero__banner img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: inherit;
}

/*
 * A banner whose image has no source yet is not a corner to sit in, so the
 * pill returns to normal flow. :has() is not universal, which is why the
 * min-height above exists as well — between them the pill is correctly placed
 * in every browser, and merely differently placed in the oldest.
 */
/*
 * No image yet: a visible placeholder frame, with the pill back in normal flow
 * because there is no corner for it to sit in.
 */
.ca-page-hero__banner:not(:has(img[src])) {
  min-height: calc((var(--ca-corner-inset) * 2) + 46px);
  background: var(--ca-sand);
  font-size: var(--ca-text-md);
}

.ca-page-hero__banner:not(:has(img[src])) > .ca-hero__eyebrow {
  position: static;
  margin: 0 auto 16px var(--ca-corner-inset);
  max-width: 100%;
}


/* Same rule as the other two rails: one card centres, several scroll. */
.ca-promos__track.is-scrolling {
  /*
   * Wider cards cover more ground per item, so the seconds-per-item goes up to
   * match — otherwise widening the cards would silently speed the row up.
   * 538px of card and gap at 11s is the same pace as the review strip.
   */
  --ca-marquee-per-item: 11s;
  width: max-content;
  justify-content: flex-start;
  animation: ca-marquee calc(var(--ca-marquee-items, 6) * var(--ca-marquee-per-item)) linear infinite;
}
