/* Public pages: the memorial (index), the WhatsApp share page (/share) and the 404.
   "A life full of people": a bright white page built around his photos, warm ink, one marigold accent.
   Tokens (colours, fonts, sizes) come from tokens.css. The living things are the mosaic and the
   drifting wall of "His life in pictures"; a few calm one-time moments (sections coming in, the name
   coming into focus...) are gathered in the "Motion" section at the end. All of it stands still under
   prefers-reduced-motion. */

[hidden] { display: none !important; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body { overflow-x: hidden; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
img { max-width: 100%; }
a { color: inherit; }
button { font: inherit; color: inherit; }
p { margin: 0; }
.nw { white-space: nowrap; }
html.lb-open { overflow: hidden; }

.skip {
  position: absolute; left: 12px; top: -80px; z-index: 60;
  padding: 12px 20px; border-radius: var(--pill); background: var(--ink); color: var(--paper);
  font-weight: 700; text-decoration: none;
}
.skip:focus { top: 12px; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 54px; padding: 0 24px; border: 2px solid transparent; border-radius: var(--pill);
  font: 700 1.125rem/1.15 var(--sans); text-align: center; text-decoration: none; cursor: pointer;
  transition: background-color .2s ease, border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.btn svg { width: 22px; height: 22px; flex: none; }
.btn--line { border-color: var(--ink); background: var(--paper); color: var(--ink); }
.btn--line:hover { background: var(--sun-wash); }
.btn--sun { background: var(--sun); border-color: var(--sun); color: var(--ink); }
.btn--sun:hover { border-color: var(--ink); }
a[data-livestream]:not([href]) { display: none; }

.linkish {
  display: inline-flex; align-items: center; min-height: var(--tap); padding: 0; border: 0; background: none;
  font: 700 1.125rem/1.2 var(--sans); color: var(--ink); cursor: pointer;
  text-decoration: underline; text-decoration-color: var(--sun); text-decoration-thickness: 3px; text-underline-offset: 6px;
}
.linkish:hover { text-decoration-color: var(--ink); }

/* ================================================================ the living mosaic */
.hero { padding: 6px 6px 0; container-type: inline-size; }
.mosaic {
  --pt: 50% 42%;                      /* where his face is in portrait.jpg */
  display: grid; gap: var(--g); justify-content: center;
  grid-template-columns: minmax(0, 1fr);
  max-width: 1740px; margin: 0 auto;
}
/* Tile size. Phones: four columns, the portrait centred in the middle two. */
.mosaic[data-variant="full"] { --t: calc((100vw - 12px - 3 * var(--g)) / 4); }
@supports (width: 1cqw) { .mosaic[data-variant="full"] { --t: calc((100cqw - 3 * var(--g)) / 4); } }
.mosaic[data-variant="mini"] { --t: min(calc((100vw - 32px - 3 * var(--g)) / 4), 104px); }

.portrait, .tile {
  position: relative; margin: 0; overflow: hidden; border-radius: var(--tr); background: var(--tint);
}
.portrait img, .tile img {
  position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover;
}
.portrait { cursor: zoom-in; border-radius: calc(var(--tr) + 2px); }
.portrait img { object-position: var(--pt); }
.tile { cursor: zoom-in; -webkit-tap-highlight-color: transparent; }
.tile img { object-position: 50% 30%; }

/* Solo (no photos published yet, or no JavaScript): the portrait and his name stand on their own. */
.mosaic:not([data-cols]) .portrait {
  justify-self: center; width: min(100%, 440px, 52svh); aspect-ratio: 3 / 4; margin-top: 10px;
}
.mosaic[data-variant="mini"]:not([data-cols]) .portrait { width: min(56%, 220px); }

/* A tile changing to another photo: the old one fades away to the warm tint, then the new one fades in
   and settles gently towards the faces (site.js sets transform-origin). Keep the durations in step with
   SWAP in site.js (out .9s, fade 1.4s, settle 2.2s). */
.tile img.outgoing { opacity: 0; transition: opacity .9s cubic-bezier(.4, 0, .7, .2); }
.tile img.incoming {
  opacity: 0; transform: scale(1.06);
  transition: opacity 1.4s cubic-bezier(.3, .1, .3, 1), transform 2.2s cubic-bezier(.22, .61, .36, 1);
}
.tile img.incoming.on { opacity: 1; transform: scale(1); }

/* The name, set like a title card in a gap in the grid. */
.nameplate {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 26px 12px 24px; text-align: center; container-type: inline-size;
}
.eyebrow, .kicker {
  margin: 0; font: 700 0.9375rem/1.3 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--sun-deep);
}
.name {
  margin: 10px 0 0; font-family: var(--display); font-variation-settings: 'SOFT' 100;
  font-weight: 600; line-height: .94; letter-spacing: -.02em;
}
.name__link { color: inherit; text-decoration: none; }
.name__first { display: block; font-size: clamp(54px, 17.5cqi, 96px); }
.name__house {
  display: block; margin-top: 12px; font-weight: 500; font-style: italic; letter-spacing: -.01em;
  font-size: clamp(27px, 7.2cqi, 38px); color: var(--ink-2);
}
.dates { margin-top: 16px; font: 600 1.1875rem/1.45 var(--sans); }
.dates__span, .dates__place { display: block; white-space: nowrap; }
.dates__dot { display: none; }
.line {
  margin-top: 8px; max-width: 34ch; text-wrap: balance;
  font: italic 400 1.25rem/1.45 var(--display); font-variation-settings: 'SOFT' 100; color: var(--ink-2);
}
.mosaic[data-variant="mini"] .nameplate { padding: 18px 12px 6px; }
.mosaic[data-variant="mini"] .name__first { font-size: clamp(44px, 13cqi, 64px); }
.mosaic[data-variant="mini"] .name__house { font-size: clamp(24px, 6cqi, 30px); margin-top: 8px; }

/* Waiting for the photos: the mosaic shows once it knows its shape (no jump). If the script never
   runs, it shows anyway after a moment. */
.js .mosaic:not(.is-ready) { visibility: hidden; animation: mosaic-fallback 0s 2.6s forwards; }
@keyframes mosaic-fallback { to { visibility: visible; } }

/* Gather-in: the portrait first, then everyone around him, ring by ring. */
.anim .mosaic.is-ready .tile:not(.in), .anim .mosaic.is-ready .portrait:not(.in) { opacity: 0; transform: scale(.94); }
.anim .mosaic.is-ready .tile.in, .anim .mosaic.is-ready .portrait.in {
  opacity: 1; transform: none; transition: opacity .9s ease, transform 1.2s cubic-bezier(.2, .7, .2, 1);
}
/* The name's own entrance (it comes into focus as they gather) is in Motion, below (3). */

/* Quick ways in */
.jump {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
  max-width: 760px; margin: 18px auto 0; padding: 0 calc(var(--gutter) - 6px);
}
.jump a {
  display: flex; align-items: center; justify-content: center; min-height: 54px; padding: 8px 14px;
  border: 1.5px solid var(--line); border-radius: var(--pill); background: var(--paper);
  font: 700 1.0625rem/1.2 var(--sans); text-align: center; text-decoration: none;
}
.jump a:hover { border-color: var(--ink); }
.jump .jump__share { background: var(--sun); border-color: var(--sun); }
.jump .jump__share:hover { border-color: var(--ink); }
.jump[data-count="3"] .jump__share, .jump[data-count="1"] .jump__share { grid-column: 1 / -1; }

/* ================================================================ sections */
.section { padding: 72px var(--gutter); }
.wrap { max-width: 1180px; margin: 0 auto; }
.wrap--wide { max-width: 1320px; }
.kicker { margin-bottom: 12px; }
.title {
  margin: 0; font-weight: 600; font-size: clamp(2.375rem, 6vw, 3.875rem); line-height: 1.02; letter-spacing: -.02em;
  text-wrap: balance;
}
.lede { margin-top: 16px; max-width: 40em; color: var(--ink-2); }
.status-line { color: var(--ink-3); font-style: italic; }

/* ---------- funeral service ---------- */
.service { padding-top: 60px; }
.service__grid { display: grid; gap: 28px; }
.service__date {
  margin: 0; font-family: var(--display); font-variation-settings: 'SOFT' 100; font-weight: 600;
  font-size: clamp(2.125rem, 5vw, 3.125rem); line-height: 1.05; letter-spacing: -.015em;
}
.service__date span { display: block; }
.service__card { border: 1.5px solid var(--line); border-radius: 22px; padding: 6px 20px 22px; }
.stop { display: grid; grid-template-columns: 112px 1fr; gap: 14px; padding: 20px 0; border-bottom: 1.5px solid var(--line); }
.stop:last-of-type { border-bottom: 0; }
.stop__time {
  margin: 0; white-space: nowrap; font-family: var(--display); font-variation-settings: 'SOFT' 100;
  font-weight: 600; font-size: 1.75rem; line-height: 1; letter-spacing: -.01em;
}
.stop__time abbr {
  display: block; margin-top: 7px; text-decoration: none;
  font: 700 0.875rem/1 var(--sans); letter-spacing: .08em; color: var(--ink-3);
}
.stop__title { margin: 0; font: 700 1.25rem/1.3 var(--sans); }
.stop__where { margin-top: 4px; color: var(--ink-2); }
.yourtime {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px;
  margin: 2px 0 18px; padding: 13px 16px; border-radius: 14px; background: var(--sun-wash);
}
.yourtime__label { font-weight: 600; color: var(--ink-2); }
.yourtime b { font-weight: 700; }
.service__actions { display: flex; flex-wrap: wrap; gap: 12px; }
.service--past { padding-top: 56px; padding-bottom: 8px; }
.service__past {
  max-width: 40rem; margin: 0 auto; text-align: center;
  font: italic 400 1.375rem/1.45 var(--display); font-variation-settings: 'SOFT' 100; color: var(--ink-2);
}
.service__past p { text-wrap: balance; }
.service__past p + p { margin-top: 18px; }

/* ---------- tribute (written by the family) ---------- */
.tribute > * { max-width: var(--measure); margin-left: auto; margin-right: auto; }
.tribute p { font: 400 1.4375rem/1.5 var(--display); font-variation-settings: 'SOFT' 100; }
.tribute p + p { margin-top: 1em; }

/* ---------- memories ---------- */
.memories { padding-top: 40px; }
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 28px 0 4px; }
.chip {
  min-height: var(--tap); padding: 0 20px; border: 1.5px solid var(--line); border-radius: var(--pill); background: var(--paper);
  font: 700 1.0625rem/1 var(--sans); cursor: pointer;
}
.chip:hover { border-color: var(--ink); }
.chip[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.memories__list { margin-top: 28px; display: grid; gap: 16px; }
.memories__list.is-masonry, .notes.is-masonry { display: flex; align-items: flex-start; gap: 16px; }
.mcol { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 16px; }

.memory {
  position: relative; overflow: hidden; background: var(--paper);
  border: 1.5px solid var(--line); border-radius: 22px;
  animation: rise .7s ease both;
}
@keyframes rise { from { opacity: 0; transform: translateY(8px); } }
.memory__body { padding: 22px 22px 22px; }
.memory__qmark {
  display: block; height: 44px; margin: 0 0 6px; font: 600 5.25rem/1 var(--display); font-variation-settings: 'SOFT' 100;
  color: var(--sun);
}
.memory__text p + p { margin-top: .8em; }
.memory__text p { overflow-wrap: break-word; }
.memory__text.is-quote p { font: 400 1.4375rem/1.42 var(--display); font-variation-settings: 'SOFT' 100; letter-spacing: -.005em; }
.memory__text.is-quote p[lang="ml"] { font-family: var(--ml); font-size: 1.25rem; line-height: 1.75; }
.memory__more { margin-top: 4px; }
.who { display: flex; align-items: center; gap: 14px; margin-top: 20px; }
.memory__media + .memory__body .who:first-child { margin-top: 0; }
.avatar {
  flex: none; display: grid; place-items: center; width: 52px; height: 52px; border-radius: 50%;
  background: var(--sun); color: var(--ink); font: 800 1.125rem/1 var(--sans); letter-spacing: .02em;
}
.avatar svg { width: 15px; height: 21px; }
.who__name { margin: 0; font: 700 1.25rem/1.25 var(--sans); overflow-wrap: anywhere; }
.who__rel { margin-top: 2px; font-size: 1.0625rem; line-height: 1.35; color: var(--ink-2); }
.memory__meta { margin-top: 14px; font-size: 1.0625rem; color: var(--ink-3); }

/* A memory's photos, shown generously: one large, then a few more. */
.memory__media { display: grid; gap: 4px; }
.mm-row { display: flex; gap: 4px; }
.mm-row > * { flex: var(--ar) 1 0; min-width: 0; }
.mm-strip { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; }
.mtile {
  position: relative; display: block; width: 100%; aspect-ratio: var(--ar, 1); overflow: hidden;
  margin: 0; padding: 0; border: 0; background: var(--tint); cursor: zoom-in;
}
.mm-strip .mtile { aspect-ratio: 1; }
.mtile img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .6s cubic-bezier(.2, .7, .2, 1); }
@media (hover: hover) { .mtile:hover img { transform: scale(1.03); } }
.mtile__label { position: absolute; inset: 0; display: grid; place-items: center; color: var(--ink-3); font-weight: 600; }
.play {
  position: absolute; left: 50%; top: 50%; display: grid; place-items: center;
  width: 72px; height: 72px; margin: -36px 0 0 -36px; border-radius: 50%;
  background: rgba(255, 255, 255, .94); box-shadow: 0 8px 26px rgba(35, 25, 21, .25); color: var(--ink);
}
.play svg { width: 26px; height: 26px; margin-left: 5px; }
.mm-strip .play, .ph--small .play { width: 48px; height: 48px; margin: -24px 0 0 -24px; }
.mm-strip .play svg, .ph--small .play svg { width: 18px; height: 18px; margin-left: 3px; }
.dur {
  position: absolute; left: 12px; bottom: 12px; padding: 6px 10px; border-radius: var(--pill);
  background: rgba(255, 255, 255, .94); font: 700 0.9375rem/1 var(--sans); color: var(--ink);
}
/* A video still being prepared: its poster under a bright veil, no play button. */
.soon {
  position: absolute; inset: 0; display: grid; place-items: center; padding: 12px;
  background: rgba(255, 255, 255, .74); text-align: center;
  font: italic 500 1.1875rem/1.25 var(--display); font-variation-settings: 'SOFT' 100; color: var(--ink);
}
.soon__short { display: none; }
.mm-strip .soon__full, .ph--small .soon__full { display: none; }
.mm-strip .soon__short, .ph--small .soon__short { display: inline; font-size: 1rem; }
.more {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: rgba(255, 255, 255, .78); font: 600 2rem/1 var(--display); font-variation-settings: 'SOFT' 100; color: var(--ink);
}

/* ---------- empty and error states ---------- */
.empty { padding: 30px 24px; border: 1.5px dashed #d9cfc6; border-radius: 22px; }
.empty__title { font: 600 1.625rem/1.2 var(--display); font-variation-settings: 'SOFT' 100; }
.empty__text { margin-top: 10px; color: var(--ink-2); max-width: 36em; }
.empty__go { margin-top: 18px; }
.empty__retry { margin-top: 16px; }

/* ---------- condolences ---------- */
.condolences { padding-top: 40px; }
.notes { display: grid; gap: 28px; margin-top: 34px; }
.notes.is-masonry .mcol { gap: 30px; }
.note { margin: 0; padding: 4px 0 4px 22px; border-left: 4px solid var(--sun); animation: rise .7s ease both; }
.note blockquote { margin: 0; font: 400 1.375rem/1.42 var(--display); font-variation-settings: 'SOFT' 100; overflow-wrap: break-word; }
.note blockquote p + p { margin-top: .7em; }
.note blockquote [lang="ml"] { font-family: var(--ml); font-size: 1.1875rem; line-height: 1.75; }
.note figcaption { margin-top: 12px; font: 600 1.0625rem/1.35 var(--sans); color: var(--ink-2); }
.note figcaption b { font-weight: 700; color: var(--ink); }

/* ---------- his life in pictures ---------- */
.photos { padding-left: 10px; padding-right: 10px; }
.photos .kicker, .photos .title, .photos .hint { margin-left: 6px; margin-right: 6px; }
.hint { display: flex; align-items: center; gap: 10px; margin-top: 16px; color: var(--ink-2); }
.hint svg { width: 22px; height: 22px; flex: none; }
/* Phones: one photo across, then two side by side (the layout is decided in site.js). */
.gallery { display: flex; flex-direction: column; gap: 8px; margin-top: 28px; }
.grow { display: flex; gap: 8px; }
.ph { position: relative; flex: var(--ar) 1 0; min-width: 0; margin: 0; animation: rise .7s ease both; }
.ph-btn {
  display: block; width: 100%; aspect-ratio: var(--ar); overflow: hidden; padding: 0; border: 0; border-radius: 10px;
  background: var(--tint); cursor: zoom-in; position: relative;
  transition: transform .35s cubic-bezier(.2, .7, .2, 1), box-shadow .35s ease;
}
.ph-btn img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ph figcaption { padding: 7px 4px 2px; font: 600 1.0625rem/1.3 var(--sans); color: var(--ink-2); overflow-wrap: anywhere; }
@media (hover: hover) {
  .ph-btn:hover { transform: translateY(-3px); box-shadow: 0 12px 28px rgba(35, 25, 21, .16); }
}
.gallery__more { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-top: 30px; text-align: center; }
.gallery__more small { font-size: 1rem; color: var(--ink-3); }

/* The endless drifting wall (site.js): edge to edge, rows of photos at one height, each its own shape.
   Each track holds its row twice and slides by exactly one copy (-50%), so the loop has no seam; the
   speed comes from site.js (animation-duration = row length / px per second). It clips sideways inside
   itself (never a sideways page scroll) but lets a lifted photo's shadow show above and below. */
.photos { --bleed: 10px; }
.wall {
  position: relative; margin: 28px calc(-1 * var(--bleed)) 0; padding: 8px 0;
  overflow: hidden; touch-action: pan-y; -webkit-user-select: none; user-select: none;
}
@supports (overflow: clip) { .wall { overflow: visible; overflow-x: clip; } }
.wall__row { height: var(--wh, 150px); }
.wall__row + .wall__row { margin-top: var(--wg, 8px); }
.wall__track {
  display: flex; width: max-content; height: 100%;
  animation: wall-drift 240s linear infinite; will-change: transform;
}
.wall__row--r .wall__track { animation-direction: reverse; }
.wall__set { display: flex; flex: none; gap: var(--wg, 8px); height: 100%; padding-right: var(--wg, 8px); }
@keyframes wall-drift { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-50%, 0, 0); } }
/* site.js eases the rows to a stop (pointing, touch, keyboard focus) and pauses them off-screen, in a
   hidden tab and under the lightbox. Only browsers that can't steer an animation stop it here. */
