/* =========================================================
   Eternal Tales unified card pattern
   Reference build: AC-v3/sandbox/aoos-text-card-060526.html v30
   LOCKED. See project_text_card_framing.md for the full pattern.
   Used by AOoS / BtM / VotF. TEotE diverges (parallax stage).

   Ported into v4 production 08.05.26 per
   project_v4_production_build_plan step 2. Replaces the per-section
   .aoos-card / .btm-card / .votf-card classes; the matching
   per-section CSS files become orphan-rule-only and are cleaned up
   in step 3 of the v4 plan.
   ========================================================= */

/* =========================================================
   Outer card glass.
   23.05.26 v2: cap back to 900px - per user, ALL cards (intro + AOoS /
   BtM / VotF + Get in Touch + the continues panel) read at 900px. The
   intro's earlier 720 override is removed so it uses this base too.
   --vp-aspect interpolates 0 at 320 viewport width to 1 at 1000,
   then locks at 1. Drives image aspect-ratio, image
   object-position, and title font-size as a single curve.
   v30: cream cap raised here from 77ch on .et-card__prose to
   100% so body padding is the only horizontal text constraint.
   ========================================================= */
.et-card {
  position: relative;
  max-width: clamp(280px, 92vw, 900px);
  margin: 0 auto;
  --vp-aspect: clamp(0, calc((100vw - 320px) / 680px), 1);
  /* 19.05.26 (pm): +5px top padding per user direction so title /
     breadcrumb / all content shifts down by 5px. Applies to all four
     cards (intro + AOoS + BtM + VotF). */
  padding: 5px 0 0;
  border-radius: var(--radius-lg);
  /* 18.05.26 (revised x5): the 3 tale cards (AOoS / BtM / VotF) are
     now FULLY white per user direction. The dark-glass top from the
     previous design is gone; only the .et-card--intro variant keeps
     dark glass (override below). Local CSS-var overrides flip the
     inherited dark-theme tokens from the data-theme="dark" section
     to light values so all descendant text reads as dark ink on the
     white page. */
  --bg:           #FFFFFF;
  --primary-text: #0F1419;
  --soft-text:    #5E7780;
  --quiet-text:   #7B8E94;
  background: var(--bg);
  color: var(--primary-text);
  /* 23.05.26: drop-shadow removed per user - the four text cards
     (intro + AOoS + BtM + VotF) now sit flat on the page rather than
     lifting off it. */
  box-shadow: none;
  overflow: hidden;
}

/* Grain on the whole card (was on .et-card__bottom::before; moved
   up so the paper texture covers the full white card surface). */
.et-card::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 400'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='3.5' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.55  0 0 0 0 0.45  0 0 0 0 0.30  0 0 0 0.5 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  background-size: 400px 400px;
  opacity: 0.08;
}
/* Lift card content above the grain pseudo (replaces the
   .et-card__bottom > *:not(...) rule from the prior design). */
.et-card > * {
  position: relative;
  z-index: 1;
}

/* =========================================================
   Breadcrumb scoped to the card header.
   Overrides shell.css's centred page-bc with a smaller fluid
   type that sits on the right of the card header. The pipe
   separator (|) is in the v30 sandbox HTML; shell.css's middle
   dot is being superseded across the v4 build (see plan step 4).
   ========================================================= */
.et-card .bc {
  margin: 0;
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 10px;
  font-family: var(--font-serif);
  font-size: clamp(11px, 0.55vw + 9px, 14px);
  letter-spacing: 0.02em;
  /* 18.05.26 (revised x6): bc inherits dark primary-text on the new
     white card. EXPLICITLY `text-shadow: none` to override shell.css's
     `.bc { text-shadow: 0 1px 6px rgba(0,0,0,0.85) }` (which sits at
     lower specificity but still applies if we just remove our own
     declaration). text-shadow is an inherited property so this also
     cascades to .bc__from / __to / __sep children. */
  color: var(--primary-text);
  text-shadow: none;
  white-space: nowrap;
  text-align: right;
}
/* 18.05.26: shell.css's .bc__from / .bc__to / .bc__sep rules have
   their own colour declarations (--quiet-text / --soft-text) which
   override the parent .bc colour via specificity ties + child color
   declarations. Re-assert white inside .et-card scope. */
.et-card .bc .bc__from,
.et-card .bc .bc__to,
.et-card .bc .bc__sep {
  color: var(--primary-text);
}

@media (max-width: 519.98px) {
  .et-card__header .bc {
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
  }
  .et-card__header .bc .bc__sep {
    display: none;
  }
}

/* =========================================================
   Header zone above the image.
   Title (left) and bc (right) sit on a shared vertical midline
   of the header zone. The header is part of the card's own
   glass extending above the image, not a separate layer.
   ========================================================= */
.et-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(12px, 2vw, 24px);
  padding: clamp(14px, 2vw, 22px) clamp(20px, 4vw, 40px);
}

/* 19.05.26: when the header is immediately followed by a subtitle,
   pull the title down by tightening the header's bottom padding so
   the subtitle reads as a sibling of the title rather than as a new
   block separated by header rhythm. Subtitle itself keeps
   padding-top: 0 (see .et-card__subtitle). */
.et-card__header:has(+ .et-card__subtitle) {
  padding-bottom: clamp(4px, 0.6vw, 8px);
}

.et-card__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  /* 19.05.26 (pm): title size 20% smaller per user (was
     calc(26px + 16px * var(--vp-aspect))) and colour flipped to
     primary-text (dark ink on the white card body, was soft-text). */
  font-size: calc(21px + 13px * var(--vp-aspect));
  line-height: 1.05;
  letter-spacing: -0.005em;
  color: var(--primary-text);
  text-align: left;
}

