/* Door 1 — RSVP flow.
 *
 * Scoped to #moc-rsvp throughout, so this can sit on its own page at /thursday or be
 * injected into the portal without either sheet repainting the other. Tokens are the
 * portal's, redeclared here only as fallbacks for the standalone page — when embedded,
 * the portal's :root wins and this inherits the brand automatically, including its
 * dark mode.
 */

/* Dark is the default here, not a preference-driven variant. The portal's dark palette,
   verbatim — same ink, same paper, same lifted green and red that the brand mark needs on
   a dark ground. Light survives only as an explicit opt-in, so the page looks the same on
   a phone set to light mode as it does on the site. */

#moc-rsvp{
  --r-paper:var(--paper,#12100D);
  --r-paper-2:var(--paper-2,#1B1815);
  --r-ink:var(--ink,#F2ECE2);
  --r-ink-2:var(--ink-2,#C4B9AA);
  --r-muted:var(--muted,#9A8D7D);
  --r-line:var(--line,#2E2822);
  --r-line-2:var(--line-2,#413931);
  --r-green:var(--green,#3E9C63);
  --r-green-lift:var(--green-lift,#57BC7D);
  --r-red:var(--red,#E0555B);
  --r-radius:var(--r,3px);
  --r-shadow:var(--shadow,0 1px 2px rgba(0,0,0,.4),0 14px 40px -22px rgba(0,0,0,.7));

  font-family:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
  color:var(--r-ink);
  max-width:560px;
  margin:0 auto;
  padding:32px 20px 72px;
}

/* Standalone page only — when embedded, the host page owns the background. */
body.moc-rsvp-page{ margin:0; background:#12100D; color-scheme:dark; }

/* Explicit opt-in only. Nothing switches this automatically. */
:root[data-theme="light"] body.moc-rsvp-page{ background:#FAF6EF; color-scheme:light; }
:root[data-theme="light"] #moc-rsvp{
  --r-paper:#FAF6EF; --r-paper-2:#FFFFFF; --r-ink:#16130F; --r-ink-2:#4A423A;
  --r-muted:#6B6157; --r-line:#E4DCD0; --r-line-2:#D3C7B6;
  --r-green:#004B1D; --r-green-lift:#0A6B31; --r-red:#AE090F;
  --r-shadow:0 1px 2px rgba(22,19,15,.05),0 14px 40px -22px rgba(22,19,15,.30);
}

/* ------------------------------------------------------------ brand + head */

/* The wordmark sits on a white plaque, exactly as the portal nav does. This was briefly a
   CSS filter instead — `brightness(0) invert(1)` — which flattened a two-colour brand mark
   to solid white and threw away the red and green entirely. The mark is never recoloured,
   never inverted, never filtered (CLAUDE.md #8); when the ground is dark, the ground gets
   a plate. */
#moc-rsvp .r-brand{
  display:inline-block;margin-bottom:24px;line-height:0;
  background:#fff;border-radius:2px;padding:7px 11px;
}
#moc-rsvp .r-brand img{ width:150px;height:auto;display:block; }

/* ------------------------------------------------------------ side rail
 * Real MOC photography, consent confirmed 2026-08-09. One column, on the left.
 *
 * The rail is anchored to the *form column's edge*, not to the viewport — `right: calc(50%
 * + 340px)` puts its right edge 340px left of centre, while the form's left edge sits at
 * 300px left of centre. That 40px gutter is guaranteed by the geometry at every width, so
 * the two can never overlap however the window is resized. An earlier version positioned
 * from the viewport edge instead and clipped the form at ~1120px.
 *
 * It appears only above 1280px, which is the first width where a 220px rail plus that
 * gutter fits without crowding anything. Below it, the form is the whole page. */

#moc-rsvp .r-rails{ display:none; }

@media (min-width:1280px){
  #moc-rsvp .r-rails{ display:block; }

  #moc-rsvp .r-rail{
    position:fixed;top:0;bottom:0;
    right:calc(50% + 340px);          /* 40px clear of the 600px form column */
    width:220px;
    overflow:hidden;pointer-events:none;z-index:0;
    /* Fades top and bottom so the loop never shows a hard edge. */
    -webkit-mask-image:linear-gradient(180deg,transparent,#000 12%,#000 88%,transparent);
            mask-image:linear-gradient(180deg,transparent,#000 12%,#000 88%,transparent);
  }

  /* Each frame is a fixed 150px + a 12px gap, so one pass of six is exactly 972px. The
     distance is declared in pixels rather than as translateY(-50%): a percentage resolves
     against the track's own height, which is near zero until the images decode, and the
     animation was therefore crawling a few pixels over 78 seconds and reading as static.
     Fixed heights also stop the rail reflowing as each photo lands. */
  #moc-rsvp .r-rail-track{
    display:flex;flex-direction:column;gap:12px;
    animation:r-rail-down 38s linear infinite;
    will-change:transform;
  }
  #moc-rsvp .r-rail-track img{
    display:block;width:220px;height:150px;object-fit:cover;
    border-radius:var(--r-radius);
    /* Present, never competing with the form. */
    opacity:.38;filter:saturate(.92);
    transition:opacity .4s ease;
  }
  #moc-rsvp .r-rail:hover .r-rail-track img{ opacity:.6; }

  @keyframes r-rail-down{
    from{ transform:translateY(-972px) }   /* 6 x (150 + 12) */
    to  { transform:translateY(0) }
  }

  /* Reduced motion slows it to a drift rather than stopping it dead — a still column of
     photographs reads as a broken carousel, which is worse than gentle movement. */
  @media (prefers-reduced-motion:reduce){
    #moc-rsvp .r-rail-track{ animation-duration:400s; }
  }

  @media (min-width:1600px){
    #moc-rsvp .r-rail{ width:270px;right:calc(50% + 380px); }
    #moc-rsvp .r-rail-track img{ width:270px;height:184px; }
    #moc-rsvp .r-rail-track{ animation-name:r-rail-down-lg; }
    @keyframes r-rail-down-lg{
      from{ transform:translateY(-1176px) }  /* 6 x (184 + 12) */
      to  { transform:translateY(0) }
    }
  }
}

/* The form always paints above the rail. */
#moc-rsvp > *:not(.r-rails){ position:relative;z-index:1; }

/* ------------------------------------------------------- the mechanic
 * The seats-and-chords diagram, on the act-break screen. It argues for the questions that
 * follow it, which is why it is there and not at the top of the page. */

#moc-rsvp .r-mech{ width:100%;height:auto;max-height:180px;display:block;margin:16px 0 6px; }
#moc-rsvp .r-mech-cap{ font-size:12px;color:var(--r-muted);text-align:center;margin:0;line-height:1.45; }

#moc-rsvp .rh-rim{ fill:none;stroke:var(--r-line-2);stroke-width:1.2;opacity:.6; }
#moc-rsvp .rh-seat{ fill:var(--r-green);opacity:.85; }
#moc-rsvp .rh-chord{
  stroke:var(--r-green-lift);stroke-width:1.1;opacity:0;
  animation:rh-in 3.2s ease-out both;
}
@keyframes rh-in{
  0%   { opacity:0 }
  12%  { opacity:.85 }
  70%  { opacity:.85 }
  100% { opacity:.12 }
}
@media (prefers-reduced-motion:reduce){
  #moc-rsvp .rh-chord{ animation:none;opacity:.6; }
}

#moc-rsvp .r-head{ margin-bottom:26px; }
#moc-rsvp .r-eyebrow{
  font-size:11.5px;letter-spacing:.07em;text-transform:uppercase;
  color:var(--r-muted);font-weight:600;margin-bottom:10px;
}
#moc-rsvp .r-head h1{
  font-family:'Poppins','Inter',system-ui,sans-serif;
  font-size:clamp(21px,4.2vw,27px);line-height:1.2;margin:0;font-weight:600;
  text-wrap:balance;
}
#moc-rsvp .r-head p{ margin:9px 0 0;color:var(--r-ink-2);font-size:14.5px;line-height:1.55; }

/* ------------------------------------------------------------ session card
 * When the session is, in the viewer's own timezone. This replaced a three-option picker,
 * so it has to earn the space: it answers the first question anyone has before they'll
 * give you a phone number. */

#moc-rsvp .r-when{
  background:var(--r-paper-2);border:1px solid var(--r-line);
  border-left:3px solid var(--r-green);border-radius:var(--r-radius);
  padding:13px 16px;margin-bottom:22px;
}
#moc-rsvp .r-when-main{
  font-family:'Poppins','Inter',system-ui,sans-serif;
  font-size:15.5px;font-weight:600;color:var(--r-ink);line-height:1.35;
}
#moc-rsvp .r-when-sub{ font-size:12.5px;color:var(--r-muted);margin-top:4px;line-height:1.45; }
#moc-rsvp .r-when-sub:empty{ display:none; }

#moc-rsvp .r-when-more{
  background:none;border:0;padding:0;margin-top:10px;cursor:pointer;
  font-family:inherit;font-size:12.5px;color:var(--r-green);font-weight:600;
  text-decoration:underline;text-underline-offset:3px;
}
#moc-rsvp .r-when-more:hover{ color:var(--r-green-lift); }

#moc-rsvp .r-dates{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(158px,1fr));gap:8px;
  margin-top:12px;padding-top:12px;border-top:1px solid var(--r-line);
}
#moc-rsvp .r-date{
  font-family:inherit;text-align:left;cursor:pointer;
  padding:9px 12px;border-radius:var(--r-radius);
  background:transparent;border:1px solid var(--r-line-2);color:var(--r-ink-2);
  transition:border-color .15s ease,background .15s ease,color .15s ease;
}
#moc-rsvp .r-date:hover{ border-color:var(--r-green);color:var(--r-green); }
#moc-rsvp .r-date[aria-pressed="true"]{
  background:var(--r-green);border-color:var(--r-green);color:#fff;
}
#moc-rsvp .r-date b{ display:block;font-size:13px;font-weight:600; }
#moc-rsvp .r-date span{
  display:block;font-size:11px;opacity:.75;margin-top:1px;
  text-transform:uppercase;letter-spacing:.05em;
}

