/* GENERATED by scripts/build-thankyou-production.mjs — DO NOT EDIT BY HAND.
   Source of truth: design-lab/experiences/thankyou-share/follow.css

   Shipped standalone for post 3248. The thank-you page gets the identical bytes
   concatenated into campaign-thankyou.{css,js} instead, so both surfaces run one
   component and there is no second implementation to keep in step. */
/* GENERATED by scripts/build-thankyou-production.mjs — DO NOT EDIT BY HAND.
   Source of truth: design-lab/experiences/thankyou-share/follow.css

   Shipped standalone for post 3248. The thank-you page gets the identical bytes
   concatenated into campaign-thankyou.{css,js} instead, so both surfaces run one
   component and there is no second implementation to keep in step. */
/* ═══════════════════════════════════════════════════════════════════════════
   FOLLOW THE CAMPAIGN — the consent control's appearance.

   THE BRIEF IT IS ANSWERING: "do not drop an ugly generic HubSpot form into the
   campaign. The donor should experience The Last Mile's product."

   So it is built from the campaign's own material vocabulary — the same rule
   hairlines, sand/cream/quiet type ramp and gold accent the rest of the page
   uses — and NOT from the default apparatus of a subscription widget: no boxed
   card, no drop shadow, no full-bleed gold panel, no icon, no "Subscribe"
   wordmark. A single underlined field and one button, on the page's own ground.

   GOLD IS THE SUBMIT AND NOTHING ELSE. The band must not out-shout "Share the
   campaign" above it, so the control's only saturated element is the button,
   and even that is the same token at the same size as the campaign's other
   secondary actions rather than the hero's.
   ═══════════════════════════════════════════════════════════════════════════ */

/* THE BAND IS HIDDEN UNTIL A LIVE CONTROL LANDS IN IT.
   The section's ground, hairline and vertical padding belong to a control that
   may not be enabled — /follow answers 503 until a HubSpot subscription type
   exists — and an empty band with a rule across it is a visible defect on a page
   that is otherwise finished. The component adds `is-live` only after a form is
   actually in the DOM, so a page without the script, or with JavaScript off,
   renders nothing here rather than an orphan rule. */
.jsf-follow-band { display: none; }
.jsf-follow-band.is-live { display: block; }

.jsf-follow { display: grid; gap: 10px; }