/* v30: heading wrapper - allows title + series-line to stack on
   the left of the header while bc remains on the right. BtM uses
   this; AOoS / VotF can omit and place title directly. */
.et-card__heading {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

/* v30: series-line under the title (BtM uses for "Seven Stories
   from the Deep Past of Ireland"). */
.et-card__series-line {
  margin: 0;
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(12px, 0.4vw + 11px, 15px);
  line-height: 1.3;
  letter-spacing: 0.01em;
  /* 18.05.26: series-line flipped to primary-text (white on dark
     theme). Sits on the dark glass top of the card. */
  color: var(--primary-text);
  text-align: left;
}

/* Left-aligned italic tagline (19.05.26 revised x2): sits directly
   under the title with a one line-height gap, indented to the same
   left edge as the title (so it visually reads as a sub-headline
   under the h2 rather than a standalone centred line). Font-size
   reverted to the original size; the +20% bump from the morning
   was retired per user. */
.et-card__subtitle {
  margin: 0;
  padding: 0 clamp(20px, 4vw, 40px) clamp(16px, 2vw, 28px);
  font-family: var(--font-display);
  /* 18.05.26 (pm): italic removed per user. The subtitle now reads
     as a roman display line under the title, not as a stylised
     tag-line. */
  font-style: normal;
  font-weight: 500;
  font-size: clamp(14px, 1.6vw, 20px);
  line-height: 1.4;
  color: var(--soft-text);
  text-align: left;
}

/* 19.05.26 (pm): BtM subtitle dropped its bottom padding because
   the subtitle then sat directly above the intro body prose, and
   the standard clamp read as an extra line-break there.
   06.07.26 (late v9): override REMOVED - the card now opens with
   the cover artwork directly under the subtitle, so with
   padding-bottom: 0 the subtitle sat right on the image edge, per
   user. It inherits the base .et-card__subtitle bottom padding
   again, matching the AOoS/VotF subtitle-to-artwork gap. */

/* =========================================================
   Image stage.
   aspect-ratio interpolates 3:4 portrait at 320 to 3:2
   landscape at 1000+ via --vp-aspect; object-position pans
   from right anchor at 320 (book-cover composition) to centre
   at 1000+ (full landscape revealed). Source artwork should
   be the full landscape master so cropping is non-destructive.
   ========================================================= */
.et-card__media {
  margin: 0;
  position: relative;
  width: 100%;
  /* Stepped fallback first (used by browsers that can't parse calc()
     inside aspect-ratio, e.g. Honor / Huawei stock browser). The
     calc() form below overrides this on capable browsers and gives
     the smooth 320 -> 1000 transition. */
  aspect-ratio: 3 / 4;
  aspect-ratio: calc(0.75 + 0.75 * var(--vp-aspect));
  overflow: hidden;
  border-radius: 0;
  /* 18.05.26 (revised x3): background flipped to transparent. The
     earlier "black band" between image and white-bottom was caused
     by margin-collapse on the .btm-eras ul (a first-child margin-top
     escaping out of .et-card__bottom and revealing the .et-card's
     own dark-glass background); that fix moved the 12px clearance
     to padding-top on the ul instead. With the band root cause
     addressed, the figure no longer needs a defensive white
     background, and transparent lets VotF's intentional gaps
     between the main image and the 4-image stack show the card's
     glass effect (dark .et-card backdrop-filter + chamber behind)
     instead of a hard white panel. box-shadow: var(--shadow-lift)
     stays removed (it projected onto the white bottom as a hard
     band when the bottom flipped from cream to pure white). */
  background: transparent;
  /* Safety net: even if aspect-ratio fails entirely, the figure can
     never stretch taller than the viewport. Prevents the extreme
     y-axis stretch reported on Android Honor (10.05.26). */
  max-height: 100vh;
}
@media (min-width: 576px) {
  .et-card__media {
    aspect-ratio: 1 / 1;
    aspect-ratio: calc(0.75 + 0.75 * var(--vp-aspect));
  }
}
@media (min-width: 768px) {
  .et-card__media {
    aspect-ratio: 5 / 4;
    aspect-ratio: calc(0.75 + 0.75 * var(--vp-aspect));
  }
}
@media (min-width: 1000px) {
  .et-card__media {
    aspect-ratio: 3 / 2;
    aspect-ratio: calc(0.75 + 0.75 * var(--vp-aspect));
  }
}

/* 09.05.26: <picture> defaults to display: inline in every UA, which
   leaves no block-level containing block for the img's height: 100%
   to resolve against. At narrow viewports the img falls back to its
   intrinsic aspect and renders shorter than the figure, producing a
   navy gap below the image (and pushing BtM era icons below the
   image's visible bottom). Forcing picture to display: block + 100%
   width + 100% height gives the img a definite-height parent so its
   height: 100% resolves against the figure's aspect-ratio-derived
   height. The v30 sandbox already had this fix scoped to
   .et-card--votf .votf-stack picture; this generalises it. */
.et-card__media picture {
  display: block;
  width: 100%;
  height: 100%;
}

.et-card__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Stepped object-position fallback (right-anchored at narrow,
     centred at desktop). Calc form below overrides on capable
     browsers for smooth pan from right anchor to centre. */
  object-position: 100% center;
  object-position: calc(100% - 50% * var(--vp-aspect)) center;
}
@media (min-width: 1000px) {
  .et-card__image {
    object-position: 50% center;
    object-position: calc(100% - 50% * var(--vp-aspect)) center;
  }
}

