/* =========================================================
   BEFORE THE MYTH - section wrapper
   Created 05.08.26 with the card's port from the Eternal Tales
   build.

   DELIBERATELY NOT a copy of ET's own css/v3/section-btm.css. That
   file is 697 lines, and its principal selectors (.btm-card,
   .btm-chips, .btm-stage, .btm-copy, .btm-selector, .btm-dots) appear
   ZERO times in ET's own index.html - it is the corpse of the era
   cross-fade contraption the card replaced. Only the section wrapper
   below was still live, so only the section wrapper came across.

   The card's own layout - .btm-band, .btm-hero, .btm-hero__text,
   .btm-sample, .btm-story - lives in the head <style> block of
   index.html, ported alongside this file.
   ========================================================= */

/* ---- The card's slot in the tile stack (05.08.26 v2) ----
   There is NO .section--btm on this site any more. The card is not a
   section of its own: it is an <li> in .et-tales-grid inside
   #our-stories, so the sticky Eternal Tales lockup stays pinned on the
   left while the card scrolls up the right-hand column. The column
   offset and width come from #eternal-tales-tales in
   section-our-stories-intro.css - nothing here should restate them, or
   the two will drift apart.

   A bare <li>, so the browser's list marker and the grid's own tile
   treatment both need clearing. .et-tale-tile is deliberately NOT used
   (it is a white card with dark ink). */
.et-tales-card {
  list-style: none;
  margin: 0;
  padding: 0;
  min-width: 0;
}

/* =========================================================
   ACCENT SCOPING - CONFIRMED BY HIM, 06.08.26. Coral stays.

   Measured before he ruled: the accent renders in exactly TWO
   places on this card - the "James Hutton" credit link and the
   "Save the dates" action with its calendar icon. Nothing else,
   and no pseudo-element. .et-card__title::after does inherit
   var(--accent) from section-et-card.css, but the card's own
   <h2> is .visually-hidden, so it never paints. If a future
   change makes that title visible, this list grows by one.

   The two sites do not share an accent. animatedcreative.ie is
   --accent: #FF3FD1, a vivid fuchsia. The Eternal Tales build is
   --accent: #FF6B4A, Living Coral, and its tokens.css records that
   the coral REPLACED the fuchsia on 19.05.26 - so the fuchsia here is
   the older colour, still correct as the studio's own mark.

   Before the Myth is Eternal Tales work. Ported unscoped, its accent
   sites would render fuchsia and the card would not match
   eternaltales.ie, where the same card is the book's own page. Scoped
   here rather than globally so the studio keeps its fuchsia everywhere
   else on the page, including the sibling tiles.

   05.08.26 v4: the card turned WHITE, and plain coral is 2.82:1 on
   white - a fail at every size. Every accent site inside this file now
   uses --accent-on-light (#C8452A, 4.84:1), which is that same coral
   darkened to clear AA. This block still matters for anything the card
   INHERITS a var(--accent) from elsewhere, such as
   .et-card__title::after in section-et-card.css.

   06.08.26: the fuchsia alternative was built and shown to him
   side by side. Raw #FF3FD1 is 3.05:1 on white and cannot carry the
   12px credit, so it had to be walked down its own hue to #D400A2
   (4.86:1) to be a fair comparison at all. He chose coral. To
   reverse it later, delete this block and swap --accent-on-light
   through this file to #D400A2.
   ========================================================= */
.et-tales-card {
  --accent:      #FF6B4A;
  --accent-soft: #E85838;
  --accent-tint: #FFE0D7;
}


/* =========================================================
   THE CARD ITSELF
   Ported 05.08.26 from the head <style> block of the ET build's
   index.html (its lines 2380-2999), where it lived inside
   <style id="preorder-ribbon-css">. It is in a FILE here, not a head
   block, because this build keeps all of its CSS in linked
   stylesheets - and because an inline duplicate that wins on source
   order is exactly the trap that made the ET contact-link colour take
   two edits to change.

   This file must stay linked AFTER section-et-card.css so these rules
   win where specificity ties.

   ET's .et-card--intro.fade-up timing override (its 2787-2793) was
   deliberately NOT carried: it retunes the ETERNAL TALES intro card's
   entrance, this build has its own intro card, and its pacing is not
   part of this port.
   ========================================================= */

/* The cue's bob. Defined in ET beside the hero pre-order CTA and used
   by BOTH that CTA and .btm-sample__cue below. The CTA's scroll
   hand-off could not travel (this build has no pinned lockup and no
   __etScroll registry), so the keyframe comes across HERE instead -
   port the card without it and the open-book cue's bob dies silently
   with no error anywhere. */
