/* ============================================================
   components/forms.css
   Inputs, primary button, the subscribe band, the legal line.
   One form per page, where the reader finished. No outer margin.
   ============================================================ */
/* One input, everywhere (account + subscribe). Full width of its column; tall enough to be
   comfortable; 16px font so iOS never zooms the page on focus. Border and radius are tokens. */
.rfi-input {
  width: 100%; min-width: 0; min-height: 48px; padding: 12px 16px;
  font-size: 16px; line-height: 1.4; font-family: inherit;
  border: 1px solid var(--rfi-border); border-radius: var(--rfi-radius);
  background: var(--rfi-surface); color: var(--rfi-text);
}
.rfi-input::placeholder { color: var(--rfi-text-3); }
.rfi-input:focus { outline: 0; border-color: var(--rfi-teal); }

/* Field = a visible label stacked above its input. The label is a real caption (14px,
   text-secondary), never only a placeholder: the placeholder disappears on input and the
   person would otherwise lose the context of what they are typing. */
.rfi-field { display: flex; flex-direction: column; gap: 6px; }
.rfi-field__label { font-family: var(--rfi-font-ui); font-size: 14px; font-weight: 500; color: var(--rfi-text-2); }
.rfi-btn {
  height: 42px; padding: 0 24px; background: var(--rfi-teal); color: var(--rfi-inverse); border: 0;
  border-radius: var(--rfi-radius); font-family: var(--rfi-font-ui); font-size: 14px; font-weight: 500;
  white-space: nowrap; display: inline-flex; align-items: center; justify-content: center;
}
.rfi-btn:hover { background: var(--rfi-teal-dark); }
/* The second button on the site. Both are inline-flex and centred, so each reads the
   same whether it is a <button> in a form or an <a> to somewhere else, and no call
   site has to know which it is (design-decisions.md 3). */
.rfi-btn--secondary { background: var(--rfi-surface); border: 1px solid var(--rfi-border); color: var(--rfi-navy); padding: 0 22px; }
.rfi-btn--secondary:hover { background: var(--rfi-surface); border-color: var(--rfi-teal); color: var(--rfi-teal); }
/* The header scale. The masthead is a 74px bar, so a 42px button would dominate it;
   this is the size the wireframe draws there. It is a modifier ON the button rather
   than an override reaching in from masthead.css, so the site still has exactly one
   button component and its sizes live with it. */
.rfi-btn--sm { height: 38px; font-size: 13.5px; padding: 0 18px; }
/* Form submit buttons match the input height (48px) so the field column reads as one scale. */
.rfi-authform__submit, .rfi-subscribe__submit { height: 48px; }
/* A form wrapper owns the small gap to the legal line, so the leaf sets no margin. */
.rfi-form { display: flex; flex-direction: column; gap: 8px; }
.rfi-legal { font-size: 13px; line-height: 1.5; color: var(--rfi-text-3); }
.rfi-legal a { color: var(--rfi-navy); text-decoration: underline; }

/* The honeypot must never be visible or focusable: it is a spam control, not a
   field. Off-canvas rather than display:none, which some bots skip. */
.rfi-subscribe__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.rfi-subscribe__status:empty { display: none; }
.rfi-subscribe__status { font-size: var(--rfi-desc); color: var(--rfi-text-2); }
.rfi-subband .rfi-subscribe__status { color: var(--rfi-inverse); }

/* ---- subscribe widget: one form shape, three variants -----------------------------------
   'stack' (the /subscribe/ landing): fields stacked, full-width button under them.
   'row'   (homepage navy band, article inline): fields + button on one line on wide screens,
           MANDATORY collapse to a full-width column below 768px so nothing squeezes on mobile. */
