/* ===========================================================
   Wedding Clips — ported from the Purim JEM build
   Fonts, color-mode variables, type scale, layout metrics,
   pagination and marker-reveal all follow the Purim source.
   =========================================================== */

@font-face { font-family: Pinyon; src: url(fonts/pinyonscript.ttf) format("truetype");
             font-weight: 400; font-style: normal; font-display: swap; }

@font-face { font-family: Greed;  src: url(fonts/greedstandardvf.ttf) format("truetype");
             font-weight: 300 900; font-style: normal; font-display: swap; }

@font-face { font-family: Season; src: url(fonts/seasonseriftrial-light.ttf) format("truetype");
             font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: Season; src: url(fonts/seasonseriftrial-lightitalic.ttf) format("truetype");
             font-weight: 300; font-style: italic; font-display: swap; }
@font-face { font-family: Season; src: url(fonts/seasonseriftrial-regular.ttf) format("truetype");
             font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: Season; src: url(fonts/seasonseriftrial-regularitalic.ttf) format("truetype");
             font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: Season; src: url(fonts/seasonseriftrial-medium.ttf) format("truetype");
             font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: Season; src: url(fonts/seasonseriftrial-mediumitalic.ttf) format("truetype");
             font-weight: 500; font-style: italic; font-display: swap; }
@font-face { font-family: Season; src: url(fonts/seasonseriftrial-semibold.ttf) format("truetype");
             font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: Season; src: url(fonts/seasonseriftrial-semibolditalic.ttf) format("truetype");
             font-weight: 600; font-style: italic; font-display: swap; }
@font-face { font-family: Season; src: url(fonts/seasonseriftrial-bold.ttf) format("truetype");
             font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: Season; src: url(fonts/seasonseriftrial-bolditalic.ttf) format("truetype");
             font-weight: 700; font-style: italic; font-display: swap; }

/* ---- Purim's color modes, verbatim -------------------------- */

:root, .light-mode {
  --text--title:      #000;
  --text--subtitle:   #000000bf;
  --text--eyebrow:    #00000080;
  --bg--primary:      #faf9f9;
  --bg--secondary:    #f6f4f4;
  --bg--tertiary:     #ede9e9;
  --bg--quaternary:   #ffffff;
  --border--main:     #0000001a;
}

.dark-mode {
  --text--title:      #fff;
  --text--subtitle:   #ffffffbf;
  --text--eyebrow:    #ffffff80;
  --bg--primary:      #131515;
  --bg--secondary:    #1d2020;
  --bg--tertiary:     #272b2b;
  --bg--quaternary:   #0a0b0b;
  --border--main:     #ffffff1a;
}

:root {
  --marker: #C9A24B;              /* the one wedding accent */
  --serif:  Season, Georgia, serif;
  --sans:   Greed, "Helvetica Neue", Arial, sans-serif;
  --ease:   cubic-bezier(0.625, 0.05, 0, 1);
  --pag-ease: cubic-bezier(.165, .84, .44, 1);

  /* How much of the viewport the host page covers when this is framed
     inside another site — a fixed header over the top of the iframe.
     50px by default, which is the bar on the site this is embedded in;
     the CMS sets it per-site and 0 turns it off, and ?chrome= overrides
     both for a one-off test. Everything that fills the viewport or pins
     to it subtracts this, so nothing is cut off underneath. */
  --host-chrome: 50px;
  --view-h: calc(100svh - var(--host-chrome));

  /* The same at the bottom: how much of the view the screen hides. In
     the host's frame on Android Chrome the frame is sized as if the
     address bar were hidden, so while it shows the frame's bottom runs
     past the screen. app.js measures it; 0 when nothing is cut. */
  --view-cut: 0px;
}

* { box-sizing: border-box; }

html { height: 100%; scrollbar-width: none; -webkit-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; }
html::-webkit-scrollbar { display: none; }

/* The clips are a plain list, so the page scrolls freely — snapping
   would fight an ordinary read. The hero and closing still fill a
   screen; they simply are not snap targets. */
html { overflow-y: scroll; }

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 17px; font-weight: 400; line-height: 1.5;
  color: var(--text--title);
  background-color: var(--bg--primary);
  /* clip, not hidden: hidden makes the body a scroll box of its own,
     and the clip rail could then never stick to the window */
  overflow-x: hidden;
  overflow-x: clip;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
::selection { background: var(--marker); color: #fff; }

.g-main { width: 100%; }

/* ---- Purim layout metrics ----------------------------------- */

.u-section {
  background-color: var(--bg--primary);
  display: flex; flex-flow: column;
  justify-content: flex-start; align-items: center;
  min-height: var(--view-h);
  padding: 8rem 0;
  position: relative;
}

.u-container {
  width: 100%;
  max-width: 45rem;          /* Purim's container */
  margin: 0 auto;
  /* a gutter on both sides, so nothing sits against the screen edge */
  padding-inline: 7px;
  box-sizing: border-box;
}

.u-head-wrap {
  display: flex; flex-flow: column;
  gap: 2rem; width: 100%;
  padding: 4rem;
  text-align: left;
}

.u-vid-container {
  display: flex; flex-flow: column;
  justify-content: flex-start; align-items: center;
  gap: 2rem; width: 100%;
}

/* ---- Purim type scale --------------------------------------- */

.u-h1 {
  font-family: var(--serif); font-weight: 400;
  font-size: 66px; line-height: 1em; letter-spacing: -.025em;
  margin: 0;
}
.u-step-title {
  font-family: var(--serif); font-weight: 600;
  font-size: 34px; line-height: 1.1em; letter-spacing: -.01em;
  color: var(--text--title); margin: 0;
}
.u-h3 {
  font-family: var(--serif); font-weight: 600;
  font-size: 36px; line-height: 1.05em; letter-spacing: -.01em; margin: 0;
}

/* gradient-filled eyebrow, exactly as Purim does it */
.u-step-eyebrow {
  font-family: var(--sans); font-size: 16px; font-weight: 400;
  letter-spacing: .05em; text-transform: uppercase;
  background-image: linear-gradient(145deg, var(--text--subtitle), var(--text--eyebrow));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--text--subtitle);
  margin: 0;
}