.wall--css.is-away .wall__track, .wall--css:hover .wall__track, .wall--css:focus-within .wall__track { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .wall__track { animation: none; } }

.wtile {
  position: relative; display: block; flex: none; height: 100%; margin: 0; padding: 0; border: 0; overflow: hidden;
  border-radius: 10px; background: var(--tint); cursor: zoom-in; -webkit-tap-highlight-color: transparent;
  transition: transform .35s cubic-bezier(.2, .7, .2, 1), box-shadow .35s ease;
}
.wtile img { display: block; width: 100%; height: 100%; object-fit: cover; -webkit-user-drag: none; }
@media (hover: hover) { .wtile:hover { transform: translateY(-3px); box-shadow: 0 12px 28px rgba(35, 25, 21, .18); } }
/* Keyboard focus drawn inside the photo (a photo can sit at the very edge of the screen). */
.wtile:focus-visible { outline: none; }
.wtile:focus-visible::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  box-shadow: inset 0 0 0 4px var(--sun), inset 0 0 0 6px rgba(35, 25, 21, .6);
}
.wall .play { width: 46px; height: 46px; margin: -23px 0 0 -23px; }
.wall .play svg { width: 17px; height: 17px; margin-left: 3px; }
.wall .dur { left: 8px; bottom: 8px; padding: 5px 9px; font-size: .8125rem; }
.wall .soon { padding: 8px; }
.wall .soon__full { display: none; }
.wall .soon__short { display: inline; font-size: 1rem; }
.wall__all { margin-top: 26px; }