/* =========================================================
   Meta row + credit.
   Sits below the image, centred. Underline on links is a 1px
   border-bottom rather than text-decoration so vertical rhythm
   is preserved.
   ========================================================= */
/* Artist credit (18.05.26 revised x6): flipped to top-left and
   inset to match the body prose's left padding so the credit
   left-edge aligns with the body text boundary below it. nowrap
   removed - the VotF combined credit needs to wrap on narrow
   viewports. */
.et-card__meta {
  position: absolute;
  top: 12px;
  left: clamp(24px, 4.2vw, 46px);
  right: clamp(24px, 4.2vw, 46px);
  margin: 0;
  padding: 0;
  z-index: 2;
}

.et-card__credit {
  margin: 0;
  padding: 0;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(11px, 0.3vw + 10px, 12px);
  line-height: 1.5;
  color: var(--quiet-text);
  text-align: left;
}

.et-card__credit a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid rgba(190, 183, 170, 0.25);
  transition: color 150ms ease, border-color 150ms ease;
}
.et-card__credit a:hover {
  color: var(--accent-tint);
  border-bottom-color: var(--accent);
}

/* =========================================================
   Body panel (verse + prose).
   v30: horizontal padding pulled in close to header bounds so
   the prose reads at almost the same horizontal extent as the
   title (left) and bc (right), with only a slight indent.
   .et-card__prose max-width is 100% so body padding is the only
   horizontal constraint (was 77ch pre-v30).
   .et-card__verse retained for any future use; current canon
   does not use it (AOoS verse opener removed at v30).
   ========================================================= */
.et-card__body {
  padding: clamp(12px, 1.6vw, 20px) clamp(24px, 4.2vw, 46px) clamp(18px, 2.4vw, 32px);
  /* 18.05.26: body / verse / prose flipped to primary-text. Resolves
     to white on the dark glass top (dark theme), and to #0F1419
     (darker) inside .et-card__bottom (which sets its own local
     light-theme token overrides). One rule covers both surfaces. */
  color: var(--primary-text);
}

.et-card__verse {
  margin: 0 auto clamp(12px, 1.4vw, 20px);
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(14px, 0.25vw + 13px, 16px);
  line-height: 1.6;
  color: var(--primary-text);
  max-width: 68ch;
}
.et-card__verse p { margin: 0; }

.et-card__prose {
  margin: 0 auto;
  font-family: var(--font-serif);
  font-size: clamp(14px, 0.2vw + 13px, 15px);
  line-height: 1.7;
  color: var(--primary-text);
  max-width: 100%;
}
.et-card__prose p { margin: 0 0 var(--s-3); }
.et-card__prose p:last-child { margin-bottom: 0; }
.et-card__prose em { font-style: italic; }

/* Historical / biological underpinning paragraph (18.05.26): sits at
   the end of each tale-card body. Smaller serif italic in soft-text
   so it reads as evidential context separate from the narrative
   prose above. Top border picks up the body-bottom rhythm without
   needing a horizontal rule. */
.et-card__underpinning {
  margin-top: var(--s-4);
  padding-top: var(--s-3);
  border-top: 1px solid rgba(94, 119, 128, 0.18);
  font-style: italic;
  font-size: 0.9em;
  line-height: 1.55;
  color: var(--soft-text);
}

/* Release line (18.05.26 pm v2): moved out of the body content and
   under the icon row per user. Sits inside .et-card__release,
   below the .et-card__formats list, centred horizontally to read
   as a single end-statement under the format icons.
   23.05.26: de-italicised and made clearer per user - upright, full
   white (--primary-text) instead of the muted --soft-text, and a
   step up in size so the release date reads at a glance. */
.et-card__releasing {
  margin: clamp(10px, 1.2vw, 16px) 0 0;
  font-family: var(--font-serif);
  font-style: normal;
  font-size: clamp(13px, 0.3vw + 12px, 15px);
  line-height: 1.4;
  color: var(--primary-text);
  letter-spacing: 0.01em;
}


/* =========================================================
   BtM modifiers
   Visibility-toggle pattern: era-stage figures, captions, body
   paragraphs, and format markers are stacked into single grid
   cells and toggled visible/hidden by data-era on the card root.
   Card height stays constant when the era changes.
   The .btm-glass-sheen SVG filter referenced by the era icons
   is defined inline once in the page body.
   ========================================================= */
.et-card--btm .btm-stage__figure {
  margin: 0;
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 400ms ease;
}
.et-card--btm[data-era="1"] .btm-stage__figure[data-era="1"],
.et-card--btm[data-era="2"] .btm-stage__figure[data-era="2"],
.et-card--btm[data-era="3"] .btm-stage__figure[data-era="3"] {
  opacity: 1;
}
.et-card--btm .btm-stage__figure img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* 18.05.26: object-position anchored at top so the bottom of the
     artwork (which can render as a dark band at certain viewport
     aspect ratios where the natural image bottom edge is darker
     scratched-texture content - previously masked by the
     box-shadow: var(--shadow-lift) drop, now stripped) gets cropped
     out by object-fit: cover instead of butting against the white
     bottom block as a hard dark line. Composition still reads well
     since the focal content (cave entrance, mammoth scene, etc.)
     sits in the upper-middle of each era's artwork. */
  object-position: 50% 0%;
}
/* WFOB source images re-cropped to 1.41 aspect (matching Cave +
   Womb-Lake) on 18.05.26 - originals archived to
   archive/wfob-originals-180526/. The 1.06 scale hack that
   previously compensated for the source aspect mismatch is no
   longer needed: all three era images now have the same aspect
   in source and crop the same way in the card + lightbox. */

