/* The front door. Standalone on purpose: it must not pull in the application's stylesheet, which
   is ~150 KB written for a signed-in reader with a sidebar, a reader pane and thirty-eight views —
   none of which exist here. The palette is copied from web/css/styles.css rather than imported for
   the same reason. */
:root {
  --bg: #f4efe4;
  --bg-panel: #fbf8f1;
  --bg-elevated: #ffffff;
  --border: #ddd2bd;
  --border-subtle: #e8e0cf;
  --text: #2a2318;
  --text-muted: #5b5140;
  --text-dim: #7c7059;
  --accent: #c99a20;
  --accent-soft: rgba(201, 154, 32, 0.15);
  --on-accent: #2a2318;
  --link: #574000;
  --link-2: #094f48;
  --danger: #8f2418;
  --r: 14px;
  --r-sm: 8px;
  --ring: rgba(201, 154, 32, 0.5);
  --shadow: 0 14px 40px rgba(74, 60, 30, 0.13), 0 2px 8px rgba(74, 60, 30, 0.07);
  --shadow-sm: 0 1px 3px rgba(74, 60, 30, 0.10);
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #14171d;
  --bg-panel: #191d24;
  --bg-elevated: #20252e;
  --border: #2f3742;
  --border-subtle: #232932;
  --text: #eef1f5;
  --text-muted: #aab3bf;
  --text-dim: #7b8492;
  --accent: #e0bd6a;
  --accent-soft: rgba(224, 189, 106, 0.15);
  --on-accent: #14171d;
  --link: #e6c67c;
  --link-2: #5cc0b2;
  --danger: #f0857a;
  --ring: rgba(224, 189, 106, 0.55);
  --shadow: 0 14px 40px rgba(0, 0, 0, 0.5);
  --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.4);
}
/* No stored preference and no JS: follow the system rather than force parchment onto a dark screen. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;
    --bg: #14171d; --bg-panel: #191d24; --bg-elevated: #20252e;
    --border: #2f3742; --border-subtle: #232932;
    --text: #eef1f5; --text-muted: #aab3bf; --text-dim: #7b8492;
    --accent: #e0bd6a; --accent-soft: rgba(224, 189, 106, 0.15); --on-accent: #14171d;
    --link: #e6c67c; --link-2: #5cc0b2; --danger: #f0857a; --ring: rgba(224, 189, 106, 0.55);
    --shadow: 0 14px 40px rgba(0, 0, 0, 0.5); --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.4);
  }
}

* { box-sizing: border-box; }

/* [hidden] MUST WIN. The UA stylesheet says `[hidden] { display: none }` at the lowest possible
   specificity, so ANY rule of ours that sets `display` — `.btn { display: inline-flex }` and
   `.or { display: flex }` here — silently outranks it and the element renders anyway.
   Measured, not assumed: with `hidden` set, #siGoogle computed to `inline-flex` and was on screen.
   The consequence was the precise failure oauth_google.configured() exists to prevent — a dead
   "Continue with Google" on a deployment that has no Google credentials, which looks like the
   supported way in and fails with a 404 the visitor cannot interpret.
   This is the SECOND time this codebase has lost an hour to it (see /ui2/'s invisible full-screen
   backdrop in PROJECT_STATUS), so it goes in as a rule at the top of the sheet rather than as a
   fix on the four elements that happened to be caught this time. */
[hidden] { display: none !important; }

html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  min-height: 100dvh;
}

/* ---- utility row + centred masthead ---- */
.utility {
  display: flex; justify-content: flex-end;
  max-width: 68rem; margin: 0 auto;
  padding: clamp(.875rem, 2.5vw, 1.25rem) clamp(1rem, 4vw, 2rem) 0;
}
.masthead {
  max-width: 68rem; margin: 0 auto;
  padding: clamp(.5rem, 2vw, 1.25rem) clamp(1rem, 4vw, 2rem) 0;
  text-align: center;
}
.brand { display: inline-block; text-decoration: none; }
/* logo.webp is a PORTRAIT lockup (560x646) — the mark with the wordmark beneath it. Sized by
   height so the wordmark stays legible; width follows the intrinsic ratio. */
.brand-logo {
  height: clamp(96px, 15vw, 148px); width: auto; display: block;
}
/* The wordmark is a dark teal that disappears on a dark ground. The application solves this with a
   second file that recolours ONLY the wordmark — a filter would turn the mark itself to mud — so
   the front door does exactly the same thing rather than inventing a third answer. */
