/* ============================================================
   The Tee Family House — css/pages.css
   Styles for the stories system: stories.html (archive) and
   every generated story-<id>.html. Builds on top of the tokens
   and shells defined in css/base.css (owned by the brain) —
   never redefines a token, only consumes them.
   ============================================================ */

/* ---------------- Floating glass pill header ----------------
   The SAME nav pill as the landing page's .v3nav (css/v3-hero.css),
   re-created on the inner pages' markup: fixed + centered, dark glass,
   copper accent (#ee7c2b — literal because these pages load base.css,
   not v3-base.css, so var(--acc) does not exist here), gold donate
   CTA. One comprehensive nav (7 links, never wrapping); under 1080px
   the links hide and the burger opens the dropdown card. body::before
   (end of this block) reserves the vertical room a fixed header no
   longer occupies in flow — js/banner.js's body padding then stacks
   ON TOP of that spacer, so the emergency banner needs no special
   casing here. */
.pages-header {
  position: fixed; top: 18px; inset-inline: 0; z-index: 40;
  display: flex; justify-content: center;
  pointer-events: none;
}
.pages-header .header-inner {
  pointer-events: auto;
  display: flex; align-items: center;
  gap: clamp(10px, 1.6vw, 20px);
  width: auto; max-width: calc(100vw - 20px);
  margin: 0; padding: 9px 18px 9px 12px;
  background: rgba(8, 7, 6, 0.62);
  border: 1px solid rgba(246, 242, 235, 0.09);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border-radius: 99px;
  color: #f6f2eb;
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.35);
}
.pages-header .brand {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 700; font-size: 14px; letter-spacing: -0.01em;
  color: #f6f2eb; white-space: nowrap;
}
/* the paw SVG ships with the pink brand fill inline; the pill recolors
   it to the landing accent so both headers read as one family */