/* Era dots (19.05.26): restored to overlay position on the image
   after a one-day below-image stint (18.05.26 pm v3). Sits inside
   .et-card__media; absolute-positioned, centred near the bottom of
   the figure. Light fill + drop shadow so dots read against varied
   image content. Gap bumped from the prior overlay 8px to 12px per
   user direction ("space them apart slightly"). Dot size held at
   the post-relocation 10px (smaller than the original 14px overlay,
   but the user shrunk them in the below-image state and that smaller
   scale carries over). */
.et-card--btm .btm-dots {
  position: absolute;
  bottom: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  display: flex;
  gap: 12px;
  margin: 0;
  padding: 0;
}
.et-card--btm .btm-dot {
  width: 10px;
  height: 10px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.4);
  cursor: pointer;
  transition: background-color 160ms ease;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45));
  -webkit-tap-highlight-color: transparent;
}
.et-card--btm .btm-dot[aria-selected="true"] {
  background: rgba(255, 255, 255, 0.95);
}
.et-card--btm .btm-dot:hover,
.et-card--btm .btm-dot:focus-visible {
  background: rgba(255, 255, 255, 0.95);
}
.et-card--btm .btm-dot:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Era bar (revised): now only carries the caption. Centred bar
   under the image with the active-era caption sitting in its grid
   stack. */
.btm-era-bar {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(8px, 1.2vw, 14px) clamp(20px, 4vw, 56px) clamp(8px, 1.2vw, 14px);
}

.et-card--btm .btm-captions {
  display: grid;
  width: 100%;
  text-align: center;
}
.et-card--btm .btm-caption {
  grid-column: 1;
  grid-row: 1;
  margin: 0;
  font-family: var(--font-serif);
  color: var(--primary-text);
  visibility: hidden;
}
.et-card--btm[data-era="1"] .btm-caption[data-era="1"],
.et-card--btm[data-era="2"] .btm-caption[data-era="2"],
.et-card--btm[data-era="3"] .btm-caption[data-era="3"] {
  visibility: visible;
}
.et-card--btm .btm-caption__primary {
  display: block;
  font-size: clamp(15px, 0.4vw + 13px, 19px);
  line-height: 1.25;
}
.et-card--btm .btm-caption__sep {
  opacity: 0.5;
  margin: 0 6px;
}
/* 06.07.26 (late v11): era title roman, not italic, per user.
   (late v13): also -20% in size (calc 1.15 base * 0.8 = 0.92) and
   recoloured to the site's off-white support tone (--soft-text,
   used on subtitles / location / underpinning) instead of pure
   white, per user. */
.et-card--btm .btm-caption__title {
  font-style: normal;
  font-size: calc(var(--body-lead) * 0.92);
  color: var(--soft-text);
}
.et-card--btm .btm-caption__location {
  display: block;
  font-style: italic;
  /* 19.05.26: +15% on previous clamp(11px, 0.25vw + 10px, 13px). */
  font-size: clamp(13px, 0.29vw + 12px, 15px);
  color: var(--soft-text);
  margin-top: 3px;
}

/* 18.05.26: per-era body content (story prose + underpinning) is
   now grouped under a div[data-era] wrapper so both paragraphs swap
   together on era change. Previously each era was a single <p
   data-era="N">; restructured so the underpinning paragraph can sit
   beneath the story prose within the same era stack. */
.et-card--btm .btm-body-b {
  display: grid;
}
.et-card--btm .btm-body-b > div[data-era] {
  grid-column: 1;
  grid-row: 1;
  margin: 0;
  visibility: hidden;
}
.et-card--btm[data-era="1"] .btm-body-b > div[data-era="1"],
.et-card--btm[data-era="2"] .btm-body-b > div[data-era="2"],
.et-card--btm[data-era="3"] .btm-body-b > div[data-era="3"] {
  visibility: visible;
}
.et-card--btm .btm-body-b > div > p {
  margin: 0 0 var(--s-3);
}
.et-card--btm .btm-body-b > div > p:last-child {
  margin-bottom: 0;
}

/* v30: per-era animation status anchored to the bottom of the
   card content via grid-stack (separate from .btm-body-b so it
   does not drift with variable-length era prose). */
.btm-era-format-slot {
  display: grid;
  margin-top: clamp(14px, 2vw, 22px);
}
.btm-era-format {
  grid-column: 1;
  grid-row: 1;
  margin: 0;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(11px, 0.3vw + 10px, 13px);
  line-height: 1.4;
  color: var(--quiet-text);
  letter-spacing: 0.01em;
  visibility: hidden;
}
.et-card--btm[data-era="1"] .btm-era-format[data-era="1"],
.et-card--btm[data-era="2"] .btm-era-format[data-era="2"],
.et-card--btm[data-era="3"] .btm-era-format[data-era="3"] {
  visibility: visible;
}

/* WFOB (era 2) format slot. 25.05.26: was a YouTube "Watch the
   Animation" link; now a "View still image" button (the video plays
   from the large play overlay on the era 2 image itself, so the slot's
   remaining job is the still-image affordance). The selectors below
   target both the legacy <a> form and the new .btm-era-format__btn so
   the visual treatment is shared; the button gets the appearance reset
   (no native chrome) on top. */