/* Counts screens, never percentages — "4 of 10" is a promise the form can keep. */
#moc-rsvp .r-progress{
  display:flex;align-items:center;gap:10px;
  font-size:12px;color:var(--r-muted);margin-bottom:20px;
  font-variant-numeric:tabular-nums;
}
#moc-rsvp .r-bar{ flex:1;height:2px;background:var(--r-line);border-radius:2px;overflow:hidden; }
#moc-rsvp .r-bar i{ display:block;height:100%;background:var(--r-green);transition:width .25s ease; }

/* -------------------------------------------------------------- screens */

#moc-rsvp .r-screen{ display:none; }
#moc-rsvp .r-screen.is-on{ display:block;animation:r-in .22s ease both; }
@keyframes r-in{ from{opacity:0;transform:translateY(6px)} to{opacity:1;transform:none} }
@media (prefers-reduced-motion:reduce){
  #moc-rsvp .r-screen.is-on{ animation:none; }
  #moc-rsvp .r-bar i{ transition:none; }
}

#moc-rsvp .r-q{
  font-family:'Poppins','Inter',system-ui,sans-serif;
  font-size:19px;font-weight:600;margin:0 0 6px;line-height:1.3;
}
#moc-rsvp .r-help{ font-size:13.5px;color:var(--r-muted);margin:0 0 18px;line-height:1.5; }