.u-main-paragraph {
  font-family: var(--sans); font-size: 19px; font-weight: 500;
  line-height: 1.45em; letter-spacing: -.01em;
  color: var(--text--subtitle); margin: 0;
}
.u-p-sm {
  font-size: 14px; font-weight: 400; letter-spacing: .01em;
  line-height: 1.3em; color: var(--text--eyebrow); margin: 0;
}

@media (max-width: 767px) {
  .u-h1 { font-size: 48px; }
  .u-step-title { font-size: 28px; }
  .u-h3 { font-size: 26px; }
  .u-main-paragraph { font-size: 18px; }
  .u-head-wrap { padding: 2rem 20px; }
  .u-section { padding: 5rem 0; }
}

/* ---- Hero: the invitation's palette ------------------------
   Ivory paper, warm gold leaf, soft sage — taken from the
   wedding invitation. No background elements; the type carries it.
------------------------------------------------------------- */

.hero_section.is-invite {
  --text--title:    #33291A;   /* deep sepia ink */
  --text--subtitle: #6B5B41;
  --text--eyebrow:  #8A7A5E;
  --border--main:   rgba(120, 98, 58, .30);
  --marker:         #94793F;   /* darker gold leaf */

  background-color: #EFE8DA;   /* deeper paper, no glow */
  padding: 0; justify-content: center; overflow: hidden;
}

.hero_container { position: relative; z-index: 3; }
.hero_head_wrap {
  gap: 1.5rem; padding-top: 0; padding-bottom: 0;
  text-align: center; align-items: center;
}

/* monogram: ring draws, letters rise */
.monogram_wrap {
  position: relative; width: 132px; height: 132px;
  display: grid; place-items: center;
}
.monogram_svg {
  position: absolute; inset: 0;
  width: 132px; height: 132px; color: rgba(176,145,88,.6);
  overflow: visible;
}
.mono_ring { will-change: stroke-dashoffset; }

/* the Greenwald mark, drawn inside the ring. The artwork is dark
   charcoal on transparent, so it is tinted to the gold-leaf accent
   rather than left to sit as a black blot on the paper. */
.monogram_mark {
  position: relative; z-index: 1;
  width: auto; height: 76px;
  object-fit: contain;
  will-change: transform, opacity;
  /* charcoal → gold leaf, without shipping a second asset */
  filter: brightness(0) saturate(100%)
          invert(50%) sepia(37%) saturate(718%)
          hue-rotate(5deg) brightness(92%) contrast(88%);
}

.hero_eyebrow { letter-spacing: .2em; margin-bottom: .35rem; }

.hero_h1 {
  position: relative;
  /* set exactly like the topic titles (Shalom Bayis), on one line */
  display: flex; flex-flow: row nowrap; align-items: center;
  justify-content: center; gap: .25em; white-space: nowrap;
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(1.75rem, 7.4vw, 5rem);
  letter-spacing: -.01em;
  color: var(--text--title);
  line-height: 1.05;
}

/* given names in the invitation's script */
.hero_names {
  display: flex; flex-wrap: wrap;
  align-items: baseline; justify-content: center; gap: 0 .3em;
  font-family: Pinyon, var(--serif);
  font-size: .92em; line-height: 1.3;
  letter-spacing: .01em;
  color: var(--marker);
}

.hero_body { display: flex; flex-flow: column; align-items: center; gap: 1rem; text-align: center; }
.hero_scroll { will-change: transform, opacity; }

.split-line { overflow: hidden; }

/* ---- Clip card: editorial panel overlapping the media ------- */

.u-step-section { justify-content: center; padding: 6rem 0 9rem; }
.u-step-section .u-container {
  display: flex; flex-flow: column; align-items: center; gap: 2.5rem;
}
/* The topic's opening card is as tall as its words, not a whole
   screen. Opening a topic should land you with its description read
   and the first video already starting underneath — a full-height
   intro pushed that video below the fold every time. */
.u-step-section.is-intro {
  justify-content: center;
  min-height: 0;
  padding: 4.5rem 0 2.5rem;
}
/* the generic head-wrap reserves 4rem all round; an intro that has to
   leave room for the video below it does not need that much */
.u-step-section.is-intro .u-head-wrap { padding: 0 1.5rem; gap: 1.25rem; }

@media (max-width: 767px) {
  .u-step-section.is-intro { padding: 3rem 0 1.75rem; }
}
.u-step-title.is-big { font-size: 46px; letter-spacing: -.02em; }

.topic_hebrew {
  font-family: var(--serif); font-weight: 400; font-size: 22px;
  color: var(--marker); margin: 0;
}

.clip_card { position: relative; width: 100%; }