.rfi-subscribe { display: flex; flex-direction: column; gap: 10px; }
.rfi-subscribe__fields { display: flex; flex-direction: column; gap: 14px; }
.rfi-subscribe--stack .rfi-subscribe__submit { width: 100%; }
.rfi-subscribe--row .rfi-subscribe__fields { flex-direction: row; align-items: flex-end; gap: 10px; }
.rfi-subscribe--row .rfi-field { flex: 1 1 0; min-width: 0; }
.rfi-subscribe--row .rfi-subscribe__submit { flex: 0 0 auto; }
@media (max-width: 767px) {
  .rfi-subscribe--row .rfi-subscribe__fields { flex-direction: column; align-items: stretch; gap: 14px; }
  .rfi-subscribe--row .rfi-subscribe__submit { width: 100%; }
}

/* Subscribe band (navy), before the footer / after an article. */
.rfi-subband { background: var(--rfi-navy); border-radius: var(--rfi-radius); padding: 28px 30px; display: flex; align-items: center; gap: 30px; color: var(--rfi-inverse); }
.rfi-subband__t { font-family: var(--rfi-font-ui); font-size: 22px; font-weight: 600; }
.rfi-subband__s { font-size: 14px; color: var(--rfi-inverse-soft); margin-top: 5px; }
.rfi-subband__form { margin-left: auto; flex: 1; max-width: 620px; }
.rfi-subband .rfi-input { border: 0; }
.rfi-subband .rfi-legal { color: var(--rfi-inverse-mute); }
.rfi-subband .rfi-legal a { color: var(--rfi-inverse-strong); }
@media (max-width: 900px) { .rfi-subband { flex-direction: column; align-items: stretch; gap: 16px; } .rfi-subband__form { margin-left: 0; max-width: none; } }

/* The /subscribe/ landing: ONE centred column, max 560px. Stacked top to bottom: title, subtitle,
   the bare subscribe form, the no-spam note, then the "Already have an account? Sign in" line. */
.rfi-substack {
  max-width: 560px; margin: 30px auto 0;
  background: var(--rfi-surface); border-radius: var(--rfi-radius); box-shadow: var(--rfi-shadow);
  padding: 28px 30px;
}
.rfi-substack__title { font-family: var(--rfi-font-ui); font-size: 22px; font-weight: 600; color: var(--rfi-text); margin: 0 0 6px; }
.rfi-substack__sub { font-size: 14px; line-height: 1.55; color: var(--rfi-text-2); margin: 0; }
.rfi-substack .rfi-subscribe { margin-top: 20px; }
.rfi-substack__cta { margin-top: 16px; }
/* The alt line reads as a site link (navy, teal on hover). */
.rfi-substack__alt { font-size: 13.5px; color: var(--rfi-text-3); margin-top: 16px; }
.rfi-substack__alt a { color: var(--rfi-navy); font-weight: 600; }
.rfi-substack__alt a:hover { color: var(--rfi-teal); }

/* Turnstile client-side status (auth-turnstile.js): a clear message when the widget
   is verifying or fails, instead of a generic server rejection. */