/* --------------------------------------------------------------- fields */

#moc-rsvp .r-field{ margin-bottom:16px; }
#moc-rsvp .r-field label{
  display:block;font-size:13px;font-weight:600;color:var(--r-ink-2);margin-bottom:6px;
}
#moc-rsvp input[type=text],
#moc-rsvp input[type=tel],
#moc-rsvp input[type=email],
#moc-rsvp textarea{
  width:100%;box-sizing:border-box;
  font-family:inherit;font-size:16px;   /* 16px stops iOS zooming on focus */
  padding:11px 13px;
  background:var(--r-paper-2);color:var(--r-ink);
  border:1px solid var(--r-line-2);border-radius:var(--r-radius);
  transition:border-color .15s ease;
}
#moc-rsvp textarea{ min-height:84px;resize:vertical;line-height:1.5; }
#moc-rsvp input:focus,#moc-rsvp textarea:focus{
  outline:none;border-color:var(--r-green);box-shadow:0 0 0 3px rgba(0,75,29,.10);
}
#moc-rsvp input::placeholder,#moc-rsvp textarea::placeholder{ color:var(--r-muted);opacity:.7; }

/* ------------------------------------------------------- choice + chips */

#moc-rsvp .r-choices{ display:grid;gap:10px; }
#moc-rsvp .r-choice{
  display:block;width:100%;text-align:left;cursor:pointer;
  background:var(--r-paper-2);border:1px solid var(--r-line-2);border-radius:var(--r-radius);
  padding:14px 16px;font-family:inherit;color:var(--r-ink);
  transition:border-color .15s ease,background .15s ease;
}
#moc-rsvp .r-choice:hover{ border-color:var(--r-green); }
#moc-rsvp .r-choice[aria-pressed="true"]{ border-color:var(--r-green);background:rgba(0,75,29,.05); }
#moc-rsvp .r-choice b{ display:block;font-size:15px;font-weight:600;margin-bottom:2px; }
#moc-rsvp .r-choice span{ display:block;font-size:13px;color:var(--r-muted);line-height:1.45; }

