/* ==========================================================================
   HezeMoore.com
   Rebuilt from the original Webflow site. Every colour, size and spacing
   value below was measured directly from the live page.

   Deliberate changes are marked A11Y. They exist because the site's visitors
   skew over 60. Nothing else has been altered.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Fonts, served from this site rather than from Google
   Converted from Adele's own .ttf files, subset to Latin and Latin Extended
   and compressed to woff2: 641 KB of TrueType became 120 KB.

   Roboto is Apache 2.0. Great Vibes is SIL Open Font License; its OFL.txt
   sits beside the files in fonts/, which that licence requires.

   Allison is SIL Open Font License too. It ships in Regular only, so the
   photograph titles at font-weight 700 are synthesised bold by the browser.
   That is exactly what the Webflow original did, and it is reproduced here
   on purpose. For a cleaner, finer script, change .shot__title and
   .lightbox__title to font-weight 400.

   Nothing on this site is fetched from anywhere else. No Google Fonts, no
   CDN, no outside requests at all.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: Roboto; font-style: normal; font-weight: 400;
  font-display: swap; src: url("../fonts/roboto-400.woff2") format("woff2");
}
@font-face {
  font-family: Roboto; font-style: italic; font-weight: 400;
  font-display: swap; src: url("../fonts/roboto-400italic.woff2") format("woff2");
}
@font-face {
  font-family: Roboto; font-style: normal; font-weight: 500;
  font-display: swap; src: url("../fonts/roboto-500.woff2") format("woff2");
}
@font-face {
  font-family: Roboto; font-style: normal; font-weight: 700;
  font-display: swap; src: url("../fonts/roboto-700.woff2") format("woff2");
}
@font-face {
  font-family: "Great Vibes"; font-style: normal; font-weight: 400;
  font-display: swap; src: url("../fonts/greatvibes-400.woff2") format("woff2");
}
@font-face {
  font-family: Allison; font-style: normal; font-weight: 400;
  font-display: swap; src: url("../fonts/allison-400.woff2") format("woff2");
}

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */
:root {
  --smoke:       #f3f0f0;

  /* Two slates, because the live site has two. I unified these on #5e748b at
     one point, reasoning from Adele's InDesign layout, which uses that value
     throughout. The built site does not: its panels are #69798a and only the
     columns behind the photographs are #5e748b. The layout is the intention,
     the live site is what shipped, and the live site is the brief.
     Measured from hezemoore.com, not inferred. */
  /* A11Y — #69798a as measured, darkened by about 2%. White text on the
     measured value is 4.47:1 and AA asks 4.5, so every panel on a slate
     ground was a hair short, the Homegoing details included. This value
     carries white at 4.80:1 with room to spare. The shift is roughly one
     step in each channel and does not read as a different blue. */
  --slate:       #647485;
  --slate-deep:  #5e748b;
  --ink:         #333333;
  --rule:        #c7cbd1;   /* the hairline under a panel title */
  --white:       #ffffff;

  /* The ground behind Heze's Reel, and the only dark ground on the site.
     Adele picked it on a phone and the reason it works is that this is the one
     section with nothing to read on it: a title and a film. Light grounds read
     better for text, which is why everything else here is light. That cost
     does not exist here. 12.63:1 against the white above it. */
  --reel-ground: #333333;
  --black:       #000000;

  /* SPLIT OUT FOR DARK MODE, and useful on their own.

     --white stays pure white and is only ever ink or a hairline, almost all of
     it on a slate ground, so it holds in either mode.

     --surface is the paper a page or a card is printed on. It was --white and
     is now separate, because in dark mode a background has to move and a
     white letter on slate does not.

     --mount is the card a photograph sits on, in the filmstrip and in the
     lightbox. Separate again, because a photograph's immediate surround
     changes how the photograph itself reads. */
  --surface:     #ffffff;
  --mount:       #f3f0f0;

  /* The script. Allison and Great Vibes, on photo titles, memory names and
     the down arrows. It was --black, which also fills the hymn player and the
     black half of the home page. Those two want different things in the dark:
     a video well stays black, a handwritten name has to be readable. */
  --script-ink:  #000000;

  /* A link inside a paragraph, as opposed to a nav link or a button. Only the
     disclosures page has these today, and every page the business sells will
     have more. 6.02:1 on white. */
  --link-ink:    #4e657e;

  /* A11Y — contrast corrections. Original body copy (#69798a on #f3f0f0)
     measured 3.99:1 and nav links (#83888f on #ffffff) 3.57:1; WCAG AA needs
     4.5:1. Same hues, darkened to 5.4:1 and 5.7:1. */
  --body-ink:    #55636f;
  --nav-ink:     #5f6670;

  --row-h:       900px;
  --band-h:      550px;
  --frame-gap:   77px;

  /* Filmstrip photo height. Sized against the window so the strip and its
     captions sit on one screen wherever possible, rather than making people
     scroll down and then sideways. */
  --shot-h:      clamp(320px, calc(100vh - 430px), 560px);
  --focus:       #1d4ed8;
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--surface);
  color: var(--ink);
  font-family: Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 16px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; border: 0; display: block; }
h1, h2, h3, p { margin: 0; }
a { color: inherit; }