/* ================================================================ share */
.share { background: var(--sun); padding: 72px var(--gutter) 80px; }
.share__grid { display: grid; gap: 34px; align-items: center; }
.mini { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; max-width: 420px; }
.mini:empty { display: none; }
.mini > * { position: relative; aspect-ratio: 1; overflow: hidden; border-radius: 12px; background: rgba(255, 255, 255, .35); }
.mini img { display: block; width: 100%; height: 100%; object-fit: cover; }
.mini .mini__wide { display: none; }
.mini--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); max-width: 330px; }
.mini--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 240px; }
.mini__yours {
  display: grid; place-items: center; align-content: center; gap: 4px; padding: 4px;
  border: 2.5px dashed rgba(35, 25, 21, .5); text-align: center; font: 700 0.9375rem/1.2 var(--sans);
}
.mini__yours svg { width: 30px; height: 30px; }
.share__title {
  margin: 0; max-width: 15em; font-weight: 600; font-size: clamp(2.125rem, 5.4vw, 3.5rem); line-height: 1.04; letter-spacing: -.02em;
  text-wrap: balance;
}
.tips { display: grid; gap: 12px; margin: 26px 0 0; padding: 0; list-style: none; }
.tips li { display: flex; align-items: center; gap: 14px; font-weight: 600; }
.tips__ic { flex: none; display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; background: rgba(255, 255, 255, .6); }
.tips__ic svg { width: 22px; height: 22px; }
.share__consent { margin-top: 22px; font-size: 1.125rem; color: rgba(35, 25, 21, .86); }
.share :focus-visible { outline-color: var(--ink); }