.btm-era-format--link {
  font-style: normal;
}
.btm-era-format--link a,
.btm-era-format__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--primary-text);
  text-decoration: none;
  border-bottom: 1px solid rgba(94, 119, 128, 0.35);
  transition: color 150ms ease, border-color 150ms ease;
}
.btm-era-format__btn {
  /* Strip native button chrome so it visually matches the legacy <a>. */
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(94, 119, 128, 0.35);
  padding: 0;
  margin: 0;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.btm-era-format--link a:hover,
.btm-era-format--link a:focus-visible,
.btm-era-format__btn:hover,
.btm-era-format__btn:focus-visible {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.btm-era-format__btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
.btm-era-format__icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
@media (prefers-reduced-motion: reduce) {
  .btm-era-format--link a,
  .btm-era-format__btn { transition: none; }
}


/* =========================================================
   VotF modifiers
   Source artwork is portrait (4093x5787, ~5:7); the card holds
   that aspect at every viewport, overriding the 0.75->1.5 curve.
   Two-column row at 768+ (main image + 4-thumbnail vertical
   stack); reflows to main + 2x2 grid below 768.
   ========================================================= */
.et-card--votf .et-card__media {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  /* 18.05.26 (pm): gap reduced ~25% per user (was 6-10, now 5-8). */
  gap: clamp(5px, 0.6vw, 8px);
  aspect-ratio: auto;
}
.et-card--votf .votf-main {
  flex: 1 1 0;
  margin: 0;
  aspect-ratio: 5 / 7;
  overflow: hidden;
  position: relative;
  /* Safety net for browsers where aspect-ratio fails (10.05.26). */
  max-height: 100vh;
}
.et-card--votf .votf-main img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% center;
}
.et-card--votf .votf-stack {
  list-style: none;
  margin: 0;
  padding: 0;
  /* 18.05.26 (pm): stack width bumped 24% -> 27% per user so the
     animal tiles read slightly larger. Internal gap reduced ~25%
     to match the figure gap above. */
  flex: 0 0 27%;
  display: flex;
  flex-direction: column;
  gap: clamp(5px, 0.6vw, 8px);
}
.et-card--votf .votf-stack li {
  flex: 1 1 0;
  position: relative;
  overflow: hidden;
  background: #1a1617;
  min-height: 0;
}
.et-card--votf .votf-stack picture {
  display: block;
  width: 100%;
  height: 100%;
}
.et-card--votf .votf-stack img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% center;
}

/* Hover swap: blue narrator (default) fades to alt colour. Same
   crop, same dimensions. Disabled under prefers-reduced-motion. */
.et-card--votf .votf-stack__alt {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 220ms ease;
  pointer-events: none;
}
.et-card--votf .votf-stack li:hover .votf-stack__alt,
.et-card--votf .votf-stack li:focus-within .votf-stack__alt {
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .et-card--votf .votf-stack__alt {
    transition: none;
  }
}

/* (BtM era-bar narrow-viewport stack rule removed 18.05.26 - era
   selector now overlays the image; bar only holds the caption.) */

@media (max-width: 767.98px) {
  .et-card--votf .et-card__media {
    flex-direction: column;
    /* 11.05.26: disable the 100vh Honor safety net for VotF when the
       media stacks. votf-main at 5/7 aspect plus the 2x2 votf-stack
       grid easily total >100vh on short viewports (landscape phone,
       short browser windows); the base .et-card__media max-height
       was clamping the column and overflow:hidden was clipping the
       bottom row of profile tiles. */
    max-height: none;
  }
  .et-card--votf .votf-main {
    flex: 0 0 auto;
    width: 100%;
  }
  .et-card--votf .votf-stack {
    flex: 0 0 auto;
    width: 100%;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(6px, 1.6vw, 12px);
  }
  .et-card--votf .votf-stack li {
    flex: none;
    aspect-ratio: 1 / 1;
    min-height: 0;
  }
}


/* =========================================================
   Bottom block: cream lighter glass + ink-on-paper text.
   Wraps credit + (BtM era-bar) + body so the lower half of the
   card reads as printed paper against the upper dark glass.
   AOoS / BtM / VotF all opt in via the .et-card__bottom sibling.
   Subtle two-layer text-shadow simulates ink absorption + press.
   ========================================================= */
/* 18.05.26 (revised x8): .et-card is now fully white; bottom block
   inherits the white bg + light-theme tokens from .et-card. This
   rule just keeps it positioned (for the absolute credit child)
   and sets a small padding-top to reserve room for the absolute
   credit on AOoS/VotF where body prose would horizontally overlap
   the credit otherwise. BtM overrides padding-top below for the
   3-line push-down per user. */
.et-card .et-card__bottom {
  position: relative;
  padding-top: clamp(32px, 4vw, 44px);
  /* 18.05.26 (pm): padding-bottom bumped from 10px to clamp(22-32px)
     per user so the releasing line (now sitting under the format
     icons) has clear breathing space between itself and the bottom
     edge of the card. */
  padding-bottom: clamp(22px, 2.6vw, 32px);
}
/* BtM: 18.05.26 (revised) - gap between credit and caption stack
   tightened back to default per user direction. The earlier ~3 line
   push-down has been retired now that the credit sits top-left and
   no longer competes with the centred caption stack for horizontal
   space.
   06.07.26 (late v12): padding-top cut from 32/4vw/44 to a small
   value - at wide viewports the 44px, stacked with the intro-prose
   body's bottom padding and the lifted panel's own margin, opened a
   large void between the prose and the era panel, per user. */
.et-card--btm .et-card__bottom {
  padding-top: clamp(8px, 1vw, 14px);
}

/* 06.07.26 (late v12): trim the intro-prose body's bottom padding on
   BtM (direct child only - not the era-text body inside the duo) so
   the prose-to-panel gap stays tight. */
