/* s-invite.css: Krista's first minutes. The invitation and her yes, the questions, the wait and the
   reveal. Loaded after app/ui.css; it places and sizes the shared Candlelight components for these
   screens and draws their moments. Every color is a token from design/tokens.css. The calendar
   leaf is day paper in both looks (data-look="day" in app.js), so its inks are the day tokens.

   The moments (her yes, the seal pressing in, the answers turning over) run on one clock each: the
   element carries --t, minus the seconds since the moment began, and every delay is
   calc(var(--t) + its own offset). A render in the middle of a moment therefore picks it up where it
   was instead of starting over. Under reduced motion ui.css ends every animation at once, so the
   last frame shows. */

/* ============================== The invitation ============================== */

/* The scene at poster size. The drawing keeps its proportions and grows by a quarter, cropped at
   the sides only, so the train runs about a third bigger than on any other screen and the sky
   stays whole above it (on a phone that is about 280 px of picture). */
@media (max-width: 719px) {
  .invite-screen .hero-art { aspect-ratio: 400 / 317.5; max-height: 380px; }
  .invite-screen .hero-art > .window { display: flex; align-items: flex-end; justify-content: center; overflow: hidden; }
  .invite-screen .hero-art > .window > svg { flex: none; width: 127%; max-width: none; height: auto; }
  /* The words sit on the snow below the picture, 22 px under the lowest pine at any width
     (the drawing's last 28 of its 250 units are page-colored snow: 8.9 vw at this scale). */
  .invite-screen .hero-art + * { margin-top: calc(12px - 8.9vw); }
}
.invite-screen .hero > .eyebrow { margin-bottom: 2px; }
.invite-screen .hero-sub { max-width: 30ch; }
.invite-screen .hero { margin-bottom: 4px; }
/* The envelope's line breaks as two short phrases, not one word on its own */
.invite-screen .env > .sub { text-wrap: balance; }

/* Her answer stays under her thumb: until she answers, the two buttons ride at the foot of the
   screen over a soft fall of the page color, the way an invitation app keeps its reply in reach.
   After yes, "Start the questions" rides there the same way until the questions are done. */
.invite-screen.is-first > .screen-foot,
.invite-screen.is-next > .screen-foot {
  position: sticky;
  bottom: 0;
  z-index: 5;
  margin-inline: calc(-1 * max(var(--gutter), env(safe-area-inset-left)));
  margin-bottom: calc(-1 * (36px + env(safe-area-inset-bottom)));
  padding: 22px max(var(--gutter), env(safe-area-inset-right)) calc(14px + env(safe-area-inset-bottom)) max(var(--gutter), env(safe-area-inset-left));
  background: linear-gradient(to bottom, color-mix(in srgb, var(--bg) 0%, transparent), color-mix(in srgb, var(--bg) 88%, transparent) 26px, var(--bg) 60%);
}
.iv-answer { display: flex; align-items: center; gap: 8px; }
.iv-answer > .btn-primary { flex: 1; }
.iv-answer > .btn-quiet { flex: none; min-height: 56px; padding-inline: 16px; }

/* "Not this time?": asked once, in a card of its own where the two answers were */
.iv-ask {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 18px 18px 8px;
  border-radius: var(--r-l);
  background: var(--sheen), var(--surface);
  box-shadow: var(--shadow-2), 0 0 0 1px var(--edge-strong);
  animation: iv-rise .32s var(--ease-out) both;
}
.iv-ask > .h2 { font-size: 22px; outline: none; }
.iv-ask > .fine { margin: -4px 0 6px; color: var(--text-2); }
.iv-ask > .btn-quiet { margin-top: -2px; }
@keyframes iv-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* Akshay's note unfolds out of its envelope; under it her heart, her words, and what she wrote */
.iv-note.is-opening .note { animation: iv-unfold .56s var(--ease-out) both; transform-origin: 50% 0; }
.iv-note.is-opening .note-replies { animation: iv-rise .4s var(--ease-out) .32s both; }
@keyframes iv-unfold { from { opacity: 0; transform: perspective(900px) rotateX(-24deg) translateY(-10px); } to { opacity: 1; transform: none; } }
.iv-write textarea {
  min-height: 92px;
  padding: 14px 16px;
  border-radius: var(--r-m);
  background: var(--note-paper);
  color: var(--note-ink);
  font: 400 17px/1.45 var(--font-ui);
  box-shadow: inset 0 0 0 1px var(--note-line), var(--shadow-1);
  resize: none;
}
.iv-write textarea::placeholder { color: var(--note-ink-2); opacity: .8; }
.iv-write .actions { display: flex; justify-content: flex-end; gap: 6px; }
.iv-wrote {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  padding: 14px 16px 6px;
  border-radius: var(--r-m);
  background: var(--sheen), var(--surface);
  box-shadow: var(--shadow-1), 0 0 0 1px var(--edge);
}
.iv-wrote > p { margin: 0; font-size: 17px; line-height: 1.45; color: var(--text); overflow-wrap: anywhere; }
.iv-wrote > .iv-wrote-edit { align-self: flex-end; min-height: 40px; padding-inline: 12px; font-size: 15px; }

