/* THE THREE FONTS, DEFINED ONCE (2026-08-04).
   ============================================================

   A scan found the site was not inconsistent so much as BROKEN:

   - --serif and --sans were used 124 times and defined NOWHERE, so every one
     of those rules fell back to the browser default.
   - --mono, --display and --body were defined only in app/styles.css, which
     27 root pages never load — so var(--mono) on admin, pricing, privacy,
     start, support, terms and 21 others resolved to nothing as well.

   The app therefore rendered in Newsreader and IBM Plex Mono while much of
   the rest of the site quietly rendered in Times and Arial.

   These live here because this file is linked by every page. --serif and
   --sans are aliases of the names already in use, so the 124 existing
   declarations start working rather than needing to be rewritten. */
:root {
  --display: "Newsreader", serif;
  --serif:   "Newsreader", serif;
  --body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --sans:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono:    "IBM Plex Mono", ui-monospace, Menlo, monospace;
}

/* Shared form sizing — linked by EVERY page.
   ============================================================

   Why this file exists: text box size was set per element, with `rows` on
   each individual textarea, and the only floor lived in app/styles.css. So
   how big a box was depended on which stylesheet happened to cover that page
   — the app got a floor, the 13 root pages with textareas got nothing, and
   anything added later inherited whichever the author remembered.

   Sizing belongs in one place that every page loads. `rows` still sets the
   initial height; these rules set the minimum, so a box can be made bigger
   by its own rows but never smaller than readable.

   The bar: you have to be able to READ BACK what you wrote without
   scrolling. Two or three lines is enough to type into and not enough to
   check. */

textarea {
  min-height: 160px;
  line-height: 1.6;
  padding: 14px;
  font-size: 16px;          /* under 16px, iOS zooms the page on focus */
  resize: vertical;         /* always let someone make it bigger */
  box-sizing: border-box;
  width: 100%;
}

/* A few boxes are deliberately one-liners — a title, a name, a short reply.
   Those declare rows="1" or rows="2" and get a smaller floor rather than
   being forced to 160px, which would look absurd next to a Send button. */
textarea[rows="1"] { min-height: 56px; }
textarea[rows="2"] { min-height: 84px; }

/* Anything asking for real writing gets real room, whatever rows says. */
textarea[rows="8"], textarea[rows="9"], textarea[rows="10"],
textarea[rows="12"], textarea[rows="16"], textarea[rows="20"] { min-height: 260px; }

/* Single-line inputs and selects: same reasoning, less of it. A 16px floor
   here too, for the same iOS zoom reason. */
input[type="text"], input[type="email"], input[type="password"],
input[type="search"], input[type="number"], input[type="tel"],
input[type="url"], input[type="date"], input[type="time"], select {
  min-height: 46px;
  font-size: 16px;
  box-sizing: border-box;
}

/* PLACEHOLDERS MUST BE READABLE (2026-08-16, Marc: "the default text on
   fields doesn't have enough contrast"). Nothing on the site styled
   ::placeholder, so every field fell to the browser default — the input's
   colour at roughly half opacity, which on these dark cards is barely
   there. --muted is ~7:1 against the card backgrounds while still sitting
   clearly below --ink, so a hint reads as a hint, not as typed text.
   opacity:1 because Firefox additionally dims placeholders by default. */
input::placeholder, textarea::placeholder {
  color: var(--muted, #A9CBC1);
  opacity: 1;
}

/* SELECTS MATCH THE FIELDS BESIDE THEM (2026-08-16, Marc: "dimensions
   don't match the site", from the signup page). An unstyled <select> is
   the native control — white, black text, its own height and radius —
   which reads as a hole in an otherwise dark form. This is the site-wide
   baseline; pages that style their selects deliberately (admin's inline
   styles, the app's own rules) override it as before. */
select {
  background-color: var(--surface2, var(--card2, #2E5A4E));
  color: var(--ink, #F3F9F7);
  border: 1px solid var(--edge, #40766A);
  border-radius: 8px;
  padding: 10px 12px;
  font-family: inherit;
}

@media (max-width: 640px) {
  /* More room on a phone, not less — this is where most writing happens and
     where the keyboard already eats half the screen. */
  textarea { min-height: 180px; }
  textarea[rows="8"], textarea[rows="9"], textarea[rows="10"],
  textarea[rows="12"], textarea[rows="16"], textarea[rows="20"] { min-height: 280px; }
}

/* PROSE FILLS ITS COLUMN (2026-08-04, Marc).
   ============================================================

   Body text was capped at a character count — .lede at 46ch, most page copy
   at 70 or 74ch — so it stopped around half way across its container and the
   right side of every card sat empty. The caps are removed at source; this is
   the backstop for anything added later that reaches for one out of habit.

   Genuinely narrow elements (a stat, a badge, a two-word label) set caps
   under 30ch and are untouched — those are deliberate. */
.lede, .fp-body, .isub, .fp-note { max-width: none; }