/* Two ways to share, as two big friendly buttons: write here, or send photos on WhatsApp. */
.share__body { display: grid; gap: 14px; max-width: 620px; margin-top: 28px; }
.path {
  display: flex; align-items: center; gap: 16px; width: 100%; min-height: 84px; margin: 0; padding: 14px 18px 14px 14px;
  border: 0; border-radius: 22px; background: var(--paper); color: var(--ink); text-align: left; text-decoration: none;
  cursor: pointer; box-shadow: 0 10px 28px rgba(120, 60, 0, .24);
  transition: transform .2s ease, box-shadow .2s ease;
}
@media (hover: hover) { .path:hover { transform: translateY(-2px); box-shadow: 0 14px 34px rgba(120, 60, 0, .32); } }
.path__mark { flex: none; display: grid; place-items: center; width: 52px; height: 52px; border-radius: 50%; background: var(--ink); color: var(--paper); }
.path__mark svg { width: 25px; height: 25px; }
.path--wa .path__mark { background: var(--wa); color: #fff; }
.path--wa .path__mark svg { width: 28px; height: 28px; }
.path__text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.path__title { font: 800 1.25rem/1.2 var(--sans); text-wrap: balance; }
.path__sub { font: 500 1.0625rem/1.35 var(--sans); color: var(--ink-2); }
.path__go { flex: none; width: 22px; height: 22px; color: var(--ink-2); }
.path__go svg { display: block; width: 100%; height: 100%; }
/* While no number is set in keeper.js: a quiet promise, not a button. */
.path--soon { cursor: default; background: rgba(255, 255, 255, .38); box-shadow: none; outline: 2.5px dashed rgba(35, 25, 21, .45); outline-offset: -2.5px; }
.path--soon .path__mark { background: rgba(255, 255, 255, .75); color: var(--ink); }
.path--soon .path__sub { color: var(--ink); }
.share__wa .tips { margin-top: 22px; }

/* ---------- "Write a few words": the form (remember.js) ---------- */
.rem-card {
  --field: #9c8c81;                    /* field borders: 3:1 against white, for older eyes */
  position: relative; padding: 22px 18px 24px; border-radius: 22px; background: var(--paper); color: var(--ink);
  box-shadow: 0 18px 44px rgba(120, 60, 0, .24);
  animation: rise .45s ease both;
}
.share .rem-card :focus-visible { outline-color: var(--ink); }
.rem-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.rem-card__title { margin: 6px 0 0; font-weight: 600; font-size: 1.875rem; line-height: 1.1; letter-spacing: -.015em; }
.rem-card__title:focus, .rem-done__title:focus { outline: none; }
.rem-close {
  flex: none; display: inline-flex; align-items: center; gap: 8px; min-height: var(--tap); margin: -4px -4px 0 0; padding: 0 16px 0 13px;
  border: 1.5px solid var(--line); border-radius: var(--pill); background: var(--paper); font: 700 1rem/1 var(--sans); cursor: pointer;
}
.rem-close:hover { border-color: var(--ink); }
.rem-close svg { width: 16px; height: 16px; }
.rem-card__intro { margin-top: 10px; color: var(--ink-2); text-wrap: pretty; }

.rem-form { position: relative; margin-top: 24px; }
.rem-field { display: grid; gap: 8px; min-width: 0; }
.rem-field + .rem-field { margin-top: 24px; }
.rem-label { display: block; font: 700 var(--text-base)/1.3 var(--sans); }
.rem-label__opt { font-weight: 500; color: var(--ink-3); }
.rem-input {
  display: block; width: 100%; min-height: 56px; margin: 0; padding: 12px 16px;
  border: 2px solid var(--field); border-radius: 14px; background: var(--paper); color: var(--ink);
  font: 400 var(--text-base)/1.4 var(--sans); -webkit-appearance: none; appearance: none;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.rem-input--words { min-height: 230px; padding-top: 14px; line-height: 1.55; resize: vertical; }
.rem-input::placeholder { color: var(--ink-3); opacity: 1; }
.rem-input:focus { outline: none; border-color: var(--ink); box-shadow: 0 0 0 4px rgba(255, 179, 31, .65); }
.rem-input[aria-invalid="true"] { border-color: var(--danger); }
.rem-input[aria-invalid="true"]:focus { box-shadow: 0 0 0 4px rgba(163, 39, 31, .18); }
.rem-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.rem-chip {
  display: inline-flex; align-items: center; gap: 8px; min-height: var(--tap); padding: 0 18px;
  border: 1.5px solid var(--field); border-radius: var(--pill); background: var(--paper);
  font: 600 1.0625rem/1 var(--sans); cursor: pointer;
}
.rem-chip:hover { border-color: var(--ink); }
.rem-chip[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); padding-left: 14px; }
.rem-chip[aria-pressed="true"]::before {
  content: ''; width: 12px; height: 7px; margin-top: -4px; border: solid currentColor; border-width: 0 0 2.5px 2.5px; transform: rotate(-45deg);
}
.rem-count { justify-self: end; font: 600 1.0625rem/1.3 var(--sans); color: var(--ink-3); font-variant-numeric: tabular-nums; text-align: right; }
.rem-count.is-near { color: var(--sun-deep); }
.rem-count.is-over { color: var(--danger); }
.rem-err { display: flex; align-items: flex-start; gap: 8px; font: 600 1.0625rem/1.4 var(--sans); color: var(--danger); }
.rem-err__ic { flex: none; width: 20px; height: 20px; margin-top: 1px; }
.rem-err__ic svg, .rem-msg__ic svg { display: block; width: 100%; height: 100%; }
/* The honeypot: out of sight, out of the tab order, hidden from screen readers. */
.rem-trap { position: absolute; left: -10000px; top: 0; width: 1px; height: 1px; overflow: hidden; }
/* Turnstile: invisible unless it needs a tap. */
.rem-check { max-width: 100%; overflow: hidden; }
.rem-check.is-asking { margin-top: 22px; overflow: visible; }
.rem-msg:not(:empty) { margin-top: 22px; }
.rem-msg__box { display: flex; gap: 12px; padding: 14px 16px; border-radius: 14px; background: var(--sun-wash); }
.rem-msg__ic { flex: none; width: 22px; height: 22px; margin-top: 3px; color: var(--sun-deep); }
.rem-msg__acts { display: flex; flex-wrap: wrap; gap: 0 22px; margin-top: 4px; }
.rem-actions { margin-top: 26px; }
.rem-send { width: 100%; min-height: 60px; font-size: 1.1875rem; }
.rem-send__arrow { display: inline-flex; }
.rem-send__arrow svg { width: 22px; height: 22px; }
.rem-send.is-busy { cursor: progress; }
.rem-send.is-busy .rem-send__arrow { display: none; }
.rem-spin { display: none; }
.rem-send.is-busy .rem-spin {
  display: block; width: 18px; height: 18px; border: 2.5px solid currentColor; border-right-color: transparent; border-radius: 50%;
  animation: rem-spin .8s linear infinite;
}
@keyframes rem-spin { to { transform: rotate(360deg); } }
.rem-note { margin-top: 16px; font-size: 1.0625rem; line-height: 1.5; color: var(--ink-2); text-wrap: pretty; }

/* Thank you, and how it will appear (drawn by the same code as the memorial). */
.rem-done { animation: rise .5s ease both; }
.rem-done__mark { display: grid; place-items: center; width: 56px; height: 56px; border-radius: 50%; background: var(--sun); color: var(--ink); }
.rem-done__mark svg { width: 28px; height: 28px; }
.rem-done__title { margin: 16px 0 0; font-weight: 600; font-size: clamp(2.125rem, 5vw, 2.625rem); line-height: 1.05; letter-spacing: -.02em; }
.rem-done__text { margin-top: 8px; font-size: 1.25rem; line-height: 1.5; }
.rem-done__label { margin-top: 30px; font: 700 0.9375rem/1.3 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--sun-deep); }
.rem-preview { margin-top: 12px; padding: 14px; border-radius: 22px; background: var(--tint); }
.rem-preview .memory { border-color: transparent; box-shadow: 0 6px 20px rgba(35, 25, 21, .08); }
.rem-preview .note { margin: 6px 4px; padding: 20px 20px 20px 22px; border-radius: 0 16px 16px 0; background: var(--paper); box-shadow: 0 6px 20px rgba(35, 25, 21, .08); }
.rem-done__actions { margin-top: 26px; }