:root[data-theme="dark"] .brand-logo { content: url("/logo-dark.webp?v=430"); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .brand-logo { content: url("/logo-dark.webp?v=430"); }
}
.tagline {
  margin: 1rem 0 0; font-size: clamp(.8125rem, 2vw, .9375rem);
  letter-spacing: .13em; text-transform: uppercase; color: var(--text-dim);
}
.badge {
  display: inline-block; margin: 1rem 0 0;
  padding: .3125rem .875rem; border-radius: 999px;
  font-size: .72rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
  color: var(--link); background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
}

/* ---- shell ---- */
.gate {
  max-width: 68rem; margin: 0 auto;
  padding: clamp(1.75rem, 5vw, 3rem) clamp(1rem, 4vw, 2rem) 3rem;
}
/* ---- the two actions, side by side, above everything else ---- */
.actions {
  max-width: 68rem; margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 2.25rem) clamp(1rem, 4vw, 2rem) 0;
  display: grid; gap: clamp(1rem, 2.5vw, 1.5rem);
}
@media (min-width: 62rem) {
  /* Request access is wider because its form runs in two columns; sign in needs one. */
  .actions { grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); }
}
/* EQUAL HEIGHT. `align-items: stretch` is the grid default, so the two grid ITEMS already match —
   but the visible box is the .panel inside each, and without this it shrink-wraps its content and
   the shorter card floats with a gap under it. Stretching the panel itself is what makes the two
   cards actually finish on the same line. */
.actions > .panel { height: 100%; display: flex; flex-direction: column; }
/* A hidden panel must not claim a grid cell — [hidden] is forced to display:none at the
   top of this sheet, and `display:flex` here would otherwise outrank it. */
.actions > .panel[hidden] { display: none; }
/* Push the small print to the bottom of whichever card is shorter, so the two baselines agree
   instead of leaving one card with dead space in the middle. */
.actions > .panel > .notice:last-child { margin-top: auto; }
/* Grow to fill the card, but do NOT set `display` here: `.actions .form` (0,2,0) outranks
   `.form-2col` (0,1,0), so declaring flex on it silently overrode the two-column grid and the
   request form rendered as a single stacked column. Layout belongs to each form's own class. */
.actions .form { flex: 1 1 auto; }
.actions .form:not(.form-2col) { display: flex; flex-direction: column; }

/* ---- the request form, in two columns ---- */
.form-2col { display: grid; gap: 0 .875rem; grid-template-columns: 1fr; }
@media (min-width: 34rem) {
  .form-2col { grid-template-columns: 1fr 1fr; }
  .form-2col .span2 { grid-column: 1 / -1; }
}
/* The textarea is the one field that should grow into whatever height the neighbouring card sets. */
.form-2col .field.span2 { display: flex; flex-direction: column; }
.form-2col .field.span2 textarea { flex: 1 1 auto; }

.claimblock {
  max-width: 68rem; margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 2.5rem) clamp(1rem, 4vw, 2rem) 0;
}
.intro-lead {
  max-width: 68rem; margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 2.5rem) clamp(1rem, 4vw, 2rem) 0;
}
.intro-lead .lead-open {
  max-width: 46rem; margin: 0 auto; text-align: center;
  font-size: clamp(1.02rem, 2.1vw, 1.14rem);
}
.panel-solo { max-width: 30rem; margin: 0 auto; }

/* ---- type ---- */
.eyebrow {
  margin: 0 0 .75rem; font-size: .72rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--link);
}
h1 {
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(1.85rem, 5vw, 2.7rem); line-height: 1.16;
  margin: 0 0 1rem; letter-spacing: -.018em;
}
h2 {
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(1.15rem, 2.6vw, 1.35rem); line-height: 1.25;
  margin: 0 0 .5rem; letter-spacing: -.008em;
}
p { margin: 0 0 1rem; color: var(--text-muted); }
.lead { color: var(--text); font-size: clamp(1.02rem, 2.2vw, 1.125rem); line-height: 1.6; }
.card-lead { font-size: .9375rem; margin-bottom: 1.25rem; }
/* Inline, NOT display:block — `.feat strong` is a block on purpose (it is a heading for its item)
   and copying that here would break each emphasised word onto its own line mid-sentence. */
.card-lead strong { color: var(--text); font-weight: 650; }

/* ---- the differentiators ---- */
.feat {
  list-style: none; margin: 1.75rem 0 0; padding: 0;
  display: grid; gap: 1.125rem 2rem;
}
@media (min-width: 52rem) { .feat { grid-template-columns: 1fr 1fr; } }
.feat li {
  position: relative; padding-left: 1.5rem;
  font-size: .9375rem; line-height: 1.6; color: var(--text-muted);
}
/* A rule, not a bullet glyph: at this size a disc reads as a list of chores. */
.feat li::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: .625rem; height: 2px; border-radius: 1px; background: var(--accent);
}
.feat strong { display: block; color: var(--text); font-weight: 650; margin-bottom: .15rem; }