@keyframes heroPreorderBob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(4.24px); }
}

/* ---- The three stories (02.08.26, two columns 02.08.26 v2) ----
   One row per story, nothing hidden behind dots. The title, date
   and place now sit ABOVE the telling in the same column rather
   than in a third column of their own, so each row is simply
   text and image. The image column is the wider of the two
   relative to its earlier size, but still narrower than the
   cover above it, which stays the largest thing in the section.
   Rows separate with a hairline rather than boxes, so the card
   does not turn into a stack of panels. */
/* 03.08.26 v3, his read: at full card width the rows had "lost
   some visual identity". They now sit INSET from the card's
   content edge - a visibly narrower column than the full-bleed
   cover above, so the hierarchy reads cover first, tellings
   beneath it - and the image column steps down (2fr/1fr below,
   was 1.75/1.25) with the titles a notch smaller to match. */
.btm-stories {
  list-style: none;
  /* 05.08.26 v4: the bottom margin is NEW and load-bearing. The
     .et-card__release row that follows only carries
     margin-top: clamp(10px, 1.2vw, 16px) of its own, so the last
     telling - "Night by the Forest of Stone" - sat almost on top of
     the three format icons. Sized to the gap BETWEEN rows so the list
     ends with at least as much air as it has inside it. */
  margin: clamp(20px, 2.6vw, 36px) 0 clamp(26px, 3.2vw, 42px);
  padding: 0 clamp(32px, 7.5vw, 92px);
  display: grid;
  gap: clamp(18px, 2.2vw, 30px);
}
/* An open telling ends flush with its own panel, so the last row needs
   its own foot as well as the list's - otherwise the gap above the
   icons collapses the moment the third telling is opened. */
.btm-story:last-child {
  padding-bottom: clamp(6px, 0.9vw, 12px);
}
/* ---- The rows: TEXT WRAPS THE IMAGE (04.08.26 v12) ----
   His read: they were reading loose, and his instinct to wrap
   the text round the image was the right one. Why the grid was
   costing height, measured on the page before the change:
     - the title and date sat in a full-width band of their own
       above the columns, 57px tall for one short line of type;
     - the image was 37px SHORTER than the text beside it, so
       the right column ended in dead space;
     - the closing note formed a third full-width band below.
   Three stacked zones, each as tall as its tallest element.
   A float collapses them into one column of type with the
   image set into it: the title now sits beside the image, the
   prose closes underneath it, and the note follows on. Grid
   cannot do this - it has no way to flow text around a taller
   sibling - which is why the markup moved the <figure> to the
   head of each row and dropped the .btm-story__cols wrapper.
   Vertical rhythm tightened with it: less padding above each
   row, tighter head and note gaps. */
/* ---- COLLAPSED, ONE DISCLOSURE EACH (05.08.26 v3, his direction)
   The three tellings now open individually. ONE EACH rather than all
   three behind a single control, because the titles and their dates
   are the spine of this block: the order is deliberate and ascending
   (32,050 BCE, then 10,800, then 3,600), so the tellings climb
   towards the present and end nearest Weletos's own night. Hidden
   behind one toggle that reading disappears; left visible, the three
   titles read as a contents list and each opens on its own.

   The float still lives inside each panel, so an open telling reads
   exactly as it did before it collapsed. What moved is WHERE the
   float is contained: the clearfix and the phone ordering are now on
   .btm-story__panel-inner, not on .btm-story, because the row itself
   is only a heading plus a panel now. */
.btm-story {
  padding-top: clamp(14px, 1.7vw, 24px);
  /* 05.08.26 v4: ink hairline, see the card's white treatment. */
  border-top: 1px solid rgba(15, 20, 25, 0.14);
}
.btm-story:first-child { border-top: 0; padding-top: 0; }

/* The head is an <h3> wrapping the button, so the heading outline
   survives the collapse and the control is the whole row. */
.btm-story__head { margin: 0; }
.btm-story__toggle {
  /* Strip native button chrome; this is a row of type, not a button. */
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  width: 100%;
  display: grid;
  /* Title, date and chevron all on ONE row. The chevron had a row of
     its own under the date at first, which left it floating in space
     whenever a title wrapped to two lines and added height to a block
     whose whole purpose is to save it. */
  grid-template-columns: 1fr auto auto;
  align-items: baseline;
  column-gap: clamp(10px, 1.4vw, 18px);
  text-align: left;
}
.btm-story__toggle:focus-visible {
  outline: 2px solid var(--accent-on-light);
  outline-offset: 4px;
}
.btm-story__toggle .btm-story__date {
  /* The date rides the title's first baseline, not a line of its own -
     the collapsed state is one row per telling. */
  grid-column: 2;
  grid-row: 1;
  margin: 0;
  white-space: nowrap;
}
.btm-story__chevron {
  grid-column: 3;
  grid-row: 1;
  width: 9px;
  height: 9px;
  /* Nudged off the baseline: a rotated square has no baseline of its
     own and sits high against the small-caps date without this. */
  margin-bottom: 2px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transform-origin: 60% 60%;
  opacity: 0.55;
  transition: transform 300ms ease, opacity 300ms ease;
}
.btm-story__toggle[aria-expanded="true"] .btm-story__chevron {
  transform: rotate(-135deg);
  opacity: 0.9;
}
.btm-story__toggle:hover .btm-story__chevron { opacity: 0.9; }
.btm-story__toggle:hover .btm-story__title {
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}