#moc-rsvp .r-chips{ display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px; }
#moc-rsvp .r-chip{
  font-family:inherit;font-size:13.5px;cursor:pointer;
  padding:7px 13px;border-radius:100px;
  background:transparent;color:var(--r-ink-2);
  border:1px solid var(--r-line-2);
  transition:border-color .15s ease,background .15s ease,color .15s ease;
}
#moc-rsvp .r-chip:hover{ border-color:var(--r-green);color:var(--r-green); }
#moc-rsvp .r-chip[aria-pressed="true"]{
  background:var(--r-green);border-color:var(--r-green);color:#fff;
}
/* Reaching the cap should read as "that's enough", not as breakage. */
#moc-rsvp .r-chip[disabled]{ opacity:.34;cursor:not-allowed; }

/* "Not applicable", on the audience question. Set apart from the answers beside it —
   dashed until chosen — because it is a different kind of thing: everything else on that
   row describes who you want, this one says the question does not apply. Latches like any
   other chip once picked, so its selected state needs no special case. */
#moc-rsvp .r-chip-na,
#moc-rsvp .r-chip-other{ border-style:dashed; margin-left:4px; }
#moc-rsvp .r-chip-other[aria-pressed="true"]{ border-style:solid; }
#moc-rsvp .r-chip-na[aria-pressed="true"]{ border-style:solid; }
#moc-rsvp .r-chip-na[hidden]{ display:none; }

/* Sentence openers. Quieter than a real chip and they never latch, because they are not
   an answer — they type three words into the box below and get out of the way. Dashed so
   the difference from a selectable chip is visible before you tap one. */
#moc-rsvp .r-stems{ margin-bottom:10px; }
#moc-rsvp .r-stem{
  border-style:dashed; font-size:12.5px; padding:5px 11px;
  color:var(--r-muted);
}
#moc-rsvp .r-stem:hover{ border-style:solid; }
#moc-rsvp .r-count{ font-size:12.5px;color:var(--r-muted);font-variant-numeric:tabular-nums; }

/* -------------------------------------------------------------- uploads
 * Optional, and styled to look it — a ghost button and a status line, never a dashed
 * drop-zone rectangle that reads as a required slot waiting to be filled. */

#moc-rsvp .r-upload{ display:flex;align-items:center;gap:12px;flex-wrap:wrap; }
#moc-rsvp .r-upload-state{ font-size:12.5px;color:var(--r-muted);line-height:1.45;flex:1;min-width:150px; }
#moc-rsvp .r-upload-state.is-ok{ color:var(--r-green-lift);font-weight:600; }
#moc-rsvp .r-upload-state.is-warn{ color:var(--r-ink-2); }
/* Marks a field as genuinely optional in the label itself, so it reads as permission
   rather than as something the member forgot to fill in. */