/* ---- cards ---- */
.card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: clamp(1.25rem, 3vw, 1.75rem);
  box-shadow: var(--shadow-sm);
}
.card-request { background: var(--bg-elevated); }
/* The right column is the DO column: request access, then sign in. Every sibling card gets the
   same gap so the order can change without a spacing rule changing with it. */

/* Sticky only when the column is genuinely shorter than the argument beside it; with two cards it
   usually is not, and a sticky element taller than the viewport traps the scroll. */


/* ---- form ---- */
.form { margin: 0; }
.field { margin-bottom: 1rem; }
label { display: block; margin-bottom: .3rem; font-size: .875rem; font-weight: 600; color: var(--text); }
input, textarea {
  width: 100%; padding: .6875rem .75rem;
  font: inherit; font-size: 1rem;         /* 16px: anything smaller makes iOS zoom on focus */
  color: var(--text); background: var(--bg-elevated);
  border: 1px solid var(--border); border-radius: var(--r-sm);
}
.card-request input, .card-request textarea { background: var(--bg); }
textarea { resize: vertical; line-height: 1.55; min-height: 5rem; }
input:focus-visible, textarea:focus-visible, button:focus-visible, a:focus-visible {
  outline: 2px solid var(--ring); outline-offset: 2px;
}
/* Error styling only AFTER the person has had a go at the field.
   `:invalid:not(:placeholder-shown)` looked right and was wrong: `:placeholder-shown` never
   matches an input that has no placeholder attribute, so the sign-in fields — which have none —
   were painted with a red error border the moment the page loaded, before anyone had typed a
   character. Telling a member their empty password is wrong before they attempt it is a poor
   greeting. `:user-invalid` is the selector that actually means "they tried, and it is not right". */
input:user-invalid, textarea:user-invalid { border-color: var(--danger); }
.hint { margin: .375rem 0 0; font-size: .8125rem; color: var(--text-dim); }
.err {
  margin: 0 0 .875rem; padding: .625rem .75rem;
  font-size: .875rem; color: var(--danger);
  background: color-mix(in srgb, var(--danger) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--danger) 28%, transparent);
  border-radius: var(--r-sm);
}

/* ---- buttons ---- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  width: 100%; min-height: 46px;          /* above the WCAG 2.5.5 target, not a round number */
  padding: .6875rem 1rem; font: inherit; font-size: 1rem; font-weight: 650;
  border: 1px solid transparent; border-radius: var(--r-sm);
  cursor: pointer; text-decoration: none; letter-spacing: .005em;
}
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary:hover { filter: brightness(1.06); }
.btn-primary[disabled] { opacity: .6; cursor: progress; }
.btn-google {
  margin-top: .75rem; background: var(--bg-elevated);
  color: var(--text); border-color: var(--border);
}
.btn-google:hover { border-color: var(--text-dim); }
/* The header's sign-in: an affordance, not a call to action — it must not compete with the one
   button on the page that we actually want a stranger to press. */
.btn-quiet {
  width: auto; min-height: 42px; padding: .4375rem 1rem;
  font-size: .9375rem; background: transparent;
  color: var(--link); border-color: var(--border);
  /* Without this it breaks to "Sign / in" on a phone, where the header is tightest and a
     two-line button in the corner looks like a mistake. */
  white-space: nowrap; flex: 0 0 auto;
}
.btn-quiet:hover { background: var(--bg-panel); }
.linkbtn {
  padding: 0; font: inherit; font-size: .9375rem; font-weight: 600;
  color: var(--link); background: none; border: 0;
  cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
}
.or {
  display: flex; align-items: center; gap: .75rem;
  margin: 1.25rem 0 0; color: var(--text-dim); font-size: .8125rem;
}
.or::before, .or::after { content: ""; flex: 1; height: 1px; background: var(--border-subtle); }

/* ---- small print ---- */
.notice {
  margin: 1rem 0 0; padding: .75rem .875rem;
  font-size: .8125rem; line-height: 1.5; color: var(--text-muted);
  background: var(--bg-panel); border: 1px solid var(--border-subtle); border-radius: var(--r-sm);
}
.card-request .notice { background: var(--bg); }
.notice a, .foot a, .lead a { color: var(--link); }
.alt { margin-top: 1.125rem; margin-bottom: 0; font-size: .9375rem; }
.sep { margin: 0 .5rem; color: var(--text-dim); }