a:focus-visible,
button:focus-visible,
.strip:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--surface); color: var(--ink);
  padding: 14px 22px; font-size: 17px; text-decoration: none;
  border: 2px solid var(--ink);
}
.skip-link:focus { left: 12px; top: 12px; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------------
   3. Masthead and navigation
   -------------------------------------------------------------------------- */
.masthead { background: var(--surface); padding-top: 30px; }

.masthead__inner { max-width: 940px; margin: 0 auto; padding: 19px 0 7px; }

.masthead__wordmark { display: block; width: 626px; max-width: 100%; margin: 0 auto; }

.nav {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  flex-wrap: wrap;
  /* Was 460px for two items. Three need the room, and wrapping keeps the
     third from being pushed off a narrow phone. */
  max-width: 760px; margin: 0 auto; padding-bottom: 64px;
}

/* A11Y — same size and letterspacing as the original, darker ink, 48px target. */
.nav__link {
  display: inline-flex; align-items: center;
  min-height: 48px; padding: 0 20px;
  color: var(--nav-ink);
  font-size: 19px; letter-spacing: 2px; text-transform: uppercase;
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
.nav__link:hover { color: var(--ink); }
.nav__link[aria-current="page"] { color: var(--ink); border-bottom-color: var(--ink); }

.nav__divider { color: var(--nav-ink); font-size: 19px; user-select: none; }

/* Below 490px the three items no longer fit on one line, and each divider is
   its own flex item, so one of them ends up stranded at the end of a row with
   nothing after it. The links already carry 20px of padding either side, which
   is separation enough once they are stacked. */
@media (max-width: 489px) {
  .nav__divider { display: none; }
}

/* ==========================================================================
   3b. THE NAVIGATION AS A BAR, ABOVE THE BANNER

   TO PUT IT BACK THE WAY IT WAS: delete this whole block, down to the end
   marker, and nothing else. No HTML moved. The wordmark still comes first in
   the markup on all five pages and the bar is lifted above it with flex
   order, so undoing this is one deletion rather than an edit to five files.

   WHAT IT LOOKED LIKE BEFORE, for certain:
     .masthead        background white, padding-top 30px, no flex
     .masthead__inner max-width 940px, margin 0 auto, padding 19px 0 7px
     .nav             centred under the banner, gap 8px, max-width 760px,
                      margin 0 auto, padding-bottom 64px,
                      no background of its own and no rule
     .nav__link       font-size 19px, letter-spacing 2px, padding 0 20px,
                      min-height 48px
     .nav__divider    visible, 19px
     under 768px      .nav gap 2px, padding-bottom 40px
                      .nav__link font-size 17px, padding 0 14px
     under 490px      .nav__divider hidden

   WHAT CHANGED AND WHY:
     Type goes 19px to 17px. Still well above the 14 or 15px a nav bar
     usually runs at, which matters here: the people using this site are
     mostly over 60. The 48px touch target is untouched; the bar is 58px.
     The dividers go, because a bar separates by position and a rule, and
     pipes inside one read as leftovers.
   ========================================================================== */
.masthead {
  display: flex; flex-direction: column;
  /* Samaria asked for more air above and below the bar. Above comes from here,
     below from .masthead__inner. The bar itself is untouched at 58px, so the
     touch targets do not move. */
  padding-top: 20px;
}

.nav {
  order: -1;                       /* above the banner, without moving markup */
  /* The base rule centres this with auto side margins. An auto margin beats
     the column's stretch, so without clearing it the bar is only as wide as
     its own links and the rule underneath stops short of both edges. */
  max-width: none; margin: 0; gap: 0;
  padding: 0 24px;
  border-bottom: 1px solid var(--rule);
}

.nav__link {
  min-height: 58px; padding: 0 22px;
  font-size: 17px; letter-spacing: 1.5px;
}

.nav__divider { display: none; }

/* The air the banner used to get from the masthead's own padding now sits
   under the bar instead, so the wordmark keeps the same room above it.
   Raised from 34px on Samaria's note. */
.masthead__inner { padding-top: 52px; }

/* Written as .masthead .nav rather than .nav so these hold whatever else the
   stylesheet says further down. The phone rules for the old centred layout
   are still in section 13 and would otherwise win on being later. */
@media (max-width: 767px) {
  .masthead { padding-top: 14px; }
  .masthead .nav { padding: 0 10px; }
  .masthead .nav__link { font-size: 16px; padding: 0 13px; min-height: 48px; }
  .masthead .masthead__inner { padding-top: 36px; }
}
/* ===================== end of the nav bar block ========================== */

/* --------------------------------------------------------------------------
   4. Alternating image + text rows
   -------------------------------------------------------------------------- */
.row { display: flex; width: 100%; min-height: var(--row-h); }
.row--flip { flex-direction: row-reverse; }

.row__half {
  width: 50%; position: relative; display: flex;
  overflow: hidden; background: var(--slate-deep);
}
.row__half--smoke { background: var(--smoke); }
.row__half--slate { background: var(--slate); }
.row__half--black { background: var(--black); }

/* The cover page only has the one row, so a smoke half met the white masthead
   in a hard horizontal seam with nothing above or below to make sense of it.
   White carries the header straight down the page instead. */
.row__half--white { background: var(--surface); }

/* Out of flow so the photo sits in its half however tall the row is. In flow
   it would push the row to its own aspect ratio.

   The photo fills its column edge to edge. Fitting it inside instead left
   bands of the column colour down the sides, which read as a mistake rather
   than as a mount.

   Where the proportions differ something has to be trimmed, and the rule is
   Adele's: keep a little clear space above the head and take the rest off the
   bottom. That is what --pos carries. Each photograph sets its own value in
   the HTML, because the subject sits at a different height in every one; a
   single global value would behead somebody. The number is the share of the
   image kept above the crop, so a low percentage holds the top of the frame. */
.row__photo,
.band__photo {
  object-fit: cover;
  object-position: var(--pos, center);
}

.row__photo {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
}

/* The father-and-baby photograph, where the top of his head must survive
   whatever the row does. It still fills its column, but the crop is taken
   from the top of the frame, so anything the column cannot hold comes off
   the bottom and never off his head. Row height below is set to the
   picture's own proportion, so on a normal screen nothing is trimmed at all
   and his hand under the baby stays in shot too. */
.row__photo--whole { object-fit: cover; object-position: center top; }

.panel {
  flex: 1;
  display: flex; flex-direction: column;
  align-items: center;
  /* SAMARIA'S NOTE: the two halves should start level. They did not, because
     this was centred: a panel with a lot of visible text filled its frame and
     looked top-aligned, while the shorter Tribute panel floated to the middle
     of its own. Started from the top, every panel on the site begins at the
     same height whatever its length. */
  justify-content: flex-start;
  /* The title brings 55px of air down from the top of the frame; the foot
     needs the same or the Read More button sits on the border. */
  margin: var(--frame-gap); padding: 48px 0;
  border: 1px solid var(--black); border-radius: .5px;
}
.panel--light { border-color: var(--white); }

/* Weight is declared on every heading below, and that is deliberate. Left
   undeclared, an <h1> or <h2> falls through to the browser's own default of
   700 and the tag ends up choosing the design: the hymn subtitle, a <p>, drew
   at 400 while the identical-looking biography subtitle, an <h2>, drew at 700.
   Measured on the live site: Roboto 400, not 500 and certainly not 700. The
   InDesign layout embeds Roboto-Medium, so the intention was 500, but what
   Webflow actually built is 400. Uppercase and the letterspacing carry the
   emphasis instead of weight. */
.panel__title {
  /* Set by measuring Adele's own capture of the original and matching its
     proportions, not by copying declarations. Cap height, the width of the
     words against it, the gap down to the rule and the gap on to the subhead
     are all within 3% of hers. Tracking reads lower than the original
     stylesheet's 1px because what matters is the rendered result, and this is
     what reproduces it. */
  font-size: 28px; line-height: 36px; font-weight: 400;
  letter-spacing: .45px;
  text-transform: uppercase; text-align: center;
  color: var(--ink);

  /* Holding 28px on a phone means a long title wraps where the original
     shrank it instead. Balanced so the two lines come out close in length,
     rather than one long line and one short one under a full-width rule. */
  text-wrap: balance;
  display: inline-block; max-width: calc(100% - 40px);
  margin: 55px 0 10px;
  padding: 0 1.5px 4px 0.5px;   /* the rule reaches a hair past the words, as the original does */
  border-bottom: 1.5px solid var(--rule);
}
.panel__title--light { color: var(--white); border-bottom-color: var(--white); }

/* RETIRED 14 September 2026. The original site dropped the Homegoing panel's
   title 95px rather than the 55px every other panel uses (.heading.white._1).
   That made sense while the panels were vertically centred and each one found
   its own height. Now that they all start from the top it read as a mistake,
   and Adele's call was to level it: "It's ok to fix irregularities from the
   original design." The class is gone from index.html too.
   .panel__title--low { margin-top: 95px; } */

.panel__subtitle {
  margin-top: 0; margin-bottom: 0;
  font-size: 18px; line-height: 30px; letter-spacing: .65px; font-weight: 400;
  text-transform: uppercase; text-align: center;
  color: var(--ink); padding: 0 24px;
}
/* var(--white), not var(--smoke). The sibling title and body on this same
   panel both use --white, and this one line used the page-ground token
   instead. That reads as a near-white in light mode and a NEAR-BLACK in dark
   mode, where it measured 1.14:1 on the slate and was effectively invisible.
   White fixes both: 4.80:1 in light, where --smoke was 4.23:1 and also short. */
.panel__subtitle--light { color: var(--white); margin-top: 9px; line-height: 21px; }

/* A11Y — was 17px/30px in a colour that failed contrast, and the biography was
   trapped in a 502px scroll box hiding about 80% of the text. */
.panel__body {
  /* Original: 17px/30px with a 32px lead-in. This is 18px/32px for legibility,
     a factor of 1.06, so the lead-in scales to 34px rather than staying at the
     smaller type's value. */
  margin-top: 34px; padding: 0 52px; max-width: 60ch;
  font-size: 18px; line-height: 32px; color: var(--body-ink);
}
.panel__body--light { color: var(--white); }
.panel__body--center { text-align: center; }

.panel__body a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }

/* --------------------------------------------------------------------------
   5. Wordmark bands
   -------------------------------------------------------------------------- */
.band { display: flex; width: 100%; min-height: var(--band-h); }
.band--flip { flex-direction: row-reverse; }

/* Pin both bands to the same height on desktop, as on the original site. */
@media (min-width: 992px) {
  .band { height: var(--band-h); }
  .band__figure { height: 100%; }

  /* One exception. The Shanghai photograph is the only one whose subject is
     partly the place: the Oriental Pearl Tower identifies it as Pudong. The
     spire sits about 8% down the frame and the family's heads at 48%, so
     squeezing it into the standard band meant losing 89px with nowhere to
     take it from that did not cut either the landmark or the people. This
     band grows instead, and the photograph is shown whole. */
  .band--tall { height: auto; min-height: var(--band-h); }
  .band--tall .band__figure { height: auto; }
  .band--tall .band__photo { flex: 0 0 auto; height: auto; width: 100%; }

  /* The father-and-baby photograph has the top of his head at 7% of the frame
     and his hand under the baby at 87-97%. Cropping to a window shorter than
     the picture always cost one or the other, and Adele's answer was that
     neither should go. So this row takes its height from the photograph
     instead of imposing one: half the viewport wide, times the picture's own
     1:1.487 proportion. The photograph then fills its column edge to edge at
     every desktop width with nothing trimmed at all. */
  .row--tall { min-height: calc(50vw * 1.4874); }
}

.band__figure {
  width: 50%; margin: 0; background: var(--slate);
  display: flex; flex-direction: column; overflow: hidden;
}

.band__photo { width: 100%; flex: 1; min-height: 0; }

.band__caption-title {
  padding: 20px 16px 0;
  font-size: 25px; line-height: 1.1; text-transform: uppercase;
  text-align: center; color: var(--white);
}

.band__caption-text {
  padding: 8px 16px 20px;
  font-size: 17px; line-height: 1.4; letter-spacing: .5px;
  text-align: center; color: var(--white);
}

.band__text {
  width: 50%;
  display: flex; flex-direction: column; justify-content: center;
  background: var(--surface);
}

/* A11Y — was 30px Great Vibes, very light at that size.

   No margin above it. The white column centres its contents, so a margin on
   the first line is counted as part of the group and pushes the whole thing
   down: the block ended up with 120px of white above the script and 51px
   below it, which is the lopsidedness Adele spotted. With the margin gone the
   group sits true and the white above and below matches. */
.band__lead-in {
  margin-top: 10px;
  padding: 0 78px;
  font-family: "Great Vibes", cursive;
  font-size: 34px; line-height: 1.3; font-weight: 400; color: var(--ink);
}

/* height:auto is load-bearing. The width and height attributes on the img are
   there to reserve space and stop the page jumping as it loads, but the height
   attribute also pins the box to the SVG's raw file height. With the CSS width
   overriding the width and the attribute still holding the height, the box was
   540 by 182, and the wordmark shrank to fit inside that squashed box and sat
   marooned in white space. Releasing the height lets it scale properly.

   111px of side padding matches the live site, where the wordmark occupies
   about 69% of its column. */
.band__wordmark { width: 100%; height: auto; padding: 17px 111px 0; }

/* --------------------------------------------------------------------------
   6. Gallery filmstrip
   One continuous horizontal run of photographs, all the same height, each as
   wide as its own proportions require. Nothing is cropped and there is no
   dead space beside the upright pictures.
   -------------------------------------------------------------------------- */
.gallery { background: var(--smoke); padding: 0 0 40px; }

/* More room above than below. A gap reads as belonging to what comes after
   it, so an even one leaves the heading floating between two sections rather
   than sitting at the head of its own. 88 above, 40 below. */
.gallery__intro { max-width: 820px; margin: 0 auto; padding: 88px 24px 40px; text-align: center; }

.gallery__heading {
  font-size: 28px; line-height: 40px; letter-spacing: 1px; font-weight: 400;
  text-transform: uppercase; color: var(--ink);
/* The same rule the panel titles carry: inline-block so it is exactly as wide
   as the words, 1.5px in the pale grey, sitting tight underneath. */
  display: inline-block; max-width: calc(100% - 40px);
  padding-bottom: 9px;
  border-bottom: 1.5px solid var(--rule);
}

.gallery__note { margin-top: 14px; font-size: 18px; line-height: 30px; color: var(--body-ink); }

/* Decade jump bar. Always visible, no hidden menus, 48px targets. */
.decades {
  position: sticky; top: 0; z-index: 20;
  background: rgba(243, 240, 240, .97);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid #ddd6d6;
  padding: 8px 16px; margin-top: 22px;
}

.decades__list {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 4px;
  max-width: 1100px; margin: 0 auto; padding: 0; list-style: none;
}

.decades__btn {
  display: inline-flex; align-items: center;
  min-height: 48px; padding: 0 18px;
  background: none; border: 1px solid transparent; border-radius: 2px;
  font: inherit; font-size: 17px; letter-spacing: 1px;
  color: var(--body-ink); cursor: pointer;
}
.decades__btn:hover { color: var(--ink); border-color: var(--ink); }
.decades__btn[aria-current="true"] {
  color: var(--ink); border-color: var(--ink); background: rgba(255, 255, 255, .7);
}

/* ---- the strip itself ----
   The blue band is the original slider's own background (#69798A). Each
   photograph sits on a smoke-white mount inside it, with a deeper margin at
   the foot carrying the title and the description, exactly as the Webflow
   slides did. */
.strip-wrap {
  position: relative;
  padding: 0 76px;
  background: var(--slate);
}

.strip {
  display: flex; align-items: flex-start; gap: 26px;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x proximity;
  scroll-padding-left: 8px;
  padding: 38px 8px 32px;
  scrollbar-color: var(--smoke) #4d5c6b;
}

/* A visible, generously sized scrollbar. The usual thin one is easy to miss. */
.strip::-webkit-scrollbar { height: 14px; }
.strip::-webkit-scrollbar-track { background: #4d5c6b; border-radius: 7px; }
.strip::-webkit-scrollbar-thumb { background: var(--smoke); border-radius: 7px; }
.strip::-webkit-scrollbar-thumb:hover { background: var(--surface); }

/* Decade divider, riding inside the blue band. */
.marker {
  flex: 0 0 auto; align-self: stretch;
  display: flex; align-items: center;
  padding-right: 8px; border-left: 1px solid rgba(255, 255, 255, .45);
  padding-left: 22px; margin-left: 4px;
  scroll-snap-align: start; scroll-margin-left: 8px;
}
.marker:first-child { border-left: 0; margin-left: 0; padding-left: 0; }

/* 26px and medium weight. White on this blue measures 4.47:1, a hair under
   the 4.5 minimum for normal text, but comfortably over the 3:1 that applies
   once type is this size. Bigger is the honest fix here, not a colour that
   drifts away from the original palette. */
.marker__label {
  writing-mode: vertical-rl; transform: rotate(180deg);
  font-size: 26px; font-weight: 500; letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--white); white-space: nowrap;
}

/* ---- one mounted photograph ----
   Every mount is exactly the same size, whatever shape the photograph is.
   That is Adele's own solution from the Webflow slides, and it uses two
   arrangements of the same card:

     landscape  photo inset with a margin, deeper at the foot, text centred
                underneath it
     portrait   photo run full height and flush to the right edge, text in
                the white column left of it, sitting on the baseline

   So the strip keeps one steady rhythm instead of a ragged run of widths. */
.shot {
  flex: 0 0 auto;
  position: relative;
  height: var(--shot-h);
  /* 6:5 rather than 4:3. A wider card starves a landscape photograph of
     height and leaves white gutters down both sides; at this proportion the
     photo reaches the card's edges the way it does in the original slides. */
  width: calc(var(--shot-h) * 1.2);
  padding: 0; border: 0; overflow: hidden;
  background: var(--mount);
  font: inherit; color: inherit; cursor: pointer;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
  scroll-snap-align: start; scroll-margin-left: 8px;
  transition: transform .2s ease, box-shadow .2s ease;
}
.shot:hover, .shot:focus-visible {
  transform: translateY(-4px);
  box-shadow: 0 14px 30px rgba(0, 0, 0, .32);
}

/* Type is sized against the card rather than in fixed pixels, so the mounts
   keep the original's proportions at every screen size. */
/* Type scales with the card so the mounts keep the original's proportions,
   but never below a floor. Pure proportional sizing put the description at
   under 9px on a small phone, which is unreadable for anybody and useless
   for a reader with tired eyes. */
.shot__title {
  font-family: Allison, "Great Vibes", cursive;
  /* The original sets no weight on .script, so these are 400. The rebuild had
     them at 700 on the assumption Webflow synthesised bold. It did not. */
  font-weight: 400; color: var(--script-ink);

  /* A11Y — bigger, and weighted. The original's .script is 48px; this ran at
     34px, and Allison at 34px is hairline thin, which is what made Adele call
     it hard to read. The size now tracks the card and reaches the low forties
     on a desktop.

     Size first: the original's .script is 48px where this ran at 34px, and
     Allison at 34px is hairline thin, which is what made these hard to read.

     Then a light stroke. The stylesheet records no weight on .script, so I
     took that to mean none was wanted and removed it. Adele compared the
     ladder against the live site and picked this value, and she is the one
     looking at the real thing. A stroke grows every contour by the same
     amount, so the hand keeps its shape and simply holds a little more ink,
     which is what the face needs at this size. A browser without the property
     renders the plain weight, which is still legible at 43px. */
  font-size: max(32px, calc(var(--shot-h) * .092));
  -webkit-text-stroke: .022em currentColor;

  /* Allison drops a long tail off the z, the y and the g, and 1.12 gave the
     line box 48px where the glyphs want 51. The clamp below trims anything
     that does not fit, so the tails were being shaved off and what was left
     sat hard against the description. 1.26 holds the whole letter with room
     over. */
  line-height: 1.26;
  /* A title longer than its column used to paint straight across the
     photograph beside it. Long words now break rather than bleed, and the
     title is held to two lines. */
  overflow-wrap: break-word;
  overflow: hidden;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  /* Measured on all 52 titles at five tablet sizes: the z tail in every
     "Heze" lands within about 1.5px of the cut edge, whole but with almost
     nothing in hand. This is the margin for a browser that rounds the other
     way. It sits inside the box, so no line moves. */
  padding-bottom: 3px;
}

.shot__caption {
  /* Was .008, about 4px, which put the description right under the tail of a
     descending letter even once the tail fitted. */
  margin-top: max(9px, calc(var(--shot-h) * .022));
  font-size: max(15px, calc(var(--shot-h) * .031));
  line-height: 1.4;
  color: #3f3f3f;   /* 9.3:1 on the smoke mount */
  overflow: hidden;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
}

/* Landscape: inset photo, text centred below in the deeper foot margin. */
.shot--h {
  display: flex; flex-direction: column; align-items: center;
  padding: 4.5% 4.5% 0;
}
.shot--h .shot__frame {
  flex: 1 1 auto; min-height: 0; width: 100%;
  display: flex; align-items: center; justify-content: center;
}
.shot--h .shot__img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
/* The foot gap is written out rather than left as a percentage, and the
   upright cards below carry the identical value. A percentage here resolves
   against this card's content box and there against that one's, and the two
   cards are different widths, so the same number produced two different gaps
   and the writing sat about 45px higher beside an upright photograph. Tied to
   the card height instead, every last line in the strip lands on one line.
   .044 is where the landscape cards already were, to within a pixel. */
.shot--h .shot__text {
  flex: 0 0 auto; width: 100%;
  padding: 2.5% 3% calc(var(--shot-h) * .044);
  text-align: center;
}

/* Portrait: photo full height, flush right; text on the baseline to its left. */
.shot--v { display: flex; flex-direction: row; align-items: stretch; }
.shot--v .shot__text {
  /* The markup is always picture then writing. Only here, where an upright
     photograph sits in a wide card, does the writing move to the left. */
  order: -1;
  flex: 1 1 auto; min-width: 0; overflow: hidden;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 0 4% calc(var(--shot-h) * .044) 5%;   /* same foot gap as .shot--h */
  text-align: left;
}
.shot--v .shot__caption { -webkit-line-clamp: 4; }

/* An upright card is wider than a landscape one, and that is the fix for a
   problem Adele found on an iPad held sideways.

   The card takes its size from the viewport's height, so a short screen makes
   a short card, and a short card is a narrow one. At 1024 by 768 the writing
   beside an upright photograph had about 125px of usable column: the title
   broke across two lines mid-name and the description fell into five ragged
   ones hard up against the photograph's edge. On a desktop it was 175px,
   cramped for the same reason, just less obviously.

   So the upright card grows sideways and hands the extra width to the
   writing. What carries the strip's rhythm is the shared height and the
   shared mount, not identical widths; a wider card under an upright
   photograph reads as the layout doing its job. Landscape cards are
   untouched. */
.shot--v { width: calc(var(--shot-h) * 1.44); }
.shot--v .shot__frame { flex: 0 0 auto; width: 47%; height: 100%; }
.shot--v .shot__img { height: 100%; width: 100%; object-fit: cover; display: block; }

/* ---- an empty slot, for a decade with no photograph yet ----
   Same mount, same size, so the strip keeps its rhythm. Deliberately plain
   and obviously unfinished, so one can never be mistaken for a photograph or
   quietly survive to launch. Not a button: there is nothing to enlarge. */
.shot--placeholder {
  cursor: default;
  background: #eceaea;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .10);
}
.shot--placeholder:hover {
  transform: none;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .10);
}
.shot__slot {
  flex: 1 1 auto; min-height: 0; width: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: 8%;
  border: 2px dashed #b6adad;
  color: var(--body-ink);
  font-size: max(14px, calc(var(--shot-h) * .032));
  letter-spacing: 2px; text-transform: uppercase; text-align: center;
}