/* Same collapse mechanism as the opening sample: a 0fr -> 1fr grid
   row, which animates to the panel's natural height without anyone
   having to measure it. */
/* [hidden] IS DEFEATED BY ANY display DECLARATION, and silently.
   The UA rule is `[hidden] { display: none }` at specificity (0,1,0);
   `.btm-story__panel { display: grid }` matches that and wins on source
   order, so the `hidden` attribute the toggle script sets did nothing.
   The panels still LOOKED shut, because 0fr plus overflow:hidden
   collapses them to no height - but their content stayed in the
   accessibility tree and their lightbox (i) buttons stayed in the tab
   order, so a keyboard user tabbed through three invisible controls and
   a screen reader read three closed tellings. Restoring it needs the
   attribute selector, which outranks the class. */
.btm-story__panel[hidden],
.btm-sample[hidden] {
  display: none;
}
.btm-story__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 380ms cubic-bezier(0.4, 0, 0.2, 1);
}
.btm-story__panel.is-open { grid-template-rows: 1fr; }
.btm-story__panel-inner {
  min-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: opacity 260ms ease;
}
.btm-story__panel.is-open .btm-story__panel-inner {
  opacity: 1;
  transition-delay: 90ms;
}
/* The panel must contain its own float or the image hangs past the
   hairline into the row beneath it. */
.btm-story__panel-inner::after {
  content: "";
  display: block;
  clear: both;
}
.btm-story__panel-inner > .et-card__underpinning,
.btm-story__panel-inner > .btm-watch {
  margin-top: clamp(10px, 1.1vw, 14px);
  max-width: none;
}
.btm-story__panel-inner > .btm-story__text:first-of-type {
  padding-top: clamp(8px, 1vw, 14px);
}
@media (prefers-reduced-motion: reduce) {
  .btm-story__panel,
  .btm-story__panel-inner,
  .btm-story__chevron { transition: none; }
}

@media (min-width: 760px) {
  /* Set into the type, not columned beside it. 33% keeps the
     image the same size it was in the old grid's right column,
     so nothing about its scale changes - only what happens to
     the text around it. */
  .btm-story__media {
    float: right;
    width: 33%;
    /* Full shorthand: this is the figure's only margin rule at
       this breakpoint, so it also does the <figure> default
       reset. The left gutter is the one that keeps the wrapped
       lines off the picture. */
    margin: 5px 0 clamp(12px, 1.4vw, 18px) clamp(24px, 2.8vw, 36px);
  }
}
/* Phones read prose BEFORE the picture. The <figure> leads the panel
   in the DOM so the float has something to wrap; ordering it back
   keeps the sequence place, prose, image, note. Flex only below the
   float's breakpoint, so it never fights the float. */