/* the caption above the video — a few words naming the clip. It is the
   clip's heading, so it carries the step-title scale rather than a size
   of its own. It sits under the player, at the head of the copy — the
   panel is a flex column with its own gap, so it needs no margin. */
.clip_caption {
  margin: 0;
  text-wrap: balance;
}

/* media */
.clip_media {
  position: relative; display: block;
  /* the clip's own shape, set per card from the CMS ratio; 4:3 is
     only the fallback for a row that never names one */
  aspect-ratio: var(--card-ratio, 4 / 3);
  width: 100%;
  background-color: var(--bg--tertiary);
  border-radius: 2px;
  overflow: clip;
  cursor: pointer;
}
.clip__thumb {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0;
  transition: opacity .8s var(--ease), transform 1.2s var(--ease);
  will-change: transform;
}
.clip__thumb.is-loaded { opacity: 1; }
.clip_media:hover .clip__thumb.is-loaded { transform: scale(1.04); }

.clip__scrim {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(#0000 40%, #000000b3);
}

.clip__play {
  position: absolute; inset: 0; margin: auto;
  width: 78px; height: 78px; border-radius: 100vw;
  display: grid; place-items: center;
  background: #ffffffe6; border: .5px solid #ffffff80;
  transform: scale(.9); opacity: .92;
  transition: transform .55s var(--ease), opacity .55s var(--ease);
}
.clip_media:hover .clip__play { transform: scale(1); opacity: 1; }
.clip__play svg { width: 20px; height: 20px; color: #000; margin-left: 3px; }

.clip__duration {
  position: absolute; right: 1rem; top: 1rem;
  padding: .25rem .7rem; border-radius: 2px;
  background: #000000a6; border: .5px solid #ffffff26;
  color: #fff; font-size: 13px; letter-spacing: .04em;
  font-variant-numeric: tabular-nums;
}

/* ---- placeholder, while the videos are still being cut ------
   A frame of the real shape with the real caption above it, so
   the layout can be signed off before the files arrive. It is
   deliberately inert: nothing to click, nothing to hover.
-------------------------------------------------------------- */
.clip_media.is-pending {
  cursor: default;
  background-color: var(--bg--tertiary);
  /* a quiet diagonal tick, so an empty frame reads as "reserved"
     rather than as a thumbnail that failed to load */
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(201,162,75,.07) 0 10px,
    transparent 10px 20px
  );
  border: 1px dashed var(--border--main);
}
.clip_media.is-pending .clip__scrim { opacity: .35; }

.clip__pending {
  position: absolute; inset: 0; margin: auto;
  width: max-content; height: max-content;
  padding: .45rem 1rem; border-radius: 2px;
  background: #000000a6; border: .5px solid #ffffff26;
  color: #fff; font-size: 13px; letter-spacing: .14em;
  text-transform: uppercase;
}

.clip__cta.is-pending {
  color: var(--text--eyebrow); opacity: .75;
  cursor: default; pointer-events: none;
}

/* the text panel lifts over the media's lower edge */
.clip_panel {
  position: relative;
  /* the copy sits under the player, not over it: no negative pull and
     no panel shadow, so the video keeps its whole frame. The title is
     the first thing in here and sits close under the frame; the rule
     below it opens the gap before the number and the description. */
  margin: .9rem 0 0 0;
  width: 100%;
  padding: 0;
  background-color: transparent;
  display: flex; flex-flow: column; gap: .85rem;
}
/* a little more air around the rule than between the lines it divides */
.clip_panel .clip_rule { margin: .35rem 0 .15rem; }

.clip_rule { height: 1px; width: 100%; background: var(--marker); }

.clip_index {
  display: flex; align-items: baseline; gap: .55rem; margin: 0;
  font-size: 13px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text--eyebrow);
}
/* the row carries only the topic name now — the count moved to the
   rail of dots beside the list */
.clip_topic { letter-spacing: .12em; }

.clip_caption { font-size: 26px; }

.clip__quote {
  position: relative; margin: 0; padding-left: 1.25rem;
  border-left: 2px solid var(--marker);
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: 19px; line-height: 1.4em; letter-spacing: -.01em;
  color: var(--text--title);
}

.clip_blurb {
  margin: 0; font-size: 15px; line-height: 1.55em;
  color: var(--text--subtitle);
}

.clip_foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding-top: 1rem; border-top: .5px solid var(--border--main);
}
.clip__meta {
  display: flex; align-items: center; gap: .5rem; margin: 0;
  font-size: 13px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text--eyebrow); white-space: nowrap;
}
.clip__meta span { display: inline-flex; align-items: center; }
.clip__meta span::before {
  content: ''; width: 3px; height: 3px; border-radius: 50%;
  background: var(--marker); margin-right: .5rem;
}
.clip__meta span:first-child::before { display: none; }

.clip__cta {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: 15px; color: var(--marker); white-space: nowrap;
}
.clip__cta .u-button-icon-slot { width: 1em; height: 1em; }
.clip__cta svg { width: 100%; height: 100%; stroke: currentColor; transition: transform .45s var(--ease); }
.clip_card:hover .clip__cta svg { transform: translate(2px, -2px); }