/* ---------- the quiet sticky bar (phones) ---------- */
.cta-bar { display: none; }
@media (max-width: 699px) {
  .cta-bar:not([hidden]) {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; display: block;
    padding: 10px var(--gutter) calc(10px + env(safe-area-inset-bottom));
    background: rgba(255, 255, 255, .96); border-top: 1.5px solid var(--line);
    transform: translateY(110%); visibility: hidden; transition: transform .3s ease, visibility .3s;
  }
  .cta-bar.is-visible { transform: none; visibility: visible; }
  .cta-bar .btn { width: 100%; }
}

/* ================================================================ footer */
.foot { padding: 64px var(--gutter) 56px; text-align: center; }
.foot__cross { width: 18px; height: 25px; color: var(--sun-deep); }
.foot__name { margin-top: 14px; font: 600 1.875rem/1.1 var(--display); font-variation-settings: 'SOFT' 100; letter-spacing: -.01em; }
.foot__dates { margin-top: 8px; color: var(--ink-2); }
.kin {
  display: grid; grid-template-columns: 1fr 1fr; gap: 24px 12px;
  max-width: 980px; margin: 34px auto 0; padding: 30px 0 0; border-top: 1.5px solid var(--line); list-style: none;
}
.kin b { display: block; font: 600 1.3125rem/1.25 var(--display); font-variation-settings: 'SOFT' 100; }
.kin span { display: block; margin-top: 3px; font-size: 1.0625rem; color: var(--ink-2); }
.kin b span { display: inline; margin: 0; font: inherit; color: inherit; }
.foot__kept { max-width: 34em; margin: 36px auto 0; color: var(--ink-2); }
.foot--slim { padding-top: 48px; }