/* The say: heading + lede, built by the component so they cannot outlive it. */
.jsf-follow__head {
  font-family: Fraunces, Georgia, "Times New Roman", serif;
  font-weight: 500; font-size: clamp(1.35rem, 2.4vw, 1.7rem); line-height: 1.15;
  letter-spacing: -.015em; margin: 0 0 8px; color: var(--cream, #f4efe2);
}
.jsf-follow__lede {
  margin: 0; font-size: .95rem; line-height: 1.6;
  color: var(--muted, #b3ada0); max-width: 46ch;
}
/* The anti-newsletter promise — the one phrase that says what they are NOT
   signing up for, and the only emphasis in the band. */
.jsf-follow__lede em { font-style: normal; font-weight: 600; color: var(--sand, #eace84); }

/* THE FIELD IS A RULED LINE, NOT A BOX.
   A bordered rounded input is the single most recognisable "embedded marketing
   form" signal there is. An underline reads as editorial and sits naturally on
   a dark stage where a filled white box would punch a hole. */
.jsf-follow__field {
  display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap;
}

.jsf-follow__label {
  /* Visible to assistive tech, not drawn — the placeholder plus the heading
     above already name the field, and a floating label here would add a third
     piece of chrome to a control whose whole point is restraint.
     Not display:none: that removes it from the accessibility tree too. */
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.jsf-follow__input {
  flex: 1 1 200px; min-width: 0;
  min-height: var(--tap, 44px);
  padding: 0 2px;
  background: transparent;
  color: var(--cream, #f4efe2);
  border: 0; border-bottom: 1px solid var(--rule-strong, rgba(244,239,226,.2));
  border-radius: 0;                      /* iOS adds one otherwise */
  font: inherit; font-size: 1rem;
  -webkit-appearance: none; appearance: none;
  transition: border-color .18s ease;
}
.jsf-follow__input::placeholder { color: var(--quiet, #949084); }
.jsf-follow__input:hover { border-bottom-color: var(--cream, #f4efe2); }
.jsf-follow__input:focus { outline: none; border-bottom-color: var(--gold, #daa520); }
/* The focus RING still has to exist for keyboard users — the colour change
   alone is not a focus indicator. It is drawn on the field, matching the
   campaign's one ring. */
.jsf-follow__input:focus-visible {
  outline: 3px solid var(--gold, #daa520); outline-offset: 3px; border-radius: 3px;
}

/* GHOST, NOT GOLD — and this was a correction, not a first instinct.
   The first render filled this button with --gold at the same radius and weight
   as "Share the campaign" two hundred pixels above it. Two saturated gold pills
   in one viewport is two primary actions, and the brief is explicit that the
   follow control must not damage the advocacy moment. On this page gold means
   "the thing we most want you to do", and that is sharing.
   So: same geometry, same tap target, outlined instead of filled. Subordinate by
   MATERIAL rather than by being smaller — a shrunken gold button would have been
   both hard to hit and still the loudest thing in the band. */
.jsf-follow__submit {
  flex: 0 0 auto;
  min-height: var(--tap, 44px);
  padding: 0 1.25em;
  border: 1px solid var(--rule-strong, rgba(244,239,226,.2));
  border-radius: 999px;
  background: transparent; color: var(--cream, #f4efe2);
  font: inherit; font-weight: 600; font-size: .92rem;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}
.jsf-follow__submit:hover {
  background: rgba(255, 255, 255, .1);
  border-color: var(--cream, #f4efe2);
}
.jsf-follow__submit:disabled { opacity: .5; cursor: default; }

/* THE PROMISE. Permanently visible, never a tooltip: the person has to be able
   to read what they are agreeing to at the moment they agree to it. Small, but
   at --muted rather than --quiet, because it is a term and not a disclaimer. */
.jsf-follow__promise {
  margin: 0; font-size: .76rem; line-height: 1.5;
  color: var(--muted, #b3ada0); max-width: 52ch;
}

.jsf-follow__status { margin: 0; font-size: .82rem; line-height: 1.5; }
/* An empty status must occupy NOTHING — a grid gap around a zero-height element
   still opens a gap, which made the default state sit a row taller than it
   needed to for a message that was not there. */
.jsf-follow__status:empty { display: none; }
.jsf-follow[data-state="error"] .jsf-follow__status { color: #f3b2a0; }
.jsf-follow[data-state="error"] .jsf-follow__input { border-bottom-color: #f3b2a0; }
.jsf-follow[data-state="busy"] .jsf-follow__submit { opacity: .55; }

/* THE BAND, RESOLVED. The invitation retires and the confirmation takes the full
   measure — a band that still says "Follow the campaign" beside "You're
   following the campaign" is arguing with itself.

   Both surfaces are named because each sets its own two-column grid at desktop
   and the override has to outrank it: `.ty .ty-stay__row` scores (0,2,0), so the
   done rule needs (0,3,0) there and (0,2,0) on the campaign coda. */
.jsf-follow-mount.is-done .jsf-follow__say { display: none; }
.ty .ty-stay__row.jsf-follow-mount.is-done,
.coda__row.jsf-follow-mount.is-done { grid-template-columns: 1fr; }

/* THE DONE STATE replaces the form. Sand, not gold: the campaign's confirmation
   register, the same one the gift seal uses — a second gold object here would
   claim this was as important as the gift, and it is not. */
.jsf-follow__done {
  margin: 0; font-size: 1rem; font-weight: 600; color: var(--sand, #eace84);
}
.jsf-follow__doneSub {
  margin: 4px 0 0; font-size: .85rem; line-height: 1.55; color: var(--muted, #b3ada0);
}

/* MOBILE ART DIRECTION, not a stacked desktop.
   Below 560 the field wraps anyway, so the button is given the full measure
   rather than being left as a short tab floating under a full-width rule — a
   half-width control under a full-width one reads as unfinished, and a
   full-width target is the right shape for a thumb. */
@media (max-width: 560px) {
  .jsf-follow__field { gap: 14px; }
  .jsf-follow__input { flex: 1 1 100%; }
  .jsf-follow__submit { flex: 1 1 100%; width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .jsf-follow__input, .jsf-follow__submit { transition: none; }
}

/* On paper the ghost needs an ink outline rather than a cream one. */
.jsf-follow-mount--onPaper .jsf-follow__submit {
  border-color: rgba(20, 18, 13, .3); color: #14120d;
}
.jsf-follow-mount--onPaper .jsf-follow__submit:hover {
  background: rgba(20, 18, 13, .06); border-color: #14120d;
}

/* ── THE CAMPAIGN PAGE (3248) ─────────────────────────────────────────────
   Post 3248 is a LIGHT editorial surface, so the control needs the same shape
   against paper. Only the colour roles change; the composition does not, because
   it should be recognisably the same object in both places.

   Scoped to the MOUNT rather than to the form, so the ground is declared once in
   the markup that knows what it is sitting on and the runtime stays ignorant of
   colour entirely. */
.jsf-follow-mount--onPaper .jsf-follow__input {
  color: #14120d; border-bottom-color: rgba(20, 18, 13, .28);
}
.jsf-follow-mount--onPaper .jsf-follow__input::placeholder { color: #6d6759; }
.jsf-follow-mount--onPaper .jsf-follow__input:hover { border-bottom-color: #14120d; }
/* THE ERROR COLOUR IS GROUND-DEPENDENT and the dark one does not survive here.
   #f3b2a0 is a pale salmon chosen to read on the stone; on paper (#f7f4ec) it is
   roughly 1.7:1 — the most urgent line in the band, effectively invisible. This
   is a deep burnt sienna from the same warm family, ~7:1 on paper. */
.jsf-follow-mount--onPaper .jsf-follow[data-state="error"] .jsf-follow__status { color: #8f2f14; }
.jsf-follow-mount--onPaper .jsf-follow[data-state="error"] .jsf-follow__input { border-bottom-color: #8f2f14; }
.jsf-follow-mount--onPaper .jsf-follow__promise { color: #565145; }
.jsf-follow-mount--onPaper .jsf-follow__doneSub { color: #565145; }
.jsf-follow-mount--onPaper .jsf-follow__done { color: #7a5e0c; }
.jsf-follow-mount--onPaper .jsf-follow__head { color: #14120d; }
.jsf-follow-mount--onPaper .jsf-follow__lede { color: #565145; }
.jsf-follow-mount--onPaper .jsf-follow__lede em { color: #7a5e0c; }

/* ── THE CAMPAIGN-PAGE CODA (post 3248) ───────────────────────────────────
   The band that hosts the control on the campaign page. It lives in THIS file,
   not in campaign.css, because campaign.css is adopted from production by
   scripts/flagship-css.mjs and anything authored into it locally is liable to be
   reconciled away. These rules ship with the control that needs them.

   Unused on the thank-you page, which hosts the same control in `.ty-stay`.

   QUIET BY CONSTRUCTION. No chapter numeral, no warm ground, no photograph, a
   heading roughly half a chapter title, and a hairline instead of a new colour
   field. The campaign has six chapters and ends on the ask; this is what comes
   after the last full stop, and it has to read that way or it becomes a seventh
   thing competing with the gift. */
.coda {
  border-top: 1px solid rgba(20, 18, 13, .12);
  background: #f7f4ec;
}
/* The mount IS the row: the component fills it with say + form. */
.coda__row { display: grid; gap: clamp(18px, 3vw, 44px); padding: clamp(36px, 5vw, 60px) 0; }
@media (min-width: 900px) {
  /* Narrower ask column than say column, for the same reason as the thank-you
     band: the control must not become the widest object on the page. */
  .coda__row { grid-template-columns: minmax(0, 1fr) minmax(300px, 420px); align-items: start; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   VERIFIED MODE — one decision, no field

   A donor arriving from their own completed checkout is already known to the
   server, so this band carries a single control. The field row exists only to
   position that control; with nothing to sit beside it, the button stops
   stretching to fill a column that is no longer shared.
   ═══════════════════════════════════════════════════════════════════════════ */
.jsf-follow__field--verified { display: flex; }
.jsf-follow__field--verified .jsf-follow__submit { flex: 0 0 auto; }

/* THE COUNT is evidence, not an announcement: it sits with the terms, at their
   weight, because a number that shouts is a number the reader starts auditing. */
.jsf-follow__count { margin: 0; font-size: .82rem; line-height: 1.5; opacity: .62; }
.jsf-follow__count:empty { display: none; }

/* THE WAY OUT.
   Quiet on purpose, and never the visual equal of the invitation above it — but
   a real, focusable button with a real hit area, not a footnote. The 44px floor
   is the reason for the padding rather than a smaller inline link: an
   unsubscribe that is hard to hit is a dark pattern with better manners. */
.jsf-follow__unfollow {
  align-self: start;
  margin: 2px 0 0;
  padding: 11px 2px;
  min-height: 44px;
  background: none;
  border: 0;
  border-bottom: 1px solid currentColor;
  border-radius: 0;
  font: inherit;
  font-size: .82rem;
  line-height: 1.5;
  color: inherit;
  opacity: .62;
  cursor: pointer;
  transition: opacity 160ms ease;
}
.jsf-follow__unfollow:hover,
.jsf-follow__unfollow:focus-visible { opacity: 1; }
.jsf-follow__unfollow[disabled] { cursor: default; opacity: .45; }

/* A withdrawal acknowledgement is not an error — the error colour would read as
   "something went wrong" on the one action that just went right. */
.jsf-follow[data-state="notice"] .jsf-follow__status { opacity: .72; }

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