/* OpenKarl Auth, "The Front Door" (DESIGN.md, openkarl-auth#74): the shared
   palette and components for every auth.karlfindlay.com page (#55 login, #57
   the rest). Health v3's warm paper and ink, one borderless card, and one
   colour per app, used as a signal of which app you are signing in to.
   - Every token pair below is measured for WCAG AA by
     tests/auth-pages-contrast.test.ts. Change a value and the test re-measures it.
   - Every value must equal its row in DESIGN.md (tests/design-md.test.ts).
   - Pages must not add a colour literal outside this :root block (the
     contrast test enforces that). */
:root {
  color-scheme: light;    /* light only, like Findlay Home, MealPlan and Health */
  /* Ground and ink (DESIGN.md §2.1) */
  --bg: #f7f5f2;          /* page: warm paper */
  --card: #ffffff;        /* card, inputs, QR quiet zone */
  --subtle: #f4f2ee;      /* inset blocks (MFA secret, recovery codes), secondary-button hover */
  --line: #e8e5e0;        /* hairlines only (QR frame, inset edge, spinner track), never a card border */
  --border: #858a86;      /* input / secondary-button boundary: 3.5:1 on --card */
  --text: #1f2421;        /* ink: headings, body, input text */
  --muted: #656a67;       /* subtitle, labels, hints, footer copy: 5.1:1 on --bg */
  --accent: #1f2421;      /* ink: primary button, focus ring, checkbox */
  --accent-hover: #3a403c;
  --on-accent: #faf7f6;   /* cream label on ink */
  --link: #1b5cea;        /* the portfolio's link blue: 5.1:1 on --bg */
  /* Status, functional only (DESIGN.md §2.2) */
  --danger: #9f403d;      /* destructive button */
  --danger-hover: #86302d;
  --error-bg: #f5ecec;
  --error-text: #9f403d;  /* 5.5:1 on --error-bg */
  --success-bg: #ebf1eb;
  --success-text: #337536;
  --warn-bg: #f3efe6;
  --warn-text: #856007;
  /* App identity (DESIGN.md §2.3): tile colour and the mark on it, per key in
     public/js/app-name.js APPS. The mark is large text on its tile, so ≥3:1. */
  --app-family: #1a1a1a;     --app-family-on: #faf7f6;
  --app-health: #2e9e6b;     --app-health-on: #ffffff;
  --app-mealplan: #c2661b;   --app-mealplan-on: #ffffff;
  --app-dinosquad: #452c14;  --app-dinosquad-on: #f0dfa8;
  --app-audiobooks: #2ecc71; --app-audiobooks-on: #003919;
  --app-finance: #535252;    --app-finance-on: #faf7f6;
  --app-sowhat: #4f46e5;     --app-sowhat-on: #ffffff;
  --app-provance: #2a1449;   --app-provance-on: #fc8613;
  --app-portal: #5b5bd6;     --app-portal-on: #ffffff;
  --app-karlfindlay: #181614; --app-karlfindlay-on: #cc785c;
  /* Health v3's dual soft shadow, tinted with the ink (DESIGN.md §4) */
  --shadow-card: 0 1px 2px rgba(31, 36, 33, 0.04), 0 8px 24px rgba(31, 36, 33, 0.05);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { background: var(--bg); }
body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; background: var(--bg); color: var(--text); display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; min-height: 100dvh; padding: 1.5rem 1rem; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }

/* The wordmark: the OpenKarl mark and name, above the card (DESIGN.md §5). */
.brand { display: flex; align-items: center; gap: 0.625rem; width: 100%; max-width: 400px; margin-bottom: 1.25rem; font-size: 1.0625rem; font-weight: 800; letter-spacing: -0.02em; color: var(--text); }
.brand-mark { display: block; width: 28px; height: 28px; }

.card { width: 100%; max-width: 400px; padding: 2rem; background: var(--card); border-radius: 20px; box-shadow: var(--shadow-card); }
@media (max-width: 479.98px) { .card { padding: 1.5rem; } }

/* The requesting app's tile. Hidden until applyAppBrand() (js/app-name.js)
   sets data-app from the fixed APPS table; [data-app] only selects tokens. */