/* ================================================================ lightbox (bright, like the page) */
.lightbox {
  position: fixed; inset: 0; z-index: 50; display: grid; grid-template-rows: auto minmax(0, 1fr) auto auto;
  background: var(--paper); color: var(--ink);
}
.lightbox__bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 10px 4px 18px; }
.lightbox__count { font: 700 1rem/1 var(--sans); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.lightbox__close {
  display: inline-flex; align-items: center; gap: 8px; min-height: 52px; padding: 0 20px 0 16px;
  border: 1.5px solid var(--line); border-radius: var(--pill); background: var(--paper); cursor: pointer; font-weight: 700;
}
.lightbox__close:hover, .lightbox__nav:hover { border-color: var(--ink); }
.lightbox__close svg { width: 16px; height: 16px; }
.lightbox__stage { position: relative; display: flex; align-items: center; justify-content: center; min-height: 0; padding: 8px 12px; touch-action: pan-y pinch-zoom; }
.lightbox__stage > img, .lightbox__stage > video {
  display: block; max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 10px;
  box-shadow: 0 20px 60px rgba(35, 25, 21, .18);
}
.lightbox__stage > video { width: 100%; height: 100%; background: var(--tint); box-shadow: none; }
@supports (width: 1cqw) {
  .lightbox__stage { container-type: size; }
  .lightbox__stage > video {
    width: min(100cqw - 24px, calc((100cqh - 16px) * var(--ar, 1.7778))); height: auto; aspect-ratio: var(--ar, 1.7778);
    border-radius: 10px;
  }
}
.lightbox__fallback { max-width: 26rem; text-align: center; color: var(--ink-2); padding: 24px; }
.lightbox__soon { position: relative; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; }
.lightbox__soon img { display: block; max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 10px; opacity: .35; }
.lightbox__soon-note {
  position: absolute; left: 16px; right: 16px; top: 50%; transform: translateY(-50%); text-align: center;
  font: italic 500 clamp(1.6rem, 5vw, 2.2rem)/1.2 var(--display); font-variation-settings: 'SOFT' 100; color: var(--ink);
}
.lightbox__foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 6px 12px 8px; }
/* A single photo has no strip: the foot keeps the bottom breathing room (and the phone's safe area). */
.lightbox__foot:has(+ .lightbox__strip[hidden]) { padding-bottom: calc(16px + env(safe-area-inset-bottom)); }

/* The strip of every photo along the bottom: scrolls sideways, the current one ringed in marigold. */
.lightbox__strip {
  display: flex; gap: 8px; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity; scrollbar-width: none;
  padding: 8px 12px calc(14px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line);
}
.lightbox__strip::-webkit-scrollbar { display: none; }
.lightbox__strip[hidden] { display: none; }
.lightbox__thumb {
  position: relative; flex: none; width: 64px; height: 64px; padding: 0; border: 0; border-radius: 8px;
  overflow: hidden; background: var(--tint); cursor: pointer; scroll-snap-align: center;
  opacity: .55; transition: opacity .2s ease, transform .2s ease;
}
.lightbox__thumb img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }
.lightbox__thumb:hover { opacity: .85; }
.lightbox__thumb.is-current { opacity: 1; }
.lightbox__thumb.is-current::after {
  content: ''; position: absolute; inset: 0; border: 3px solid var(--sun); border-radius: 8px; pointer-events: none;
}
.lightbox__thumb:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }
.lightbox__thumb-play {
  position: absolute; right: 5px; bottom: 5px; width: 18px; height: 18px; border-radius: 50%; background: rgba(255, 255, 255, .92);
}
.lightbox__thumb-play::before {
  content: ''; position: absolute; left: 7px; top: 5px; border-style: solid; border-width: 4px 0 4px 7px;
  border-color: transparent transparent transparent var(--ink);
}
@media (min-width: 700px) {
  .lightbox__strip { gap: 10px; padding-left: 24px; padding-right: 24px; }
  .lightbox__thumb { width: 78px; height: 78px; border-radius: 10px; }
  .lightbox__thumb.is-current::after { border-radius: 10px; }
}
.lightbox__nav {
  flex: none; display: grid; place-items: center; width: 56px; height: 56px; border: 1.5px solid var(--line); border-radius: 50%;
  background: var(--paper); cursor: pointer;
}
.lightbox__nav svg { width: 22px; height: 22px; }
.lightbox__nav[hidden] { display: grid !important; visibility: hidden; }
.lightbox__info { flex: 1; min-width: 0; text-align: center; }
.lightbox__caption { font: 600 1.1875rem/1.35 var(--sans); max-width: var(--measure); margin: 0 auto 2px; overflow-wrap: break-word; }
.lightbox__credit { font-size: 1.0625rem; color: var(--ink-2); overflow-wrap: anywhere; }

/* ================================================================ share page and 404 */
.page-share .hero { padding-top: 16px; padding-bottom: 30px; }
.share-page__back { display: flex; justify-content: center; padding: 40px var(--gutter) 0; }
.share--page .share__grid { grid-template-columns: minmax(0, 1fr); max-width: 760px; }
.lost { min-height: 100svh; display: grid; place-items: center; padding: 40px var(--gutter); text-align: center; }
.lost__portrait { width: 150px; height: 150px; margin: 0 auto; border-radius: 50%; overflow: hidden; background: var(--tint); }
.lost__portrait img {
  display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 40%;
  transform: scale(1.55); transform-origin: 53% 46%; /* close on his face (portrait.jpg) */
}
.lost__title { margin: 26px 0 0; font-weight: 600; font-size: clamp(2.125rem, 6vw, 3rem); line-height: 1.05; letter-spacing: -.02em; }
.lost__text { margin: 14px auto 28px; max-width: 26em; color: var(--ink-2); }

