/* Base styles.
 *
 * These are the interface rules from docs/SPEC.md, started here rather than
 * retrofitted later: 18px base, high contrast, generous line height, touch
 * targets at least 44px, and no hover-only affordances anywhere.
 *
 * Deliberately plain CSS in one file. There is no build step, no preprocessor
 * and no framework, matching the travel log repo.
 *
 * ---------------------------------------------------------------------------
 * THE LOOK: A TOWN REGISTER SOMEBODY HAS BEEN PASTING INTO.
 *
 * What this replaced was a white page in the system sans-serif. It was legible
 * and it said nothing. The thing this site replaces is a hand-compiled paper
 * document, and the site should read as its continuation rather than as an app
 * that happens to hold names: aged paper, a book face, ruled lines, small
 * capital labels, and entries that look pasted in rather than rendered.
 *
 * NONE OF IT IS ALLOWED TO COST LEGIBILITY. Every rule in docs/SPEC.md still
 * holds and the decoration is subordinate to all of them:
 *
 *   - Contrast is measured rather than eyeballed. Ink on paper is 14.6:1 and
 *     the muted tone is 7.6:1 — both HIGHER than the white-page values they
 *     replace, because the paper tone was chosen after the ink rather than
 *     before it.
 *   - The grain is a tint, not a picture. It never sits behind body text at a
 *     strength that competes with it.
 *   - Nothing is distinguished by colour alone, anywhere.
 *   - No hover states. Not one, on any page. The device has no hover.
 *
 * WHY EVERY FONT HERE IS A SYSTEM FONT, and it is a constraint rather than a
 * taste: public/_headers sets `font-src 'self'`, so a web font means either
 * widening the CSP to a font host or committing binary font files to this
 * repository. The stack below is the book face that iPadOS, macOS and Windows
 * each already have — Iowan Old Style on the iPad this is actually for,
 * Georgia on the Windows machine it is reviewed on.
 *
 * THE TRAP, WRITTEN DOWN BECAUSE IT WOULD COST AN HOUR: a Google Fonts link
 * added here will look perfect on a local run and be silently blocked in
 * production, because the CSP is only enforced on the deployed site. Same
 * asymmetry as _headers itself.
 */

:root {
  /* 18px is the floor the spec sets, not a target. */
  --font-size-base: 18px;

  /* The book face. Iowan Old Style ships with iPadOS and is a text face
     rather than a display one; Georgia carries the Windows review. */
  --font-body: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua",
               Georgia, "Times New Roman", serif;

  /* For the few places where a fact is quoted rather than read as prose — an
     email address, an identifier. It reads as typed into the register, and it
     stops a domain being mistaken for a word. */
  --font-typed: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  /* High contrast. No light grey on white — or, here, on paper — anywhere. It
     is the single most common reason an older reader gives up on a screen.
     The ratio beside each is against --colour-background, measured. */
  --colour-text: #211d17;        /* 14.6:1 */
  --colour-text-muted: #524a3a;  /*  7.6:1 */
  --colour-background: #f4efe3;  /* aged paper, not white */
  --colour-card: #fbf7ee;        /* a slip pasted onto it */
  --colour-rule: #cfc3ab;        /* hairline rules and borders */
  --colour-rule-strong: #9c8f76; /* the heavier half of a double rule */

  /* The binding. One primary control per page, and the marks that stand in for
     a stamp. 9.1:1 against paper, so it can carry text as well as decoration. */
  --colour-accent: #6b2c26;
  --colour-danger: #8a1c1c;

  /* Focus is deliberately NOT the accent colour. It is a utility and it has to
     read as unmistakably not-decoration wherever it lands. 8.4:1. */
  --colour-focus: #173f96;

  /* Minimum touch target. Assume imprecise taps and possible tremor. */
  --touch-target-min: 44px;

  /* PAPER GRAIN. A tiled SVG of grey noise at very low opacity, as a data URI
     so it costs no request and needs no new origin in the CSP — a CSS
     background is checked against img-src, which already allows data:.
     Faint on purpose: at this strength it is a tint you would not notice
     being removed, which is the correct amount of texture under body text. */
  --paper-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)' opacity='0.05'/%3E%3C/svg%3E");
}

html {
  font-size: var(--font-size-base);
  /* Stops iOS Safari inflating text in landscape, which otherwise breaks
     layouts that were checked in portrait. */
  -webkit-text-size-adjust: 100%;

  /* THE PAPER GOES ON html, NOT ON body, AND IT IS NOT A STYLE PREFERENCE.
   *
   * It was on body first. On any page whose content is shorter than the window
   * — the welcome page, most obviously — the paper stopped in a hard horizontal
   * seam partway down the screen and the rest was flat colour. The browser
   * paints a root element's background across the whole canvas, but only when
   * the root has one; give html a background of its own and body's stops at
   * the bottom of the content box, which is what happened.
   *
   * FOUND BY LOOKING AT THE PAGE. Nothing in this repository could have seen
   * it, and it was on the one page a relative who is not expected lands on. */
  background-color: var(--colour-background);
  background-image: var(--paper-grain);
  background-repeat: repeat;
}