@media (max-width: 759px) {
  .btm-story__panel-inner { display: flex; flex-direction: column; }
  .btm-story__panel-inner::after { display: none; }
  .btm-story__panel-inner > .btm-story__text { order: 1; }
  /* Stacked: the image needs real air above it or it reads as
     clipping the last line of prose. Full shorthand here too,
     for the same reset reason as the float rule. */
  .btm-story__media { order: 2; margin: clamp(18px, 3.4vw, 26px) 0 clamp(8px, 1.4vw, 12px); }
  .btm-story__panel-inner > .et-card__underpinning,
  .btm-story__panel-inner > .btm-watch { order: 3; }
}
.btm-story__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  /* 03.08.26 v3: a notch down with the row inset (16-19 -> 15-17).
     04.08.26 v6 (ET): +50% on that, so the titles carried the rows the
     way the card's own headings carried it.
     05.08.26 v5, his read: OUT OF PROPORTION here. That bump was sized
     for the ET build, where the tellings are the card's whole lower
     half at up to 900px wide. In this column they are three collapsed
     rows in a white body, and at 22.5-25.5px they were competing with
     the cover above them and wrapping to two lines in the process.
     Back to roughly the pre-bump size: the anchors are the v3 values
     with a little of the increase kept (15 -> 17.5, 13.5 -> 15.75,
     17 -> 19.5), which reads as a heading without shouting. */
  font-size: clamp(17.5px, 0.45vw + 15.75px, 19.5px);
  line-height: 1.25;
  color: var(--primary-text);
}
.btm-story__date {
  margin: 6px 0 0;
  font-family: var(--font-serif);
  font-size: 12.5px;
  letter-spacing: 0.08em;
  /* 04.08.26 v6: the accent comes OFF the years. With
     the titles now half again as large the coral under each one
     read as a second signal competing with them; the date is
     supporting information and takes the soft tone the other
     cards' meta lines use. */
  color: var(--soft-text);
}
/* First line of the text column now, so the image aligns to it. */
.btm-story__place {
  margin: 0 0 0.7em;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 13px;
  color: var(--soft-text);
}
.btm-story__text {
  font-family: var(--font-serif);
  font-size: clamp(13.5px, 0.2vw + 13px, 15px);
  line-height: 1.65;
  color: var(--primary-text);
}
.btm-story__text > p { margin: 0 0 0.85em; }
.btm-story__text > p:last-child { margin-bottom: 0; }
/* 04.08.26 v13: the blanket `margin: 0` that stood here is GONE.
   It sat AFTER both layout rules with the same specificity, so
   it quietly won over every margin they set - the float lost
   its gutter and the stacked image lost its gap, which is why
   the images were running up against the type. Each breakpoint
   now sets the figure's margin in full shorthand, so the
   browser's default <figure> margin is still reset and there is
   no ordering trap left to fall into. */
.btm-story__media picture { display: block; }
.btm-story__media img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 2px;
}

/* 04.08.26 v7: the artwork is FULL BLEED and
   FLUSH TO THE CARD'S TOP. v6's inset put a black border on
   three sides; the black band above it was the card's own
   padding-top (the "empty top band" of 03.08, now superseded -
   .et-card--btm padding-top is 0 in section-et-card.css). The
   card's border-radius + overflow:hidden round the artwork's
   top corners for it. */
/* 05.08.26 v4, his direction: the cover was "far too zoomed in" and
   "too big". It was: at an 826px card the portrait cover rendered
   793 x 1223, over twelve hundred pixels of picture before a word of
   type, and the title baked into it came up huge.

   It is now a PLATE at 3/2, the same aspect .et-tale-tile__img uses,
   so all three cards in the section open at the same picture height.

   object-fit: CONTAIN, not cover. The tiles can crop because their
   artwork is landscape; cropping a 0.649 portrait cover into a 3/2
   landscape box would throw away most of it and show a horizontal
   band through the middle - which is exactly the "zoomed in" reading.
   Contained, the whole cover is visible, sized to the plate's height,
   centred, with the plate's own dark showing either side of it. It
   reads as a book standing on a dark ground. */
/* 05.08.26 v5, his direction: the 3/2 PLATE IS GONE with the return of
   the extended landscape. The plate existed to stop a 0.649 portrait
   cover running 1223px tall in the column; the landscape is 1.359, so
   at an 826px card it comes in around 608px on its own and needs no
   box holding it back.

   No aspect-ratio, no object-fit, no plate background: the artwork
   simply runs the card's full width at its own aspect and meets the
   card's top edge, which is the Eternal Tales arrangement and the one
   the artwork was made for. Below 700px the same <picture> serves the
   portrait cover instead, and it too runs full width at its own
   aspect - the markup's width/height pair on each branch is what keeps
   the box the right shape before the file lands. */
.btm-band {
  position: relative;
  margin: 0;
  padding: 0;
  display: block;
  overflow: hidden;
}
.btm-art__img {
  display: block;
  width: 100%;
  height: auto;
}
/* The scrim exists only where text is overlaid, i.e. from
   700px up (rule further down). On phones the cover carries no
   text, so it must not be dimmed. */
.btm-hero__scrim { display: none; }
/* The (i) moves to the bottom LEFT on this figure only. Its
   usual bottom-right corner is where the artwork prints the
   author's name, and the two sat on top of each other at every
   width. Bottom left is dark open ground in this composition. */
.btm-band .lightbox-trigger {
  left: 12px;
  right: auto;
}

/* On phones this paragraph is in normal flow beneath the
   portrait cover, but it sits OUTSIDE .et-card__body, so it
   gets none of that element's padding and ran flush to the
   card's edges while the paragraph below it was inset. Same
   clamp .et-card__body uses, so the two read as one column.
   (The 700px rule below zeroes it again for the overlay.) */