/* ================================================================ wider screens */
@media (min-width: 700px) {
  .hero { padding: 10px 10px 0; }
  /* The tile size follows the widest grid this screen can hold (--mc columns), and never grows so
     tall that the name falls below the first screen. */
  .mosaic[data-variant="full"] {
    --mc: 7;
    --t: max(64px, min(calc((100vw - 20px - (var(--mc) - 1) * var(--g)) / var(--mc)), calc((100vh - 150px - 5 * var(--g)) / 6)));
  }
  /* The 64px floor keeps the nameplate wide enough on short screens (a phone turned sideways, a
     small laptop window); the mosaic then runs a little past the first screen instead. */
  @supports (width: 1cqw) and (height: 1svh) {
    .mosaic[data-variant="full"] { --t: max(64px, min(calc((100cqw - (var(--mc) - 1) * var(--g)) / var(--mc)), calc((100svh - 150px - 5 * var(--g)) / 6))); }
  }
  .mosaic[data-variant="mini"] { --t: 112px; }
  .mosaic[data-variant="full"][data-cols] .nameplate { padding: 10px 16px; }
  .mosaic[data-variant="full"][data-cols] .name__first { font-size: clamp(44px, 12.5cqi, 96px); }
  .mosaic[data-variant="full"][data-cols] .name__house { font-size: clamp(22px, 5.2cqi, 38px); margin-top: 10px; }
  .mosaic[data-variant="full"][data-cols] .dates { margin-top: 12px; }
  .dates__span, .dates__place { display: inline; }
  .dates__dot { display: inline-block; width: 7px; height: 7px; margin: 0 .7em; border-radius: 50%; background: var(--sun); vertical-align: .2em; }
  /* A narrow nameplate (short screens) stacks the dates and place again instead of clipping them. */
  @container (max-width: 460px) {
    .dates__span, .dates__place { display: block; }
    .dates__dot { display: none; }
  }
  @container (max-width: 320px) {
    .dates__span { white-space: normal; text-wrap: balance; }
  }

  .jump { grid-template-columns: repeat(4, auto); justify-content: center; max-width: none; margin-top: 22px; }
  .jump[data-count] { grid-template-columns: none; grid-auto-flow: column; }
  .jump[data-count="3"] .jump__share, .jump[data-count="1"] .jump__share { grid-column: auto; }
  .jump a { padding: 8px 26px; }

  .section { padding-top: 104px; padding-bottom: 104px; }
  .service { padding-top: 88px; }
  .memories, .condolences { padding-top: 16px; }
  .service__card { padding: 8px 32px 30px; }
  .stop { grid-template-columns: 150px 1fr; }
  .stop__time { font-size: 2.125rem; }

  .photos { padding-left: 32px; padding-right: 32px; padding-top: 72px; --bleed: 32px; }
  .wall { margin-top: 34px; }
  .wtile { border-radius: 12px; }
  .wall .play { width: 56px; height: 56px; margin: -28px 0 0 -28px; }
  .wall .play svg { width: 20px; height: 20px; margin-left: 4px; }
  .photos .kicker, .photos .title, .photos .hint { margin-left: 0; margin-right: 0; }
  /* Justified rows: every photo whole, every row the same height. */
  .gallery { flex-direction: row; flex-wrap: wrap; gap: 12px; }
  .gallery::after { content: ''; flex: 999 1 0; }
  .gallery--cut::after { display: none; } /* more to come: the last row is whole, so it fills the width */
  .ph { flex: var(--ar) 1 calc(var(--ar) * 230px); }
  .ph-btn { border-radius: 12px; }
  .ph figcaption {
    position: absolute; left: 10px; bottom: 10px; max-width: calc(100% - 20px); padding: 7px 12px; border-radius: var(--pill);
    background: rgba(255, 255, 255, .94); color: var(--ink); font-size: .9375rem; pointer-events: none;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }

  .share { padding: 104px var(--gutter); }
  .share__grid { grid-template-columns: 7fr 5fr; gap: 64px; }
  .share.is-writing .share__grid { align-items: start; }
  .share.is-writing .mini { position: sticky; top: 32px; }
  .rem-card { padding: 30px 32px 32px; }
  .rem-send { width: auto; padding: 0 34px; }
  .rem-preview { padding: 20px; }
  .share__grid .mini { order: 2; justify-self: end; width: 100%; max-width: 470px; }
  .share__grid .mini--6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .share__grid .mini--3 { max-width: 420px; }
  .share__grid .mini--2 { max-width: 320px; }
  .mini .mini__wide { display: block; }
  .kin { grid-template-columns: repeat(4, auto); justify-content: center; column-gap: 64px; }
}
@media (min-width: 960px) {
  .service__grid { grid-template-columns: 5fr 7fr; gap: 56px; align-items: start; }
}
@media (min-width: 860px) { .mosaic[data-variant="full"] { --mc: 9; } }
@media (min-width: 1100px) {
  .mosaic[data-variant="full"] { --mc: 11; }
  .ph { flex-basis: calc(var(--ar) * 270px); }
}

/* ================================================================ motion
   A few calm, crafted moments on top of the two living things (the mosaic and the drifting wall).
   Everything here is gated on html.anim, which the page head sets only when the visitor has not asked
   for reduced motion; and anything hidden until it is revealed also needs data-rv, which site.js adds
   only to what it will reveal (motion in site.js). So without JavaScript, if site.js fails, or under
   reduced motion, every element simply stands in its final place. Transform and opacity only, apart
   from the name's one-time blur, the path's paper cover, the dash offset of the "Your photo" edge and
   the sheen's background-position. */

/* 1. Section reveals. Kickers, titles, ledes, cards, notes, the funeral stops and the family's names
   rise 14px and fade in once, as they come into view; things that arrive together follow one another
   a beat apart (site.js sets --rv-delay, in reading order). "fade" only fades; "late" fades in after
   the procession path has drawn. */
.anim [data-rv]:not(.in) { opacity: 0; transform: translateY(14px); }
.anim [data-rv="fade"]:not(.in), .anim [data-rv="late"]:not(.in) { transform: none; }
.anim [data-rv].in {
  transition: opacity .7s cubic-bezier(.33, 1, .68, 1) var(--rv-delay, 0s), transform .8s cubic-bezier(.2, .7, .2, 1) var(--rv-delay, 0s);
}
.anim [data-rv="fade"].in { transition: opacity .9s ease var(--rv-delay, 0s); }
.anim [data-rv="late"].in { transition: opacity .9s ease calc(var(--rv-delay, 0s) + 1.35s); }
/* Cards and notes used to rise as they were drawn; once registered, the reveal does it instead. */
.anim .memory[data-rv], .anim .note[data-rv] { animation: none; }

/* 2. A short marigold line under each section title, drawn left to right just after the title has
   landed. (Still pages show it drawn.) */
.title::after, .service__date::after {
  content: ''; display: block; width: 48px; height: 4px; margin-top: 18px; border-radius: 2px; background: var(--sun);
}
.anim .title[data-rv]::after, .anim .service__date[data-rv]::after { transform: scaleX(0); transform-origin: 0 50%; }
.anim .title.in::after, .anim .service__date.in::after {
  transform: none; transition: transform .8s cubic-bezier(.65, 0, .35, 1) calc(var(--rv-delay, 0s) + .45s);
}

/* 3. The name card, as everyone gathers round him (site.js: .is-ready, then .go): the line above, then
   "Raj Felix" comes into focus from a soft blur as it rises, then Kizhakkekadavil, the dates and the
   line below. This is the nameplate's only entrance. */
.anim .mosaic.is-ready:not(.go) .nameplate > :not(.name),
.anim .mosaic.is-ready:not(.go) .name__house { opacity: 0; transform: translateY(10px); }
.anim .mosaic.is-ready:not(.go) .name__first { opacity: 0; transform: translateY(12px); filter: blur(6px); }
.anim .mosaic.go .nameplate > :not(.name), .anim .mosaic.go .nameplate .name__house {
  transition: opacity .9s ease, transform 1s cubic-bezier(.2, .7, .2, 1);
}
.anim .mosaic.go .nameplate .name__first {
  transition: opacity .9s ease .5s, transform 1.3s cubic-bezier(.2, .7, .2, 1) .5s, filter 1.3s cubic-bezier(.33, 1, .68, 1) .5s;
}
.anim .mosaic.go .nameplate > .eyebrow { transition-delay: .3s; }
.anim .mosaic.go .nameplate .name__house { transition-delay: .9s; }
.anim .mosaic.go .nameplate > .dates { transition-delay: 1.15s; }
.anim .mosaic.go .nameplate > .line { transition-delay: 1.3s; }