/* wide: media left, panel overlapping from the right */
@media (min-width: 992px) {
  .u-step-section:not(.is-intro) .u-container { max-width: 72rem; }
  /* two columns: the caption and its video stack in the left one,
     the panel overlaps from the right across both rows */
  /* caption, then the player, then the copy — one column, so nothing
     is laid over the video at any width */
  .clip_card {
    display: block;
    max-width: 54rem;
    margin-inline: auto;
  }
  .clip_media { aspect-ratio: var(--card-ratio, 16 / 9); }
  .clip_panel {
    margin: 1.5rem 0 0 0; width: 100%;
    padding: 0;
    box-shadow: none;
  }
  .clip_caption { font-size: 28px; }
}

@media (max-width: 767px) {
  /* One margin on a phone for the videos and every line of text, so
     nothing hugs the screen edge and the topic title lines up with the
     cards under it. It was 7px for the cards and 31px for the title. */
  .u-container { padding-inline: 16px; }
  .u-step-section.is-intro .u-head-wrap { padding-inline: 0; }
  .u-step-section.is-intro { padding: 2.5rem 0 1.25rem; }

  /* a card's title, rule, topic and button sit closer together */
  .clip_panel { gap: .6rem; }
  .clip_panel .clip_rule { margin: .2rem 0 .1rem; }

  .u-step-title.is-big { font-size: 32px; }
  .clip_caption { font-size: 21px; }
  .clip__quote { font-size: 17px; }
  .clip_panel { margin-top: 1rem; width: 100%; padding: 0; }
  .clip__play { width: 60px; height: 60px; }
  /* the footer stacks, and the Watch button spans the card rather than
     shrink-wrapping to its label — a cramped pill left-aligned under
     the meta line was the odd thing on a phone */
  .clip_foot {
    flex-flow: column; align-items: stretch; gap: .9rem;
  }
  .clip__meta { justify-content: flex-start; }
  .clip__cta {
    width: 100%;
    justify-content: center;
    padding: .95em 1.5em;
    font-size: 14px;
  }
}

/* ---- Purim's floating pagination ------------------------------ */

.g-absolute-wrap {
  /* Pinned to the *visual* bottom. On Android the URL bar and the gesture
     area sit over a `position: fixed` element, which hid the rail; the
     safe-area inset is what that chrome actually reserves, so the bar is
     lifted by it plus a fixed gap rather than by a guess. */
  position: fixed; inset: auto 0 0 0; z-index: 30;
  display: flex; flex-flow: column; justify-content: flex-end; align-items: center;
  pointer-events: none; height: 10rem;
  padding-bottom: env(safe-area-inset-bottom, 0px);
  box-sizing: border-box;
  /* lifted clear of whatever the screen cuts off the bottom of a frame */
  translate: 0 calc(-1 * var(--view-cut));
  transition: translate .25s var(--pag-ease);
}