.app-tile { display: flex; align-items: center; justify-content: center; width: 48px; height: 48px; margin-bottom: 1rem; border-radius: 14px; background: var(--app, var(--accent)); color: var(--app-on, var(--on-accent)); font-size: 1.375rem; font-weight: 800; letter-spacing: -0.02em; line-height: 1; }
.app-tile[hidden] { display: none; }
.app-tile svg { display: none; width: 28px; height: 28px; fill: currentColor; }
.app-tile[data-app="family"] .app-glyph { display: block; }
[data-app="family"] { --app: var(--app-family); --app-on: var(--app-family-on); }
[data-app="health"] { --app: var(--app-health); --app-on: var(--app-health-on); }
[data-app="mealplan"] { --app: var(--app-mealplan); --app-on: var(--app-mealplan-on); }
[data-app="dinosquad"] { --app: var(--app-dinosquad); --app-on: var(--app-dinosquad-on); }
[data-app="audiobooks"] { --app: var(--app-audiobooks); --app-on: var(--app-audiobooks-on); }
[data-app="finance"] { --app: var(--app-finance); --app-on: var(--app-finance-on); }
[data-app="sowhat"] { --app: var(--app-sowhat); --app-on: var(--app-sowhat-on); }
[data-app="provance"] { --app: var(--app-provance); --app-on: var(--app-provance-on); }
[data-app="portal"] { --app: var(--app-portal); --app-on: var(--app-portal-on); }
[data-app="karlfindlay"] { --app: var(--app-karlfindlay); --app-on: var(--app-karlfindlay-on); }

h1 { font-size: 1.5rem; font-weight: 700; letter-spacing: -0.02em; color: var(--text); margin-bottom: 1.5rem; line-height: 1.25; }
h2 { font-size: 1rem; font-weight: 700; color: var(--text); margin-bottom: 0.75rem; }
.subtitle { font-size: 0.9375rem; color: var(--muted); margin: -1.125rem 0 1.5rem; line-height: 1.45; }
label { display: block; font-size: 0.8125rem; font-weight: 600; color: var(--muted); margin-bottom: 0.375rem; }
.optional { font-weight: 400; }
input { width: 100%; min-height: 44px; padding: 0.6875rem 0.875rem; background: var(--card); border: 1px solid var(--border); border-radius: 12px; color: var(--text); font: inherit; font-size: 1rem; margin-bottom: 1rem; }
input::placeholder { color: var(--muted); }
input:focus-visible { outline: 2px solid var(--accent); outline-offset: 0; border-color: var(--accent); }
input:disabled { background: var(--subtle); color: var(--muted); }
.hint { font-size: 0.875rem; color: var(--muted); margin-top: -0.625rem; margin-bottom: 1rem; line-height: 1.4; }
button { display: block; width: 100%; min-height: 44px; padding: 0.8125rem 1rem; background: var(--accent); color: var(--on-accent); border: 1px solid transparent; border-radius: 12px; font: inherit; font-size: 1rem; font-weight: 700; line-height: 1.25; cursor: pointer; }
button:hover { background: var(--accent-hover); }
button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
button:disabled { opacity: 0.6; cursor: not-allowed; }
button.secondary { background: var(--card); border-color: var(--border); color: var(--text); }
button.secondary:hover { background: var(--subtle); border-color: var(--accent); }
button.danger { background: var(--danger); }
button.danger:hover { background: var(--danger-hover); }
/* Loading (DESIGN.md §5): a request in flight sets aria-busy on its button,
   which keeps full opacity and draws a spinner in the label colour. */
button[aria-busy="true"] { opacity: 1; cursor: progress; }
button[aria-busy="true"]::before { content: ""; display: inline-block; width: 1em; height: 1em; margin-right: 0.5em; vertical-align: -0.15em; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: auth-spin 0.8s linear infinite; }
@keyframes auth-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { button[aria-busy="true"]::before { animation-duration: 2.4s; } }
.error { background: var(--error-bg); color: var(--error-text); padding: 0.75rem 0.875rem; border-radius: 12px; font-size: 0.9375rem; font-weight: 500; line-height: 1.4; margin-bottom: 1rem; display: none; }
.success { background: var(--success-bg); color: var(--success-text); padding: 0.75rem 0.875rem; border-radius: 12px; font-size: 0.9375rem; margin-bottom: 1rem; line-height: 1.4; display: none; }
.warn { background: var(--warn-bg); color: var(--warn-text); padding: 0.75rem 0.875rem; border-radius: 12px; font-size: 0.9375rem; margin-bottom: 1rem; line-height: 1.4; }
.footer { margin-top: 1rem; font-size: 0.9375rem; color: var(--muted); }
.footer p { display: flex; align-items: center; flex-wrap: wrap; column-gap: 0.25rem; }
/* A leading link's text lines up with the card's other text; its 44px hit
   area still extends past it. */
.footer p > a:first-child { margin-left: -0.5rem; }
/* Every standalone link is a 44px-tall target (openkarl-auth#55, #57).
   Links inside running prose (the consent sentence, the privacy policy
   body) are inline targets and exempt under WCAG 2.5.8. */
.footer a, .nav a { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 0.5rem; color: var(--link); font-weight: 600; text-decoration: underline; text-underline-offset: 0.15em; border-radius: 0.375rem; }
.footer a:hover, .nav a:hover { color: var(--accent-hover); }
a { color: var(--link); }
a:hover { color: var(--accent-hover); }
a:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
