/* ============================================================
   Resonant System v2 — the share control

   One line at the end of a reading, and one press resolves it: the link is copied, or on a phone the system share
   sheet opens. It doesn't ask which app you'd like to use first.

   A version of this expanded into Copy link and Email before doing anything.
   It was more informative and it was worse — the impulse being served here is
   someone thinking of a particular person mid-reading, and a menu puts a
   decision between that thought and the act.

   Nothing takes the page over either. The confirmation is the control itself:
   it says what happened in the line you were already looking at, then goes
   back to Share.
   ============================================================ */

.rs-share {
  /* One grid cell, and every state sits in it. The row therefore never changes
     size, which is what lets the transitions be opacity and transform only —
     no width to animate, so no layout work on any frame. An earlier version
     animated max-width and could never be made smooth, because the browser was
     re-laying out the row sixty times a second. */
  display: grid;
  justify-items: center;
  align-items: center;
  margin-top: var(--space-3);
  min-height: 2.6rem;
}
.rs-layer {
  grid-area: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  will-change: opacity;
}

/* A crossfade: both states move at once over the same 0.6s, so one dissolves
   into the other rather than the row emptying and refilling.

   The two overlap in the same grid cell, so for a moment in the middle both
   are half-present on top of each other. That's the cost of crossing rather
   than sequencing, and whether it reads as a dissolve or as a smear is the
   thing to judge on screen.

   No transform. An earlier version lifted each state 6px as it went, and the
   movement was what made it read as quick however long the timing was.

   visibility can't be interpolated, so it's switched: held until the fade has
   finished on the way out, released immediately on the way in. */
.rs-layer {
  transition: opacity 0.6s ease, visibility 0s linear 0.6s;
}
.rs-share-said {
  opacity: 0;
  visibility: hidden;
}
.rs-layer-actions {
  opacity: 1;
  visibility: visible;
}

.rs-share.is-said .rs-layer-actions {
  opacity: 0;
  visibility: hidden;
}
.rs-share.is-said .rs-share-said {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.6s ease, visibility 0s linear 0s;
}

/* On the class, not on descendants of the row. It was .rs-share button, which
   stopped applying the moment the same control was used inside the invitation
   — and a button with no reset gets the browser's own border and background,
   which is what put a box around the arrow. */
.rs-share-trigger,
.rs-share button,
.rs-share a {
  font-family: 'Inter', sans-serif;
  font-size: 0.95rem;
  font-weight: 400;
  color: var(--body);
  background: none;
  border: 0;
  cursor: pointer;
  text-decoration: none;
  letter-spacing: 0.01em;
  /* WCAG 2.2 wants 24px of target; the padding gets a 15px line there without
     making the control look like a button, which it deliberately isn't. */
  padding: 0.5rem 0.6rem;
  transition: color 0.15s;
}
.rs-share-trigger:hover,
.rs-share button:hover,
.rs-share a:hover { color: var(--accent); }

.rs-share-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.rs-share-trigger svg {
  display: block;
  width: 18px;
  height: 18px;
}

/* --- The invitation ------------------------------------------ */
/* Over the page, on the page's own paper. Not a scrim: everywhere else on this
   site things recede by going under --bg, and a dark overlay would say the
   opposite — that the reading is in shadow rather than set aside. */
.rs-invite {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: var(--space-5) 1.5rem;
  /* Scrollable, for the case where an on-screen keyboard leaves less room than
     the invitation needs. Without it the field is simply unreachable behind
     the keyboard. */
  overflow-y: auto;
  overscroll-behavior: contain;
  background: rgba(250, 250, 248, 0.94);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.5s ease, visibility 0s linear 0.5s;
}
/* The subscribe panel by id, not by class. .rs-invite is the overlay chrome and
   the Write-to-Jim panel wears it too, deliberately, to inherit it — so written
   as a class this rule opened both panels at once and the contact form, being
   later in the document, painted on top. Pressing Subscribe showed "What's on
   your mind?", and only Escape closed it: the backdrop click landed on the
   wrong panel and cleared a class that was never set.
   The page's own comment already claimed the two could never be open together.
   This is the half that was missing. #rs-invite is also what subscribe-row.js
   reaches for, so the stylesheet now names the element the script does. */