body {
  margin: 0;
  padding: 2.5rem 1.5rem;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--colour-text);
  /* Transparent, so the paper above shows through. A page that wants a
     different ground — the cover, in home.css — sets its own and covers the
     viewport itself. */
  background: transparent;
}

main {
  /* A comfortable measure for reading. The notes are the reason anyone will be
     on this site, so line length matters more here than it usually does. */
  max-width: 34rem;
  margin: 0 auto;
}

/* ---------------------------------------------------------------- headings */

h1 {
  font-size: 1.6rem;
  line-height: 1.25;
  margin: 0 0 1rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* SECTION LABELS, SET AS SMALL CAPITALS. This is the one typographic move that
   does most of the work: a ruled document labels its sections rather than
   titling them, and it is what stops a page of headings reading as a web page.
   Done with size and letter-spacing rather than font-variant, because not
   every fallback face has real small capitals and synthesised ones are uneven
   enough to look like a mistake. */
h2 {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--colour-text-muted);

  /* The rule that runs off the end of the label to the edge of the column. It
     is what makes a heading read as the head of a ruled section rather than as
     a line of bold text, and it is a flex child rather than a background so it
     fills whatever is left after the words, at any length, in any font. */
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

h2::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--colour-rule);
}

/* UPPERCASE IS FOR LABELS ONLY, NEVER FOR ANYTHING ANYBODY READS. Capitals cost
   an older reader real speed — the word shapes go — so they are confined to
   two- or three-word section labels, where the shape is the point and the word
   is already known. Names, dates, prose and error messages are never set in
   them anywhere on this site. */

p {
  margin: 0 0 1rem;
}

.lede {
  font-size: 1.125rem;
}

/* A DOUBLE RULE — thick over thin — is the mark of a ruled document, and it is
   one border plus one pseudo-element rather than an image. Applied by adding
   the class, so a page can rule a heading without any markup gaining a
   decorative element of its own. */
.rule-under {
  position: relative;
  padding-bottom: 0.55rem;
  border-bottom: 2px solid var(--colour-rule-strong);
}

.rule-under::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -5px;
  height: 1px;
  background: var(--colour-rule);
}

/* ------------------------------------------------------------------ status */

.status {
  padding: 0.75rem 1rem;
  border: 1px solid var(--colour-rule);
  /* Barely rounded. Paper is cut square; an 8px radius is a web convention and
     it is the detail that most makes a card read as a UI element. */
  border-radius: 3px;
  background: var(--colour-card);
  color: var(--colour-text-muted);
}

/* Success and failure are distinguished by a word and a border weight, never by
   colour alone. */
.status[data-state="signed-in"] {
  border-color: var(--colour-text);
  border-width: 2px;
  color: var(--colour-text);
}

.status[data-state="error"] {
  border-color: var(--colour-text);
  border-width: 2px;
  color: var(--colour-text);
}

a {
  color: var(--colour-text);
  /* Underlined, always. A link identified only by colour fails for anyone who
     cannot distinguish it, and there are no hover states to fall back on.
     The rule is drawn in the paler ink so that a line of links does not read
     as a line of strikethroughs. */
  text-decoration: underline;
  text-decoration-color: var(--colour-rule-strong);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* Anything tappable gets the full target, even when its text is short. */
a,
button {
  min-height: var(--touch-target-min);
  display: inline-flex;
  align-items: center;
}

/* FOCUS IS STYLED EVERYWHERE AND REMOVED NOWHERE. Stated once here so that no
   page has to remember it, and so that a page added later gets it for free. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--colour-focus);
  outline-offset: 2px;
}

/* ------------------------------------------------------------- printing */

/* PRINT-ONLY CONTENT IS HIDDEN HERE AND SHOWN BY print.css.
 *
 * A class rather than the `hidden` attribute, deliberately. `hidden` means
 * "not relevant in any presentation", and this content IS relevant — it is
 * relevant on paper and nowhere else. Overriding `hidden` for a medium would
 * be using an accessibility signal to mean something it does not mean, and
 * this project keeps `hidden` on the behaviour side of the seam. */
.print-only {
  display: none;
}

/* THE PRINT CONTROL READS AS A LINK, NOT AS A PLATE.
 *
 * It is a <button> because it acts on this page rather than going somewhere —
 * but the person page already carries three plate buttons that change the
 * archive (add someone, correct details, take them out), and a fourth that
 * merely prints must not sit among them with the same weight.
 *
 * A class beats the element selectors that style buttons elsewhere, so this
 * needs no !important and no page-specific override. */
.print-link {
  font-family: inherit;
  font-size: 1.05rem;
  background: none;
  border: 0;
  padding: 0;
  color: var(--colour-accent);
  text-decoration: underline;
  text-decoration-color: var(--colour-accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  cursor: pointer;
}