/* After yes the stub sits below the four punched marks */
.invite-screen .ticket-stub > b { font-family: var(--font-display); font-weight: 560; }
/* After no: the way forward and the way back sit together at the foot */
.invite-screen.is-declined > .screen-foot { padding-top: 4px; }

/* ============================== Her yes ============================== */

/* One screen, no bar: the train pulls into the picture, "You are going to the North Pole", the four
   marks punch in one by one, a line from Akshay in his hand, that he knows, and the next step. */
.invite-screen.is-yes { gap: 18px; }
@media (max-width: 719px) { .invite-screen.is-yes .hero-art { aspect-ratio: 400 / 292; } }
.invite-screen.is-yes [data-act="yes-skip"] { cursor: pointer; }
.iv-yes-hero { gap: 6px; }
.iv-yes-hero .hero-title { font-size: clamp(40px, 12vw, 60px); }
.iv-yes-hero .hero-title em { display: block; }
/* The train glides in from the right and settles where it rests in every drawing */
.iv-yes-hero .hce-train { animation: iv-train 2.6s cubic-bezier(.12, .7, .25, 1) calc(var(--t, 0s) + 0s) both; }
@keyframes iv-train { from { transform: translateX(380px); } to { transform: translateX(-60px); } }
.iv-yes-hero > .eyebrow { animation: iv-rise .5s var(--ease-out) calc(var(--t, 0s) + .2s) both; }
.iv-yes-hero > .hero-title { animation: iv-rise .6s var(--ease-out) calc(var(--t, 0s) + .32s) both; }

.iv-yes-body { display: flex; flex-direction: column; align-items: center; gap: 18px; }
/* The four marks, large and centered: Akshay's star is in already; Krista, Brex and Zayde punch in */
.iv-yes-marks { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; width: 100%; margin: 4px 0 0; padding: 0; list-style: none; }
.iv-yes-mark { display: flex; flex-direction: column; align-items: center; gap: 8px; font: 600 14.5px/1.2 var(--font-ui); color: var(--text); }
.iv-yes-mark > .avatar {
  position: relative;
  width: 62px;
  height: 62px;
  box-shadow: inset 0 0 0 1.5px var(--gold), 0 0 0 4px color-mix(in srgb, var(--gold) 14%, transparent), var(--accent-glow);
}
.iv-yes-mark > .avatar svg { width: 28px; height: 28px; }
/* Before its punch each place is a dashed ring, as on the ticket; the mark lands on it with a pop
   and a ring of gold */