#moc-rsvp .r-opt{
  font-weight:400;font-size:11.5px;color:var(--r-muted);
  text-transform:uppercase;letter-spacing:.05em;margin-left:6px;
}
#moc-rsvp .r-note-sm{ font-size:12px;color:var(--r-muted);margin:8px 0 0;line-height:1.45; }

/* ------------------------------------------------------------- consent */

#moc-rsvp .r-consent{
  display:flex;gap:11px;align-items:flex-start;
  padding:13px 15px;margin:16px 0 0;
  background:var(--r-paper-2);border:1px solid var(--r-line);border-radius:var(--r-radius);
}
#moc-rsvp .r-consent input{ margin:2px 0 0;flex:none;width:16px;height:16px;accent-color:var(--r-green); }
#moc-rsvp .r-consent label{ font-size:13.5px;line-height:1.5;color:var(--r-ink-2);margin:0;font-weight:400; }

/* ----------------------------------------------------------- nav + msg */

#moc-rsvp .r-nav{ display:flex;align-items:center;gap:12px;margin-top:24px; }
#moc-rsvp .r-btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  font-family:inherit;font-size:14.5px;font-weight:600;
  padding:11px 20px;border-radius:var(--r-radius);border:1px solid transparent;
  cursor:pointer;text-decoration:none;
  transition:background .16s ease,color .16s ease,border-color .16s ease;
}
#moc-rsvp .r-btn-primary{ background:var(--r-green);color:#fff; }
#moc-rsvp .r-btn-primary:hover{ background:var(--r-green-lift); }
#moc-rsvp .r-btn-primary[disabled]{ opacity:.5;cursor:default; }
#moc-rsvp .r-btn-ghost{ border-color:var(--r-line-2);color:var(--r-ink);background:transparent; }
#moc-rsvp .r-btn-ghost:hover{ border-color:var(--r-green);color:var(--r-green); }
#moc-rsvp .r-skip{
  background:none;border:0;font-family:inherit;font-size:13.5px;
  color:var(--r-muted);cursor:pointer;text-decoration:underline;text-underline-offset:3px;
}
#moc-rsvp .r-skip:hover{ color:var(--r-green); }

#moc-rsvp .r-error{
  margin-top:12px;font-size:13.5px;color:var(--r-red);line-height:1.5;
}
#moc-rsvp .r-error:empty{ display:none; }

/* ----------------------------------------------------------- act break
 * The hinge between "get a seat" and "help us seat you well". It reads as an arrival,
 * not as another question — which is what stops the nine screens after it feeling like
 * a form that wouldn't end. */

#moc-rsvp .r-act{
  background:var(--r-paper-2);border:1px solid var(--r-line);
  border-left:3px solid var(--r-green);border-radius:var(--r-radius);
  padding:20px 22px;
}
#moc-rsvp .r-act-tick{
  display:flex;align-items:center;gap:8px;
  font-size:12px;letter-spacing:.07em;text-transform:uppercase;font-weight:700;
  color:var(--r-green);margin:0 0 12px;
}
#moc-rsvp .r-act-tick::before{
  content:"";width:15px;height:8px;flex:none;
  border-left:2px solid var(--r-green);border-bottom:2px solid var(--r-green);
  transform:rotate(-45deg);margin-top:-4px;
}
#moc-rsvp .r-act .r-q{ margin-bottom:8px; }
#moc-rsvp .r-act .r-help{ margin-bottom:0; }

/* ---------------------------------------------------------------- done */

/* The prefilled note, shown before it is sent. Presented as the message it will become,
   not as a data summary — the member is about to send it from their own number, so it
   has to look like something they'd write. */
#moc-rsvp .r-note{
  background:var(--r-paper-2);border:1px solid var(--r-line);border-radius:var(--r-radius);
  padding:16px 18px;margin:0 0 18px;
  font-family:inherit;font-size:14px;line-height:1.62;color:var(--r-ink-2);
  white-space:pre-wrap;word-break:break-word;
  max-height:340px;overflow-y:auto;
}