body.is-inviting #rs-invite {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.5s ease, visibility 0s linear 0s;
}

.rs-invite-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  max-width: 30rem;
  text-align: center;
}

/* Serif, because this is the only place on the site where the author speaks to
   the reader directly rather than writing for them. Inter would make it an
   interface label. */
.rs-invite-line {
  font-family: 'Source Serif 4', serif;
  font-size: 1.15rem;
  line-height: 1.7;
  color: var(--body);
  margin: 0;
}
/* Three blocks: the question, the reasons, the permission. The question stands
   alone because it's the only part the reader has to answer. */
.rs-invite-copy,
.rs-invite-done {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}
/* The question, not the first sentence. It had been inheriting the same
   1.15rem as the lines under it, so the panel opened on three paragraphs of
   equal weight and nothing asked anything. Larger and in --heading, it lands as
   a question and the rest reads as the answer. */
.rs-invite-ask {
  margin: 0;
  /* Serif for the same reason .rs-invite-line is: this panel is the author
     speaking, not the interface labelling. It had been inheriting Inter from
     the panel, so the question arrived in a different voice from its own
     answer. */
  font-family: 'Source Serif 4', serif;
  font-size: 1.55rem;
  font-weight: 500;
  line-height: 1.2;
  color: var(--heading);
}
@media (max-width: 640px) { .rs-invite-ask { font-size: 1.35rem; } }

/* Hidden until there's something to say, and it never replaces the invitation
   — a typo is not a reason to take away what someone was reading. */
.rs-invite-error {
  font-family: 'Inter', sans-serif;
  font-size: 0.9rem;
  color: var(--heading);
  margin: 0;
  min-height: 1.2em;
}
/* In flight. The request sends an email before it answers, so it isn't
   instant — and with nothing on screen changing, people press again. The row
   fades and stops accepting input; the arrow is what's obviously waiting. */
.rs-invite.is-sending .rs-invite-entry {
  opacity: 0.45;
  pointer-events: none;
}
.rs-invite.is-sending .rs-sub-go {
  animation: rs-waiting 1.1s ease-in-out infinite;
}
@keyframes rs-waiting {
  0%, 100% { opacity: 0.4; }
  50%      { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .rs-invite.is-sending .rs-sub-go { animation: none; }
}

.rs-invite-done { display: none; }
.rs-invite.is-done .rs-invite-copy,
.rs-invite.is-done .rs-invite-entry,
.rs-invite.is-done .rs-invite-error { display: none; }
.rs-invite.is-done .rs-invite-done { display: flex; }

.rs-invite-entry {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

/* The close sits in the corner of the screen, which is a real edge to be
   anchored to — the reason the inline × didn't work was that it had none. */
.rs-invite-close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  padding: 0.6rem;
  background: none;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.15s;
}
.rs-invite-close:hover { color: var(--heading); }
.rs-invite-close svg { display: block; }

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

.rs-sub-input {
  width: 14rem;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  background: none;
  font-family: 'Inter', sans-serif;
  font-size: 0.95rem;
  color: var(--body);
  padding: 0.35rem 0.2rem;
  outline: none;
  transition: border-color 0.15s;
}
.rs-sub-input::placeholder { color: var(--muted-strong); }
/* The focus state darkens the rule rather than colouring it. --accent here was
   the one UI-ish thing in an otherwise editorial page. */
.rs-sub-input:focus { border-bottom-color: var(--muted-strong); }
.rs-sub-input.is-error { border-bottom-color: var(--heading); }
.rs-sub-go { padding: 0.3rem 0.4rem; line-height: 1; }
.rs-sub-go svg { width: 15px; height: 15px; }

.rs-share-said {
  font-family: 'Inter', sans-serif;
  font-size: 0.95rem;
  color: var(--muted-strong);
  padding: 0.5rem 0.6rem;
}

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