.iv-yes-mark { position: relative; }
.iv-yes-mark::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 62px;
  height: 62px;
  margin-left: -31px;
  border-radius: 50%;
  border: 1.5px dashed color-mix(in srgb, var(--text) 45%, transparent);
  box-sizing: border-box;
  animation: iv-ghost .24s linear calc(var(--t, 0s) + .78s + var(--i) * .3s) both;
}
.iv-yes-mark.was-in::before { display: none; }
.iv-yes-mark > .avatar::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 2px solid var(--gold);
  opacity: 0;
  animation: iv-ring .7s var(--ease-out) calc(var(--t, 0s) + .7s + var(--i) * .3s) both;
}
.iv-yes-mark:not(.was-in) > .avatar { animation: iv-punch .46s cubic-bezier(.2, .9, .3, 1.4) calc(var(--t, 0s) + .7s + var(--i) * .3s) both; }
.iv-yes-mark.was-in > .avatar { animation: iv-rise .5s var(--ease-out) calc(var(--t, 0s) + .45s) both; }
.iv-yes-mark.was-in > .avatar::after { display: none; }
.iv-yes-mark > span:last-child { animation: iv-fade .4s var(--ease-out) calc(var(--t, 0s) + .75s + var(--i) * .3s) both; }
@keyframes iv-punch { 0% { transform: scale(.4); opacity: 0; } 55% { transform: scale(1.16); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
@keyframes iv-ring { 0% { opacity: .9; transform: scale(.7); } 100% { opacity: 0; transform: scale(1.35); } }
@keyframes iv-ghost { to { opacity: 0; } }
@keyframes iv-fade { from { opacity: 0; } to { opacity: 1; } }

/* Akshay's line on his cream card, written in as if by hand */
.iv-yes-note {
  position: relative;
  width: min(100%, 340px);
  margin: 6px 0 0;
  padding: 16px 20px 12px;
  border-radius: var(--r-m);
  background: var(--note-paper);
  color: var(--note-ink);
  box-shadow: inset 0 0 0 1px var(--note-line), var(--shadow-1);
  transform: rotate(-1.2deg);
  animation: iv-rise .5s var(--ease-out) calc(var(--t, 0s) + 1.75s) both;
}
.iv-yes-note blockquote { margin: 0; }
.iv-yes-note .note-hand { font-size: 21px; line-height: 1.4; animation: iv-write 1s steps(28, end) calc(var(--t, 0s) + 1.95s) both; }
.iv-yes-note .note-sign { margin: 2px 0 0; text-align: right; animation: iv-fade .4s var(--ease-out) calc(var(--t, 0s) + 2.75s) both; }
@keyframes iv-write { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }

/* That he knows: a check in holly, one line */
.iv-yes-told { display: flex; align-items: center; gap: 8px; margin: 0; font: 600 16px/1.35 var(--font-ui); color: var(--text); animation: iv-rise .45s var(--ease-out) calc(var(--t, 0s) + 2.6s) both; }
.iv-yes-told > svg { flex: none; width: 22px; height: 22px; padding: 3px; border-radius: 50%; background: var(--good); color: var(--bg); }
.iv-yes-foot { animation: iv-rise .5s var(--ease-out) calc(var(--t, 0s) + 2.85s) both; }
.iv-yes-foot > .fine { margin-bottom: 2px; color: var(--text-2); }

/* ============================== The questions ============================== */

.question-screen > .progress { margin-bottom: 6px; }
.question-screen .head { gap: 8px; }
.question-screen .head .h1 { font-size: clamp(34px, 10.4vw, 48px); line-height: 1.04; letter-spacing: -.022em; }
.question-screen .head .lede { margin-top: 0; }
.question-screen > .options { margin-top: 8px; }
/* The step under "Neither works for us" slides in like any new screen; its way back sits at the foot */
.question-screen.is-follow > .screen-foot > .btn-quiet:only-child { margin-top: 0; }

/* The card she taps takes her mark and the accent ring for a moment before the next question */
.question-screen .option.is-punching {
  border-color: var(--accent-ring);
  background: linear-gradient(var(--accent-soft), var(--accent-soft)), var(--surface);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 14%, transparent), var(--accent-glow), var(--shadow-1);
  transition: transform .16s var(--ease), box-shadow .16s var(--ease);
}
.question-screen .options:has(> .is-punching) > .option:not(.is-punching) { opacity: .55; transition: opacity .2s var(--ease); }

/* The weekend's first day on a calendar leaf: a band in the accent with the month, the day below
   in the display serif. The leaf is day paper in both looks. */
.option-art:has(> .q-date) { background: none; box-shadow: none; }
.q-date {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: 14px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--edge-strong), 0 1px 2px var(--edge-strong);
}
.q-date b { display: block; padding: 4px 0 3px; background: var(--btn-fill); font: 700 11px/1.1 var(--font-ui); letter-spacing: .14em; text-transform: uppercase; text-align: center; color: var(--on-accent); }
.q-date i { display: grid; flex: 1; place-items: center; padding-bottom: 2px; font: 560 25px/1 var(--font-display); font-style: normal; letter-spacing: -.02em; color: var(--text); font-variant-numeric: lining-nums tabular-nums; }
.question-screen .option-title, .invite-screen .option-title { text-wrap: balance; }
/* An answer with no second line keeps its title level with the picture */
.question-screen .option:not(:has(> .option-sub)) > .option-title, .invite-screen .option:not(:has(> .option-sub)) > .option-title { grid-row: 1 / span 6; align-self: center; }

/* "Neither works for us": a quiet line under the two weekends, not a third card. Once picked it
   carries her answer to "What works better?" under it. */
.q-neither { flex-wrap: wrap; min-height: var(--tap); margin-top: -2px; padding: 6px 18px; gap: 2px 8px; font-size: 15.5px; color: var(--text-2); }
.q-neither:hover { color: var(--text); }
.q-neither.is-picked { color: var(--text); font-weight: 650; }
.q-neither.is-picked svg { width: 18px; height: 18px; color: var(--good); }
.q-neither > small { flex-basis: 100%; font-size: 14px; font-weight: 500; color: var(--text-2); }