.btm-hero__text {
  padding: clamp(16px, 2vw, 24px) clamp(24px, 4.2vw, 46px) 0;
}

/* ---- The artwork as the card's opening (04.08.26 v7) ----
   From 700px up the extended artwork is scaled 15% and pinned
   to the RIGHT, so the title, the fire and the author name all
   hold their place and the surplus crops away at the card's
   LEFT edge - his instruction exactly. The dark gradient that
   survives on the left is where the opening paragraph sits.
   The 115%/-15% pair is one movement: the image spans -15% to
   100% of the card, so its right edge stays flush while the
   left runs off. max-width:none because shell.css caps every
   img at 100% and would silently undo the scale.
   Mobile keeps the portrait cover at 100%, uncropped. */
/* ---- THE OVERLAY IS RETIRED ON THIS SITE (05.08.26 v2) ----
   The ET build overlays both lede paragraphs and the cue ON the
   artwork from 980px up. That whole block is removed here, and it
   had to be: it was a MEASURED fit against a 900px full-width card,
   keyed to a VIEWPORT query as a proxy for "the card has reached its
   cap". On this site the card sits in the chamber's right column, so
   at a 1440px viewport the query would fire while the card is only
   ~580px wide - and the overlaid column, whose type has a floor the
   picture's height does not, would finish well below the artwork and
   spill onto whatever follows. That is the same failure the ET build
   measured at a 705px viewport, where the cue ended 206px below the
   picture.

   With the production cover instead of the extended landscape there
   is nothing to overlay onto in any case: the portrait cover carries
   its own title and has no painted gradient lane for type to sit in.

   So the card reads in ONE arrangement at every width: cover, then
   credit, then prose, then the cue. That is the arrangement the ET
   build falls back to below 980px, and the one that needs no
   guarding. Do not reintroduce the overlay here without re-measuring
   against the COLUMN width, not the viewport. */
/* (04.08.26 v5: .btm-book__object / .btm-book__img are RETIRED
   with the standing cover panel. The card shows his extended
   artwork full bleed, which needs no object treatment: no
   halo, no page edge, no standing shadow. The btm-book-*
   image files stay on disk - the /preorder page's share image
   still points at the portrait cover, which is the right
   picture for a link preview.) */

/* ---- Embers (01.08.26, rebuilt 02.08.26) ----
   His direction: the SAME particle field the chamber already
   uses, pulled in front here and burned to ember colour. So
   this is the chamber's recipe, not a new one: the identical
   six-circle gradient set at the same 7 to 12px mote sizes,
   moved by exactly one tile on transform so the loop is
   seamless. The only changes are the palette (amber to
   ember), a 750px tile instead of 1500 because this block is
   a fraction of the chamber's area and the motes would
   otherwise be too sparse to read, and z-index, which puts
   them IN FRONT of the cover rather than behind everything.

   Drift speed is deliberately matched to the chamber, not
   guessed: 1500px in 224s is ~6.7px/s, so 750px takes 112s.
   The two fields move at the same rate, which is what makes
   them read as one effect across the page.

   It only runs while the cover is on screen: the observer at
   the foot of <body> toggles .is-live. Off screen the
   animation is not merely paused, it is not applied. */
.btm-embers {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  overflow: hidden;
  opacity: 0;
  transition: opacity 1200ms ease;
}
.btm-band.is-live .btm-embers { opacity: 1; }
.btm-embers::before {
  content: "";
  position: absolute;
  left: -30%;
  width: 160%;
  top: -60%;
  height: 220%;
  background-repeat: repeat;
  will-change: transform;
  background-image:
    radial-gradient(circle 10px at 20% 20%, rgba(255, 176, 92, 0.20), transparent 80%),
    radial-gradient(circle  8px at 70% 60%, rgba(255, 150, 68, 0.16), transparent 80%),
    radial-gradient(circle 12px at 40% 80%, rgba(255, 188, 108, 0.18), transparent 80%),
    radial-gradient(circle  9px at 85% 35%, rgba(255, 160, 78, 0.17), transparent 80%),
    radial-gradient(circle 11px at 10% 65%, rgba(255, 190, 112, 0.16), transparent 80%),
    radial-gradient(circle  7px at 55% 10%, rgba(255, 168, 84, 0.18), transparent 80%);
  background-size: 750px 750px;
}
.btm-band.is-live .btm-embers::before {
  animation: btmEmberRise 112s linear infinite;
}
@keyframes btmEmberRise {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-150px, -750px, 0); }
}
/* Sparks that do not rise are just dots on a book, so the
   whole layer goes rather than merely stopping. */
