/* Design tokens retargeted to the live Academy site + Available Classes palette (2026-07-28). */
:root {
  --and-emerald-900: #0f3a2e;
  --and-emerald-800: #1b4d3e;
  --and-emerald-700: #256d56;
  --and-gold: #c5a059;
  --and-gold-soft: #e7d3a3;
  --and-gold-pill-bg: #fff3d6;
  --and-gold-pill-fg: #8a6b1e;
  --and-cream: #f9f7f2;
  --and-ivory: #ffffff;
  --and-ink: #06140c;
  --and-muted: #535e57;
  --and-line: #e3ddcf;
  --and-error: #a23b1f;
  --and-shadow: 0 24px 70px rgba(15, 58, 46, 0.16);
  --and-font-heading: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --and-font-body: 'Source Sans 3', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  /* rc.3 layout tokens: maximum width of the centred content grid, and the
     minimum gutter that keeps that grid clear of the edge-anchored carousel
     arrows. Tightened per the operator-directed hero composition: text now
     starts 40-55px from the hero edge instead of ~100px. */
  --and-content-max: 1720px;
  /* rc.5: full-bleed outer hero, inset inner content. The roughly one-inch
     breathing room the operator wants lives INSIDE the hero as internal
     edge padding (about 80px at 1440, 96px on very wide desktops), not as
     an outer page gutter. */
  --and-edge-min: clamp(48px, 5.5vw, 96px);
}

.and-campaign-shell,
.and-campaign-shell * {
  box-sizing: border-box;
}

/*
 * rc.3: the hero and the announcement bar are the FULL-WIDTH homepage band,
 * not a card inside the page column. Whatever container the theme or page
 * builder puts the shortcode in, both elements break out to the viewport
 * width (the 50% - 50vw technique), which removes the cream side frame and
 * the boxed composition entirely. When the container already spans the
 * viewport the margins compute to 0 and this is a no-op. The one known
 * trade-off: on browsers with classic (non-overlay) scrollbars, 100vw
 * includes the scrollbar width; themes such as Astra clip that overflow at
 * the page level, and the Phase 2 staging gate must confirm it.
 */
.and-campaign-shell > .and-announcement,
.and-campaign-shell > .and-hero {
  width: 100vw;
  max-width: 100vw !important;
  margin-left: calc(50% - 50vw) !important;
  margin-right: calc(50% - 50vw) !important;
}

.and-campaign-shell {
  width: 100%;
  position: relative;
  isolation: isolate;
  color: var(--and-ink);
  font-family: var(--and-font-body);
}

/*
 * r4 announcement bar: refined gold-to-emerald gradient with a larger message and
 * a very restrained particle drift behind the text.
 *
 * The particles are two pseudo-element layers of tiny radial-gradient dots,
 * translated by exactly one background tile in each axis so the loop is seamless.
 * No JavaScript and no animation library. Transform-only, so it runs on the
 * compositor. Both layers are pointer-events: none and sit at z-index 0, beneath
 * the message, so they cannot interfere with clicking, selecting or reading.
 *
 * The gold end of the gradient is a deep antique gold rather than a bright one,
 * because cream text over bright gold would not hold contrast.
 */
/*
 * Footprint of the dismiss control, declared once on the component and consumed
 * by both the control and the message. The message reserves exactly this much
 * inline-end space, so text and link can never come to rest under the control's
 * hit area. Both values are used in two places; keeping them here is what stops
 * the reservation and the control from drifting apart, which is how the two
 * previously disagreed by 44px.
 *
 * The control's own padding is zeroed for the same reason the dots and the
 * play/pause toggle zero theirs: the site theme applies generous button padding
 * that otherwise inflates the rendered box beyond the declared width. Left
 * unreset it rendered 80px wide, which was an accident of the theme rather than
 * a design decision, and it is what the reservation failed to account for. The
 * control is square at 40x40, comfortably above the 24x24 target minimum.
 */