.et-card--btm > .et-card__body {
  padding-bottom: clamp(10px, 1.2vw, 16px);
}
.et-card .et-card__bottom .et-card__credit a {
  color: inherit;
  border-bottom-color: rgba(94, 119, 128, 0.35);
}
.et-card .et-card__bottom .et-card__credit a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

@media (prefers-reduced-motion: reduce) {
  .et-card__credit a { transition: none; }
}


/* =========================================================
   Release row (19.05.26 pm)
   Format icons + release date, anchored at the bottom of the
   .et-card__bottom block. Left padding matches body prose so
   the icons sit under the left boundary of the body text. The
   .et-card__bottom carries padding-bottom: 10px so the icon
   row sits exactly 10px above the card's outer edge.

   Gap above the row: the preceding .et-card__body already has
   padding-bottom of clamp(18px, 2.4vw, 32px) which keeps the
   last body line well clear of the icons (min(10px, ~2 line-
   heights) constraint always satisfied at desktop and narrow).
   ========================================================= */
.et-card__release {
  padding: 0 clamp(24px, 4.2vw, 46px);
  /* Belt-and-braces guarantee on the gap-from-body-text rule
     even at viewport sizes where body padding-bottom clamps
     to its minimum. */
  margin-top: clamp(10px, 1.2vw, 16px);
}

/* 18.05.26 (pm): release row restructured to icon + date pairs per
   user. Each .et-card__format is a vertical stack (icon on top,
   release date below). Pairs sit in a flex row with wrap, gap
   between pairs. */