/* ---- paging arrows ----
   Horizontal scrolling is unfamiliar to a lot of people, so the strip never
   relies on it alone. These are always visible, always in the same place. */
.pager {
  position: absolute; top: calc(34px + var(--shot-h) / 2);
  transform: translateY(-50%);
  width: 58px; height: 92px;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); color: var(--ink);
  border: 1px solid #cdc4c4; border-radius: 3px;
  font-size: 26px; cursor: pointer;
  box-shadow: 0 3px 12px rgba(0, 0, 0, .13);
  transition: background .15s ease, color .15s ease;
}
.pager:hover:not(:disabled) { background: var(--ink); color: var(--white); }
.pager:disabled { opacity: .3; cursor: default; }
.pager--prev { left: 8px; }
.pager--next { right: 8px; }

.strip-hint {
  margin: 0 auto; max-width: 820px; padding: 18px 24px;
  text-align: center; font-size: 16px; color: var(--body-ink);
}

/* --------------------------------------------------------------------------
   7. Lightbox
   -------------------------------------------------------------------------- */
.lightbox[hidden] { display: none !important; }

.lightbox {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(20, 20, 22, .97);
  display: flex; flex-direction: column;
}

.lightbox__bar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 12px 18px; color: var(--white); flex: 0 0 auto;
}

.lightbox__counter { font-size: 17px; letter-spacing: 1px; }

/* A11Y — controls carry words, not bare icons, and are 48px tall. */
.lb-btn {
  display: inline-flex; align-items: center; gap: 10px;
  min-height: 48px; padding: 0 20px;
  background: transparent; color: var(--white);
  border: 1px solid rgba(255, 255, 255, .55); border-radius: 2px;
  font: inherit; font-size: 17px; letter-spacing: 1px; text-transform: uppercase;
  cursor: pointer; transition: background .15s ease, border-color .15s ease;
}
.lb-btn:hover:not(:disabled) { background: rgba(255, 255, 255, .14); border-color: var(--white); }
.lb-btn:disabled { opacity: .35; cursor: default; }
.lb-btn:focus-visible { outline: 3px solid #93b4ff; outline-offset: 3px; }

.lightbox__stage {
  flex: 1 1 auto; min-height: 0;
  display: flex; align-items: center; justify-content: center; gap: 14px;
  padding: 0 18px 18px;
}

/* The enlarged photograph gets the same mount as the strip: smoke card, photo
   inset, writing in the margin beneath it. Before this the image filled the
   window and was clipped top and bottom, and the caption sat on top of the
   photograph where it could not be read. min-height:0 down the whole flex
   chain is what actually lets max-height hold the image inside the window. */
.lb-card {
  display: flex; flex-direction: column; align-items: center;
  min-height: 0; max-height: 100%;
  max-width: min(1080px, 88vw);
  margin: 0; padding: 22px 22px 0;
  width: auto;
  background: var(--mount);
  box-shadow: 0 12px 44px rgba(0, 0, 0, .55);
}

/* The photograph is capped against the viewport rather than against its
   parent. A percentage max-height cannot resolve inside a flex box with no
   definite height, which is why max-height:100% was ignored and the image
   overflowed its own card. vh is definite, so it holds, and the card then
   sizes itself to whatever the photograph turns out to be. */
.lb-card__frame {
  flex: 0 1 auto; min-height: 0;
  display: flex; align-items: center; justify-content: center;
}
.lb-card__img {
  width: auto; height: auto;
  max-width: 100%; max-height: 70vh;
  object-fit: contain; display: block;
}

.lb-card__text {
  flex: 0 0 auto; width: 100%;
  padding: 14px 10px 22px;
  text-align: center;
}

/* Previous and Next are pinned to the window, not laid out beside the card.
   The card changes width with every photograph, and when the row re-centred
   the buttons slid up to 238px sideways between one photo and the next. A
   second click then landed on the backdrop and shut the viewer, which read
   as the page jumping back to the small pictures on its own. */
@media (min-width: 992px) {
  .lightbox__stage { position: relative; }
  #lb-prev, #lb-next {
    position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  }
  #lb-prev { left: 28px; }
  #lb-next { right: 28px; }
  /* keep the card clear of the pinned buttons at any window width */
  .lb-card { max-width: min(1080px, calc(100vw - 420px)); }
}
.lb-card__title {
  font-family: Allison, "Great Vibes", cursive;
  font-size: 48px; line-height: 1.26; font-weight: 400; color: var(--script-ink);
  -webkit-text-stroke: .022em currentColor;   /* matches the strip, see .shot__title */
}
.lb-card__caption {
  margin-top: 10px;
  font-size: 20px; line-height: 1.4; color: #3f3f3f;
}

/* --------------------------------------------------------------------------
   8. Footer
   -------------------------------------------------------------------------- */
.footer {
  background: var(--surface); padding: 48px 24px;
  text-align: center; color: var(--body-ink);
  font-size: 16px; line-height: 28px;
}

/* ---- back to the top ----
   A plain link to the masthead, so it works with JavaScript switched off and
   the browser does the gliding itself: `scroll-behavior: smooth` is already
   set on the page, and already switched off for anyone who has asked their
   device for less motion.

   The arrow is the page's own down arrow turned over, so it belongs to the
   same family. It lifts twice as the foot of the page arrives and then keeps
   still, which is the same restraint the other arrows show: enough to be
   noticed once, not a thing fidgeting in the corner while you read. */
.totop {
  display: inline-flex; flex-direction: column; align-items: center;
  gap: 7px;
  margin: 0 auto 26px; padding: 6px 20px;
  min-height: 48px;                       /* the site's touch target floor */
  color: var(--body-ink); text-decoration: none;
  font-size: 15px; letter-spacing: 1.6px; text-transform: uppercase;
  border-radius: 3px;
}
.totop:hover, .totop:focus-visible { color: var(--ink); }

.totop__arrow {
  display: block;
  transition: transform .32s cubic-bezier(.22, .61, .36, 1);
}
.totop:hover .totop__arrow,
.totop:focus-visible .totop__arrow { transform: translateY(-4px); }

.totop__word { border-bottom: 1px solid transparent; transition: border-color .25s ease; }
.totop:hover .totop__word,
.totop:focus-visible .totop__word { border-bottom-color: currentColor; }

/* Twice, then still. Runs only where the reveal script is in charge, and only
   once this has actually scrolled into view. */
.reveal-on .totop.is-revealed .totop__arrow {
  animation: totop-lift 2.6s ease-in-out .45s 2;
}
@keyframes totop-lift {
  0%, 100% { transform: translateY(0); }
  32%      { transform: translateY(-7px); }
  64%      { transform: translateY(0); }
}

@media (max-width: 767px) {
  .totop { font-size: 14px; margin-bottom: 20px; }
}

/* --------------------------------------------------------------------------
   8b. Long-form story blocks
   The original trapped the biography in a 502px box with a hidden inner
   scrollbar. Here the opening runs full size and the rest unfolds behind one
   plainly worded button. With JavaScript off the whole story simply shows.
   -------------------------------------------------------------------------- */
.story > p + p { margin-top: 22px; }
.story__rest > p:first-child { margin-top: 22px; }
.story__rest > p + p,
.story__rest > ol + p { margin-top: 22px; }