.and-announcement {
  --and-close-size: 40px;
  --and-close-inset: 10px;
  --and-close-clearance: calc(var(--and-close-inset) + var(--and-close-size) + 8px);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: linear-gradient(100deg, #7d621c 0%, #6a5a24 20%, var(--and-emerald-700) 60%, var(--and-emerald-900) 100%);
  color: var(--and-cream);
  border-bottom: 1px solid rgba(231, 211, 163, 0.6);
  font-family: var(--and-font-body);
}

.and-announcement::before,
.and-announcement::after {
  content: "";
  position: absolute;
  inset: -25% -15%;
  z-index: 0;
  pointer-events: none;
  background-repeat: repeat;
  will-change: transform;
}

.and-announcement::before {
  background-image:
    radial-gradient(circle at 12% 30%, rgba(255, 248, 225, 0.28) 0 1.6px, transparent 2.1px),
    radial-gradient(circle at 39% 71%, rgba(255, 248, 225, 0.20) 0 1.2px, transparent 1.7px),
    radial-gradient(circle at 64% 21%, rgba(255, 248, 225, 0.24) 0 1.5px, transparent 2px),
    radial-gradient(circle at 87% 63%, rgba(255, 248, 225, 0.18) 0 1.1px, transparent 1.6px);
  background-size: 190px 90px;
  animation: andParticleDriftA 52s linear infinite;
}

.and-announcement::after {
  background-image:
    radial-gradient(circle at 23% 57%, rgba(231, 211, 163, 0.20) 0 1.3px, transparent 1.9px),
    radial-gradient(circle at 56% 33%, rgba(231, 211, 163, 0.14) 0 1px, transparent 1.5px),
    radial-gradient(circle at 79% 77%, rgba(231, 211, 163, 0.18) 0 1.4px, transparent 2px);
  background-size: 260px 120px;
  animation: andParticleDriftB 74s linear infinite;
}

/* Exactly one tile in each axis, so the drift loops with no visible jump. */
@keyframes andParticleDriftA {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-190px, -90px, 0); }
}

@keyframes andParticleDriftB {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(260px, 120px, 0); }
}

.and-announcement[hidden] {
  display: none !important;
}

.and-announcement__inner {
  width: min(1400px, calc(100% - 32px));
  min-height: 54px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding-block: 11px;
  padding-inline: var(--and-close-clearance);
  position: relative;
  z-index: 1;
  text-align: center;
}

.and-announcement__icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--and-gold-soft);
}

.and-announcement__icon svg {
  width: 100%;
  height: 100%;
  display: block;
}

.and-announcement__message {
  font-size: clamp(1rem, 0.92rem + 0.35vw, 1.2rem);
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: 0.005em;
}

.and-announcement__link {
  color: #f6e6bd;
  font-size: clamp(0.98rem, 0.9rem + 0.32vw, 1.16rem);
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}