/* the strip app.js watches to find how much of the bottom is cut */
.view_probe {
  position: fixed; left: 0; bottom: 0;
  width: 1px; height: 160px;
  visibility: hidden; pointer-events: none;
}
.pag-bg {
  position: absolute; inset: auto 0 0 0; z-index: 10;
  width: 100%; height: 10rem; pointer-events: none;
  background-image: linear-gradient(#0000, #0000001a);
}
.dark-mode .pag-bg { background-image: linear-gradient(#0000, #00000059); }

.floating_list {
  position: relative; z-index: 30;
  display: flex; flex-flow: row; justify-content: center; align-items: center;
  gap: .5rem; margin-bottom: 2rem; pointer-events: auto;
  max-width: 100%;
}

/* On a phone the rail sits closer to the edge, but never under the home
   indicator or Android's gesture bar, and it may scroll sideways rather
   than overflow the screen when a topic name is long. */
@media (max-width: 767px) {
  .g-absolute-wrap { height: 9rem; }
  .floating_list {
    /* well clear of Android's gesture bar and the iOS home indicator,
       which sit over a fixed element on top of the safe-area inset */
    margin-bottom: 2.75rem;
    gap: .4rem;
    padding: 0 .75rem;
    box-sizing: border-box;
  }
}

.pag-wrap {
  position: relative; z-index: 0;
  display: flex; flex-flow: column; justify-content: center; align-items: center;
  gap: .4rem; padding: .35rem .5rem;
  border: .5px solid rgba(255,255,255,.14);
  background-color: rgba(10,11,11,.72);
  border-radius: 100vw; pointer-events: auto;
  backdrop-filter: blur(10px);
}
.pag-list {
  position: relative; z-index: 20;
  display: flex; flex-flow: row; justify-content: center; align-items: center;
  gap: .45rem; height: 34px;
}
/* three round, filled topic icons */
.pag-item {
  cursor: pointer; border: 0; padding: 0; flex: none;
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  background-color: rgba(255,255,255,.12);
  color: rgba(255,255,255,.55);
  transition: background-color .3s var(--pag-ease),
              color .3s var(--pag-ease);
}
.pag-item svg { width: 17px; height: 17px; fill: currentColor; display: block; }
.pag-item:hover { background-color: rgba(255,255,255,.22); color: rgba(255,255,255,.85); }

.pag-item.is-current {
  background-color: var(--marker);
  color: #fff;
}


.floating_share_button {
  display: flex; justify-content: center; align-items: center;
  width: 45px; height: 45px; font-size: 16px;
  border: .5px solid rgba(255,255,255,.14);
  background-color: rgba(10,11,11,.72);
  backdrop-filter: blur(10px);
  border-radius: 100vw; cursor: pointer;
  /* The capsule stays dark whichever section is behind it, so the icon
     is white — `var(--text--title)` was overriding the `#fff` set a
     line above and turning it black over a light section. */
  color: #fff;
  pointer-events: auto;
  transition: transform .3s var(--pag-ease);
}
.floating_share_button:hover { transform: scale(1.06); }
.floating_share_button svg { width: 1em; height: 1em; }

/* ---- Marker reveal (Purim's signature) ------------------------ */

[data-marker-reveal] { visibility: hidden; }

[data-marker-reveal] .marker-line {
  width: auto; display: inline-block !important;
  margin: -0.055em 0; position: relative;
}
.marker-bar {
  position: absolute; inset: -0.055em 0; z-index: 1;
  pointer-events: none; background-color: var(--marker);
}

/* ---- Closing --------------------------------------------------- */

.closing_section { justify-content: center; text-align: center; }
.closing_section .u-head-wrap { text-align: center; align-items: center; }
/* names set in an engraved script, as on the invitation */
.closing__names {
  margin: .35rem 0 0;
  display: flex; flex-wrap: wrap;
  align-items: baseline; justify-content: center;
  gap: 0 .35em;
  font-family: Pinyon, var(--serif);
  font-weight: 400; font-style: normal;
  font-size: clamp(2.6rem, 6vw, 4.5rem);
  line-height: 1.25;
  letter-spacing: .01em;
  color: var(--marker);
}
.closing__names .name { position: relative; display: inline-block; white-space: nowrap; }

/* the Hebrew honorific sits small and high, as printed */
.closing__names .hon {
  font-family: var(--sans);
  font-size: .17em; font-weight: 400;
  letter-spacing: 0; color: var(--text--eyebrow);
  margin-left: .25em; vertical-align: .9em;
}
.closing__names .amp { font-size: .74em; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-snap-type: none; }
  * { animation: none !important; transition-duration: .01ms !important; }
}

/* ---- the button, shared by the hero and each clip's CTA ------
   A quiet outline that fills from the bottom on hover. -------- */

.u-button {
  position: relative; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 1.05em 2.9em;
  border: 1px solid var(--marker); border-radius: 999px;
  background: transparent; color: var(--marker);
  font-family: var(--sans); font-size: 15px; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase;
  text-decoration: none; cursor: pointer;
  overflow: hidden; -webkit-tap-highlight-color: transparent;
  transition: color .45s var(--ease), transform .45s var(--ease),
              box-shadow .45s var(--ease);
}
.u-button:hover { transform: translateY(-1px); }
.u-button:active { transform: translateY(0); }
.u-button-content {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: .5rem;
}
.u-button-bg {
  position: absolute; inset: 0; z-index: 0;
  background: var(--marker);
  transform: translateY(101%);
  transition: transform .55s var(--ease);
}
.u-button:hover { color: var(--bg--primary); }
.u-button:hover .u-button-bg { transform: translateY(0); }
.hero_section.is-invite .u-button:hover { color: #FBF8F2; }
.u-button:focus-visible { outline: 2px solid var(--marker); outline-offset: 3px; }

.hero_button { margin-top: 1.4rem; }

/* With no speaker or year beside it, the Watch button stands alone: no
   rule above it, and no padding to hold a line that isn't there. */
.clip_foot.is-solo { border-top: 0; padding-top: 0; margin-top: .35rem; }

/* the clip CTA is a button now, so it sheds the old inline-link look */
.clip__cta { font-size: 14px; padding: .7em 1.7em; }

@media (prefers-reduced-motion: reduce) {
  .u-button, .u-button-bg { transition: none; }
}

/* ---- hero ground --------------------------------------------
   No bloom, no grid, no waves — a plain warm ground a few shades
   deeper than the paper, so the type carries the panel. ------ */



/* ---- a topic is a panel ---------------------------------------
   One topic is open at a time, so the end of a topic is the end of
   the scroll; the rail moves between them. `hidden` does the work,
   and is only overridden here for print, where all of it should be
   on the page at once. */

.topic_panel[hidden] { display: none; }

@media print {
  .topic_panel[hidden] { display: block !important; }
}

/* ---- the clip rail --------------------------------------------
   Where you are in a topic: the count, then a bar with a dot per
   clip. It replaces the 01 / 04 that used to sit under each player,
   out of sight while the video was on screen.

   The rail has a lane of its own to the left of the cards and sticks
   level with the top of the player while the list scrolls past, so it
   is in view for as long as the clips are and gone over the hero and
   the closing. The frame and the ghost inside it repeat the card's
   box, so the lane is measured off the card's real left edge. ------ */

.clip_list {
  --rail-w:     2.5rem;    /* the lane */
  --rail-gap:   1.25rem;   /* lane to card */
  --rail-edge:  .75rem;    /* lane to window, where the gutter is tight */
  --rail-inset: 7px;       /* the container's own gutter, unless widened */
  --slide-pad:  3.5rem;    /* a card's top padding — the rail starts under it */
  --dot-pitch:  1.4rem;
  --dot-size:   9px;
}
@media (max-width: 767px) {
  .clip_list {
    --rail-w: 1.4rem; --rail-gap: .4rem; --rail-edge: .35rem;
    --slide-pad: 1.75rem;
    --dot-pitch: 1.35rem; --dot-size: 7px;
  }
}

/* Where the gutter is too narrow for the lane, the cards step in to
   leave it room rather than being written underneath it. */
@media (max-width: 859px), (min-width: 992px) and (max-width: 1023px) {
  .clip_list.has-rail {
    --rail-inset: calc(var(--rail-w) + var(--rail-gap) + var(--rail-edge));
  }
}
.clip_list.has-rail .clip_slide .u-container { padding-left: var(--rail-inset); }

.cliprail_lane {
  position: absolute; inset: 0; z-index: 2;
  pointer-events: none;
}
.cliprail_frame {
  width: 100%; height: 100%;
  max-width: 45rem; margin: 0 auto;
  padding: 0 7px 0 var(--rail-inset);
}
.cliprail_ghost { position: relative; width: 100%; height: 100%; margin: 0 auto; }
@media (min-width: 992px) {
  .cliprail_frame { max-width: 72rem; }
  .cliprail_ghost { max-width: 54rem; }
}

/* from the top of the first player to the foot of the last card */
.cliprail_col {
  position: absolute;
  top: var(--slide-pad); bottom: var(--slide-pad);
  right: calc(100% + var(--rail-gap));
  width: var(--rail-w);
}

.cliprail {
  position: sticky;
  top: calc(var(--host-chrome) + var(--slide-pad));
  display: flex; flex-flow: column; align-items: center;
  gap: .85rem;
  pointer-events: auto;
}

/* the count — the clip you are on, over how many there are */
.cliprail_count {
  margin: 0;
  display: flex; flex-flow: column; align-items: center; gap: .35rem;
  font-variant-numeric: lining-nums tabular-nums;
}
.cliprail_now {
  display: block; overflow: clip;
  font-family: var(--serif); font-weight: 500;
  font-size: 26px; line-height: 1; letter-spacing: -.01em;
  color: var(--marker);
  /* the top of the figure, not of its line box, meets the player's edge */
  margin-top: -.12em;
}
.cliprail_now > span { display: block; }
.cliprail_total {
  font-family: var(--sans); font-size: 11px; line-height: 1;
  letter-spacing: .12em; white-space: nowrap;
  color: var(--text--eyebrow);
}

/* the bar, from the first dot to the last, and the gold that fills it
   as far as the clip you are on */
.cliprail_track {
  position: relative;
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-flow: column; align-items: center;
}
.cliprail_track li { display: block; }
.cliprail_track::before,
.cliprail_track::after {
  content: ''; position: absolute; left: 50%;
  top: calc(var(--dot-pitch) / 2); bottom: calc(var(--dot-pitch) / 2);
  width: 1px; margin-left: -.5px;
}
.cliprail_track::before {
  background: color-mix(in srgb, var(--text--title) 16%, transparent);
}
.cliprail_track::after {
  background: var(--marker);
  transform: scaleY(var(--progress, 0)); transform-origin: top;
  transition: transform .6s var(--ease);
}

/* the button is the whole pitch, so a dot is easy to hit; the dot
   itself is drawn inside it */
.cliprail_dot {
  position: relative;
  display: grid; place-items: center;
  width: var(--rail-w); height: var(--dot-pitch);
  padding: 0; border: 0; background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.cliprail_dot::before {
  content: '';
  width: var(--dot-size); height: var(--dot-size);
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--text--title) 42%, transparent);
  /* the page behind it, so a dot ahead reads as a ring with the bar
     stopping at its edge */
  background: var(--bg--primary);
  transition: background-color .35s var(--ease), border-color .35s var(--ease),
              transform .35s var(--ease), box-shadow .35s var(--ease);
}
.cliprail_dot.is-past::before {
  background: var(--marker); border-color: var(--marker);
}
.cliprail_dot.is-current::before {
  background: var(--marker); border-color: var(--marker);
  transform: scale(1.45);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--marker) 24%, transparent);
}
.cliprail_dot:hover::before { border-color: var(--marker); }
.cliprail_dot:not(.is-current):hover::before { transform: scale(1.25); }
.cliprail_dot:focus-visible { outline: none; }
.cliprail_dot:focus-visible::before { outline: 2px solid var(--marker); outline-offset: 3px; }