.story__list { margin: 16px 0 0; padding-left: 24px; }
.story__list li + li { margin-top: 12px; }

/* Centred on the card's own axis of symmetry, matching the centred title and
   subtitle above it. The usual "left-align a Read more link" rule is about
   links inside flowing article text, where the eye returns to the left margin
   on every line. This is a discrete control closing a symmetric card. */
.story__toggle {
  display: flex; align-items: center; justify-content: center;
  width: fit-content; margin: 26px auto 0;
  min-height: 52px; padding: 0 26px;
  background: transparent; color: var(--ink);
  border: 1px solid currentColor; border-radius: 2px;
  font: inherit; font-size: 16px; letter-spacing: 1.5px; text-transform: uppercase;
  cursor: pointer; transition: background .15s ease, color .15s ease;
}
.story__toggle:hover { background: var(--ink); color: var(--smoke); }

.panel--light .story__toggle { color: var(--white); }
.panel--light .story__toggle:hover { background: var(--surface); color: var(--ink); }

.no-js .story__rest[hidden] { display: block !important; }
.no-js .story__toggle { display: none; }

/* When a story is open its row grows well past 900px. Only then does the
   portrait become sticky, so it rides alongside the reading. */
@media (min-width: 992px) {
  .row.is-expanded .row__half { overflow: visible; }
  .row.is-expanded .sticky-photo {
    position: sticky; inset: auto; top: 0;
    height: 100vh; align-self: flex-start;
  }

  /* Reading the story pins the photograph to one screen's height, which is
     far wider in proportion than the picture. Filling the column there would
     cost either the top of his head or his hand under the baby, and Adele
     wants both. So while the story is open the whole picture is shown, and
     the column colour carries it as an even mount down each side. */
  .row.is-expanded .row__photo--whole { object-fit: contain; }
}

/* Labelled detail pairs, clearer than a run of line breaks and better read
   aloud by a screen reader. */
.details { margin: 30px 0; padding: 0; display: grid; gap: 34px; text-align: center; }
.details__pair { margin: 0; }
.details dt { font-size: 14px; letter-spacing: 2px; text-transform: uppercase; opacity: .78; }
.details dd { margin: 4px 0 0; font-size: 19px; line-height: 28px; }
.details a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }

/* Phone, email and the rest are ordinary links, and on a phone they are also
   tap targets, so they carry the same 48px height as every other target. */
.details a {
  display: inline-block;
  padding: 10px 2px; min-height: 28px;
}

/* Written out only after the link has been pressed on a machine that cannot
   dial. It sits on its own line so it reads as the answer to the press. */
#phone-digits { display: block; margin-top: 2px; }

/* --------------------------------------------------------------------------
   9. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 991px) {
  :root { --frame-gap: 40px; --shot-h: clamp(300px, calc(100vh - 400px), 420px); }

  .row, .band { flex-direction: column; min-height: 0; }
  .row--flip, .band--flip { flex-direction: column; }

  .row__half, .band__figure, .band__text { width: 100%; }
  /* nothing to letterbox against any more */
  .row__half { overflow: visible; }

  /* Stacked layout: photographs run the full width of the screen at their
     own natural height. No box, no cap, no crop, and therefore no slate
     showing at the edges. Different photographs are different heights here,
     which is correct: on a phone you see one at a time.

     A max-height here was the bug that put blue bars down the sides. Any
     photo taller than the cap got shrunk to fit it, pulling the image off
     the edges and exposing the column colour behind. */
  .row__photo, .band__photo {
    position: static; inset: auto;
    width: 100%; height: auto; max-height: none;
    object-fit: fill; flex: 0 0 auto;
  }
  .row__photo--crop, .band__photo--crop { height: 46vh; object-fit: cover; }

  .panel { margin: 28px; padding: 40px 0; }
  .panel__body { padding: 0 28px; }

  /* Percentages, not pixels, so the wordmark and the script hold the same
     share of the screen they hold of a desktop column. Fixed paddings made
     both grow relative to the screen as the screen shrank. */
  .band__text { padding: 40px 0; }
  .band__lead-in { padding: 0 11%; text-align: center; text-wrap: balance; }
  .band__wordmark { padding: 14px 15.5% 0; }

  .masthead__wordmark { width: 520px; }
}

@media (max-width: 767px) {
  :root { --shot-h: 330px; }

  .masthead__wordmark { width: 100%; padding: 0 20px; }

  .nav { gap: 2px; padding-bottom: 40px; }
  .nav__link { font-size: 17px; padding: 0 14px; }

  /* Type sizes hold. Only the side padding gives, because the column does.
     A heading that shrinks below its own body copy is the one thing a phone
     layout must not do. */
  .panel__title { padding-left: 0; padding-right: 0; }
  .panel__subtitle { padding: 0 16px; }
  .panel__body { font-size: 18px; line-height: 31px; padding: 0 20px; }

  /* On a desktop the wordmark holds about 69% of its column and the script
     line about 78%. On a phone the side padding was shrinking as the screen
     did, so the wordmark ended up at 87% of the screen and the block sprawled:
     the script broke to a second line carrying two words, and the capitals ran
     nearly edge to edge. Adele described it as stretching out weirdly and that
     is exactly what it was.

     These paddings are set as percentages instead, so both hold the same share
     of the screen they hold of a desktop column, whatever the phone. */
  .band__text { padding: 34px 0; }
  .band__lead-in {
    font-size: 30px; padding: 0 11%;
    text-align: center;
    /* Stops the last line coming down alone: the browser evens the lines out
       instead of filling the first and orphaning the remainder. */
    text-wrap: balance;
  }
  .band__wordmark { padding: 14px 15.5% 0; }

  /* The arrows stay on phones. Swiping works, but it has to be discovered,
     and the instruction above the strip tells people to click the arrow. They
     move below the photographs where there is room for a proper target
     instead of a sliver pinned to the edge of the screen. */
  .strip-wrap {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-areas: "strip strip" "prev next";
    gap: 14px 12px;
    padding: 0 14px 18px;
  }
  .strip {
    grid-area: strip;
    gap: 18px; padding: 22px 4px 20px;
    scroll-padding-left: 4px;
    margin: 0 -14px; padding-left: 14px; padding-right: 14px;
  }
  .pager {
    position: static; transform: none;
    width: auto; height: 56px; font-size: 24px;
  }
  .pager--prev { grid-area: prev; }
  .pager--next { grid-area: next; }

  /* The decade bar wraps to three rows of buttons on a phone. Pinned to the
     top that is a third of the screen gone before a single photograph shows,
     so here it scrolls away with the page. */
  .decades { position: static; padding: 10px 12px 12px; }

  /* Every mount stacks on a phone, upright photographs included. Beside a
     tall photo the description column is barely a ribbon; underneath it the
     text has the full width and stays at a readable size. Heights stay equal
     so the strip keeps its rhythm. */
  .shot, .shot--h, .shot--v {
    flex-direction: column; align-items: center;
    width: 84vw; max-width: 430px;
    height: auto;
    padding: 5% 5% 0;
  }
  .shot--h .shot__frame, .shot--v .shot__frame {
    width: 100%; height: 38vh; max-height: 330px;
    display: flex; align-items: center; justify-content: center;
    flex: 0 0 auto;
  }
  .shot--h .shot__img, .shot--v .shot__img {
    width: auto; height: auto;
    max-width: 100%; max-height: 100%;
    object-fit: contain;
  }
  .shot--h .shot__text, .shot--v .shot__text {
    /* Stacked, so the writing goes back under the picture where it belongs. */
    order: 0;
    /* A floor, not a ceiling. 132px keeps every mount the same depth, which is
       what gives the strip its rhythm. On a 320px screen one title runs to two
       lines and its description to three, which together want 167px, and a
       fixed height cut the last line off. Below that width a mount fills the
       screen on its own, so the one taller card is never seen beside another. */
    width: 100%; min-height: 132px;
    padding: 12px 2% 0;
    text-align: center;
    justify-content: flex-start;
  }
  .shot__title { font-size: 30px; }
  .shot__caption,
  .shot--v .shot__caption { font-size: 16px; -webkit-line-clamp: 3; }

  /* Previous and Next move to a fixed bar at the foot, where a thumb reaches
     them. Flanking the photograph they left it about 190px wide. */
  .lightbox { padding-bottom: 78px; }
  .lightbox__stage { padding: 0 10px; }
  #lb-prev, #lb-next {
    position: fixed; bottom: 14px; z-index: 2;
    width: 44%; justify-content: center;
    min-height: 52px; padding: 0 10px; font-size: 16px;
  }
  #lb-prev { left: 3%; }
  #lb-next { right: 3%; }

  .lb-card__img { max-height: 56vh; }
  .lb-card { padding: 14px 14px 0; }
  .lb-card__title { font-size: 38px; }
  .lb-card__caption { font-size: 17px; }
  .lightbox__text { font-size: 18px; line-height: 28px; }
  .lb-btn { padding: 0 14px; font-size: 15px; }
}