/* 4. His portrait breathes, very slowly: a Ken Burns breath in towards his face and out again. It rests
   while the mosaic is off-screen (site.js: .is-away) and under the lightbox. */
.anim .mosaic .portrait.in img { animation: breathe 22s ease-in-out infinite alternate; transform-origin: var(--pt); }
.anim .mosaic.is-away .portrait.in img, .anim.lb-open .mosaic .portrait.in img { animation-play-state: paused; }
@keyframes breathe { to { transform: scale(1.035); } }

/* 5. The funeral card. A dotted marigold path runs from 2:30 down to 3:00, like the procession (it
   parts the line between the stops); as the first stop comes in, a paper cover slides off it so it
   draws itself downward. "Your time" (data-rv "late") fades in once it has drawn. */
.stop { position: relative; }
.stop__path {
  position: absolute; left: 13px; top: calc(20px + 1em + 21px + 8px); bottom: -13px; width: 4px; overflow: hidden;
  background: radial-gradient(circle, var(--sun) 1.6px, transparent 2.1px) 50% 1px / 4px 9px repeat-y var(--paper);
}
.anim .stop[data-rv] .stop__path::after { content: ''; position: absolute; inset: 0; background: var(--paper); }
.anim .stop.in .stop__path::after {
  transform: translateY(101%); transition: transform 1.1s cubic-bezier(.45, 0, .3, 1) calc(var(--rv-delay, 0s) + .55s);
}

/* 6. A short memory's marigold quote mark settles in from a little smaller; a condolence's marigold rule
   draws downward beside the words. */
.anim .memory[data-rv] .memory__qmark { opacity: 0; transform: scale(.6); transform-origin: 18px 34px; }
.anim .memory.in .memory__qmark {
  opacity: 1; transform: none;
  transition: opacity .5s ease calc(var(--rv-delay, 0s) + .25s), transform 1s cubic-bezier(.3, 1.35, .5, 1) calc(var(--rv-delay, 0s) + .25s);
}
.anim .note[data-rv] { position: relative; border-left-color: transparent; }
.anim .note[data-rv]::before {
  content: ''; position: absolute; left: -4px; top: 0; bottom: 0; width: 4px; background: var(--sun);
  transform: scaleY(0); transform-origin: 50% 0;
}
.anim .note.in::before { transform: none; transition: transform .9s cubic-bezier(.65, 0, .35, 1) calc(var(--rv-delay, 0s) + .15s); }

/* 7. Buttons. A gentle press on tap (site.js adds the touch listener iOS needs for :active), and on a
   desktop hover one soft sheen glides once across the marigold buttons. */
.anim .jump a, .anim .chip, .anim .rem-chip, .anim .rem-close, .anim .lightbox__close, .anim .lightbox__nav {
  transition: transform .2s cubic-bezier(.2, .7, .2, 1);
}
.anim .btn:active, .anim .jump a:active, .anim .chip:active, .anim .rem-chip:active,
.anim .rem-close:active, .anim .lightbox__close:active, .anim .lightbox__nav:active { transform: scale(.97); transition-duration: .08s; }
.anim .path:not(.path--soon):active { transform: scale(.985); transition-duration: .08s; }
@media (hover: hover) and (pointer: fine) {
  .anim .btn--sun, .anim .jump .jump__share {
    background-image: linear-gradient(100deg, transparent 40%, rgba(255, 255, 255, .5) 50%, transparent 60%);
    background-size: 250% 100%; background-repeat: no-repeat; background-position: 100% 0;
  }
  .anim .btn--sun:hover, .anim .jump .jump__share:hover { animation: sheen 1.1s cubic-bezier(.4, 0, .2, 1) both; }
}
@keyframes sheen { from { background-position: 100% 0; } to { background-position: 0 0; } }

/* 8. The "Your photo" tile in the share block (an SVG frame from site.js takes over from the CSS border).
   Every six seconds, while it is on screen, the tile stirs (site.js: .is-stirring): its dashed edge
   walks one dash round and the + lifts for a moment. (A non-stop march would repaint every frame.) */
.anim .mini__yours.has-ants { border: 0; padding: 6.5px; }
.mini__yours .mini__ants {
  position: absolute; left: 1.25px; top: 1.25px; width: calc(100% - 2.5px); height: calc(100% - 2.5px);
  overflow: visible; pointer-events: none;
}
.mini__ants rect { fill: none; stroke: rgba(35, 25, 21, .5); stroke-width: 2.5; stroke-dasharray: 8 6; }
.anim .mini__yours.is-stirring .mini__ants rect { animation: ants 1.6s cubic-bezier(.45, 0, .55, 1); }
.anim .mini__yours.is-stirring .mini__plus { animation: plus-lift 1.2s ease-in-out .2s; }
@keyframes ants { to { stroke-dashoffset: -14; } }
@keyframes plus-lift { 50% { transform: translateY(-5px); } }

/* 9. The lightbox fades up over the page and the photo eases in from a touch smaller, once it can be
   drawn (site.js: .is-opening, .lb-wait, .lb-arrive); closing is the same, quicker, in reverse. */
.anim .lightbox.is-opening { animation: lb-in .26s ease-out both; }
.anim .lightbox__media.lb-wait { opacity: 0; }
.anim .lightbox__media.lb-arrive { animation: lb-photo .3s cubic-bezier(.2, .7, .2, 1) both; }
.anim .lightbox.is-closing { animation: lb-out .18s ease-in both; pointer-events: none; }
.anim .lightbox.is-closing .lightbox__media { animation: lb-photo-out .18s ease-in both; }
/* Carousel: moving through the photos, the next one slides in from the side you're heading towards;
   a swipe that's let go too early springs back (site.js: .lb-next, .lb-prev, .is-springing). */
.anim .lightbox__media.lb-next { animation: lb-from-right .34s cubic-bezier(.2, .7, .2, 1) both; }
.anim .lightbox__media.lb-prev { animation: lb-from-left .34s cubic-bezier(.2, .7, .2, 1) both; }
.lightbox__media.is-springing { transition: transform .26s cubic-bezier(.2, .7, .2, 1), opacity .26s ease; }
@keyframes lb-from-right { from { opacity: 0; transform: translateX(56px); } }
@keyframes lb-from-left { from { opacity: 0; transform: translateX(-56px); } }
@keyframes lb-in { from { opacity: 0; } }
@keyframes lb-photo { from { opacity: 0; transform: scale(.965); } }
@keyframes lb-out { to { opacity: 0; } }
@keyframes lb-photo-out { to { transform: scale(.975); } }