@media (prefers-reduced-motion: reduce) {
  .btm-embers { display: none; }
}
/* 04.08.26 v5: height:100% is GONE with the standing cover.
   The artwork sets the band's height from its own aspect
   (width:100%, height:auto on the img), so a stretched picture
   box would only fight it. */
/* height is back to auto with the plate gone: the img sizes itself
   from its own aspect now (width: 100%, height: auto), so a stretched
   picture box would only fight it.
   If a fixed-height plate is ever wanted here again, remember that
   .btm-art__img's height percentage resolves against THIS element and
   not against .btm-band - leave this at auto and the img silently
   falls back to its intrinsic height, object-fit does nothing, and
   .btm-band's overflow: hidden crops the cover. */
.btm-band picture {
  display: block;
  width: 100%;
}

/* 03.08.26: the Vision card arrives on a slower, gentler curve
   than the other cards. The base .fade-up is 400ms with a 72px
   rise; this takes it to 1100ms and eases it out rather than
   through, so the card settles rather than snaps and the
   chamber flooding behind it stays readable for longer while it
   does. Only this card: the tale cards keep the house timing,
   or the whole page starts to feel slack. */

/* ---- The sample (01.08.26, rebuilt 03.08.26) ----
   Was a <details> living inside the text column beside the
   cover. Two problems on click: the passage opened at half the
   card's measure, so a long quoted paragraph became a narrow
   ribbon of text, and the whole card jumped as the column grew.
   Now the CUE stays in the column (it is the last thing there,
   which is what lines it up with the artwork credit) and the
   PASSAGE opens full width beneath the lede.
   button + [hidden] panel instead of <details> so the control
   can carry aria-expanded, say what it does, and animate. */
/* (03.08.26 v3: the .btm-title rules that lived here - Ireland
   a step larger in the cover's cream - are gone with the
   visible title itself. The cover artwork now
   carries the title alone; the card's h2 survives visually
   hidden for the outline and aria-labelledby.) */

/* ---- Read-the-opening cue (03.08.26 v2) ----
   A proper button now: white text on a quiet bordered pill,
   centred in its column, filling with the accent on hover. The
   copy invites rather than labels. */
.btm-sample__cue {
  margin: clamp(14px, 1.6vw, 22px) 0 0;
  text-align: center;
}
/* 03.08.26 v3: compact (flame + three words, one line).
   v4: the box outline is GONE - the cue now speaks
   in the site's bare text-action voice (same species as Watch
   the animation / the btm-actions below): flame, white caps,
   no border, turning accent on hover. Padding kept small only
   for the hit area. */
/* 04.08.26 v9: the icon STACKS above the label and
   leads, so it is the book you see first and it sits centred
   under the column. Column flow rather than a row; the label
   keeps the site's caps-tracked action voice. */
.btm-sample__toggle {
  cursor: pointer;
  background: none;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  padding: 6px 2px;
  border: 0;
  font-family: var(--font-serif);
  font-size: var(--body-small);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--primary-text);
  transition: color var(--t-standard) var(--ease-standard);
}
/* (04.08.26 v8: renamed from --flame with the icon swap to the
   open book. v9: bigger again, 18 -> 30, now that it
   leads the cue rather than sitting beside the words.) */
.btm-sample__toggle-icon {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  display: block;
}
/* 04.08.26 v9: the cue rides the same bob as the hero's
   pre-order block (heroPreorderBob, defined with that rule) -
   the cue animates like the initial CTA. Same
   1.8s period and easing, so anything else bobbing on the page
   moves with it rather than against it. */
.btm-sample__cue {
  animation: heroPreorderBob 1.8s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .btm-sample__cue { animation: none; }
}
.btm-sample__toggle:hover,
.btm-sample__toggle:focus-visible {
  color: var(--accent-on-light);
}
/* (04.08.26 v9: the down arrow is REMOVED, and the
   rotate-on-open rule goes with it. The book icon and the
   label's own swap to "Close the book" carry the state.) */
.btm-sample__toggle:focus-visible {
  outline: 2px solid var(--accent-on-light);
  outline-offset: 3px;
}

/* The panel animates on grid-template-rows 0fr -> 1fr, which is
   the one way to transition to an AUTO height without pinning a
   max-height guess that clips long content or eases oddly. The
   inner element carries overflow:hidden so the rows collapse
   cleanly. Browsers without it simply get the open state with
   no animation, since [hidden] still does the showing. */
.btm-sample {
  margin: clamp(16px, 2vw, 26px) clamp(24px, 4.2vw, 46px) 0;
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 420ms var(--ease-standard, ease);
}
.btm-sample.is-open { grid-template-rows: 1fr; }
/* 03.08.26 v2: retuned on his read. The +50% pass overshot into
   display sizes (26px in a 46ch ribbon), which read as badly
   designed rather than generous. Now a proper reading column: a
   shade up on the card's own prose, at book measure. Still a
   centred BLOCK with left-aligned text, no hairline. */