.rfi-turnstile-status:empty { display: none; }
.rfi-turnstile-status {
	margin: 8px 0 0;
	font-size: 13px;
	color: var(--rfi-text-2, #6B6B6B);
}

/* ============================================================
   The contact form on /about/contact/.
   Reuses .rfi-input and .rfi-btn above rather than restyling them: this block owns layout and
   the two states the prototype specifies (field error, sent), nothing else.
   Message first, then name and email side by side, stacking on a narrow screen.
   ============================================================ */
.rfi-contactform {
  max-width: 560px;
  margin: 40px 0 0;
  padding: 28px 30px;
  border: 1px solid var(--rfi-border);
  border-radius: 12px;
  background: var(--rfi-surface);
}
.rfi-contactform__title { margin: 0 0 6px; font-size: 23px; line-height: 1.25; }
.rfi-contactform__lede { margin: 0 0 22px; color: var(--rfi-text-2, #6B6B6B); font-size: 15px; }
.rfi-contactform__row { margin: 0 0 18px; }
.rfi-contactform__label { display: block; margin: 0 0 7px; font-size: 14px; font-weight: 600; }
.rfi-contactform__ta { min-height: 130px; resize: vertical; }

/* Two short fields read as one step. One column below the small breakpoint. */
.rfi-contactform__pair { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 560px) { .rfi-contactform__pair { grid-template-columns: 1fr; gap: 0; } }

/* The error says what happens if it is not fixed; the value the person typed is kept. */
.rfi-input.is-error { border-color: var(--rfi-danger, #C4402F); background: #FCF1EF; }
.rfi-contactform__err { margin: 6px 0 0; font-size: 13px; color: var(--rfi-danger, #C4402F); }

.rfi-contactform__submit { margin: 4px 0 0; }
.rfi-contactform__legal { margin: 16px 0 0; font-size: 13px; color: var(--rfi-text-2, #6B6B6B); }

/* Honeypot: out of view for people, still reachable for a bot that reads the DOM. */
.rfi-contactform__hp {
  position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;
}

.rfi-contactform__ok {
  padding: 20px 22px; border: 1px solid var(--rfi-ok-border, #B7E3D2);
  border-radius: 10px; background: var(--rfi-ok-bg, #ECF8F3);
}
.rfi-contactform__oktitle { margin: 0 0 6px; font-size: 16px; font-weight: 600; }
.rfi-contactform__ok span { display: block; font-size: 15px; color: var(--rfi-text-2, #6B6B6B); }
.rfi-contactform__small { margin-top: 8px; font-size: 13px; }

/* The email fallback under the form: quieter than the form, and clearly the alternative to it. */
.rfi-contactform__fallback {
  max-width: 560px;
  margin: 14px 0 0;
  font-size: 14px;
  color: var(--rfi-text-2, #6B6B6B);
}

/* ============================================================
   THE GUEST AUTH PAGE, 2026-08-16

   Sign in, forgot password and set password share one card and
   one message row, which is not only tidiness: a failure has to
   look identical whichever form produced it, because the whole
   design of these forms is ONE ANSWER FOR EVERY CAUSE. Two
   differently styled failure states would leak through the CSS
   what the copy is careful not to say.

   Everything below is layout. The field, the input, the button
   and the legal line are the components already declared above
   and are not restyled here.
   ============================================================ */
.rfi-authwrap { display: flex; justify-content: center; }
.rfi-authform {
  background: var(--rfi-surface); border-radius: var(--rfi-radius); box-shadow: var(--rfi-shadow);
  padding: 28px 28px 24px; width: 100%; max-width: 420px;
  display: flex; flex-direction: column; gap: 14px;
}
/* The card owns its own heading scale: an h1 at the page scale would dwarf a 420px card. */
.rfi-authform .rfi-t-h1 { font-size: 26px; line-height: 1.25; margin: 0; }

/* ONE ROW, TWO TONES. Same box, same weight, same position, so the eye lands in the same
   place whether the message is a refusal or a reassurance. Only the colour differs. */
.rfi-authform__msg {
  margin: 0; padding: 10px 12px; border-radius: var(--rfi-radius-sm);
  font-size: 13.5px; line-height: 1.45;
}
.rfi-authform__msg--error { background: #FCF1EF; color: var(--rfi-danger, #C4402F); }
.rfi-authform__msg--notice { background: var(--rfi-input); color: var(--rfi-text-2); }

/* The checkbox row reads horizontally where every other field is a stacked label. */
.rfi-field--check { flex-direction: row; align-items: center; gap: 8px; font-size: 14px; color: var(--rfi-text-2); }

@media (max-width: 480px) {
  .rfi-authform { padding: 20px 18px 18px; box-shadow: none; }
}

/* ============================================================
   THE TAB ROW, and the platform-move notice under it.
   Both added 2026-08-16 with the tabbed auth shell. Geometry is COMPUTED here, not seen:
   every value below is derived from what the card already declares, not measured in a browser.
   ============================================================ */

/* Three links on one row, sharing the card's 420px measure. `gap: 2px` rather than a border
   between them: the active tab is marked by weight and by its underline, so a divider would be a
   third signal saying the same thing. The row sits directly under the h1 and takes the card's own
   14px flex gap above it, so it declares no top margin. */
.rfi-authtabs { display: flex; gap: 2px; border-bottom: 1px solid var(--rfi-border); }
.rfi-authtab {
  flex: 1; text-align: center; padding: 8px 4px 10px;
  font-family: var(--rfi-font-ui); font-size: 14px; font-weight: 500;
  color: var(--rfi-text-2); text-decoration: none;
  /* The underline is transparent rather than absent, so the active state changes a colour and
     never a height: a tab gaining a 2px border on activation would move the whole card. */
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.rfi-authtab:hover { color: var(--rfi-text); }
.rfi-authtab.is-active { color: var(--rfi-navy); font-weight: 600; border-bottom-color: var(--rfi-navy); }

/* The platform-move notice. Toned as information rather than as a warning: it is the expected
   state for 3844 of the people who will read it, and an alarm colour would tell them something
   has gone wrong when nothing has. It reuses the notice tone of .rfi-authform__msg and adds the
   left rule, which is what distinguishes a standing explanation from a response to a submission. */
.rfi-authnote {
  background: var(--rfi-input); border-left: 3px solid var(--rfi-navy);
  border-radius: var(--rfi-radius-sm); padding: 12px 14px;
  display: flex; flex-direction: column; gap: 4px;
}
.rfi-authnote__h { margin: 0; font-family: var(--rfi-font-ui); font-size: 14px; font-weight: 600; color: var(--rfi-text); }
.rfi-authnote__b { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--rfi-text-2); }
.rfi-authnote__a { margin: 0; font-size: 13.5px; }
.rfi-authnote__a a { color: var(--rfi-navy); font-weight: 600; }

/* The subscribe page's standfirst: the same scale as the notice body, because it does the same
   job of setting expectations before the fields. */
.rfi-authform__lead { margin: 0; font-size: 14px; line-height: 1.55; color: var(--rfi-text-2); }


/* The line under the newsletter checkbox. Smaller than the label it explains, and indented so it
   sits under that label's text rather than under the box, which is what makes it read as belonging
   to the control instead of as a new paragraph.

   24px IS A DELIBERATE APPROXIMATION, NOT A DERIVED VALUE, and saying so matters because every
   other measurement in this stylesheet is derived. A native checkbox has no width we declare: it
   is a UA-rendered control, typically 13px in this family plus the 8px gap .rfi-field--check sets,
   and it is not identical across browsers. Nothing breaks if it is off by two pixels, which is why
   an approximation is acceptable here and would not be for the card measure. Added 2026-08-17. */
.rfi-field__hint {
  margin: -8px 0 0 24px; font-size: 12.5px; line-height: 1.4; color: var(--rfi-text-2);
}

/* ============================================================
   THE PROFILE LEFT THIS FILE ON 2026-08-19.

   It was declared here on 2026-08-17 as a widening of the auth
   card: `.rfi-authform--wide` at 560px, `.rfi-profile__id`,
   `.rfi-profile__email`, `.rfi-field--set`, `.rfi-field__hint--top`,
   `.rfi-checkgrid`, `.rfi-checkgrid__item`, `.rfi-checkgroup__label`
   and a `.rfi-field.is-error` rule. Eleven selectors, and the
   rebuild to the donor's shape emits none of them: the screen is
   cards and chips now, in components/account.css.

   DELETED RATHER THAN LEFT, which is this file's own precedent. The
   filter panel rewrite found twenty-one donor selectors declared
   here that nothing had ever emitted, and the lesson recorded then
   was that a rule nothing emits reads as load-bearing to the next
   person. Checked before deleting: `grep -rl` over wp-content finds
   no PHP emitting any of the eleven.
   ============================================================ */