.et-card__formats {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: clamp(14px, 1.8vw, 22px);
  align-items: flex-start;
}
.et-card__format {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.et-card__format-icon {
  display: block;
  width: clamp(18px, 2vw, 24px);
  height: clamp(18px, 2vw, 24px);
  color: var(--primary-text);
}
/* 23.05.26: visible hover/focus tooltip for the format icons. The
   native SVG <title> was too easy to miss on these 18-24px icons, so
   each list item shows a small label bubble above the icon naming the
   format. The label text is keyed off the icon's existing aria-label
   via :has(), so no per-icon markup is needed (:has() is already used
   elsewhere in this file). The bubble is dark with white text plus a
   hairline border + lift, so it reads on both the white work cards and
   the dark intro card. z-index sits above the .et-card::before grain. */
.et-card__formats li {
  position: relative;
}
.et-card__formats li::after {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  padding: 4px 9px;
  border-radius: var(--radius-sm, 6px);
  background: #0F1419;
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
  color: #FFFFFF;
  font-family: var(--font-sans);
  font-style: normal;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.01em;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 160ms ease, transform 160ms ease;
  z-index: 5;
}
.et-card__formats li:hover::after,
.et-card__formats li:focus-within::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.et-card__formats li:has([aria-label="Novel"])::after     { content: "Novel"; }
.et-card__formats li:has([aria-label="Audiobook"])::after { content: "Audiobook"; }
.et-card__formats li:has([aria-label="Video"])::after     { content: "Video"; }
.et-card__formats li:has([aria-label="Podcast"])::after   { content: "Podcast"; }
.et-card__formats li:has([aria-label="Video game"])::after { content: "Video game"; }
@media (prefers-reduced-motion: reduce) {
  .et-card__formats li::after { transition: opacity 160ms ease; transform: translateX(-50%); }
}
.et-card__format-date {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(10px, 0.25vw + 9px, 11px);
  line-height: 1.3;
  color: var(--quiet-text);
  letter-spacing: 0.01em;
  white-space: nowrap;
  text-align: center;
}

/* Legacy: kept in case any HTML still references it; current
   markup uses .et-card__format-date per icon instead. */
.et-card__release-date {
  margin: clamp(6px, 0.8vw, 10px) 0 0;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(11px, 0.3vw + 10px, 13px);
  line-height: 1.4;
  color: var(--quiet-text);
  letter-spacing: 0.02em;
}

/* Intro card variant: no .et-card__bottom wrapper to carry the
   bottom clearance, so apply it directly to the release row.
   The intro is dark-glass throughout, so the format icons inherit
   the white --primary-text via the .et-card--intro token override.
   19.05.26 (pm): bumped from 10px to ~one body-line-height + 10
   per user (line-break added between icon row and card outer
   bottom). */
.et-card--intro .et-card__release {
  padding-bottom: clamp(28px, 3vw, 36px);
}


/* =========================================================
   Intro variant (v4-v3d, 08.05.26)
   Image-less, dark-glass throughout. The five-paragraph ET-voice
   introduction that previously sat inside the chamber pin
   (.our-stories__body) was unscrollable because the pin is
   position: fixed; on squat desktop viewports the last paragraphs
   clipped. The intro card moves the body into normal scroll flow
   under the .et-card pattern. No .et-card__media (no image), no
   .et-card__bottom (no cream paper treatment, dark glass continues
   throughout); the body sits directly inside the article on the
   card's own glass.
   Header carries title only (no bc) since this card IS Eternal
   Tales; nothing in the hierarchy sits above it except Our Stories
   itself. Body padding-top is bumped because there's no .et-card__meta
   row above it to provide breathing room from the header.
   ========================================================= */
.et-card--intro .et-card__body {
  padding-top: clamp(28px, 3vw, 44px);
}

/* 23.05.26 v3: the three tale cards (AOoS / BtM / VotF) carry an
   occluded dark glass - bumped from 0.70 to 0.88 per user so they read
   as more solid/less see-through while still sitting as glass over the
   chamber (blur retained). Light tokens flip their text + format icons
   to white; grain hidden (paper texture doesn't belong on glass).
   The intro ("Eternal Tales") card is intentionally NOT in this rule
   any more - per user it flips to the base WHITE treatment for greater
   impact (this reverses the earlier "first slide should be glass"
   call), so it falls through to the white .et-card base with dark ink
   + the paper grain. */
.et-card--aoos,
.et-card--btm,
.et-card--votf,
.et-card--continues,
.et-card--tyki {
  --bg:           #0F1419;
  --primary-text: #FFFFFF;
  --soft-text:    #A7B6BA;
  --quiet-text:   #76878C;
  background: rgba(14, 11, 12, 0.88);
  -webkit-backdrop-filter: blur(8px) saturate(1.1);
  backdrop-filter: blur(8px) saturate(1.1);
}
.et-card--aoos::before,
.et-card--btm::before,
.et-card--votf::before,
.et-card--continues::before,
.et-card--tyki::before {
  display: none;
}

/* 06.07.26: the intro card flips BACK to a dark treatment,
   reversing the 23.05.26 white-for-impact call per user direction:
   the card now opens with the "Think You Know Ireland?" video
   header (see index.html + section-featured.css
   .featured-panel--card-media) and the video still needs a dark
   surface to read as one piece with the card. Same-day revision:
   the first pass used an opaque #14191F, which read as a navy
   tint against the tale cards; per user the intro now carries the
   EXACT tale-card glass (0.88 warm dark + blur - the inline
   no-blur override in index.html was removed the same day). The
   12% see-through over the white logo lockup during the rise is
   acceptable: the lockup scroll-fades out as the card overlaps it
   (per-element ownership script), and behind blur(8px) any
   residue is imperceptible. Dark tokens flip all descendant text
   + format icons to light values; the paper grain ::before is
   hidden (texture belongs to the white treatment); padding-top
   drops to 0 (the base 5px offset existed to push card headers
   down, and here it would read as a hairline dark strip above
   the video header). */
.et-card--intro {
  --bg:           #0F1419;
  --primary-text: #FFFFFF;
  --soft-text:    #A7B6BA;
  --quiet-text:   #76878C;
  background: rgba(14, 11, 12, 0.88);
  -webkit-backdrop-filter: blur(8px) saturate(1.1);
  backdrop-filter: blur(8px) saturate(1.1);
  padding-top: 0;
}
.et-card--intro::before {
  display: none;
}

/* (06.07.26 late v7: the .et-card--btm padding-top: 0 flush-cover
   rule that lived here is gone - the title + subtitle moved above
   the cover to match the AOoS card order, per user, so the card
   opens with its header again and takes the base 5px top padding
   like the other tale cards.) */

/* =========================================================
   Think You Know Ireland card (06.07.26 late v20)
   The intro card split in two, per user: #about above is now
   text-only, and this card carries the video header (flush to
   the top edge, same as the old combined card), the series
   copy, and a Subscribe-on-YouTube pill in place of the format
   icon row. Dark tokens / grain-hide / black shell come from
   the family lists above. margin-top opens the standard
   inter-card gap inside the shared #our-stories section.
   ========================================================= */
.et-card--tyki {
  padding-top: 0;
  margin-top: clamp(48px, 6vw, 80px);
}

/* 06.07.26 (late v21): the text-only Vision card (#about) gets the
   family opening - coral eyebrow above a coral-ruled display title -
   so it no longer reads as bare paragraphs after the hero, per user.
   Same standalone-eyebrow treatment as the What's Next card (the
   shared .et-card__header is a flex row, so the label sits above it,
   not inside). The first prose line steps up to the display serif as
   a lead. */
.et-card--intro > .section-label {
  margin: 0;
  padding: clamp(16px, 2vw, 24px) clamp(20px, 4vw, 40px) 2px;
}

.et-card--intro .et-card__prose > p:first-child {
  font-family: var(--font-display);
  font-size: clamp(17px, 1vw + 11px, 21px);
  line-height: 1.55;
}

.tyki__subscribe {
  padding: clamp(6px, 0.8vw, 10px) clamp(24px, 4.2vw, 46px) clamp(28px, 3vw, 36px);
  /* 06.07.26 (late v22): centred, per user (was left-aligned with
     the prose column). */
  text-align: center;
}

/* Coral text CTA (06.07.26 late v23): no pill / no outline in any
   form, per user. Same plain action voice as "Watch the animation"
   and "Register your interest": uppercase coral text with the
   YouTube glyph (currentColor) ahead of it and the site's arrow
   nudge behind. Links to the channel with ?sub_confirmation=1 so
   YouTube opens its subscribe prompt. */
.tyki-subscribe {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  text-decoration: none;
  font-size: var(--body-small);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1;
}

.tyki-subscribe::after {
  content: "\2192"; /* -> */
  display: inline-block;
  transition: transform var(--t-standard) var(--ease-standard);
}

.tyki-subscribe:hover::after,
.tyki-subscribe:focus-visible::after {
  transform: translateX(4px);
}

.tyki-subscribe:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .tyki-subscribe::after {
    transition: none;
  }
}

.tyki-subscribe__icon {
  width: 20px;
  height: 20px;
  display: block;
}

/* The intro card is shorter than the image-bearing tale cards (no
   image to inflate height). Without this override, the global .section
   min-height: 100vh leaves a tall empty space below the intro card
   before #an-oath-on-stone begins, making the visual gap between
   #eternal-tales and #an-oath-on-stone larger than the gaps between
   the tale cards (AOoS / BtM / VotF, whose images push their card
   heights to roughly fill 100vh). min-height: auto sizes this section
   to its content plus the standard .section padding (nav-height + s-6
   top, s-9 bottom), so the gap reduces to the standard inter-section
   padding gap, matching what the user sees between the tale cards. */