/* Who sees the answer: a small picture and one line */
.q-private { margin-top: 2px; color: var(--text-3); }
.q-private svg { color: var(--text-3); }

/* The note about the kids: a roomy field, Send right under it (it wakes with the first word) */
.q-note textarea { min-height: 156px; padding: 14px 16px; border-radius: var(--r-l); font-size: 17px; line-height: 1.5; box-shadow: var(--shadow-1); }
.q-note textarea::placeholder { color: var(--text-3); }
.q-note .actions { margin-top: 4px; }
.question-screen.is-note > .btn-quiet { margin-top: -10px; }

/* ============================== Waiting ============================== */

/* Your seal pressed, theirs a dashed place to fill: his star on the left, her heart on the right */
.q-seals { display: flex; justify-content: center; gap: 34px; margin: 8px 0 0; padding: 0; list-style: none; }
.q-seal { display: flex; flex-direction: column; align-items: center; gap: 10px; width: 112px; font: 600 14px/1.3 var(--font-ui); color: var(--text-2); text-align: center; }
.q-seal.is-mine { color: var(--text); }
.q-seal-wax { display: block; filter: var(--ticket-shadow); }
.q-seal-wax svg { display: block; width: 76px; height: 76px; }
.q-seal.is-mine:first-child .q-seal-wax { transform: rotate(-8deg); }
.q-seal.is-mine:last-child .q-seal-wax { transform: rotate(7deg); }
.q-seal-spot {
  display: grid;
  place-items: center;
  width: 76px;
  height: 76px;
  border-radius: 50%;
  border: 1.5px dashed color-mix(in srgb, var(--text) 42%, transparent);
  background: color-mix(in srgb, var(--text) 4%, transparent);
  color: var(--text-3);
}
.q-seal-spot svg { width: 30px; height: 30px; }
.q-seal-spot .shape { fill: none; stroke: currentColor; stroke-width: 1.4; stroke-dasharray: 2.4 2.4; }
/* Right after the last answer the seal comes down and presses in */
.q-seals.is-pressing .q-seal.is-mine .q-seal-wax svg { animation: q-press .7s cubic-bezier(.3, .7, .2, 1.2) calc(var(--t, 0s) + .15s) both; }
.q-seals.is-pressing .q-seal-name { animation: iv-fade .5s var(--ease-out) calc(var(--t, 0s) + .7s) both; }
@keyframes q-press { 0% { transform: translateY(-46px) scale(1.5); opacity: 0; } 55% { transform: translateY(0) scale(.92); opacity: 1; } 75% { transform: scale(1.04); } 100% { transform: scale(1); opacity: 1; } }
.q-wait-head { align-items: center; text-align: center; margin-top: 4px; }
.q-wait-head > .lede { max-width: 28ch; text-wrap: balance; }
.waiting-screen > .steps { margin: 4px 0 2px; }
.q-mine-list > .fine { margin-top: -6px; }
.q-mine .row-icon:has(> .q-date) { width: 44px; height: 44px; background: none; box-shadow: none; }
.q-mine .q-date b { padding: 3px 0 2px; font-size: 9.5px; }
.q-mine .q-date i { font-size: 19px; }
.q-mine .row-title { font-family: var(--font-display); font-size: 18px; font-weight: 560; }
.q-mine-seal { display: block; transform: rotate(-10deg); opacity: .9; }
.q-mine-seal svg { display: block; width: 26px; height: 26px; }
.q-meanwhile > .eyebrow { margin-bottom: -2px; }
.q-nothing { margin-top: 2px; }

/* No weekend yet */
.q-wait { gap: 12px; padding-top: 10px; }
.q-wait > .window { width: min(300px, 80%); border-radius: var(--r-xl); box-shadow: 0 0 0 1px var(--edge), var(--shadow-1); --art-ground: var(--art-snow); }
.q-wait > .h1 { margin-top: 6px; }
.q-wait > .lede { margin-top: -6px; font-size: 18px; color: var(--text-2); }
.q-wait-pic { display: grid; place-items: center; width: 104px; height: 104px; border-radius: 30px; background: var(--tile); box-shadow: var(--tile-glow); }
.q-wait-pic svg { width: 68px; height: 68px; }
.q-neither-line { max-width: 32ch; margin-inline: auto; }
.waiting-screen > .screen-foot .fine { margin: 2px 0 4px; }

/* ============================== The reveal ============================== */

/* The scene, closed with two wax seals, then three lines and the button at the foot. The block
   sits in the middle of the free space; the button settles under the thumb. */