/* 03.08.26 v3: the passage opens AS A PAGE OF THE BOOK, his
   direction: the site's cream tokens (the interior prints on
   cream paper), dark ink, generous page margins.
   STRUCTURE MATTERS HERE: .btm-sample__inner is the collapse
   element (overflow hidden, min-height 0, NO padding: with
   border-box a padded element cannot shrink below its padding,
   which would stall the 0fr collapse at a cream sliver). The
   padding, background and shadow all live on .btm-sample__page
   nested inside it, so the collapse closes to a true zero and
   the page clips cleanly while it moves. */
.btm-sample__inner {
  overflow: hidden;
  min-height: 0;
  max-width: min(66ch, 94%);
  margin-inline: auto;
  opacity: 0;
  transition: opacity 300ms var(--ease-standard, ease);
}
.btm-sample.is-open .btm-sample__inner { opacity: 1; }
.btm-sample__page {
  text-align: left;
  background: var(--cream);
  border-radius: 2px;
  box-shadow:
    inset 0 -3px 0 var(--cream-deep),
    0 12px 34px rgba(0, 0, 0, 0.55);
  padding: clamp(26px, 3.4vw, 44px) clamp(22px, 3vw, 40px);
}
.btm-sample__page p {
  margin: 0 0 0.9em;
  font-family: var(--font-display);
  font-size: clamp(17px, 0.3vw + 16px, 19.5px);
  line-height: 1.65;
  color: var(--cream-text);
}
.btm-sample__spoken { font-style: italic; }
.btm-sample__note {
  margin: 0 !important;
  font-family: var(--font-serif) !important;
  font-size: 12px !important;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  /* 0.66, not 0.55: at 12px on the cream page (#EFE7D8) the old
     alpha measured 3.37:1, under the 4.5:1 AA floor for small
     text. 0.66 measures 4.60:1. Do not lighten it again without
     re-measuring. */
  color: rgba(42, 36, 28, 0.66) !important;
}
@media (prefers-reduced-motion: reduce) {
  .btm-sample,
  .btm-sample__inner { transition: none; }
}

/* ---- The two routes: calendar, or the list (01.08.26) ----
   03.08.26 v3: icon-led and short (see the markup
   note). The full-width underline went with the long labels;
   the hover affordance is now an underline on the label span
   alone, so the glyphs stay clean.
   v4: the pair stands in its own BAND at the card's foot, a
   hairline above, generous air on both sides of the line, the
   two routes centred and well apart. The breathing room here is
   load-bearing, not decoration. */