.pages-header .brand-paw circle { fill: #ee7c2b; }
.pages-nav { display: flex; align-items: center; gap: clamp(10px, 1.4vw, 20px); }
.pages-nav a {
  position: relative; white-space: nowrap;
  font-size: 13.5px; font-weight: 500;
  color: rgba(246, 242, 235, 0.68);
  padding-block: 6px;
  transition: color 0.3s;
}
.pages-nav a::after {
  content: ''; position: absolute; bottom: 0; inset-inline-start: 0;
  height: 2px; width: 0; background: #ee7c2b; border-radius: 2px;
  transition: width 0.35s var(--ease-soft);
}
.pages-nav a:hover { color: #f6f2eb; }
.pages-nav a:hover::after { width: 100%; }
.pages-nav a[aria-current="page"] { color: #f6f2eb; }
.pages-nav a[aria-current="page"]::after { width: 100%; }
.header-actions { display: flex; align-items: center; gap: 8px; }
#lang-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  border: 0; padding: 0;
  color: rgba(246, 242, 235, 0.8); font-size: 11.5px; font-weight: 700;
  transition: background 0.3s, color 0.3s;
}
#lang-toggle:hover { background: rgba(246, 242, 235, 0.1); color: #f6f2eb; }
.pages-header .btn-primary {
  background: linear-gradient(120deg, #f7b27a 0%, #ee7c2b 45%, #c05f1a 100%);
  color: #14110e; border: 0; border-radius: 99px;
  padding: 10px 20px; font-size: 13px; font-weight: 600; white-space: nowrap;
  box-shadow: 0 12px 34px -12px rgba(238, 124, 43, 0.55);
  transition: transform 0.3s var(--ease-soft), box-shadow 0.3s;
}
.pages-header .btn-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 18px 44px -12px rgba(238, 124, 43, 0.7);
}
.btn-small { padding: 9px 20px; font-size: 0.88rem; }

/* Hamburger — same bare three-bar button as the landing pill's. */
.pages-burger {
  display: none;
  flex-direction: column; align-items: center; justify-content: center;
  gap: 5px; width: 34px; height: 34px;
  border: 0; border-radius: 50%; background: transparent;
}
.pages-burger span {
  display: block; width: 20px; height: 2px;
  background: #f6f2eb; border-radius: 2px;
  transition: transform 0.35s var(--ease-soft), opacity 0.3s;
}
.pages-burger:hover { background: rgba(246, 242, 235, 0.1); }
.pages-burger:focus-visible { outline: 2px solid #ee7c2b; outline-offset: 2px; }
/* Open state (JS toggles aria-expanded): bars morph into an X. */
.pages-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.pages-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.pages-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Fullscreen menu — the SAME numbered overlay as the landing page's
   .v3menu (css/v3-hero.css): near-black sheet, big display type, small
   italic copper numerals. `hidden` (toggled by js/pages.js) removes it
   from layout and the a11y tree alike. The pill (.header-inner) gets
   z-index 2 so it stays clickable ON TOP of the open sheet — its
   burger-turned-X is the close control, exactly like the landing. */
.pages-header .header-inner { position: relative; z-index: 2; }
.pages-menu {
  pointer-events: auto;
  position: fixed; inset: 0; z-index: 1;
  background: rgba(8, 7, 6, 0.97);
  display: flex; align-items: center; justify-content: center;
  padding-inline: clamp(28px, 8vw, 60px);
  opacity: 0; visibility: hidden;
  transition: opacity 0.45s, visibility 0.45s;
}
.pages-menu.is-open { opacity: 1; visibility: visible; }
.pages-menu__links { display: flex; flex-direction: column; gap: 2px; }
.pages-menu__links a {
  display: flex; align-items: baseline; gap: 16px;
  font-family: 'Alexandria', 'Space Grotesk', sans-serif;
  color: #f6f2eb; font-weight: 700; letter-spacing: -0.02em;
  /* vh-capped so the full 8-item site map always fits one phone screen */
  font-size: clamp(22px, min(6vw, 4.6vh), 42px); line-height: 1.35;
  padding-block: 7px;
  opacity: 0; transform: translateY(26px);
  transition: opacity 0.5s, transform 0.5s var(--ease-soft), color 0.3s;
}
.pages-menu.is-open .pages-menu__links a { opacity: 1; transform: none; }
.pages-menu.is-open .pages-menu__links a:nth-child(1) { transition-delay: 0.05s; }
.pages-menu.is-open .pages-menu__links a:nth-child(2) { transition-delay: 0.1s; }
.pages-menu.is-open .pages-menu__links a:nth-child(3) { transition-delay: 0.15s; }
.pages-menu.is-open .pages-menu__links a:nth-child(4) { transition-delay: 0.2s; }
.pages-menu.is-open .pages-menu__links a:nth-child(5) { transition-delay: 0.25s; }
.pages-menu.is-open .pages-menu__links a:nth-child(6) { transition-delay: 0.3s; }
.pages-menu.is-open .pages-menu__links a:nth-child(7) { transition-delay: 0.35s; }
.pages-menu.is-open .pages-menu__links a:nth-child(8) { transition-delay: 0.4s; }
.pages-menu__links a i {
  font-style: italic; font-family: 'Amiri', 'Playfair Display', serif;
  font-size: 16px; font-weight: 700;
  color: #ee7c2b; flex: none;
}
.pages-menu__links a:hover { color: #ee7c2b; }
.pages-menu__links a[aria-current="page"] { color: #ee7c2b; }
.pages-menu__donate span { color: #ee7c2b; }

@media (max-width: 1080px) {
  /* mirror the landing pill on small screens: links AND the donate CTA
     hide (donate lives in the menu as item 08), leaving brand + lang +
     burger — the same silhouette as .v3nav */
  .pages-nav, .pages-header .btn-primary { display: none; }
  .pages-burger { display: flex; }
}

/* The room in normal flow that the fixed pill no longer reserves —
   js/banner.js's body padding (emergency banner) stacks on top of this
   spacer independently, with no rule conflict. */
body::before { content: ''; display: block; height: 76px; }

html.reduce-motion .pages-burger span,
html.reduce-motion .pages-nav a,
html.reduce-motion .pages-nav a::after,
html.reduce-motion .pages-header .btn-primary,
html.reduce-motion .pages-menu,
html.reduce-motion .pages-menu__links a { transition: none; }
html.reduce-motion .pages-menu__links a { transform: none; }
html.reduce-motion .pages-header .btn-primary:hover { transform: none; }

/* ---------------- Story hero ---------------- */
.story-hero { padding-block: clamp(28px, 6vh, 56px) clamp(48px, 8vh, 80px); }
.story-back {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 0.9rem; color: var(--muted-on-light); margin-bottom: 20px;
  transition: color 0.2s;
}
.zone-dark .story-back { color: var(--muted-on-dark); }
.story-back:hover { color: var(--pink-deep); }
.zone-dark .story-back:hover { color: var(--pink); }

/* Direction-aware chevron: content is decided by [dir], independent of
   the language text swap, so it always points "back toward the list"
   regardless of which language is active. */
.back-arrow::before { content: '\2190'; }
[dir='rtl'] .back-arrow::before { content: '\2192'; }

/* Cinematic letterbox, never a crop: most source photos and every video
   clip are portrait, so forcing a landscape/square box with object-fit:
   cover was slicing heads and paws off. Instead the frame holds a fixed
   height, a blurred/zoomed copy of the same image fills it as ambient
   backdrop, and the real photo floats centered at its full aspect ratio
   on top — the whole frame is always visible, nothing is ever cut. */
.story-hero-media {
  position: relative; overflow: hidden;
  height: min(68vh, 640px);
  display: flex; align-items: center; justify-content: center;
}
.story-hero-media .story-hero-backdrop {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  filter: blur(28px) saturate(1.15) brightness(0.72);
  transform: scale(1.15);
}
.story-hero-media .story-hero-fg {
  position: relative; height: 100%; width: auto; max-width: 100%;
  object-fit: contain; border-radius: 14px;
  box-shadow: 0 20px 50px -16px rgba(0, 0, 0, 0.55);
}
.story-hero-video { background: var(--night-2); }
.story-hero-video .story-hero-backdrop { display: block; }
.story-hero-video video.story-hero-fg {
  display: block; height: 100%; width: auto; max-width: 100%;
  object-fit: contain; background: transparent;
}

.story-hero-meta { margin-top: 24px; display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.story-hero-meta h1 { font-size: clamp(2rem, 5vw, 3.4rem); }

/* Pink-bordered stamp chip, gently rotated — echoes the landing page's
   stamp language without depending on a class from a file we don't own. */
.story-stamp {
  display: inline-flex; align-items: center;
  padding: 7px 16px; border: 1.5px solid var(--pink-deep);
  border-radius: 999px; font-size: 0.85rem; font-weight: 600;
  color: var(--pink-deep); transform: rotate(-3deg);
  background: var(--pink-soft);
}
.zone-dark .story-stamp { background: rgba(244, 143, 177, 0.12); color: var(--pink); border-color: var(--pink); }

.story-date { font-size: 0.85rem; }

/* ---------------- Story body ---------------- */
.story-body-inner { max-width: 65ch; }
.story-body p { font-size: 1.06rem; line-height: 1.9; margin-block-end: 1.3em; }
.story-body p:last-child { margin-block-end: 0; }

/* ---------------- Updates timeline ----------------
   Admin-authored progress notes (story.updates — empty on every case
   today, styled defensively since the markup already exists and the
   brief asked for it ahead of real content). A vertical connecting line
   drawn in the ul's own inline-start gutter (::before per item) with a
   pink dot per entry (::after) — no markup change needed, both are pure
   decoration. The date is the existing shared .glass-chip tinted pink;
   the body paragraph gets a white card treatment so each entry reads as
   one discrete note rather than a run of floating text. */
.story-updates-list {
  padding-inline-start: 26px;
  display: flex; flex-direction: column; gap: 32px;
}
.story-update { position: relative; }
.story-update::before {
  content: ''; position: absolute; inset-inline-start: -26px;
  top: 6px; bottom: -32px; width: 1px; background: var(--hairline-light);
}
.story-update:last-child::before { display: none; }
.story-update::after {
  content: ''; position: absolute; inset-inline-start: calc(-26px - 3px);
  top: 4px; width: 9px; height: 9px; border-radius: 50%;
  background: var(--pink); box-shadow: 0 0 0 3px var(--cream);
}
.zone-dark .story-update::before { background: var(--hairline-dark); }
.zone-dark .story-update::after { box-shadow: 0 0 0 3px var(--night); }

.story-update-date { color: var(--pink-deep); font-weight: 600; margin-bottom: 10px; }
.zone-dark .story-update-date { color: var(--pink); }
.story-update p {
  background: var(--card); border-radius: 12px; padding: 14px 16px;
  box-shadow: 0 1px 0 var(--hairline-light), 0 10px 24px -16px rgba(44, 33, 38, 0.3);
  margin: 0;
}
.zone-dark .story-update p { background: var(--night-2); box-shadow: 0 1px 0 var(--hairline-dark), 0 10px 24px -16px rgba(0, 0, 0, 0.5); color: var(--text-on-dark); }
.story-update-photo {
  margin-top: 12px; width: 100%; max-width: 320px; height: auto;
  border-radius: 12px; display: block;
}

/* ---------------- Videos — the emotional heart ----------------
   These are portrait phone clips; a fixed aspect-ratio + object-fit:
   cover box hid most of the frame. Each figure instead just centers the
   video at its own natural ratio, capped to a comfortable max height —
   the full clip is always visible, never sliced into a letterslot. */
.story-videos-grid { display: grid; gap: clamp(24px, 4vw, 40px); max-width: 760px; margin-inline: auto; }
.story-video { display: flex; justify-content: center; }
.story-video video {
  display: block; max-height: 560px; width: auto; max-width: 100%; height: auto;
  border-radius: var(--radius);
  box-shadow: 0 1px 0 var(--hairline-light), 0 20px 50px -20px rgba(44, 33, 38, 0.35);
  border: 1px solid var(--hairline-light);
}
.zone-dark .story-video video { border-color: var(--hairline-dark); box-shadow: 0 1px 0 var(--hairline-dark), 0 20px 50px -20px rgba(0, 0, 0, 0.6); }
.story-video figcaption { margin-top: 12px; text-align: center; font-family: var(--font-hand); font-size: 1.3rem; color: var(--ink-soft); }
.zone-dark .story-video figcaption { color: var(--muted-on-dark); }

/* ---------------- Gallery ----------------
   Some shots are portrait, some are landscape (golden-2, muffin-2, the
   tooth arc) and the published pink cards are a tall 562x1000 — no
   single fixed ratio fits all of them without cropping. A CSS-columns
   masonry lets every image render at its own natural ratio instead. */
.story-gallery-grid { columns: 2; column-gap: 20px; }
.story-gallery-item { display: block; break-inside: avoid; margin-bottom: 20px; }
.story-gallery-item img { width: 100%; height: auto; display: block; }
.story-gallery-card { max-width: 340px; margin-inline: auto; }
.story-gallery-card figcaption { margin-top: 8px; text-align: center; font-family: var(--font-hand); font-size: 1.15rem; color: var(--muted-on-light); }
@media (max-width: 640px) {
  .story-gallery-grid { columns: 1; }
  .story-gallery-card { max-width: 100%; }
}

/* ---------------- Transparency log — receipt cards ----------------
   The bills this case's donations paid for, as received from the clinic
   — this is the trust artifact of the whole donate ask, so it earns
   real card treatment rather than bare list text. A soft cream-2 band
   sets it apart from the surrounding cream sections.

   Markup is flat (badge/title/meta are three sibling <span>s inside one
   <a>, generated by build-stories.mjs — not owned by this unit): title
   is stacked over meta using CSS Grid's explicit placement rather than
   a wrapping element, so no markup change was needed. Grid's column
   order (badge → text → icon) follows the document's own inline
   direction automatically — RTL (Arabic) mirrors it for free, no
   physical left/right anywhere below. The download icon is a CSS-only
   circle: an inline SVG arrow as a background-image on ::after, since
   the emitted markup has no icon element to hook. */
.story-docs { background: var(--cream-2); border-top: 1px solid var(--hairline-light); }
.zone-dark.story-docs { background: var(--night-2); border-top-color: var(--hairline-dark); }
.story-docs-intro { font-size: 0.92rem; color: var(--muted-on-light); max-width: 56ch; margin-top: -6px; margin-bottom: 28px; }
.zone-dark .story-docs-intro { color: var(--muted-on-dark); }

.story-docs-list { display: flex; flex-direction: column; gap: 12px; }
/* Caps the list only once it actually needs capping (a 9th doc exists) —
   :has() lets this be conditional without any JS or a class the
   generator would need to add; browsers without :has() just show the
   full uncapped list, which is a safe fallback, not a broken one. */
.story-docs-list:has(li:nth-child(9)) {
  max-height: 620px; overflow-y: auto; padding-inline-end: 6px;
  mask-image: linear-gradient(to bottom, black calc(100% - 36px), transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, black calc(100% - 36px), transparent 100%);
}

.story-doc-link {
  display: grid;
  grid-template-columns: 44px 1fr 32px;
  grid-template-rows: auto auto;
  align-items: center; column-gap: 14px; row-gap: 2px;
  padding: 14px; border-radius: 12px;
  background: var(--card);
  box-shadow: 0 1px 0 var(--hairline-light), 0 10px 24px -18px rgba(44, 33, 38, 0.35);
  transition: transform 0.2s var(--ease-soft), box-shadow 0.2s var(--ease-soft);
}
.story-doc-link:hover {
  transform: translateY(-2px);
  box-shadow: 0 1px 0 var(--hairline-light), 0 18px 34px -16px rgba(44, 33, 38, 0.4);
}
.zone-dark .story-doc-link {
  background: var(--night-2);
  box-shadow: 0 1px 0 var(--hairline-dark), 0 10px 24px -18px rgba(0, 0, 0, 0.5);
}
.zone-dark .story-doc-link:hover { box-shadow: 0 1px 0 var(--hairline-dark), 0 18px 34px -16px rgba(0, 0, 0, 0.6); }

.story-doc-badge {
  grid-column: 1; grid-row: 1 / 3;
  width: 44px; height: 44px; border-radius: 10px;
  background: var(--pink-soft); color: var(--pink-deep);
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.03em;
  display: flex; align-items: center; justify-content: center;
}
.story-doc-title { grid-column: 2; grid-row: 1; font-weight: 600; color: var(--ink); }
.zone-dark .story-doc-title { color: var(--text-on-dark); }
.story-doc-meta { grid-column: 2; grid-row: 2; font-size: 0.82rem; color: var(--muted-on-light); }
.zone-dark .story-doc-meta { color: var(--muted-on-dark); }

/* Download affordance — grid item 3, so it lands at inline-end (right in
   RTL, left in LTR) without any explicit side property. */
.story-doc-link::after {
  content: '';
  grid-column: 3; grid-row: 1 / 3; justify-self: center;
  width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid var(--hairline-light);
  background-color: transparent;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235c4e55' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4v12m0 0l-5-5m5 5l5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: center; background-size: 14px 14px;
  transition: background-color 0.2s var(--ease-soft);
}
.story-doc-link:hover::after { background-color: var(--pink-soft); }
.zone-dark .story-doc-link::after { border-color: var(--hairline-dark); }

@media (max-width: 480px) {
  .story-doc-link { grid-template-columns: 40px 1fr 28px; padding: 12px; column-gap: 10px; }
  .story-doc-badge { width: 40px; height: 40px; }
  .story-doc-link::after { width: 28px; height: 28px; }
}

/* ---------------- Funding progress module ----------------
   Sits inside the CTA band (both the normal and memorial branches — a
   memorial case can still carry unpaid bills), above the ask. Absent
   entirely when a case has no goal, so this block only ever affects
   pages that actually render it. The bar's width is set inline by the
   generator for both the un-CSS'd and CSS'd cases; the transition here
   only takes effect on a later width change (e.g. a live progress
   update), not on first paint — base.css's global reduced-motion rule
   already zeroes every transition-duration, so no separate guard is
   needed here. No physical left/right anywhere below: the fill is a
   plain block box, so it grows from the inline-start edge automatically
   in both RTL (Arabic) and LTR (English) without extra rules. */
.story-funding { margin-bottom: 28px; text-align: center; }
.story-funding-line { font-size: 0.95rem; color: var(--muted-on-dark); margin-bottom: 10px; }
.story-funding-bar {
  width: 100%; max-width: 420px; margin-inline: auto;
  height: 8px; border-radius: 999px; overflow: hidden;
  background: var(--hairline-dark);
}
.story-funding-fill {
  height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--pink-deep), var(--pink));
  transition: width 1.2s var(--ease-out);
}
.story-funding-pct {
  display: inline-flex; align-items: center; margin-top: 10px;
  padding: 4px 12px; border-radius: 999px; font-size: 0.78rem; font-weight: 600;
  color: var(--pink); background: rgba(244, 143, 177, 0.12);
  border: 1px solid var(--hairline-dark);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.story-funding-reached { margin-top: 10px; font-size: 0.9rem; color: var(--pink-deep); }

/* ---------------- CTA band ---------------- */
.story-cta { text-align: center; padding-block: clamp(56px, 9vh, 96px); }
.story-cta-line { font-size: clamp(1.2rem, 2.4vw, 1.6rem); margin-bottom: 24px; max-width: 44ch; margin-inline: auto; }
.story-cta-actions { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }

/* Ariel's memorial band: a soft pink glow instead of a donation ask. */
.story-cta-memorial { background: radial-gradient(ellipse at 50% 0%, rgba(244, 143, 177, 0.1), transparent 70%); }
.story-candle {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-accent); font-style: italic; font-size: 1.3rem;
  color: var(--pink); border-bottom: 1px solid var(--hairline-dark);
  padding-block-end: 4px; transition: border-color 0.2s;
}
.story-candle:hover { border-color: var(--pink); }

/* ---------------- Prev/next pager ---------------- */
.story-pager { padding-block: clamp(40px, 7vh, 72px); }
.story-pager-inner { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.story-pager-link { flex: 1 1 240px; text-align: center; }
.pager-dir { opacity: 0.65; font-size: 0.85em; }

/* ---------------- Footer ---------------- */
.pages-footer { padding-block: 32px; text-align: center; font-size: 0.85rem; color: var(--muted-on-dark); background: var(--night); }
.pages-footer a { color: var(--pink); }

/* ============================================================
   stories.html — the archive
   ============================================================ */
.archive-hero { padding-block: clamp(64px, 10vh, 120px) clamp(32px, 6vh, 56px); }
.archive-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(18px, 2.4vw, 28px);
  margin-top: clamp(32px, 5vh, 56px);
}
@media (max-width: 980px) { .archive-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .archive-grid { grid-template-columns: 1fr; } }

.story-card {
  position: relative; display: block; border-radius: var(--radius);
  overflow: hidden; aspect-ratio: 4 / 5;
  transition: transform 0.35s var(--ease-soft), box-shadow 0.35s var(--ease-soft);
}
.story-card:hover { transform: translateY(-6px); box-shadow: 0 24px 48px -20px rgba(44, 33, 38, 0.4); }
.story-card img {
  width: 100%; height: 100%; object-fit: cover;
  /* Faces sit in the top third of most portrait source photos; without
     this the uniform 4:5 card crop centers on chests/paws instead. */
  object-position: center 22%;
  transition: transform 0.5s var(--ease-soft);
}
.story-card:hover img { transform: scale(1.04); }
.story-card-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(18, 13, 16, 0.92) 0%, rgba(18, 13, 16, 0.35) 45%, transparent 75%);
}
.story-card-body { position: absolute; inset-inline: 0; bottom: 0; padding: 18px; color: var(--text-on-dark); }
.story-card-name { font-size: 1.2rem; font-weight: 600; margin-bottom: 4px; }
.story-card-teaser { font-size: 0.85rem; color: var(--muted-on-dark); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.story-card-stamp {
  position: absolute; top: 14px; inset-inline-start: 14px;
  padding: 5px 12px; border-radius: 999px; font-size: 0.72rem; font-weight: 600;
  background: rgba(255, 255, 255, 0.12); backdrop-filter: blur(8px);
  border: 1px solid var(--hairline-dark); color: var(--text-on-dark);
}
.story-card-play {
  position: absolute; top: 14px; inset-inline-end: 14px;
  width: 30px; height: 30px; border-radius: 50%;
  background: rgba(244, 143, 177, 0.9); color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 0.75rem;
}

/* Archive card mini funding strip — same data as .story-funding on the
   story page, compressed for a card. story-card-body already sits
   pinned to the card's bottom edge, over the scrim and image (see
   above), so this naturally reads as "a strip at the card's bottom
   over the gradient" without any extra positioning of its own; it just
   needs to be thinner (5px, vs. the story page's 8px) to read as a
   secondary detail rather than compete with the name/teaser above it. */
.story-card-funding { margin-top: 10px; }
.story-card-funding-bar {
  height: 5px; border-radius: 999px; overflow: hidden;
  background: var(--hairline-dark);
}
.story-card-funding-fill {
  height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--pink-deep), var(--pink));
  transition: width 1.2s var(--ease-out);
}
.story-card-funding-pct {
  display: inline-flex; align-items: center; margin-top: 6px;
  padding: 2px 9px; border-radius: 999px; font-size: 0.68rem; font-weight: 600;
  color: var(--pink); background: rgba(244, 143, 177, 0.14);
  border: 1px solid var(--hairline-dark);
}

/* Ariel's card is set apart — dark, quiet, no hover-scale image race. */
.story-card-memorial { background: var(--night-2); }
.story-card-memorial .story-card-scrim { background: linear-gradient(to top, rgba(18, 13, 16, 0.96) 0%, rgba(18, 13, 16, 0.55) 60%, rgba(18,13,16,0.2) 100%); }
.story-card-memorial:hover img { transform: none; }