.reveal-gate { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-block: auto; padding-top: 8px; text-align: center; }
.reveal-art { position: relative; width: 100%; max-width: 460px; margin-bottom: 34px; }
.reveal-art > .window { aspect-ratio: 400 / 250; border-radius: var(--r-xl); overflow: hidden; box-shadow: 0 0 0 1px var(--edge), var(--shadow-1); --art-ground: var(--art-snow); }
.rv-seals {
  appearance: none;
  position: absolute;
  left: 50%;
  bottom: -34px;
  display: flex;
  padding: 0;
  border: 0;
  background: none;
  translate: -50% 0;
  cursor: pointer;
}
.rv-seal { display: block; filter: var(--ticket-shadow); }
.rv-seal svg { display: block; width: 68px; height: 68px; }
.rv-seal.is-star { margin-right: -14px; transform: rotate(-9deg); }
.rv-seal.is-heart { transform: rotate(8deg); }
.rv-seals:focus-visible { outline-offset: 0; border-radius: 40px; }
.reveal-gate > .h1 { margin-top: 10px; }
.reveal-gate > .lede { max-width: 26ch; }
/* Opening: the two seals break apart and fall away, then the answers turn over */
.reveal-gate.is-opening .rv-seal.is-star { animation: rv-break-l .55s cubic-bezier(.4, 0, .7, .2) both; }
.reveal-gate.is-opening .rv-seal.is-heart { animation: rv-break-r .55s cubic-bezier(.4, 0, .7, .2) both; }
.reveal-gate.is-opening > .h1, .reveal-gate.is-opening > .lede { transition: opacity .4s var(--ease); opacity: 0; }
@keyframes rv-break-l { 0% { transform: rotate(-9deg); } 30% { transform: rotate(-15deg) scale(1.08); } 100% { transform: translate(-56px, 40px) rotate(-50deg) scale(.6); opacity: 0; } }
@keyframes rv-break-r { 0% { transform: rotate(8deg); } 30% { transform: rotate(14deg) scale(1.08); } 100% { transform: translate(56px, 40px) rotate(50deg) scale(.6); opacity: 0; } }

/* How the answers met: the cards turn over two at a time; where both picked the same, his star and
   her heart light up together in gold. */
.reveal-met { display: flex; flex-direction: column; gap: 16px; padding-top: 4px; }
.reveal-met[data-act="reveal-skip"] { cursor: pointer; }
.reveal-met > .head { animation: iv-rise .5s var(--ease-out) calc(var(--t, 0s) + 0s) both; }
.reveal-met .landed { overflow: visible; background: none; box-shadow: none; gap: 10px; }
.reveal-met .landed > .row {
  min-height: 76px;
  padding: 14px 16px;
  border-radius: var(--r-l);
  background: var(--sheen), var(--surface);
  box-shadow: var(--shadow-1), 0 0 0 1px var(--edge);
  transform-origin: 50% 50%;
  backface-visibility: hidden;
}
.reveal-met .landed > .row::before { display: none; }
.reveal-met .landed > .row .row-title { font-family: var(--font-display); font-size: 21px; font-weight: 560; line-height: 1.2; }
.reveal-met .landed.is-live > .row { animation: rv-turn .62s cubic-bezier(.2, .8, .25, 1) calc(var(--t, 0s) + .3s + var(--p, 0) * .42s + var(--s, 0) * .1s) both; }
@keyframes rv-turn { 0% { opacity: 0; transform: perspective(900px) rotateY(-88deg) scale(.96); } 60% { opacity: 1; } 100% { opacity: 1; transform: none; } }
.reveal-met .landed > .row.is-match { box-shadow: 0 0 0 1.5px var(--gold), 0 0 26px -6px color-mix(in srgb, var(--gold) 70%, transparent), var(--shadow-1); }
.reveal-met .landed.is-live > .row.is-match .marks .mk { animation: punch .44s cubic-bezier(.2, .9, .3, 1.4) calc(var(--t, 0s) + .85s + var(--i) * .2s) both; }
.rv-both { display: inline-flex; align-items: center; gap: 8px; margin-top: 3px; font-weight: 650; color: var(--gold-ink); }
.rv-both .marks { display: inline-flex; gap: 1px; }
.rv-both .mk svg { width: 19px; height: 19px; }
.rv-both .mk .shape { fill: var(--gold-ink); }
.rv-met-foot { animation: iv-rise .5s var(--ease-out) calc(var(--t, 0s) + 1.5s) both; }

/* ============================== Wider windows ============================== */
@media (min-width: 720px) {
  .invite-screen .hero-art { height: 300px; }
  .invite-screen .hero-art + * { margin-top: 12px; }
  .question-screen .head .h1 { font-size: 46px; }
  .q-wait > .window { width: 340px; }
}