.btm-actions {
  margin: clamp(28px, 3.6vw, 52px) 0 clamp(6px, 0.8vw, 12px);
  padding-top: clamp(20px, 2.6vw, 34px);
  /* 05.08.26 v4: ink hairline. The card is white now; a white rule
     on white is invisible. */
  border-top: 1px solid rgba(15, 20, 25, 0.14);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(14px, 2vw, 28px) clamp(32px, 5vw, 72px);
  align-items: center;
}
.btm-action {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-serif);
  font-size: var(--body-small);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-on-light);
  text-decoration: none;
  border-bottom: none;
}
.btm-action__icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  display: block;
}
.btm-action:hover span,
.btm-action:focus-visible span {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
.btm-action:focus-visible {
  outline: 2px solid var(--accent-on-light);
  outline-offset: 3px;
}
.btm-action--soft { color: var(--soft-text); }
.btm-action--soft:hover,
.btm-action--soft:focus-visible { color: var(--primary-text); }



/* The hero pre-order CTA's rules lived here until 06.08.26. Removed
   with the CTA, parked in the launch runbook. @keyframes heroPreorderBob
   above is NOT part of it and must stay - .btm-sample__cue uses it. */


/* =========================================================
   THE RELEASE DETAIL AS THE BODY'S LEAD (05.08.26 v5)
   His direction: larger, and ahead of the prose rather than at the
   card's foot beneath the tellings.

   It was .et-card__releasing at clamp(11px, 0.3vw + 10px, 13px) in
   --soft-text, sitting under the format icons - the smallest and
   quietest type on the card, carrying the only time-critical fact on
   it. The two dates are the whole reason the card is on the studio
   site before the book exists, so this line now opens the body and is
   set at roughly the prose's own size.

   Not the accent. It is a statement of fact, not a control, and the
   card already spends its accent on Save the dates below; a second
   coloured line above the prose would read as a second button.
   --primary-text at 18.51:1 carries it on weight and position alone.

   LAUNCH PERIOD ONLY: after 31 August this rule and the markup that
   uses it come out together.
   ========================================================= */
.et-card__releasing--lead {
  margin: 0 0 clamp(16px, 2vw, 26px);
  font-size: clamp(15px, 0.35vw + 13.6px, 17px);
  line-height: 1.45;
  color: var(--primary-text);
  /* Not italic. At this size the italic serif started to read as a
     pull-quote rather than a date line. */
  font-style: normal;
  letter-spacing: 0.005em;
  /* A rule under it, so it reads as a standing detail above the prose
     rather than as the prose's own first paragraph. */
  padding-bottom: clamp(12px, 1.5vw, 18px);
  border-bottom: 1px solid rgba(15, 20, 25, 0.14);
}

/* 07.09.26 night, his word: the buy link goes onto the same line as
   Out now. The lead becomes a flex row, the date line left and the
   action right, both on one baseline. On a phone too narrow for both
   the action wraps under the line, still right aligned. The note above
   about not spending the accent here is superseded by his ruling: the
   action IS the accent on this card now, the foot carries none. */
.et-card__releasing--lead {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 16px;
}
.et-card__releasing-text { flex: 1 1 auto; }
.btm-action--lead { margin-left: auto; white-space: nowrap; }
/* From 760px up the row never wraps: the action holds the first line
   beside Out now, and where the column is too narrow for the whole
   date line beside it (measured 434px at 1280 wide against the 430px
   the sentence needs at 17px) the date alone wraps beneath, the
   action staying level with Out now. On a phone the action drops
   under the line instead, right aligned, since three lines of date
   beside a button would be worse. */
@media (min-width: 760px) {
  .et-card__releasing--lead { flex-wrap: nowrap; }
  .et-card__releasing-text { flex: 1 1 0; min-width: 0; }
}

/* ---- SAVE THE DATES, CENTRED (05.08.26 v5) ----
   .btm-actions was a flex row built to hold TWO routes apart from each
   other; with "Join the fireside" removed at his direction it holds
   one, and justify-content: center already centres it. What did not
   survive the removal is the column gap, which was doing the visual
   work of keeping the pair off each other - stated here so nobody
   re-adds a second action and wonders where the spacing went. */
.btm-actions {
  justify-content: center;
  text-align: center;
}


/* ---- Landing offset for the card's own anchor (05.08.26) ----
   #before-the-myth had no scroll-margin-top, so both routes to it - the
   nav child link and the hero pre-order CTA - put the card's top edge
   at viewport y=0, behind the fixed nav. The visitor arrived at the
   book with the first 76 to 100px of it covered.

   var(--nav-height) is a clamp(). That is fine HERE, because CSS
   resolves it; it is NOT fine in JS, where parseFloat on the raw
   custom-property string yields NaN and the readers fall back to a
   hardcoded 100. nav.js reads this back through
   getComputedStyle(target).scrollMarginTop, which is already resolved,
   so the clamp is honoured on the jump. */
#before-the-myth {
  scroll-margin-top: calc(var(--nav-height) + clamp(12px, 1.5vh, 24px));
}


/* ---- The artwork credit, on the white card (05.08.26) ----
   Fallout from the card turning white in v4. The base .et-card__credit
   is --quiet-text (#7B8E94), which tokens.css itself marks as AA for
   LARGE TEXT ONLY - and this sets it at 12px. Measured on the card's
   resolved #FFFFFF backdrop it came to 3.42:1, a fail.

   --soft-text is 4.74:1 at the same size and is the token this build
   already uses for small text on light surfaces.

   The link needed its own fix as well: it inherited the credit's colour
   exactly, so "James Hutton" was distinguished from the words around it
   only by a border-bottom at 0.25 alpha, which is not a reliable
   affordance and disappears entirely against some displays. It now
   takes the accent and a legible underline. */
.et-card--btm .et-card__credit {
  color: var(--soft-text);
}
/* 06.08.26: the underline was a hardcoded rgba(200, 69, 42, 0.4) - the
   literal value of --accent-on-light at the time. That decoupled it from
   the token, so any change to the accent left a coral underline under a
   differently-coloured word. Derived from the token now. color-mix is
   already load-bearing in nav.css, so it costs no new support floor. */
.et-card--btm .et-card__credit a {
  color: var(--accent-on-light);
  border-bottom-color: color-mix(in srgb, var(--accent-on-light) 40%, transparent);
}
.et-card--btm .et-card__credit a:hover,
.et-card--btm .et-card__credit a:focus-visible {
  color: var(--accent-on-light);
  border-bottom-color: var(--accent-on-light);
}