@media (max-width: 479px) {
  :root { --shot-h: 280px; }
  .row__photo--crop, .band__photo--crop { height: 38vh; }
  .panel { margin: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --------------------------------------------------------------------------
   10. Password cover page

   Rebuilt 17 September 2026 against the live Webflow page, measured in the
   browser rather than eyeballed from a screenshot. The original's own rules,
   for the record (.text-div-border, .heading-3, .field-label, .text-field,
   .submit-button, .practice-image-fit):

     column        50% x 900px, #5e748b, photo object-fit cover, anchored TOP
     frame         margin 77px, height 736px, 1px #f3f0f0, radius .5px,
                   flex column, everything centred both ways
     Welcome       Roboto 400, 28px/44px, 2px tracking, uppercase,
                   1px rule under the word, 10px below
     label         Roboto 400, 18px/34px, 2px tracking, uppercase, 5px below
     field         75% of the frame, 38px tall, 8px 12px, 1px #ccc, square,
                   Roboto 14px, 10px below
     button        25% of the frame, 38px tall, 9px 15px, #3f3f3f, white
                   Roboto 14px, 1px tracking, "Submit", 6px above
     masthead      20px above and below the wordmark

   Two things are not copied. Text is white rather than #f3f0f0, because white
   on this slate is 4.83:1 and the off-white is 4.26:1 (AA wants 4.5; this was
   Adele's call earlier and still stands; nobody can see the difference). And
   the wrong-password message sits inside the frame under the button, where a
   person can see it. The original put it under the whole row, which on most
   screens is below the fold.

   Added on Adele's ask: a Show password box under the field.
   -------------------------------------------------------------------------- */
.masthead--cover { padding-top: 0; }
.masthead--cover .masthead__inner { padding: 20px 0; }

/* The frame. flex: 1 fills the column's width; the height is the original's
   own, measured from the top margin, which leaves 87px under it and 77px
   everywhere else, exactly as the live page does. */
.panel--cover {
  align-self: flex-start; height: 736px;
  padding: 0; justify-content: center;
}

.panel--cover .panel__title--cover {
  margin: 0 0 10px; padding: 0;
  font-size: 28px; line-height: 44px; letter-spacing: 2px;
  color: var(--white); border-bottom: 1px solid var(--white);
}

.gate {
  display: flex; flex-direction: column; align-items: center;
  width: 100%; padding: 0;
}

.gate__label {
  margin: 0 0 5px;
  font-size: 18px; line-height: 34px; letter-spacing: 2px;
  text-transform: uppercase; text-align: center;
  color: var(--white);
}

.gate__field {
  display: block; width: 75%; height: 38px; margin: 0 0 10px;
  padding: 8px 12px;
  font: inherit; font-size: 14px; line-height: 1.42857; color: #333333;
  background: #ffffff;
  border: 1px solid #cccccc; border-radius: 0;
}
.gate__field:focus { border-color: #3898ec; outline: 0; }
.gate__field:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

/* Show password. Set like the button's text so it belongs to the same
   family, and kept small so it does not compete with the label. */
.gate__show {
  display: inline-flex; align-items: center; gap: 8px;
  margin: 0 0 4px; min-height: 24px;
  font-size: 14px; line-height: 20px; letter-spacing: 1px;
  color: var(--white); cursor: pointer;
}
.gate__show input { width: 16px; height: 16px; margin: 0; cursor: pointer; accent-color: #3f3f3f; }

.gate__submit {
  display: block; width: 25%; min-width: max-content; margin: 6px 0 0;
  padding: 9px 15px;
  font: inherit; font-size: 14px; line-height: 20px; letter-spacing: 1px;
  color: #ffffff; background: #3f3f3f;
  border: 0; border-radius: 0; cursor: pointer;
}
.gate__submit:hover { background: #2a2a2a; }
.gate__submit:focus-visible { outline: 3px solid var(--white); outline-offset: 2px; }

/* The original's pink box (.w-form-fail), with the page's own ink on it
   rather than the slate it inherited, which was 3.56:1. */
.gate__error[hidden] { display: none; }
.gate__error {
  width: 75%; margin: 10px 0 0; padding: 10px;
  font-size: 14px; line-height: 20px; text-align: center;
  color: #333333; background: #ffdede;
}

/* Stacked layouts. The frame no longer has a column height to fill, so it
   takes its height from the form plus the air the original gave it on a
   phone (a 300px frame round a 186px form: 57px each side). */
@media (max-width: 991px) {
  .panel--cover { align-self: auto; height: auto; margin: 39px 38px; padding: 100px 0; }
}
@media (max-width: 479px) {
  .panel--cover { margin: 11px; padding: 42px 0; }
}

/* --------------------------------------------------------------------------
   11. The hymn, beneath the timeline
   Same typographic treatment as the home page panels: uppercase Roboto
   heading, uppercase subhead, then the material itself.
   -------------------------------------------------------------------------- */
/* The top padding is short on purpose. The arrow below wants to read as
   coming out of the slate band rather than floating in the middle of the
   white, so the air that used to sit above it now sits under it instead. */
.hymn { background: var(--surface); padding: 12px 24px 72px; }

.hymn__inner { max-width: 940px; margin: 0 auto; text-align: center; }

.hymn__title {
  font-size: 28px; line-height: 44px; letter-spacing: 1px; font-weight: 400;
  text-transform: uppercase; color: var(--ink);
  text-wrap: balance;
/* The same rule the panel titles carry: inline-block so it is exactly as wide
   as the words, 1.5px in the pale grey, sitting tight underneath. */
  display: inline-block; max-width: calc(100% - 40px);
  padding-bottom: 9px;
  border-bottom: 1.5px solid var(--rule);
}

/* Sentence case, matching the note under Heze's Life Timeline above. The
   heading carries the rule and the uppercase; the line beneath it is plain
   reading text, and setting it in caps made two shouting lines in a row. */
.hymn__subtitle {
  margin-top: 14px;
  font-size: 18px; line-height: 30px; font-weight: 400;
  color: var(--body-ink);
}

.hymn__video {
  display: block; width: 100%; height: auto;
  margin: 34px auto 0;
  background: var(--black);
  border: 1px solid var(--ink);
}

.hymn__caption {
  margin-top: 18px;
  font-size: 17px; line-height: 28px; color: var(--body-ink);
}

@media (max-width: 767px) {
  .hymn { padding: 10px 18px 48px; }
  .hymn__title { font-size: 23px; line-height: 33px; }
  .hymn__subtitle { font-size: 16px; line-height: 26px; }
  .hymn__caption { font-size: 16px; }
}

/* --------------------------------------------------------------------------
   11b. Heze's Playlist

   The timeline again, at about a quarter of the size. Same slate band, same
   arrows either side, same sideways scroll, so nobody has to learn a second
   way of moving around. Everything is smaller: a card is 176px where a
   photograph card is four or five hundred, and the band is 152px deep
   against the timeline's five hundred and more.

   The seven cards are sized so the row lands inside a 1440px desktop with a
   little to spare, and scrolls on anything narrower. The arrows hide
   themselves when there is nothing to scroll, rather than sitting there
   greyed out.
   -------------------------------------------------------------------------- */
.songs { background: var(--smoke); padding: 0 0 46px; }

/* Less air above than the timeline's 88, because this sits under a section
   rather than opening the page. */
.songs__intro { max-width: 820px; margin: 0 auto; padding: 48px 24px 26px; text-align: center; }

.songs__heading {
  font-size: 28px; line-height: 40px; letter-spacing: 1px; font-weight: 400;
  text-transform: uppercase; color: var(--ink);
  display: inline-block; max-width: calc(100% - 40px);
  padding-bottom: 9px;
  border-bottom: 1.5px solid var(--rule);
}

.songs__note { margin-top: 14px; font-size: 18px; line-height: 30px; color: var(--body-ink); }

/* The nudge that the row moves. Quieter than the subtitle above it, and it
   only exists when there is something off the side to reach. */
.songs__hint {
  margin-top: 8px;
  font-size: 15px; line-height: 24px; letter-spacing: .4px;
  color: var(--body-ink);
}

.songs-wrap { position: relative; padding: 0 60px; background: var(--slate); }

.songs__strip {
  list-style: none; margin: 0;
  display: flex; align-items: flex-start; justify-content: center; gap: 18px;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x proximity;
  /* Matches the padding below. Without it the snap pulls the first card flush
     against the edge of the band and eats its gutter. */
  scroll-padding-left: 8px;
  padding: 26px 8px 22px;
  scrollbar-color: var(--smoke) #4d5c6b;
}
/* justify-content: center looks right with seven cards on a wide screen, but
   it cuts off the first card once the row overflows. This hands the job back
   to the start edge exactly when that happens. */
@media (max-width: 1330px) { .songs__strip { justify-content: flex-start; } }

.songs__strip::-webkit-scrollbar { height: 10px; }
.songs__strip::-webkit-scrollbar-track { background: #4d5c6b; border-radius: 5px; }
.songs__strip::-webkit-scrollbar-thumb { background: var(--smoke); border-radius: 5px; }
.songs__strip::-webkit-scrollbar-thumb:hover { background: var(--surface); }

.song { flex: 0 0 auto; scroll-snap-align: start; }

.song__btn {
  display: flex; flex-direction: column;
  width: 168px; padding: 0; margin: 0;
  background: transparent; border: 0; cursor: pointer;
  font: inherit; color: inherit; text-align: left;
  transition: transform .18s ease;
}
.song__btn:hover { transform: translateY(-3px); }

/* A 16:9 window on a mount, with the cover shown whole inside it.

   COVER, NOT CONTAIN, WAS WRONG HERE. The covers Adele supplied run from 1.09
   to 1.80 in proportion, and filling a 16:9 window with the squarer ones took
   the top of Big Bill Broonzy's head off and cut the Choraleers' album title
   in half. Shown whole they all read, and the mount around them behaves like
   the smoke mount under a photograph in the timeline. It also means a cover
   she swaps in later needs no per-picture crop setting to look right. */
.song__tile {
  position: relative; display: block;
  width: 168px; height: 95px;
  background: #3f4c59;                 /* the mount, a shade under the band */
  border: 1px solid rgba(255, 255, 255, .28);
  overflow: hidden;
}
.song__thumb { display: block; width: 100%; height: 100%; object-fit: contain; }

/* In the corner rather than the middle. Centred, it sat squarely on Clark
   Terry's face, on Big Bill Broonzy's, and on Jimmy Rushing's. These covers
   are photographs of the men who made the music, so the mark gets out of
   their way. */
.song__play {
  position: absolute; left: 6px; bottom: 6px;
  width: 32px; height: 32px;
  opacity: .95; transition: opacity .18s ease, transform .18s ease;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .55));
}
.song__btn:hover .song__play { opacity: 1; transform: scale(1.08); }

.song__name {
  display: block; margin-top: 10px;
  font-size: 15px; line-height: 21px; font-weight: 500; color: var(--white);
  overflow-wrap: break-word;
}
.song__by {
  display: block; margin-top: 3px;
  /* A11Y — was white at 78%, which measured 3.63:1 on this blue and needed
     4.5:1. Opacity cannot get there: even 96% only reaches 4.57:1, and the
     band was darkened once already to clear AA. So the artist line takes the
     same white as the name, 4.80:1, and the two are told apart by size and
     weight instead of by fading one of them. */
  font-size: 13px; line-height: 19px; color: var(--white);
  overflow: hidden;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
}

.song.is-playing .song__tile { border-color: var(--white); border-width: 2px; }
.song.is-playing .song__name { text-decoration: underline; text-underline-offset: 3px; }

/* The arrows are the timeline's, sized for a shorter band. */
.songs__pager { top: 50%; width: 44px; height: 64px; font-size: 22px; }

/* ---- the player, which only exists once a song has been pressed ---- */
.songs__player { background: var(--smoke); padding: 30px 24px 0; text-align: center; }

.songs__frame {
  position: relative; width: 100%; max-width: 680px; margin: 0 auto;
  aspect-ratio: 16 / 9; background: var(--black);
  border: 1px solid var(--ink);
}
.songs__iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.songs__now { margin-top: 16px; font-size: 17px; line-height: 27px; color: var(--body-ink); }

.songs__close {
  margin-top: 14px; padding: 11px 26px; min-height: 44px;
  background: transparent; color: var(--ink);
  border: 1px solid var(--ink); border-radius: 3px;
  font: inherit; font-size: 15px; letter-spacing: 1.4px; text-transform: uppercase;
  cursor: pointer; transition: background .15s ease, color .15s ease;
}
.songs__close:hover { background: var(--ink); color: var(--smoke); }

@media (max-width: 767px) {
  .songs__intro { padding: 40px 20px 24px; }
  .songs__heading { font-size: 23px; line-height: 33px; }
  .songs__note { font-size: 16px; line-height: 26px; }
  .songs__hint { font-size: 14px; line-height: 22px; }
  /* The arrows would eat a third of a phone's width, so the strip is swiped
     instead and they step aside. */
  .songs-wrap { padding: 0; }
  .songs__pager { display: none; }
  .songs__strip { padding: 20px 18px 18px; gap: 16px; scroll-padding-left: 18px; }
  .song__btn, .song__tile { width: 152px; }
  .song__tile { height: 86px; }
  .song__name { font-size: 14px; line-height: 20px; }
  .song__by { font-size: 12px; line-height: 17px; }
}

/* --------------------------------------------------------------------------
   12. Shared Memories
   Art direction taken from the filmstrip: a slate band for the form, and the
   memories themselves on smoke-white mounts with the same shadow, the same
   Allison script for names, the same Roboto beneath.
   -------------------------------------------------------------------------- */
.memories { background: var(--smoke); padding: 0 0 90px; }

.memories__intro { max-width: 820px; margin: 0 auto; padding: 88px 24px 40px; text-align: center; }

.memories__heading {
  font-size: 28px; line-height: 40px; letter-spacing: 1px; font-weight: 400;
  text-transform: uppercase; color: var(--ink);
/* The same rule the panel titles carry: inline-block so it is exactly as wide
   as the words, 1.5px in the pale grey, sitting tight underneath. */
  display: inline-block; max-width: calc(100% - 40px);
  padding-bottom: 9px;
  border-bottom: 1.5px solid var(--rule);
}

.memories__note { margin-top: 14px; font-size: 18px; line-height: 30px; color: var(--body-ink); }

/* ---- the form, on the strip's blue band ---- */
.share { background: var(--slate); padding: 64px 24px 72px; }

.share__inner { max-width: 680px; margin: 0 auto; }

.share__title {
  font-size: 26px; line-height: 38px; letter-spacing: 1px; font-weight: 400;
  text-transform: uppercase; text-align: center; color: var(--white);
  padding-bottom: 9px; border-bottom: 1.5px solid var(--white);
  display: block; width: fit-content; max-width: calc(100% - 40px);
  margin: 0 auto 38px;
}

.share__form { display: block; }

/* Was 26px, which read as crowded on a form this long. Each question needs
   to look like its own question, not part of a block. */
/* SAMARIA'S NOTE: the form read a little spacious. 38px between fields on a
   form this long added up to a lot of scrolling on a phone. 28px still leaves
   each field clearly its own thing. */
.field { margin-bottom: 28px; }

.field__label {
  display: block; margin-bottom: 8px;
  font-size: 18px; letter-spacing: 1px; color: var(--white);
}

/* SAMARIA'S NOTE: numbering the fields. It tells somebody how much is left,
   which matters on a form people fill in while grieving. The numeral sits
   inside the label rather than beside it, so a screen reader announces
   "3, Your email" and the count is not lost to anyone listening. */
.field__num {
  display: inline-block; min-width: 1.45em;
  font-variant-numeric: tabular-nums;
  /* Was rgba(255,255,255,.72), and the note beside it claimed 5.1:1 on the
     slate. Measured, it is 3.35:1 in light mode and 4.48:1 in dark, so it
     failed in both. Opacity cannot reach 4.5:1 here: even .95 only gets to
     4.51, which is too close to survive rounding. Same answer as the playlist
     artist line, which had the identical fault. Full white, and the numeral
     stays distinct from the label by the 1.45em well it sits in rather than by
     being dimmer than it. */
  color: var(--white);
}

.field__optional {
  font-size: 15px; letter-spacing: 0; text-transform: none;
  color: var(--white);   /* A11Y — was #d8e0e8 at 3.35:1 */
}

/* 56px tall, well past the 48px minimum. Anyone filling this in may be doing
   it on a phone, in their eighties, possibly upset. */
.field__input {
  display: block; width: 100%;
  min-height: 56px; padding: 14px 16px;
  font: inherit; font-size: 18px; color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--ink); border-radius: 6px;
}
.field__input--area { min-height: 0; line-height: 1.5; resize: vertical; }
.field__hint + .field__input--area { margin-top: 12px; }
.field__input:focus-visible { outline: 3px solid var(--white); outline-offset: 2px; }

.field__file {
  display: block; width: 100%;
  padding: 16px; font: inherit; font-size: 17px;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--ink); border-radius: 6px;
}

/* A hint sits close under whatever it explains. Two hints in a row are two
   separate remarks, so the second gets real air above it rather than reading
   as a fourth line of the first. */
.field__hint + .field__hint { margin-top: 24px; }

.field__hint {
  margin-top: 8px; font-size: 16px; line-height: 24px;
  color: var(--white);   /* A11Y — #e2e8ee measured 3.62:1 here; size carries the hierarchy instead of colour */
}

/* ---- writing / audio / video ----------------------------------------------

   One segmented control over one drop area, replacing three separate cards.
   Adele found the pattern and she is right about it: three cards asked people
   to weigh three things against each other, and a person who has never done
   this before does not know what they are weighing. Joined into a single
   control it reads as one question, the answers are obviously alternatives,
   and the area below changes to match whichever is chosen.
   -------------------------------------------------------------------------- */
.kinds { margin: 0 0 26px; padding: 0; border: 0; }

/* One pill, divided. The rounded outer edge and the hairlines between the
   segments are what say "these three belong to each other". */
.segments {
  display: flex; margin-top: 12px;
  background: var(--surface);
  border: 2px solid var(--ink);
  border-radius: 999px;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .22), 0 4px 12px rgba(0, 0, 0, .18);
}

.segment { flex: 1 1 0; display: flex; min-width: 0; }
.segment + .segment .segment__face { border-left: 1px solid var(--rule); }
.segment input { position: absolute; opacity: 0; width: 0; height: 0; }

.segment__face {
  flex: 1 1 auto;
  display: flex; align-items: center; justify-content: center;
  text-align: center;
  min-height: 62px; padding: 12px 8px;
  font-size: 18px; letter-spacing: 1.2px;
  color: var(--ink); background: var(--surface);
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}

/* Hover is worth having and cannot carry selection: there is no hover on a
   phone, which is where most of these will be filled in. */
.segment:hover .segment__face { background: var(--smoke); }

/* Filled against outlined. This is the pair every mature design system uses
   for "pick one of these", and not as a matter of taste: the difference is
   fill rather than hue, so it survives a bright phone screen, a cataract and
   colour-blindness alike. One signal, doing the whole job. */
.segment input:checked + .segment__face {
  background: var(--ink); color: var(--white);
  border-left-color: var(--ink);
}
.segment:hover input:checked + .segment__face { background: #232323; }

/* The segment to the right of the chosen one would otherwise draw its hairline
   against the dark fill, which reads as a seam. */
.segment:has(input:checked) + .segment .segment__face { border-left-color: var(--ink); }

.segment input:focus-visible + .segment__face {
  outline: 3px solid var(--white); outline-offset: -5px;
}

/* The fill has to follow the pill's curve. Square-cornered against a rounded
   clip leaves a white crescent at each end, which reads as a rendering fault
   rather than as a shape. */
.segment:first-child .segment__face { border-radius: 999px 0 0 999px; }
.segment:last-child  .segment__face { border-radius: 0 999px 999px 0; }

/* ---- the drop area ----

   A dashed edge is the one convention people already read as "your file goes
   here". The wording leads with choosing because a good many of the people
   writing here have never dragged a file anywhere, and a box that only
   mentions dropping strands them. */
.drop__input {
  /* Present and focusable, just not drawn. display:none would take it off the
     keyboard entirely and out of the accessibility tree. */
  position: absolute; width: 1px; height: 1px;
  opacity: 0; overflow: hidden; clip-path: inset(50%);
}

.drop {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; text-align: center; gap: 6px;
  margin-top: 12px; padding: 34px 24px; min-height: 150px;
  background: rgba(0, 0, 0, .12);
  border: 2px dashed var(--white);
  border-radius: 10px;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
.drop:hover { background: rgba(0, 0, 0, .18); }

/* While a file is over the box. Set by js/memories.js. */
.drop.is-over {
  background: rgba(0, 0, 0, .26);
  border-color: var(--white);
  border-style: solid;
}

.drop__input:focus-visible + .drop {
  outline: 3px solid var(--white); outline-offset: 4px;
}

/* Adele found this one too: an icon, the action in plain large type, then the
   drag line quieter underneath. The icon does the work of saying "a file goes
   here" before anybody reads a word, which matters most for the people who
   have never done this. Decorative, so it is hidden from screen readers; the
   words below say the same thing. */
.drop__icon { flex: 0 0 auto; color: var(--white); opacity: .85; margin-bottom: 2px; }

.drop__lead { font-size: 21px; line-height: 30px; color: var(--white); }

/* The quieter half of the pair. Dragging is the alternative, not the
   instruction, and it reads that way. */
.drop__second { font-size: 16px; line-height: 24px; color: var(--white); opacity: .88; }

/* Underlined so it reads as the thing to press, which is what carries the
   whole control for anybody who will never think to drag. */
.drop__verb { text-decoration: underline; text-underline-offset: 4px; }

.drop__hint {
  font-size: 16px; line-height: 24px; max-width: 46ch;
  color: var(--white);   /* A11Y — #e2e8ee measured 3.62:1 here; size carries the hierarchy instead of colour */
}

/* What they picked, said back to them. The native control says it for itself;
   once it is hidden, something has to. */
.drop__chosen {
  margin-top: 4px; padding: 8px 14px;
  font-size: 16px; line-height: 22px;
  color: var(--ink); background: var(--surface);
  border-radius: 6px;
  max-width: 100%; overflow-wrap: anywhere;
}

.share__submit {
  display: block; width: 100%;
  min-height: 64px; margin-top: 40px; padding: 0 28px;

  /* Same near-black as a chosen option, so the page has one button colour
     rather than two. Rounded to match. */
  background: var(--ink); color: var(--white);
  border: 2px solid var(--ink); border-radius: 6px;
  font: inherit; font-size: 19px; letter-spacing: 2px; text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .22), 0 4px 12px rgba(0, 0, 0, .18);
  transition: box-shadow .18s ease, transform .18s ease;
}
.share__submit:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, .26), 0 9px 22px rgba(0, 0, 0, .26);
}
.share__submit:active { transform: translateY(0); }
.share__submit[disabled] {
  opacity: .65; cursor: default; transform: none;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}

.share__status[hidden] { display: none; }
.share__status {
  margin-top: 20px; padding: 16px;
  font-size: 18px; line-height: 27px; text-align: center;
  background: rgba(255, 255, 255, .12); color: var(--white);
  border: 1px solid rgba(255, 255, 255, .5);
}
.share__status--good { background: var(--surface); color: #23502f; border-color: var(--white); }
.share__status--bad  { background: #ffe4e4; color: #7a2020; border-color: #ffe4e4; }

.share__small {
  margin-top: 20px; font-size: 16px; line-height: 24px; text-align: center;
  color: var(--white);   /* A11Y — was #e2e8ee at 3.62:1 */
}

/* ---- the memories themselves ---- */
.wall__grid {
  display: grid; gap: 26px;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  max-width: 1180px; margin: 0 auto; padding: 0 24px;
  align-items: start;
}

/* The filmstrip mount, standing still. */
.memory {
  background: var(--surface);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
  padding: 30px 30px 26px;
}

.memory__head { text-align: center; padding-bottom: 16px; }

.memory__name {
  font-family: Allison, "Great Vibes", cursive;
  /* 400 with a light stroke rather than 700. Allison ships in Regular only,
     so 700 asks the browser to smear the glyphs sideways; a stroke grows every
     contour evenly. Same value as the photograph titles, so all the script on
     the site is weighted alike. */
  font-weight: 400; color: var(--script-ink);
  -webkit-text-stroke: .022em currentColor;
  font-size: 40px; line-height: 1.22;   /* room for the tails, as .shot__title */
}

.memory__relation {
  margin-top: 9px;
  font-size: 16px; letter-spacing: 1px; text-transform: uppercase;
  color: var(--body-ink);
}

.memory__body { margin-top: 4px; font-size: 17px; line-height: 29px; color: #3f3f3f; }
.memory__body p + p { margin-top: 16px; }

.memory__audio { display: block; width: 100%; margin: 4px 0 18px; }

.memory__video {
  display: block; width: 100%; height: auto;
  margin: 4px 0 18px; background: var(--black);
}

/* The cover standing in for a film that is not in the folder yet. Same mount
   colour as the playlist covers, so the two placeholders on this site read as
   the same idea. */
.memory__video--pending {
  aspect-ratio: 16 / 9;
  background: #3f4c59;
  color: rgba(255, 255, 255, .60);
  display: flex; align-items: center; justify-content: center;
}
.memory__video--pending svg { display: block; width: 58px; height: 58px; }

.memory__date {
  margin-top: 20px; padding-top: 14px;
  border-top: 1px solid #e6e0e0;
  font-size: 15px; letter-spacing: .5px; color: var(--body-ink);
  text-align: center;
}

.wall__empty {
  max-width: 620px; margin: 0 auto; padding: 30px 24px;
  font-size: 18px; line-height: 30px; text-align: center; color: var(--body-ink);
}

@media (max-width: 767px) {
  .memories__intro { padding: 56px 20px 32px; }
  /* Was 20px of side padding, which put the boxes almost against the edge of
     the phone. 26px on the band plus the form's own 24px gives the content
     room to sit in. */
  .share { padding: 48px 26px 60px; }
  .share__inner { padding: 0 24px; }
  .share__title { font-size: 23px; line-height: 34px; margin-bottom: 30px; }
  .field { margin-bottom: 32px; }
  /* Three words side by side on a narrow phone leaves each of them a few
     characters wide. Stacked, the pill becomes three full-width bands and
     each stays a comfortable target. */
  .segments { flex-direction: column; border-radius: 14px; }
  .segment:first-child .segment__face { border-radius: 12px 12px 0 0; }
  .segment:last-child  .segment__face { border-radius: 0 0 12px 12px; }
  .segment + .segment .segment__face {
    border-left: 0; border-top: 1px solid var(--rule);
  }
  .segment:has(input:checked) + .segment .segment__face { border-top-color: var(--ink); }
  .segment__face { min-height: 58px; }
  .drop { padding: 28px 18px; min-height: 132px; }
  .wall__grid { grid-template-columns: 1fr; gap: 22px; padding: 0 20px; }
  .memory { padding: 26px 22px 22px; }
  .memory__name { font-size: 36px; }
}

/* --------------------------------------------------------------------------
   13. Panel type on smaller screens

   The original shrinks these hard: 28px down to 24, then 22, and the white
   ones down to 19px. At 19px the heading ends up SMALLER than the body copy
   sitting under it, which turns the hierarchy upside down on exactly the
   devices where it matters most. Adele's call, and the right one: hold the
   desktop hierarchy everywhere.

   So the type does not shrink. The space around it does, because a phone has
   less of it to give, and the proportions are kept by scaling the margins
   with the frame rather than the type.
   -------------------------------------------------------------------------- */
@media (max-width: 991px) {
  .panel__title       { margin-top: 40px; margin-bottom: 10px; }
  .panel { padding-bottom: 40px; }
}

@media (max-width: 479px) {
  .panel__title       { margin-top: 32px; margin-bottom: 10px; max-width: calc(100% - 24px); }
  .panel__title--light { margin-top: 32px; }
  .panel__subtitle    { padding: 0 16px; }
  .panel { padding-bottom: 32px; }
}
}

/* --------------------------------------------------------------------------
   14. The approval screen
   Private, so it borrows the memory card wholesale rather than earning its
   own look.
   -------------------------------------------------------------------------- */
.admin__contact {
  margin: -8px 0 14px;
  font-size: 15px; line-height: 22px; text-align: center;
  color: var(--body-ink); word-break: break-word;
}

.admin__buttons { display: flex; gap: 10px; margin-top: 18px; }

.admin__btn {
  flex: 1; min-height: 52px; padding: 0 14px;
  font: inherit; font-size: 17px; letter-spacing: 1px;
  border: 2px solid var(--ink); border-radius: 6px;
  background: var(--surface); color: var(--ink); cursor: pointer;
}
.admin__btn[disabled] { opacity: .6; cursor: default; }

.admin__btn--yes { background: var(--ink); color: var(--white); }
.admin__btn--yes:hover { background: var(--surface); color: var(--ink); }

/* Declining deletes, so it never looks like the easy button. */
.admin__btn--no { border-color: #8a2a2a; color: #8a2a2a; }
.admin__btn--no:hover { background: #8a2a2a; color: var(--white); }
.admin__btn--no[data-armed="1"] { background: #8a2a2a; color: var(--white); }

/* --------------------------------------------------------------------------
   15. The cover page holds its size
   In the original the cover page is .heading-3 and the home panels are
   .heading.white: different classes, and only the panels shrink. Sharing one
   class here meant the cover page inherited a shrink it should never have had,
   and Welcome dropped to 19px in any window under 991px. It does not move.
   -------------------------------------------------------------------------- */
@media (max-width: 479px) {
  /* Long words in a narrow column: let it wrap rather than overflow. */
  .panel__title--cover { max-width: calc(100% - 24px); }
}

/* The section headings above are inline-block so their rule hugs the words.
   Their wrappers do the centring. */
.gallery__intro, .memories__intro, .hymn__inner { text-align: center; }

/* --------------------------------------------------------------------------
   16. The arrow down to the upload panel
   The grey band and the blue one meet with nothing to carry the eye across.
   This gives the reader somewhere to go after the invitation, and it nudges
   twice on load so it is noticed without becoming a fidget.
   -------------------------------------------------------------------------- */
.point-down {
  display: block;
  margin: 26px auto 0;
  color: var(--slate);
  animation: point-down-nudge 2.4s ease-in-out 1.2s 2;
}

/* The one above the hymn, on white, drawn in the page's black. It sits high,
   near the slate band it comes out of, and carries its air underneath: a
   panel title follows it rather than a panel, and the title needs the room. */
.point-down--dark { color: var(--script-ink); margin: 0 auto 88px; }

/* The second one sits inside the blue panel, pointing on to what other people
   have written, so it is drawn in the panel's own white. */
.point-down--light { color: var(--white); margin-top: 34px; }

/* Nudging on load is wasted on an arrow that is below the fold, which the
   second one is. Where the reveal script is running, each arrow nudges as it
   comes into view instead. Without the script the load animation stands, so
   the arrow still moves on a page with JavaScript off. */
.reveal-on .point-down { animation: none; }
.reveal-on .point-down.is-revealed {
  animation: point-down-nudge 2.4s ease-in-out .35s 2;
}

@keyframes point-down-nudge {
  0%, 100% { transform: translateY(0); }
  30%      { transform: translateY(7px); }
  60%      { transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .point-down { animation: none; }
}

@media (max-width: 767px) {
  .point-down { margin-top: 20px; width: 34px; height: 39px; }
  /* Same idea as on a wide screen, scaled down: high under the band, with
     its air below. Written out because the two selectors weigh the same and
     the one above would otherwise win on being later. */
  .point-down--dark { margin-top: 0; margin-bottom: 58px; }
}

/* --------------------------------------------------------------------------
   17. Motion

   Three pieces, all of them cheap. Nothing here loads a library, and every
   animated property is opacity or transform, which the browser hands to the
   compositor. No layout, no repaint, no shift, no cost at load.

   Everything below is switched off for anyone whose device asks for reduced
   motion, and the reveal is only ever applied by script, so a page with no
   JavaScript is a page with everything already on it.
   -------------------------------------------------------------------------- */

/* ---- 1. Arriving. Text and photographs settle in as you reach them, rather
     than being there the whole way down. On a page people scroll slowly, this
     gives each section a moment of its own. 12px is deliberately small: enough
     to notice, not enough to look like a slideshow. ---- */
.reveal-on .reveal {
  opacity: 0;
  transform: translateY(12px);
}

.reveal-on .reveal.is-revealed {
  opacity: 1;
  transform: none;
  /* Slow out, no bounce. A memorial page should not feel springy. */
  transition: opacity .7s cubic-bezier(.22, .61, .36, 1) var(--reveal-delay, 0ms),
              transform .7s cubic-bezier(.22, .61, .36, 1) var(--reveal-delay, 0ms);
}

/* ---- 2. The filmstrip mounts lift under the cursor. They are buttons, so
     they should say so before they are clicked. The shadow deepens with the
     lift, which is what a real object does. ---- */
.shot { will-change: transform; }

.shot:hover,
.shot:focus-visible {
  transform: translateY(-6px);
  box-shadow: 0 10px 26px rgba(0, 0, 0, .28);
}

/* ---- 3. The enlarged photograph cross-fades between pictures instead of
     snapping. Moving along the timeline should feel like turning pages, and a
     hard cut between two photographs of the same man is jarring. ---- */
.lb-card__img {
  transition: opacity .28s ease;
}
.lb-card__img.is-swapping { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .reveal-on .reveal { opacity: 1; transform: none; transition: none; }
  .shot:hover, .shot:focus-visible { transform: none; }
  .lb-card__img { transition: none; }
}

/* The portrait somebody sends of themselves. Round, so it reads as a person
   rather than as another photograph in the gallery, and capped small so a
   full-resolution phone picture cannot dominate the card. */
/* The photograph somebody sends of themselves. A circle, Adele's choice from
   four shapes shown side by side on the real cards. */
.memory__portrait {
  display: block;
  width: 96px; height: 96px;
  margin: 0 auto 14px;
  border-radius: 50%;
  object-fit: cover;
  /* An upright photograph cropped square down the middle lands on somebody's
     chest. Taking the crop from the top puts the face in the circle. */
  object-position: center top;
  background: var(--smoke);
}

/* Holding the space until the real picture arrives. Drawn here rather than
   loaded, so there is no file to manage and nothing to clean up later. */
.memory__portrait--pending {
  background: #dfe3e7;
  color: #b3bcc6;                /* the figure, against that ground */
  overflow: hidden;
}
.memory__portrait--pending svg { display: block; width: 100%; height: 100%; }

/* --------------------------------------------------------------------------
   18. Depth on the buttons
   The page is very linear: hard edges, flat colour, right angles. A resting
   shadow lifts anything meant to be pressed off that plane, so a button reads
   as a button before it is hovered rather than after.
   -------------------------------------------------------------------------- */
.story__toggle,
.admin__btn,
.pager,
.decades__btn[aria-current="true"] {
  box-shadow: 0 1px 2px rgba(0, 0, 0, .18), 0 3px 9px rgba(0, 0, 0, .12);
  transition: box-shadow .18s ease, transform .18s ease,
              background .15s ease, color .15s ease;
}

.story__toggle:hover,
.admin__btn:hover,
.pager:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, .22), 0 8px 20px rgba(0, 0, 0, .18);
}

.story__toggle:active,
.admin__btn:active,
.pager:active:not(:disabled) { transform: translateY(0); }

.pager:disabled { box-shadow: none; }

/* Slightly rounded, matching the upload form, so every button on the site is
   the same shape. */
.story__toggle, .pager, .decades__btn { border-radius: 6px; }

@media (prefers-reduced-motion: reduce) {
  .share__submit:hover,
  .story__toggle:hover,
  .admin__btn:hover,
  .pager:hover:not(:disabled) { transform: none; }
}

/* --------------------------------------------------------------------------
   19. The private edit link, and edits waiting to be read
   -------------------------------------------------------------------------- */
.share__editlink {
  display: block; margin-top: 10px; padding: 12px;
  background: rgba(0, 0, 0, .05);
  border-radius: 6px;
  font-size: 15px; line-height: 22px; word-break: break-all;
  color: inherit;
}

.admin__edit {
  margin-top: 20px; padding: 18px;
  background: #fff8e6;                 /* held, not published: worth noticing */
  border: 1px solid #e0cf9a; border-radius: 6px;
}
.admin__edit-flag {
  font-size: 15px; letter-spacing: 1px; text-transform: uppercase; color: #7a5c12;
}
.admin__edit-what { margin-top: 6px; font-size: 15px; color: #6b6b6b; }
.admin__edit-body { margin-top: 12px; }

/* The disclosures link, in the footer of every page. Quiet on purpose: it
   should be findable and never be the loudest thing down there. */
.footer__links { margin: 0 0 6px; }
.footer__links a {
  /* Inline-block with room around it, so the tap area clears the 24px
     minimum. As plain inline text the link measured 18px tall and failed. */
  display: inline-block; padding: 5px 8px;
  font-size: 15px; line-height: 22px; letter-spacing: .3px;
  color: #55636F;            /* 5.4:1 on the footer, the body colour */
  text-decoration: underline; text-underline-offset: 3px;
}
.footer__links a:hover { color: #333; }
.footer__links a:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }

/* ==========================================================================
   16. DARK MODE

   WHY THIS EXISTS, AND WHY IT IS NOT A TOGGLE.

   It is not an accessibility requirement. WCAG has no success criterion at
   any level, A, AA or AAA, that asks for a dark mode, and none that asks a
   site to honour the system setting. The research also runs the other way for
   reading: dark text on light paper is read faster and more accurately at
   every age, and the advantage grows as type gets smaller.

   So this is here for three specific reasons, not as a default:

   1. CLOUDED EYES. People with cataracts read light-on-dark measurably
      better, because a bright background scatters across the whole retinal
      image and washes the letters out. Heze's visitors are largely over 60,
      which is exactly where cataract lives.
   2. LIGHT SENSITIVITY. Migraine, photophobia, a headache at the end of a
      hard day.
   3. THE ELEVEN O'CLOCK MOMENT. Somebody opens this link in bed, in a dark
      room, grieving. A full screen of warm white paper at that moment is
      unkind, and the phone already knows the room is dark.

   NO TOGGLE ON PURPOSE. Every phone and laptop already carries a system-wide
   setting, and anyone who needs this has set it years ago. A switch on the
   page is one more control to explain to a reader who is 80, on a site they
   will visit twice. If Adele wants one later it is a class on <html> and
   about ten lines here.

   HOW IT IS BUILT. Only tokens are redefined. Nothing about layout, spacing
   or type changes, and no rule below this block overrides a colour, so light
   and dark cannot drift apart. Every pair was measured: the worst contrast
   here is 6.85:1 against the 4.5:1 that AA asks.

   ONE THING TO WATCH, and Adele should look at it with her own eyes. A
   photograph on a dark page is perceived as slightly flatter and less
   colourful than the same photograph on light paper. That is established
   imaging science, the Bartleson-Breneman effect, not an opinion. It is why
   the mounts here are lifted away from the page rather than sunk into it: a
   print on a mat in a dimmed room, not a slide on a black wall. If the
   photographs still read flat to her, the answer is to lighten --mount, not
   to abandon the mode.
   ========================================================================== */

@media (prefers-color-scheme: dark) {
  :root {
    /* Warm, not grey. Her paper is #f3f0f0, which leans red, and a cold
       charcoal underneath these photographs looks like a different site. */
    --smoke:       #161311;   /* the page itself */
    --surface:     #1e1a18;   /* a card, a panel, the masthead, the footer */
    --mount:       #24201d;   /* the card a photograph is printed on */

    --ink:         #ece7e2;   /* 14.06:1 on a card. Not pure white: at full
                                 white the letters vibrate against the ground
                                 and smear for anyone with astigmatism, which
                                 is about half of people over 60. */
    --body-ink:    #c0b8b1;   /* 8.82:1 */
    --nav-ink:     #c8c0b9;   /* 9.62:1 */
    --rule:        #3a342f;

    /* The slate keeps the site's own blue and simply steps back, so the
       bands still read as bands. White on it is 6.85:1. */
    --slate:       #4e5c6b;
    --slate-deep:  #45535f;

    /* The reel ground has to go the other way in dark mode. Near-black here
       measures 1.37:1 against the masthead and the section disappears into the
       page. This is the light mode slate, which is lighter than the dark page
       rather than darker: 3.60:1 against the masthead, 3.86:1 against the page
       and 4.80:1 for the title on it. */
    --reel-ground: #647485;

    /* The focus ring has to be seen against a dark ground. This is the blue
       the lightbox already uses, at 9:1 on the page. */
    --focus:       #93b4ff;

    /* The handwriting. Measured at 1.3:1 when it was still black on a dark
       mount, which is why this token was split out at all. 12.6:1 now. */
    --script-ink:  #f0ebe6;
    --link-ink:    #9db7cf;   /* 8.31:1. The light-mode blue is 2.18:1 here. */
  }

  /* ---- buttons that are FILLED with the ink colour ----------------------
     A filled button is dark-on-light in the light mode and light-on-dark
     would be wrong here: --ink is now a pale warm white, so the fill is pale
     and the label has to go dark to sit on it. Measured white-on-pale at
     1.23:1 before this, which is invisible. */
  .pager:hover:not(:disabled),
  .story__toggle:hover,
  .songs__close:hover,
  .segment input:checked + .segment__face,
  .share__submit,
  .admin__btn--yes { color: #161311; }

  .share__submit:hover,
  .admin__btn--yes:hover { color: #161311; }

  /* ---- the handful of colours written literally rather than as tokens ---- */

  /* The decade bar, which sits over the strip and must stay legible through
     its own translucency. */
  .decades { background: rgba(22, 19, 17, .97); border-bottom-color: #2c2724; }
  .decades__btn[aria-current="true"] { background: rgba(255, 255, 255, .10); }

  /* Photo captions, 7.56:1 on the mount. */
  .shot__caption, .lb-card__caption, .memory__body { color: #b8b0a9; }

  /* An empty decade. Still obviously unfinished, without glowing. */
  .shot--placeholder { background: #1c1917; }
  .shot__slot { border-color: #4a433d; }

  .pager { border-color: #3a342f; }

  /* The hairline box around the biography and the Homegoing details. It is
     drawn in --black, which stays black so the hymn player and the black half
     of the home page keep their wells. On a dark page that border vanishes,
     so here it takes the ink colour instead. */
  .panel { border-color: #4a433d; }
  .panel--light { border-color: var(--white); }
  .memory__date { border-top-color: #322c28; }

  /* Scrollbars on the two sideways strips. */
  .strip, .songs__strip { scrollbar-color: #5b6a79 #20262c; }
  .strip::-webkit-scrollbar-track,
  .songs__strip::-webkit-scrollbar-track { background: #20262c; }

  /* A shadow is invisible on a dark ground, so the lift comes from the card
     being lighter than the page rather than from the shadow. Deepened anyway,
     which keeps the edge on mid-grey screens. */
  .shot, .memory { box-shadow: 0 2px 12px rgba(0, 0, 0, .55); }
  .shot:hover, .shot:focus-visible { box-shadow: 0 14px 34px rgba(0, 0, 0, .7); }

  /* Messages. The reds and greens were mixed for white paper and are muddy
     on a dark one, so they are lifted and their grounds sunk. */
  .share__status--good { background: #1b2a20; color: #a8d9ba; border-color: #3d6b4d; }
  .share__status--bad  { background: #2d1a1a; color: #f0a3a3; border-color: #6b3d3d; }
  .admin__btn--no { border-color: #d98a8a; color: #d98a8a; }
  .admin__btn--no:hover,
  .admin__btn--no[data-armed="1"] { background: #d98a8a; color: #161311; }

  /* The approval screen's "edited" flag, amber on paper, amber in the dark. */
  .admin__edit { background: #2a2417; border-color: #5a4d2a; }
  .admin__edit-flag { color: #e0cf9a; }
  .admin__edit-what { color: #b0a89f; }

  /* The upload form's drop zone, cut into the slate rather than out of it. */
  .drop { background: rgba(0, 0, 0, .28); }
  .drop:hover { background: rgba(0, 0, 0, .36); }
  .drop.is-over { background: rgba(0, 0, 0, .46); }
  .share__editlink { background: rgba(255, 255, 255, .08); }

  /* A held space, still clearly a held space. */
  .memory__portrait--pending { background: #2c3238; color: #5d6771; }

  .footer__links a { color: #c0b8b1; }
  .footer__links a:hover { color: #ece7e2; }

  /* The segmented VIDEO / WRITE IT / AUDIO control. */
  .segment:hover input:checked + .segment__face { background: #ece7e2; color: #161311; }

  /* ---- the wordmark ----------------------------------------------------
     "Celebrating the life of Hezekiah Moore" is Adele's own artwork, drawn as
     outlines in a single colour, #000000, with nothing else in the file. So
     inverting it gives exactly white and changes not one letterform. Shipping
     a second copy of the file would be two things to keep in step.

     This was invisible until it was looked at. The contrast script reads text
     and this is a picture, so nothing flagged it. Worth remembering for every
     site: measure the words, then LOOK at the page. */
  .masthead__wordmark { filter: invert(1); }

  /* Checked: the mark only ever appears inside .masthead, on all eight pages,
     so there is no second case to exempt. */

  /* A photograph carries its own light. Nothing is filtered or dimmed here,
     on purpose: dimming somebody's father is not a styling decision. */
}

/* --------------------------------------------------------------------------
   17. ON THIS PAGE
   A contents row under the banner on the home page. See the long note in
   index.html for why it is static rather than pinned.

   Type and target size are the decade bar's, because that is the site's own
   in-page jump control and two of them should not look like two ideas.
   -------------------------------------------------------------------------- */
.onpage {
  background: var(--surface);
  /* 24px at the sides, not 16, so the rule below lines up exactly with the
     edges of the film underneath it. .reel carries the same 24.

     The 18 at the foot is the air under the rule, and it has to be padding
     rather than a margin on the rule itself: a margin escapes this box and the
     smoke ground of the page shows through it as a grey stripe running the
     full width. */
  padding: 10px 24px 18px;
  text-align: center;
}

/* A short centred rule above the label, separating this from the banner.

   Not a full-width divider, and not the bottom border this used to carry. The
   site already has a mark for exactly this job: the two short rules either
   side of the word OF inside the wordmark. Borrowing it means the separation
   is made from the page's own vocabulary rather than a line imported for the
   purpose. */
.onpage::before {
  content: ""; display: block;
  width: 64px; height: 0;
  margin: 0 auto 14px;
  border-top: 1.5px solid var(--rule);
}

/* And a hairline underneath. Adele: "We just need separation for the next
   section."

   The note above used to end by saying nothing was needed here, which was true
   while this row only existed on the home page, where the first photograph is
   its own hard edge. It stopped being true the moment the row went on the Life
   Gallery, where Heze's Reel sits on the same white ground and the two read as
   one block.

   Inset to 1100px rather than run edge to edge, which is Adele's call and the
   right one: 1100 is the width of the links above it and of the film below it,
   so the line lands on an edge that is already there rather than cutting the
   page in half. */
.onpage::after {
  content: ""; display: block;
  max-width: 1100px; height: 0;
  margin: 14px auto 0;
  border-top: 1px solid var(--rule);
}

/* Sentence case, so the only words in capitals down this whole column are the
   links themselves: the three here and the three in the bar above. */
.onpage__label {
  margin: 0 0 2px;
  font-size: 15px; letter-spacing: .3px;
  color: var(--nav-ink);           /* 5.7:1 */
}

.onpage__list {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 4px;
  max-width: 1100px; margin: 0 auto; padding: 0; list-style: none;
}

.onpage__link {
  display: inline-flex; align-items: center;
  min-height: 48px; padding: 0 18px;
  border: 1px solid transparent; border-radius: 2px;
  font-size: 17px; letter-spacing: 1.5px; text-transform: uppercase;
  color: var(--body-ink);          /* 5.4:1 */
  text-decoration: none;
}
.onpage__link:hover { color: var(--ink); border-color: var(--ink); }
.onpage__link:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

/* Landing flush against the top of the window reads as though the section has
   been cut off. This drops each destination down a little as it arrives. */
#homegoing, #contact, #tribute,
#reel, #timeline, #hymn, #playlist { scroll-margin-top: 18px; }

@media (max-width: 767px) {
  .onpage { padding: 6px 18px 14px; }
  .onpage::before { width: 48px; margin-bottom: 10px; }
  .onpage::after { margin: 10px auto 0; }
  .onpage__label { font-size: 14px; }
  .onpage__link { font-size: 16px; padding: 0 13px; letter-spacing: 1px; }
}

/* --------------------------------------------------------------------------
   18. HEZE'S REEL
   Above the timeline on the Life Gallery page. Adele: "This video is really
   the centerpiece of the site."

   Built on the hymn section's pattern, because that is the site's established
   way of presenting a recording: white ground, centred, a rule under the
   title, the film, an arrow carrying the eye onward. Two differences, both
   because this one leads the page rather than closing it. The title is the
   page's h1 and sits a little larger, and the film is given the full column
   rather than the hymn's 940px, since it is twelve minutes of his own account
   of his life rather than a three minute song.
   -------------------------------------------------------------------------- */
.reel { background: var(--reel-ground); padding: 26px 24px 0; }

.reel__inner { max-width: 1100px; margin: 0 auto; text-align: center; }

.reel__title {
  font-size: 32px; line-height: 46px; letter-spacing: 1px; font-weight: 400;
  text-transform: uppercase;
  /* White in both modes, because the ground is dark in both. 12.63:1 on the
     near-black, 4.80:1 on the slate. White on slate is already what the
     filmstrip bands do. */
  color: #ffffff;
  text-wrap: balance;
  /* The panel titles' rule: inline-block so it is exactly as wide as the
     words, sitting tight underneath. Drawn out of the title's own white at
     half strength rather than in var(--rule), which is a pale grey in light
     mode and a near-black in dark and would be wrong on this ground in both. */
  display: inline-block; max-width: calc(100% - 40px);
  padding-bottom: 9px;
  border-bottom: 1.5px solid rgba(255, 255, 255, .5);
}

.reel__video {
  display: block; width: 100%; height: auto;
  aspect-ratio: 16 / 9;            /* holds the space before the still arrives */
  margin: 30px auto 0;
  background: var(--black);
  /* A faint white edge, so the film has a boundary on either ground. */
  border: 1px solid rgba(255, 255, 255, .3);
}

.reel__arrow { color: #ffffff; margin: 40px auto 34px; display: block; }

@media (max-width: 767px) {
  .reel { padding: 18px 18px 0; }
  .reel__title { font-size: 24px; line-height: 34px; }
  .reel__video { margin-top: 22px; }
  .reel__arrow { margin: 28px auto 24px; }
}

/* Only ever seen by a browser that cannot play video at all, where it sits on
   the player's own black ground. Left as inherited it was the page's near-black
   ink on black, 1.66:1. The hymn carries the same fallback and had the same
   fault, so it takes the same rule. */
.reel__fallback,
.hymn__fallback { display: block; padding: 24px; color: var(--white); }