.foot {
  margin-top: clamp(2.5rem, 7vw, 4rem); padding-top: 1.25rem;
  border-top: 1px solid var(--border-subtle);
  font-size: .8125rem; color: var(--text-dim);
}
.foot nav { margin-bottom: .5rem; }
.foot-note { margin: 0; font-size: .8125rem; color: var(--text-dim); max-width: 42rem; }

/* ---- what is inside: the destinations, with the application's own icons ---- */
.section-h {
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(1.05rem, 2.4vw, 1.2rem);
  margin: 2.5rem 0 1.25rem; padding-bottom: .625rem;
  border-bottom: 1px solid var(--border-subtle); color: var(--text);
  letter-spacing: -.005em;
}
.section-h.claim {
  font-size: clamp(1.35rem, 3.2vw, 1.75rem); border-bottom: 0;
  margin-top: 3rem; padding-bottom: 0; letter-spacing: -.015em;
}
.claimblock .section-h.claim { margin-top: 0; text-align: center; }
.lead-open { margin-bottom: 0; }

/* The intro band spans the full width, above the two columns: twelve tiles two-abreast in a narrow
   column read as a list, four-abreast across the page read as the SCOPE of the thing — which is
   the actual argument for asking for access. */
.intro {
  max-width: 68rem; margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 2.5rem) clamp(1rem, 4vw, 2rem) 0;
}
.intro .lead-open {
  max-width: 46rem; margin: 0 auto; text-align: center;
  font-size: clamp(1.02rem, 2.1vw, 1.14rem);
}
.intro .section-h { text-align: center; border-bottom: 0; margin-bottom: 1rem; }

.tiles {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: .75rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
.intro .tiles-more { text-align: center; max-width: 46rem; margin: 1rem auto 0; }
.tile {
  display: grid; grid-template-columns: auto 1fr; gap: .25rem .875rem;
  align-items: start;
  padding: .875rem .9375rem;
  background: var(--bg-panel);
  border: 1px solid var(--border-subtle);
  border-radius: var(--r-sm);
}
/* ENLARGED. The sidebar draws these at 19px because it is a dense list of thirty destinations; here
   twelve of them are the main visual argument of the page, so they get room. Same paths, same
   stroke geometry — a landing page that redraws the product's icons is showing a different product. */
.tile-ico {
  grid-row: 1 / span 2;
  width: 34px; height: 34px;
  fill: none; stroke: var(--accent); stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
  margin-top: .0625rem;
}
.tile-name { font-weight: 650; font-size: .9375rem; color: var(--text); line-height: 1.3; }
.tile-blurb { font-size: .8125rem; line-height: 1.45; color: var(--text-muted); }
.tiles-more { margin: .875rem 0 0; font-size: .8125rem; color: var(--text-dim); }

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}

/* ---- the analytics consent prompt ---------------------------------------------------------
   Same markup and the same module as the application (web/js/consent.js), restyled here because
   this page deliberately does not load the 150 KB application stylesheet that carries the rest of
   it. Refusing sits on the left and is exactly as easy as accepting — a "reject" that is harder to
   reach than "allow" is not consent, and regulators say so. */
.consent-bar {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 240;
  background: var(--bg-panel); border-top: 1px solid var(--border);
  box-shadow: 0 -6px 24px rgba(74, 60, 30, 0.10);
  padding: 14px 18px calc(14px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap; justify-content: center;
}
.consent-text { margin: 0; flex: 1 1 460px; max-width: 760px; font-size: 13.5px; line-height: 1.6;
  color: var(--text-muted); }
.consent-text strong { color: var(--text); }
.consent-text a { color: var(--link); }
.consent-acts { display: flex; gap: 10px; flex: 0 0 auto; }
.consent-bar button { font: inherit; font-size: 14px; padding: 9px 20px; border-radius: var(--r-sm);
  cursor: pointer; border: 1px solid var(--border); background: var(--bg-elevated);
  color: var(--text); min-width: 118px; }
.consent-bar button:hover { border-color: var(--accent); }
.consent-yes { border-color: var(--accent) !important; background: var(--accent) !important;
  color: var(--on-accent) !important; font-weight: 600; }
@media (max-width: 560px) {
  .consent-bar { gap: 12px; padding: 12px 14px calc(12px + env(safe-area-inset-bottom)); }
  .consent-acts { width: 100%; }
  .consent-bar button { flex: 1; min-width: 0; }
}

/* A footer control that must read as one of the footer's links, not as a button dropped into it. */
.foot-link {
  font: inherit; background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--text-dim); text-decoration: underline; text-underline-offset: 2px;
}
.foot-link:hover { color: var(--link); }