#moc-rsvp .r-done h2{
  font-family:'Poppins','Inter',system-ui,sans-serif;
  font-size:22px;font-weight:600;margin:0 0 10px;line-height:1.25;
}
#moc-rsvp .r-done > p{ font-size:14.5px;color:var(--r-ink-2);line-height:1.6;margin:0 0 18px; }
/* The two actions, stacked and full-width on a phone. Nothing sits above them but the
   headline — a member who has just finished eleven screens should be told what to press,
   not handed a paragraph to read first. */
#moc-rsvp .r-actions{ margin:18px 0 0; }
#moc-rsvp .r-act-row{ display:flex;gap:10px;flex-wrap:wrap;margin-bottom:10px; }
#moc-rsvp .r-act-row .r-btn{ flex:1;min-width:150px; }
#moc-rsvp .r-btn-wa{ display:flex;width:100%;box-sizing:border-box; }
#moc-rsvp .r-cal-when{ font-size:12.5px;color:var(--r-muted);line-height:1.5;margin:12px 0 0; }
#moc-rsvp .r-cal-when b{ color:var(--r-ink-2);font-weight:600; }
/* The standing Meet room. Sized up from the note it sits under and given the green — it is
   a link people come back to this screen for, not a footnote about one. */
#moc-rsvp .r-join{ font-size:13.5px;margin-top:8px; }
#moc-rsvp .r-join a{ color:var(--r-green);font-weight:600;overflow-wrap:anywhere; }

/* Follow links. Real anchors to real profiles — nothing here claims to follow anyone on
   their behalf, because no platform permits it. Placed after the actions because this is
   where a follow converts: they have committed and the next Thursday is a long way off. */
#moc-rsvp .r-follow{
  margin-top:24px;padding-top:20px;border-top:1px solid var(--r-line);
}
#moc-rsvp .r-follow-q{
  font-family:'Poppins','Inter',system-ui,sans-serif;
  font-size:15px;font-weight:600;color:var(--r-ink);margin:0 0 12px;
}
#moc-rsvp .r-follow-links{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px;
}
#moc-rsvp .r-follow-links a{
  display:block;padding:11px 14px;text-decoration:none;
  background:var(--r-paper-2);border:1px solid var(--r-line-2);border-radius:var(--r-radius);
  color:var(--r-ink);font-size:14px;font-weight:600;
  transition:border-color .15s ease,color .15s ease;
}
#moc-rsvp .r-follow-links a:hover{ border-color:var(--r-green);color:var(--r-green-lift); }
#moc-rsvp .r-follow-links span{
  display:block;font-size:11.5px;font-weight:400;color:var(--r-muted);margin-top:2px;
}

/* Everything explanatory, below the decision. */
#moc-rsvp .r-done-detail{
  margin-top:26px;padding-top:20px;border-top:1px solid var(--r-line);
}
#moc-rsvp .r-done-sub{ font-size:13.5px;color:var(--r-muted);line-height:1.55;margin:0 0 14px; }
#moc-rsvp .r-done-lede{ font-size:14.5px;color:var(--r-ink-2);margin:0; }

#moc-rsvp .r-ref{
  font-family:ui-monospace,Consolas,monospace;font-size:12.5px;
  color:var(--r-muted);margin-top:20px;
}
#moc-rsvp .r-foot{
  margin-top:34px;padding-top:18px;border-top:1px solid var(--r-line);
  font-size:12.5px;color:var(--r-muted);line-height:1.6;
}

#moc-rsvp .r-hp{ position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden; }

/* ---- returning-member verification -------------------------------------------------
   Shown instead of a screen, not as one. Deliberately plain: a member arrives here having
   typed three fields, and the only job left is six digits. */
.r-otp { animation: rFade .28s ease both; }
.r-otp .r-field { max-width: 260px; }
#rOtpCode {
  font-size: 26px;
  letter-spacing: .34em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.r-otp-msg {
  min-height: 20px;          /* reserved, so an error does not shift the button under a thumb */
  margin: 10px 0 0;
  font-size: 14px;
  color: var(--r-warn, #c2703a);
}
.r-otp-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-top: 18px;
}
/* The escape hatch reads as secondary but must never look disabled — someone whose old
   address is dead needs to find it. */
.r-otp-actions .r-btn-ghost { font-size: 14px; }