.section--et-intro {
  min-height: auto;
}

/* 06.07.26: the same min-height opt-out extends to the three tale
   sections. On viewports taller than a card's content, the base
   .section min-height: 100vh leaves empty slack BELOW the card
   (content flows top-down), silently inflating whichever
   inter-card gap follows the short section - the exact mechanism
   the intro rule above was added for. Surfaced when the user
   flagged the BtM -> AOoS gap as unequal: the padding swap
   (section-aoos.css / section-btm.css, same date) equalised the
   padding-driven gaps, but on tall windows the slack re-broke
   them. With every card taller than typical viewports this rule
   is usually a no-op; it only bites on tall monitors, where it
   keeps the gaps padding-driven and equal. */
.section--btm,
.section--aoos,
.section--votf {
  min-height: auto;
}

/* 19.05.26: at narrow heights (mobile + small tablet portrait), the
   five-paragraph intro plus standard section padding overflows the
   800px viewport, forcing a scroll while the chamber logo is still
   in view. Tighten the typography + body padding + section padding
   so the whole card reads in a single viewport at 800px height.
   Desktop tall (>=801) keeps its breathing room. */
@media (max-height: 800px) {
  .section--et-intro {
    /* Reduce the standard .section vertical padding which would
       otherwise consume ~170px above + below the card. */
    padding-top: calc(var(--nav-height) + 8px);
    padding-bottom: var(--s-5);
  }
  .et-card--intro .et-card__body {
    padding-top: clamp(14px, 1.6vw, 22px);
    padding-bottom: clamp(14px, 1.6vw, 22px);
  }
  .et-card--intro .et-card__prose {
    font-size: clamp(12px, 0.3vw + 11px, 14px);
    line-height: 1.5;
  }
  .et-card--intro .et-card__prose p {
    margin-bottom: var(--s-2);
  }
}

/* ---------- Intro card arrival: opacity-only ----------
   The base .fade-up animates a 72px translateY + 0.96 scale alongside
   opacity. On the intro card that compounds with the natural scroll
   rise (the card is already moving up the viewport as the visitor
   scrolls) and reads as judder over the chamber image. Override here
   to fade in by opacity alone, with a tighter transition. Also drop
   the persistent will-change layer once the card is visible so the
   compositor isn't holding a permanent GPU plane behind it. */
.et-card--intro.fade-up {
  transform: none;
  transition: opacity 260ms var(--ease-standard);
}
.et-card--intro.fade-up.is-visible {
  transform: none;
  will-change: auto;
}

/* =========================================================
   Coral accent pass (06.07.26 late v6)
   With every card on the dark treatment the page read as
   monotone, per user; these touches thread the brand coral
   ("the controlled spark" - tokens.css) through the cards
   without flipping any of them light. Four moves, all quiet:
   1. a coral hairline border on each dark card (same voice as
      the lightbox caption panel and the legacy AOoS glass);
   2. a short coral rule under each card title;
   3. the underpinning dividers switch from grey-teal to the
      coral the --border token always intended;
   4. the active era dot on the BtM stage fills coral instead
      of white, echoing the accent into the gallery.
   ========================================================= */
/* 06.07.26 (late v10): the coral hairline border is replaced by a
   solid-black card on a very slight all-sides drop shadow, per user.
   Background goes fully opaque black (#000), so the 0.88 glass +
   blur set on these cards in the earlier rules is cancelled here
   (backdrop-filter would be wasted paint on an opaque surface). The
   shadow reads as a soft dark halo just outside the card edge - on
   the #0F1419 chamber the near-black spill separates the panel from
   the backdrop the way the border used to, but quieter. Small 2px
   drop, symmetric blur + spread so it extends on every side. The
   card's own overflow: hidden clips descendants only, not this
   outset shadow, so it renders on all four edges. */
.et-card--intro,
.et-card--aoos,
.et-card--btm,
.et-card--votf,
.et-card--continues,
.et-card--tyki {
  border: 0;
  background: #000000;
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
  /* 06.07.26 (late v11): softened from 0 2px 22px 3px / 0.6. The
     heavy near-black spill was darkening the area around every card
     enough to read as a loss of card opacity, per user. Lighter and
     tighter now - just enough to lift the panel off the chamber. */
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.33);
}

.et-card__title::after {
  content: "";
  display: block;
  width: 44px;
  height: 2px;
  margin-top: clamp(10px, 1.2vw, 14px);
  border-radius: 1px;
  background: var(--accent);
}

.et-card__underpinning {
  border-top-color: rgba(255, 107, 74, 0.22);
}

.et-card--btm .btm-dot[aria-selected="true"] {
  background: var(--accent);
}
.et-card--btm .btm-dot:hover,
.et-card--btm .btm-dot:focus-visible {
  background: rgba(255, 107, 74, 0.75);
}

/* 06.07.26 (late v8): BtM's artwork credit sits directly under the
   cover (moved out of .et-card__bottom in the HTML) so it reads in
   the same place as the AOoS/VotF credits: tucked under the card's
   main artwork. The base .et-card__meta rule above anchors the
   credit absolutely at the top of .et-card__bottom; outside that
   block the absolute would anchor to the card itself (over the
   title), so this card's credit flows statically with the same
   12px drop and the shared content insets. */
.et-card--btm .et-card__meta {
  position: static;
  padding: 12px clamp(24px, 4.2vw, 46px) 0;
}