/* the clip's name, beside its dot, for a pointer or a keyboard */
.cliprail_tip {
  position: absolute; top: 50%; left: calc(50% + 1.1rem);
  max-width: 16rem;
  padding: .4rem .7rem; border-radius: 2px;
  background: #0a0b0be6; border: .5px solid #ffffff26;
  color: #fff;
  font-family: var(--sans); font-size: 12px; line-height: 1.2;
  letter-spacing: .02em; text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translate(-4px, -50%);
  transition: opacity .25s var(--ease), transform .25s var(--ease), visibility .25s;
}
@media (hover: hover) {
  .cliprail_dot:hover .cliprail_tip {
    opacity: 1; visibility: visible; transform: translate(0, -50%);
  }
}
.cliprail_dot:focus-visible .cliprail_tip {
  opacity: 1; visibility: visible; transform: translate(0, -50%);
}

/* a phone: a narrower lane, the figure alone over the dots — they
   already say how many there are */
@media (max-width: 767px) {
  .cliprail { gap: .7rem; }
  .cliprail_now { font-size: 17px; }
  .cliprail_total { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .cliprail_track::after, .cliprail_dot::before, .cliprail_tip { transition: none; }
}

/* ---- the clip list -------------------------------------------
   A topic's clips are a plain list: each one is an ordinary
   section in the flow, as tall as its own content. Nothing is
   pinned and nothing is stacked, so the page scrolls normally. */

.clip_list {
  position: relative;
  background-color: var(--bg--primary);
}

.clip_slide {
  width: 100%;
  /* a card in a list is as tall as its content — it inherits the
     full-screen minimum from .u-section, which does not apply here */
  min-height: 0;
  /* the rail lines up under this, so it is one value for both */
  padding: var(--slide-pad, 3.5rem) 0;
  scroll-snap-align: none;
}
.clip_slide .u-container { width: 100%; }

/* a hairline between clips, so the list reads as a list. It is drawn
   the width of the card, at the seam between the two, rather than across
   the window — a full-width rule ran straight through the clip rail. */
.clip_slide + .clip_slide .clip_card::before {
  content: ''; position: absolute; left: 0; right: 0;
  top: calc(-1 * var(--slide-pad, 3.5rem));
  border-top: .5px solid var(--border--main);
}

/* ══ IN-PAGE PLAYER ═══════════════════════════════════════════
   A lightbox over the page: the signed jem.tv embed plays here
   rather than sending the reader away mid-scroll.
   ═══════════════════════════════════════════════════════════ */
html.is-player-open,
html.is-player-open body { overflow: hidden; }

/* ---- the share sheet ------------------------------------------
   The page's own, rather than the OS sheet and an alert(): the same
   backdrop and paper as the player, so sharing looks like part of
   the invitation. ------------------------------------------------ */

.share_overlay {
  position: fixed; inset: var(--host-chrome) 0 var(--view-cut) 0; z-index: 9100;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(1rem, 4vw, 3rem);
}
.share_backdrop {
  position: absolute; inset: 0;
  background: #05060699;
  -webkit-backdrop-filter: blur(18px) saturate(120%);
  backdrop-filter: blur(18px) saturate(120%);
  cursor: pointer;
}
.share_panel {
  position: relative;
  width: min(100%, 34rem);
  padding: 1.75rem clamp(1.1rem, 4vw, 2.25rem) 1.25rem;
  background: #EFE8DA;                 /* the invitation's paper */
  color: #33291A;
  border-radius: 4px;
  box-shadow: 0 2.5rem 5rem #00000080;
  text-align: center;
  /* a short landscape phone may not fit the whole sheet */
  max-height: 100%;
  overflow-y: auto;
}
.share_eyebrow {
  margin: 0 0 .5rem;
  font-family: var(--sans); font-size: 13px;
  letter-spacing: .2em; text-transform: uppercase;
  color: #8A7A5E;
}
.share_title {
  margin: 0 0 1.25rem;
  font-family: var(--serif); font-size: 21px; line-height: 1.3;
  letter-spacing: -.01em; color: #33291A;
  text-wrap: balance;
}
@media (max-width: 480px) {
  .share_title { font-size: 18px; margin-bottom: 1rem; }
}
/* the places to send it: Remix Icon glyphs on the paper, outlined like
   the link field and filled with gold leaf on hover, as the page's own
   buttons are */
.share_targets {
  list-style: none; margin: 0 0 1.4rem; padding: 0;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 1rem .1rem;
}
.share_targets li { display: block; width: 4rem; }
.share_target {
  display: flex; flex-flow: column; align-items: center; gap: .45rem;
  width: 100%; padding: 0; margin: 0;
  border: 0; background: none;
  font: inherit; color: inherit; text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.share_icon {
  display: grid; place-items: center;
  width: 2.9rem; height: 2.9rem; border-radius: 50%;
  border: 1px solid rgba(120, 98, 58, .35);
  background: #FBF8F2;
  color: #94793F;
  transition: background-color .35s var(--ease), border-color .35s var(--ease),
              color .35s var(--ease), transform .35s var(--ease);
}
.share_icon svg { display: block; width: 1.25rem; height: 1.25rem; fill: currentColor; }
.share_name {
  font-family: var(--sans); font-size: 12px; line-height: 1.2;
  letter-spacing: .02em; white-space: nowrap;
  color: #6B5B41;
}
/* only where there is a pointer to hover with: on a phone a tapped
   icon would otherwise stay gold after you come back to the page */
@media (hover: hover) {
  .share_target:hover .share_icon {
    background: #94793F; border-color: #94793F; color: #FBF8F2;
    transform: translateY(-1px);
  }
}
.share_target:active .share_icon {
  background: #94793F; border-color: #94793F; color: #FBF8F2;
}
.share_target:focus-visible { outline: none; }
.share_target:focus-visible .share_icon { outline: 2px solid #94793F; outline-offset: 2px; }

/* "or copy the link", with a hairline either side */
.share_or {
  display: flex; align-items: center; gap: .75rem;
  margin: 0 0 1rem;
  font-family: var(--sans); font-size: 11px; line-height: 1;
  letter-spacing: .16em; text-transform: uppercase;
  color: #8A7A5E;
}
.share_or::before, .share_or::after {
  content: ''; flex: 1; height: 1px;
  background: rgba(120, 98, 58, .25);
}

.share_linkrow {
  display: flex; gap: .6rem; align-items: center;
  flex-wrap: wrap; justify-content: center;
}
.share_link {
  flex: 1 1 14rem; min-width: 0;
  /* one line, always: `stretch` plus a wrapped row let this grow to the
     row's full height, and a 999px radius turned that into an oval */
  height: 2.9rem;
  flex-shrink: 1;
  padding: 0 1em;
  border: 1px solid rgba(120, 98, 58, .35);
  border-radius: 999px;
  background: #FBF8F2;
  font-family: var(--sans); font-size: 14px;
  color: #6B5B41;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.share_link:focus-visible { outline: 2px solid #94793F; outline-offset: 2px; }

/* the copy button borrows the page's button, in the hero's palette */
.share_copy.u-button {
  flex: 0 0 auto;
  height: 2.9rem;              /* the same line as the field beside it */
  padding: 0 1.6em;
  font-size: 13px;
  border-color: #94793F; color: #94793F;
}
.share_copy.u-button .u-button-bg { background: #94793F; }
.share_copy.u-button:hover { color: #FBF8F2; }
.share_copy .u-button-icon-slot { width: 1em; height: 1em; }
.share_copy svg { width: 100%; height: 100%; }

.share_dismiss {
  margin-top: 1.25rem;
  border: 0; background: transparent; cursor: pointer;
  font-family: var(--sans); font-size: 13px;
  letter-spacing: .12em; text-transform: uppercase;
  color: #8A7A5E;
}
.share_dismiss:hover { color: #33291A; }

@media (max-width: 480px) {
  /* four to a row on a phone, the way a share sheet is laid out there */
  .share_targets { column-gap: 0; row-gap: 1.1rem; }
  .share_targets li { width: 25%; }
  .share_linkrow { flex-flow: column; align-items: stretch; }
  .share_link { width: 100%; flex: 0 0 auto; }
  .share_copy.u-button { width: 100%; }
}

.player_overlay {
  position: fixed;
  inset: var(--host-chrome) 0 var(--view-cut) 0;
  z-index: 9000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(1rem, 4vw, 3rem);
}

.player_backdrop {
  position: absolute;
  inset: 0;
  background: #05060699;
  -webkit-backdrop-filter: blur(18px) saturate(120%);
  backdrop-filter: blur(18px) saturate(120%);
  cursor: pointer;
}

.player_shell {
  position: relative;
  /* Height, not width, is what bounds a tall player: the frame takes the
     height available and its width follows from the aspect ratio. The
     frame sets `flex: 0 0 auto`, so being a flex container no longer
     shrink-wraps it to the close button inside it. */
  width: min(100%, 1180px);
  height: 100%;
  /* Frame then caption, each only as tall as it needs to be, and the
     pair centred in the view. `1fr` on the first row was the bug: it
     swallowed the leftover height, so the player was pinned to the top
     of a tall empty box with the caption stranded at the bottom. */
  display: flex;
  flex-flow: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  min-height: 0;
}

.player_frame {
  position: relative;
  /* Fits the viewport in both directions at once: the width is capped by
     the space across, and by the width the available height allows at
     this ratio (--ratio-wh is width over height, set per clip). */
  --gutter: clamp(1rem, 4vw, 3rem);
  /* the caption under the frame takes a line, so it is reserved here
     as well as the gutter — otherwise a tall clip overflows the view */
  --caption: 3rem;
  aspect-ratio: 9 / 16;
  width: min(100%, (100dvh - var(--host-chrome) - var(--view-cut) - 2 * var(--gutter) - var(--caption)) * var(--ratio-wh, 0.5625));
  /* the shell is a column flex box, so say the width is not to be
     shrunk to fit the close button inside it */
  flex: 0 0 auto;
  max-width: 100%;
  height: auto;
  overflow: hidden;
  border-radius: 0.75rem;
  border: 1px solid var(--border--main);
  background: #000;
  box-shadow: 0 2.5rem 5rem #00000080;
}

/* the clip's name under the player, in the page's own type */
.player_caption {
  margin: 0 auto;
  max-width: 48rem;
  text-align: center;
  font-family: var(--serif);
  font-size: 19px; line-height: 1.3;
  letter-spacing: -.01em;
  color: #F3EFE6;
}
@media (max-width: 767px) {
  .player_caption { font-size: 16px; }
}

.player_frame iframe,
.player_frame video {
  /* The jem.tv player is 16:9 inside the iframe and is cross-origin, so
     it cannot be restyled. To fill a frame of another shape, the iframe
     is given a 16:9 box big enough to cover the frame and is centred;
     the frame crops the overflow. This is object-fit: cover by hand.
     Width covers when the frame is wider than 16:9, height when it is
     taller — whichever is larger wins, so one of the two always fits. */
  --src-wh: 1.77778;                  /* the player's own 16:9 */
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  /* cover: as wide as the frame, or wider if the frame is the taller
     shape — var(--ratio-wh) is the frame's width over its height. */
  width: max(100.5%, calc(100.5% * var(--src-wh) / var(--ratio-wh, 0.5625)));
  aspect-ratio: var(--src-wh);
  height: auto;
  border: 0;
  display: block;
}

/* A file plays in a native <video>: its controls are ours, so it simply
   fits the frame rather than being scaled to cover and cropped. */
.player_frame video {
  width: 100%;
  height: 100%;
  translate: -50% -50%;
  object-fit: contain;
  background: #000;
  border-radius: inherit;
}

.player_close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border: 1px solid #ffffff2e;
  border-radius: 50%;
  background: #000000a6;
  backdrop-filter: blur(6px);
  color: #fff;
  cursor: pointer;
  transition: background .25s var(--ease), border-color .25s var(--ease);
}

.player_close:hover { background: var(--marker); border-color: var(--marker); }
.player_close:focus-visible { outline: 2px solid var(--marker); outline-offset: 3px; }
.player_close svg { width: 1.125rem; height: 1.125rem; }

/* a tighter inset on a small screen */
@media (max-width: 40rem), (max-height: 34rem) {
  .player_close { top: 0.5rem; right: 0.5rem; }
}

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