.and-announcement__link:hover,
.and-announcement__link:focus-visible {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.and-announcement__close {
  appearance: none;
  border: 0;
  background: transparent;
  color: inherit;
  /* Slightly larger glyph than before, so the mark stays prominent now that the
     box around it is square. Type size only; the hit area is unaffected. */
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
  position: absolute;
  inset-inline-end: var(--and-close-inset);
  top: 50%;
  transform: translateY(-50%);
  padding: 0;
  width: var(--and-close-size);
  height: var(--and-close-size);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
}

.and-announcement__close:hover,
.and-announcement__close:focus-visible {
  background: rgba(255, 255, 255, 0.13);
  outline: none;
}

.and-hero {
  width: 100%;
  position: relative;
  overflow: hidden;
  /* rc.3: a full-bleed band has no card radius. Overrides the r11 sheet's
     --and-radius without touching the token. */
  border-radius: 0;
  background:
    radial-gradient(circle at 15% 0%, rgba(197, 160, 89, 0.16), transparent 28%),
    radial-gradient(circle at 90% 90%, rgba(197, 160, 89, 0.10), transparent 28%),
    linear-gradient(135deg, var(--and-emerald-900) 0%, var(--and-emerald-700) 55%, var(--and-emerald-900) 100%);
  border-top: 1px solid rgba(197, 160, 89, 0.32);
  border-bottom: 1px solid rgba(197, 160, 89, 0.45);
  outline: none;
}

.and-hero:focus-visible {
  box-shadow: inset 0 0 0 3px var(--and-gold-soft);
}

/*
 * r4: the decorative diamond line-pattern is gone. It is replaced by a photograph
 * of an open mushaf, applied per slide in .and-hero__slide::after further down.
 *
 * The layer belongs to the slide, not to .and-hero, because the theme class sits
 * on the slide and CSS custom properties inherit downward only. Putting it on the
 * hero would make every theme resolve the same fallback value.
 */

.and-hero__slides {
  position: relative;
  z-index: 1;
}

.and-hero__slide {
  /* Default (unthemed) fallback; every real slide carries an explicit .and-theme-* class below. */
  --slide-copy: #fffaf0;
  --slide-muted: #dfe7e2;
  --slide-border: rgba(197, 160, 89, 0.55);
  --slide-chip: rgba(255, 255, 255, 0.08);
  width: min(1440px, calc(100% - 40px));
  min-height: 720px;
  position: relative;
  z-index: 0;
  margin: 0 auto;
  padding: clamp(36px, 5vw, 74px) clamp(24px, 5vw, 76px) 96px;
  display: none;
  grid-template-columns: minmax(0, 1fr) minmax(360px, 0.82fr);
  align-items: center;
  gap: clamp(36px, 6vw, 88px);
  color: var(--slide-copy);
}

.and-hero__slide.is-active {
  display: grid;
  /* rc.6: the legacy entrance animation is retired. It fought the r11
     opacity/visibility transitions on the same properties, and an
     interrupted hand-off during rapid manual navigation could strand a
     light slide's ivory panel painted above the active slide until the
     next slide change, which read as the hero "turning white". The r11
     transition alone provides the same crossfade and rise. */
}

/* ---- Theme families: one design system, five campaign-appropriate variations ---- */

/* Brothers' classes: deeper emerald, dark full-bleed panel. */
.and-theme-emerald-deep {
  --slide-copy: #fffaf0;
  --slide-muted: #dfe7e2;
  --slide-border: rgba(197, 160, 89, 0.55);
  --slide-chip: rgba(255, 255, 255, 0.08);
}

/* Sisters' class: warm cream/ivory card, soft emerald ink. */
.and-theme-cream-warm {
  --slide-copy: #16362b;
  --slide-muted: #5c6f66;
  --slide-border: rgba(197, 160, 89, 0.5);
  --slide-chip: rgba(27, 77, 62, 0.07);
}

/* The Gift of Arabic: elegant ivory card with a richer gold edge (the flagship slide). */
.and-theme-gift {
  --slide-copy: #16362b;
  --slide-muted: #565f56;
  --slide-border: rgba(197, 160, 89, 0.75);
  --slide-chip: var(--and-gold-pill-bg);
}

/*
 * 1.3.0: the old dark "editorial" theme block is removed. The r11 design
 * system defines and-theme-editorial as a LIGHT slide, and this dark-copy
 * block is what inverted Slide 4's palette on staging when both stylesheets
 * were loaded. No r11 slide uses the editorial token any more; removing the
 * block here makes the polarity conflict structurally impossible.
 */

/* Free resources: lighter, calmer, minimal gold. */
.and-theme-light {
  --slide-copy: #1c352c;
  --slide-muted: #5c6f66;
  --slide-border: rgba(197, 160, 89, 0.3);
  --slide-chip: rgba(27, 77, 62, 0.06);
}

.and-theme-cream-warm::before,
.and-theme-gift::before,
.and-theme-light::before {
  content: "";
  position: absolute;
  inset: 18px;
  z-index: -1;
  border-radius: 26px;
  box-shadow: var(--and-shadow);
}

.and-theme-cream-warm::before {
  background:
    radial-gradient(circle at 0% 0%, rgba(197, 160, 89, 0.14), transparent 26%),
    linear-gradient(135deg, #fffdf8, var(--and-cream));
  border: 1px solid rgba(197, 160, 89, 0.42);
}

.and-theme-gift::before {
  background:
    radial-gradient(circle at 0% 0%, rgba(197, 160, 89, 0.22), transparent 30%),
    linear-gradient(135deg, #fffefb, #fbf1de);
  border: 1px solid rgba(197, 160, 89, 0.75);
}

.and-theme-light::before {
  background: linear-gradient(135deg, #ffffff, var(--and-cream));
  border: 1px solid rgba(197, 160, 89, 0.22);
  box-shadow: 0 16px 40px rgba(15, 58, 46, 0.08);
}

.and-hero__copy {
  position: relative;
  z-index: 1;
  max-width: 680px;
}

.and-hero__eyebrow {
  margin: 0 0 16px;
  color: var(--and-gold-soft);
  font-size: clamp(0.82rem, 1.2vw, 1rem);
  font-weight: 700;
  letter-spacing: 0.13em;
  line-height: 1.45;
  text-transform: uppercase;
  font-family: var(--and-font-body);
}

.and-theme-cream-warm .and-hero__eyebrow,
.and-theme-gift .and-hero__eyebrow,
.and-theme-light .and-hero__eyebrow {
  color: var(--and-gold-pill-fg);
}

.and-hero__title {
  margin: 0;
  max-width: 760px;
  color: inherit;
  font-family: var(--and-font-heading);
  font-size: clamp(2.6rem, 5.2vw, 5.35rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.02;
  text-wrap: balance;
}

.and-hero__description {
  margin: 24px 0 0;
  max-width: 660px;
  color: var(--slide-muted);
  font-size: clamp(1rem, 1.45vw, 1.22rem);
  line-height: 1.72;
  font-family: var(--and-font-body);
}

/*
 * r5: the rounded pill chips are replaced by a single grouped information card.
 * One translucent panel with hairline separators reads as one unit of supporting
 * detail rather than a scatter of tags, and keeps the two CTA buttons as the only
 * things that look clickable.
 *
 * The PHP markup is unchanged: still the same <ul class="and-hero__details"> that
 * the settings screen fills one item per line, so no content, setting or contract
 * moves. Restyling only.
 */
.and-hero__details {
  list-style: none;
  margin: 20px 0 0;
  padding: 2px 16px;
  display: grid;
  gap: 0;
  max-width: 33rem;
  border: 1px solid var(--slide-border);
  border-radius: 14px;
  background: var(--slide-chip);
}

.and-hero__details li {
  margin: 0;
  padding: 10px 0 10px 26px;
  position: relative;
  border-top: 1px solid var(--slide-border);
  color: inherit;
  font-size: 0.96rem;
  font-weight: 500;
  line-height: 1.5;
}

.and-hero__details li:first-child {
  border-top: 0;
}

/* Restrained gold marker, drawn in CSS so no icon font or extra asset is needed. */
.and-hero__details li::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 50%;
  width: 7px;
  height: 7px;
  margin-top: -3.5px;
  transform: rotate(45deg);
  background: var(--and-gold);
  border-radius: 1px;
}

.and-hero__actions {
  margin-top: 32px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.and-button {
  min-height: 50px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 13px 22px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 0.98rem;
  font-weight: 700;
  font-family: var(--and-font-body);
  line-height: 1.2;
  text-align: center;
  text-decoration: none !important;
  transition: transform 180ms ease, box-shadow 180ms ease, background-color 180ms ease, color 180ms ease;
}

.and-button:hover,
.and-button:focus-visible {
  transform: translateY(-2px);
  outline: none;
}

.and-button--primary {
  background: linear-gradient(180deg, var(--and-gold-soft), var(--and-gold));
  color: var(--and-emerald-900) !important;
  border-color: rgba(255, 246, 207, 0.9);
  box-shadow: 0 10px 24px rgba(15, 58, 46, 0.24);
}

.and-button--primary:hover,
.and-button--primary:focus-visible {
  background: linear-gradient(180deg, color-mix(in srgb, var(--and-gold-soft) 100%, white 10%), color-mix(in srgb, var(--and-gold) 100%, black 8%));
  box-shadow: 0 14px 28px rgba(15, 58, 46, 0.3);
}

.and-button--secondary {
  background: transparent;
  color: inherit !important;
  border-color: var(--slide-border);
}

.and-button--secondary:hover,
.and-button--secondary:focus-visible {
  background: var(--slide-chip);
}

.and-hero__media {
  height: min(72vh, 700px);
  min-height: 560px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.and-hero__media::before {
  content: "";
  position: absolute;
  width: 85%;
  height: 82%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(197, 160, 89, 0.3), transparent 68%);
  filter: blur(8px);
}

.and-hero__media img {
  display: block;
  width: auto;
  max-width: 100%;
  max-height: 100%;
  position: relative;
  z-index: 1;
  border-radius: 18px;
  border: 1px solid rgba(241, 215, 147, 0.7);
  box-shadow: 0 26px 68px rgba(0, 26, 20, 0.34), 0 4px 14px rgba(0, 0, 0, 0.12);
}

.and-hero__controls {
  position: absolute;
  left: 50%;
  bottom: 24px;
  z-index: 4;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px;
  border: 1px solid rgba(197, 160, 89, 0.5);
  border-radius: 999px;
  background: rgba(15, 58, 46, 0.82);
  box-shadow: 0 10px 28px rgba(6, 20, 12, 0.28);
  backdrop-filter: blur(12px);
}

.and-hero__arrow,
.and-hero__dot {
  appearance: none;
  border: 0;
  cursor: pointer;
}

.and-hero__arrow {
  width: 38px;
  height: 38px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.09);
  color: #fffaf0;
  font-size: 1.75rem;
  line-height: 1;
}

.and-hero__arrow:hover,
.and-hero__arrow:focus-visible {
  background: rgba(255, 255, 255, 0.16);
  outline: 2px solid rgba(244, 216, 135, 0.9);
  outline-offset: 2px;
}

.and-hero__nav {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/*
 * Icon-only autoplay toggle. Sized to the dot capsule, never the old wide pill.
 * It sits beside the numbered controls rather than inside them, because the dots
 * container is a role="tablist" and a button is not a valid child of one.
 */
/*
 * 32x32 interactive target for comfortable tapping and to clear the 24x24
 * minimum with margin, while the glyph inside stays small so the control reads
 * as part of the navigation rather than competing with the slide.
 */
.and-hero__toggle {
  appearance: none;
  width: 32px;
  height: 32px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(197, 160, 89, 0.38);
  border-radius: 999px;
  background: rgba(15, 58, 46, 0.55);
  color: var(--and-gold-soft);
  font-size: 0.66rem;
  line-height: 1;
  cursor: pointer;
}

.and-hero__toggle:hover {
  background: rgba(15, 58, 46, 0.75);
}

.and-hero__toggle:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

.and-hero__dots {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 3px;
}

.and-hero__dot {
  width: 9px;
  height: 9px;
  padding: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.42);
  transition: width 180ms ease, background-color 180ms ease;
}

.and-hero__dot.is-active {
  width: 28px;
  background: var(--and-gold-soft);
}

.and-hero__dot:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

.and-hero-empty {
  padding: 24px;
  text-align: center;
}

@media (max-width: 980px) {
  .and-hero__slide {
    width: min(920px, calc(100% - 28px));
    min-height: 0;
    grid-template-columns: 1fr;
    gap: 28px;
    padding: 30px 20px 90px;
  }

  .and-theme-cream-warm::before,
  .and-theme-gift::before,
  .and-theme-light::before {
    inset: 12px;
  }

  .and-hero__media {
    grid-row: 1;
    height: auto;
    min-height: 0;
    max-width: 560px;
    width: 100%;
    margin: 0 auto;
  }

  .and-hero__media img {
    width: 100%;
    max-height: none;
  }

  .and-hero__copy {
    grid-row: 2;
    max-width: 720px;
    margin: 0 auto;
    text-align: center;
  }

  .and-hero__details,
  .and-hero__actions {
    justify-content: center;
  }
}

@media (max-width: 640px) {
  .and-announcement__inner {
    width: calc(100% - 18px);
    justify-content: flex-start;
    align-items: flex-start;
    flex-direction: column;
    gap: 4px;
    padding-block: 9px;
    /* Column layout is start-aligned, so only the inline-end side needs the
       control's clearance; mirroring it would waste scarce width on phones. */
    padding-inline: 4px var(--and-close-clearance);
    text-align: left;
  }

  .and-announcement__message {
    font-size: 0.85rem;
  }

  .and-announcement__link {
    font-size: 0.84rem;
  }

  .and-hero__slide {
    width: 100%;
    padding: 18px 15px 86px;
  }

  .and-theme-cream-warm::before,
  .and-theme-gift::before,
  .and-theme-light::before {
    inset: 8px;
    border-radius: 18px;
  }

  .and-hero__media {
    max-width: 460px;
  }

  .and-hero__media img {
    border-radius: 13px;
  }

  .and-hero__copy {
    padding: 0 7px;
  }

  .and-hero__title {
    font-size: clamp(2.15rem, 11vw, 3.5rem);
    line-height: 1.02;
  }

  .and-hero__description {
    margin-top: 18px;
    font-size: 0.98rem;
    line-height: 1.62;
  }

  .and-hero__details {
    margin-top: 22px;
    display: grid;
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .and-hero__details li {
    border-radius: 13px;
    font-size: 0.88rem;
  }

  .and-hero__actions {
    margin-top: 24px;
    display: grid;
    grid-template-columns: 1fr;
  }

  .and-button {
    width: 100%;
  }

  .and-hero__controls {
    bottom: 17px;
    max-width: calc(100% - 20px);
  }

  /*
   * The theme injects padding: 0 40px onto these buttons, which inflates each arrow from
   * its declared 38px to a used width of 80px. The controls bar then exceeds its
   * max-width, and because every flex child defaults to flex-shrink: 1 the Pause button
   * absorbs the whole deficit: it measured 19px wide at 375px and 8.4px at 320px, below
   * the 24px minimum target. Resetting that padding recovers 84px and pins both the
   * arrows and Pause at a usable 38x38, with the Pause icon and aria-label intact.
   * Total at 320px: 14 padding + 30 gaps + 38 + 130 dots + 38 + 38 = 288, inside the
   * 300px budget, so the dots never need to shrink and all seven remain intact.
   */
  .and-hero__arrow {
    width: 38px;
    padding: 0;
    flex: 0 0 38px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .and-hero__slide.is-active,
  .and-button,
  .and-hero__dot {
    animation: none;
    transition: none;
  }

  /* Particle drift stops entirely; the dots remain as a static texture. */
  .and-announcement::before,
  .and-announcement::after {
    animation: none;
  }
}

/* =============================================================================
   DESIGN REVISION r2. Full-bleed carousel shell with a centred content grid.

   Scope: DESKTOP ONLY, min-width 981px. Every rule below sits inside that one
   media query, so 980px and below remains byte-identical in behaviour to the
   tested staging baseline: the Gift stays in normal document flow, the Pause
   control stays 38x38, and the verified zero-overlap result is untouched.

   Layout model: the slide is full-bleed and centres its own content by using
   padding-inline: max(gutter, (100% - content-max) / 2). The gutter never drops
   below --and-edge-min, which is what keeps the content grid clear of the
   edge-anchored Previous and Next arrows.
   ============================================================================= */
@media (min-width: 981px) {

  /* ---- 1. Full-bleed slide, centred internal grid ---- */
  .and-hero__slide {
    width: 100%;
    max-width: none;
    margin: 0;
    min-height: clamp(460px, 32vw, 580px);
    /* rc.3: tighter vertical rhythm for the ~700-780px desktop hero target,
       while the bottom reservation still clears the centred dot navigation. */
    padding-block: clamp(16px, 1.2vw, 24px) clamp(64px, 4.6vw, 76px);
    padding-inline: max(var(--and-edge-min), calc((100% - var(--and-content-max)) / 2));
    /* Explicit content and media columns with a hard gap floor, so artwork
       (including the fanned groups' deliberate spread) can never reach the
       headline or body copy. */
    grid-template-columns: minmax(0, 0.94fr) minmax(380px, 1.06fr);
    gap: clamp(40px, 3.2vw, 72px);
  }

  /* The themed panels become full-bleed too, so no slide reads as a boxed card.
     Theme colour and border treatment are retained; only the inset box is removed. */
  .and-theme-cream-warm::before,
  .and-theme-gift::before,
  .and-theme-light::before {
    inset: 0;
    border-radius: 0;
    border-left: 0;
    border-right: 0;
  }

  /* The editorial title keeps its full display scale. Height is recovered from the
     artwork and the vertical rhythm instead, per the approved direction. The copy
     column is widened so that scale sets on fewer lines without being shrunk. */
  .and-hero__copy { max-width: 820px; }
  .and-hero__eyebrow { margin-bottom: 10px; }
  .and-hero__description { margin-top: 14px; }
  .and-hero__details { margin-top: 16px; }
  .and-hero__actions { margin-top: 18px; }

  .and-hero__media {
    height: clamp(360px, 30vw, 520px);
    min-height: 0;
  }

  /* ---- 2. Controls become a transparent full-hero layer ----
     The markup keeps Previous, dots, Pause and Next in one container. Turning
     that container into a non-interactive overlay lets each control be placed
     independently without any PHP or markup change. */
  .and-hero__controls {
    inset: 0;
    width: 100%;
    max-width: none;
    transform: none;
    display: block;
    padding: 0;
    gap: 0;
    border: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
    backdrop-filter: none;
    pointer-events: none;
    z-index: 4;
  }

  .and-hero__controls > * { pointer-events: auto; }

  /* ---- 3. Arrows near the outer edges, vertically centred ---- */
  .and-hero__arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 36px;
    height: 36px;
    padding: 0;
    flex: none;
    font-size: 1.4rem;
    border: 1px solid rgba(197, 160, 89, 0.55);
    background: rgba(9, 40, 31, 0.5);
    backdrop-filter: blur(8px);
  }

  .and-hero__controls [data-and-prev] { left: clamp(7px, 0.8vw, 13px); }
  .and-hero__controls [data-and-next] { right: clamp(7px, 0.8vw, 13px); }

  /* ---- 4. Numbered navigation centred near the bottom ---- */
  .and-hero__nav {
    position: absolute;
    left: 50%;
    bottom: clamp(30px, 2.6vw, 42px);
    transform: translateX(-50%);
  }

  .and-hero__nav .and-hero__dots {
    position: static;
    transform: none;
  }

  .and-hero__dots {
    position: absolute;
    left: 50%;
    bottom: clamp(30px, 2.6vw, 42px);
    transform: translateX(-50%);
    padding: 0;
    gap: 10px;
  }

  /* rc.3: the pause/play control sits just right of the dot cluster. In the
     overlay-controls model it previously had no desktop placement and
     rendered stranded at the hero's top-left corner. */
  .and-hero__controls .and-hero__toggle {
    position: absolute;
    left: 50%;
    bottom: clamp(32px, 2.7vw, 44px);
    margin-left: 122px;
  }

}

/* =============================================================================
   r2 follow-ups required by the full-bleed light themes.

   Removing the inset card means the cream, gift and light themes now paint the
   full carousel width. Two consequences had to be handled so those themes stay
   as readable as the dark ones.
   ============================================================================= */

/* 1. The numbered navigation sits OUTSIDE the slide in the markup, so it cannot be
      styled per theme with a descendant selector. Giving the dot cluster its own
      dark, translucent backdrop keeps the dots legible on a cream panel and on a
      deep emerald one alike, instead of white dots vanishing on ivory. */
.and-hero__dots {
  border: 1px solid rgba(197, 160, 89, 0.34);
  border-radius: 999px;
  background: rgba(9, 40, 31, 0.42);
  backdrop-filter: blur(8px);
}

@media (min-width: 981px) {
  .and-hero__dots { padding: 9px 15px; }
}

@media (max-width: 980px) {
  /* Inside the existing control bar the backdrop would double up, so it is removed. */
  .and-hero__dots {
    border: 0;
    background: none;
    backdrop-filter: none;
  }
}

/* 2. At full-bleed scale a flat panel reads as cheap, and the diamond texture on
      .and-hero is painted underneath the slide so the light themes lost it. Each
      light theme keeps its own gradient identity and regains a matching texture at
      a weight suited to a light ground. */
/*
 * Every slide shares one photograph. Only its strength changes per theme, so the
 * texture reads consistently while dark and light panels both stay readable.
 * The file itself is never washed out; faintness is opacity only, so the level can
 * be retuned here without touching the image.
 *
 * The layer paints above the light themes' ivory panel (::before, z-index -1) and
 * below the slide's real content, because ::after paints after ::before at the
 * same z-index inside the slide's stacking context.
 */
.and-hero__slide::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: var(--and-bg-opacity, 0.10);
  background-image: url("../images/quran-background.webp");
  background-size: cover;
  background-position: center 42%;
  background-repeat: no-repeat;
}

/*
 * Levels chosen by measuring luminance standard deviation in a content-free patch
 * of each theme, not by eye:
 *   deep panels  flat ground sd 4.13  ->  0.12 gives sd ~5.0
 *   pale panels  flat ground sd 0.62  ->  0.06 gives sd ~1.9, about 3x the flat
 * These are the faintest settings at which the script still reads as texture.
 */
.and-theme-emerald-deep {
  --and-bg-opacity: 0.09;
}

.and-theme-cream-warm,
.and-theme-gift,
.and-theme-light {
  --and-bg-opacity: 0.045;
}

/* =============================================================================
   r2 final refinements. Both are desktop-scoped; nothing at 980px and below is
   touched, so the approved tablet and mobile presentation is unchanged.
   ============================================================================= */

/* --- 1. Wide-desktop artwork scale -------------------------------------------
   The flyer becomes a stronger anchor and fills the right column instead of
   leaving dead space. Two segments rather than one clamp, so 1280 keeps its
   current scale and there is no visible jump at the breakpoint:
     1281-1439  interpolates 311px -> 449px
     1440+      interpolates 450px -> 480px, capped
   Total hero height is unaffected because the copy column, not the artwork, is
   the taller of the two at these widths. Verified, not assumed. */
@media (min-width: 1281px) and (max-width: 1439px) {
  .and-hero__media { height: clamp(420px, calc(100vw - 900px), 600px); }
}

@media (min-width: 1440px) {
  .and-hero__media { height: clamp(600px, calc(11vw + 450px), 650px); }
}

/* --- 2. Dot navigation -------------------------------------------------------
   Backdrop moves from a gray-green to a translucent deep emerald drawn from the
   palette (--and-emerald-900). The active indicator is warm cream-gold; inactive
   dots stay understated.

   Interactive target: the dots were 9x9 CSS pixels, well under the 24x24 minimum,
   which the original Checkpoint 12C accessibility pass flagged. Each control is
   now a genuine 24x24 target with the small visual dot drawn by a pseudo-element,
   so the understated look is preserved while the hit area is compliant.

   Desktop only. Inside the compact mobile control bar a 24px dot would push the
   cluster past the 300px budget at 320px and undo the verified Pause fix, so the
   mobile bar is deliberately left exactly as approved. */
@media (min-width: 981px) {
  .and-hero__dots {
    padding: 8px 12px;
    gap: 4px;
    border: 1px solid rgba(197, 160, 89, 0.38);
    background: rgba(15, 58, 46, 0.55);
  }

  .and-hero__dot {
    width: 24px;
    height: 24px;
    padding: 0;
    background: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: width 180ms ease;
  }

  .and-hero__dot::before {
    content: "";
    display: block;
    width: 8px;
    height: 8px;
    border-radius: 999px;
    background: rgba(247, 241, 227, 0.45);
    transition: width 180ms ease, background-color 180ms ease;
  }

  .and-hero__dot:hover::before {
    background: rgba(247, 241, 227, 0.72);
  }

  .and-hero__dot.is-active {
    width: 38px;
    background: none;
  }

  .and-hero__dot.is-active::before {
    width: 24px;
    background: var(--and-gold-soft);
  }
}

/* Clearance between the enlarged artwork and the Gift is governed by the bottom
   reservation minus the Gift's own footprint, on slides where the artwork is the
   taller column. At bottom:38px the Gift occupied 91px of a 94px reservation,
   leaving 3px. Seating the Gift closer to the shell edge restores ~20-26px at
   every desktop width, without shrinking the artwork, without changing the
   centred composition, and without adding any hero height. */

/* =============================================================================
   r2 accessibility completion: numbered-dot targets at tablet and mobile.

   The dots were 9x9 CSS pixels inside the compact control bar, well under the
   24x24 minimum. The visual dot is preserved at 9px and drawn by a pseudo-element
   inside a genuine 24x24 transparent button, so nothing about the understated
   look changes while the hit area becomes compliant.

   Budget check at 320px, the tightest case. Control bar contents:
     prev 38 + dots (7 x 24 = 168) + pause 38 + next 38 = 282
     + 3 gaps x 3px = 9,  + padding 5px x 2 = 10   ->  301px
   Available: calc(100% - 8px) = 312px. Fits in one row with 11px to spare, so
   the two-row fallback is not needed and Previous, Pause and Next all keep 38x38.
   Adjacent 24px targets sit flush, which is permitted and keeps the cluster tight.
   ============================================================================= */
@media (max-width: 980px) {
  .and-hero__dots {
    gap: 0;
    padding: 0;
  }

  .and-hero__dot {
    width: 24px;
    height: 24px;
    padding: 0;
    background: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 24px;
  }

  .and-hero__dot::before {
    content: "";
    display: block;
    width: 9px;
    height: 9px;
    border-radius: 999px;
    background: rgba(247, 241, 227, 0.45);
    transition: width 180ms ease, background-color 180ms ease;
  }

  .and-hero__dot.is-active {
    width: 24px;
    background: none;
  }

  .and-hero__dot.is-active::before {
    width: 18px;
    background: var(--and-gold-soft);
  }
}

/* Rebalanced spacing so the wider dot cluster still fits one row at 320px
   without shrinking Previous, Pause or Next below 38x38. */
@media (max-width: 640px) {
  .and-hero__controls {
    max-width: calc(100% - 8px);
    padding: 5px;
    gap: 3px;
  }
}

/* =============================================================================
   r3: desktop carousel height stability.

   Measured on live staging: because only the active slide was laid out
   (display: none on the rest), the shell's height tracked whichever slide was
   showing. Switching between slide 1 (604px) and slides 2 or 7 (715px) moved
   "Share Your Reflections" and everything below it by 111px at 1672 and 98px at
   1440, on every transition.

   Fix: at desktop, stack all slides in a single grid cell so the container is
   always as tall as the tallest slide, and hide the inactive ones with
   visibility rather than display. The height then comes from the real content of
   the tallest approved slide at whatever the current viewport is, with no
   hard-coded number to drift out of date, and it self-corrects if copy changes.

   Nothing is shrunk: headline, artwork, chips and description are untouched.
   visibility: hidden also keeps inactive slides out of the accessibility tree and
   out of the tab order, which display: none did previously.

   Desktop only. At 980px and below slides keep display:none and stack normally,
   so the approved mobile presentation is unchanged.
   ============================================================================= */
/*
 * 1.3.0-rc.2: the stacking model now applies at EVERY width, not just
 * desktop. Below 981px the earlier display:none fallback let the carousel
 * resize to each active slide (measured 388-431px of variance across
 * breakpoints), producing a page-layout jump on every 4-second rotation.
 * With all seven slides sharing one grid cell at all widths, the carousel
 * always reserves the tallest slide's height; inactive slides stay
 * invisible, untabbable and out of the accessibility tree through
 * visibility/opacity/pointer-events exactly as on desktop.
 */
.and-hero__slides {
  display: grid;
}

.and-hero__slide {
  grid-area: 1 / 1;
  display: grid;
  /* Rows pack together, centred in the reserved (tallest-slide) cell, so a
     shorter slide reads as a centred composition rather than content pinned
     to the cell's edges. On the single-row desktop grid this is visually
     identical to the previous stretch behaviour. */
  align-content: center;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

.and-hero__slide.is-active {
  /* rc.6: the active slide always paints above every inactive slide, so
     no mid-transition or stuck state on another slide can ever cover it. */
  z-index: 3;
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
}
