/* Site-wide styling — hand-authored, no framework (§2.7, task 041).
   Single-column centered layout, accessible focus indicators per NFR-3
   (WCAG 2.2 AA), AA-contrast colors. Implements the §5.7 visual design
   system (task 046): self-hosted Inter, brand palette, two-tone wordmark,
   responsive hamburger nav, hero, rounded forms/buttons, link affordance
   rule, sticky footer, and zebra-striped result tables. Every rule is
   named for its job. */

/* §5.7.3 Self-hosted Inter (SIL OFL 1.1) — woff2 committed under
   public/fonts/, served by the /public/ @fastify/static mount. No CDN, no
   npm, no build step. font-display:swap so body text paints immediately in
   the fallback stack while the webfont loads. Weights: 400 body, 600 form
   labels, 700 headings/wordmark. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/public/fonts/Inter-Regular.woff2") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/public/fonts/Inter-SemiBold.woff2") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/public/fonts/Inter-Bold.woff2") format("woff2");
}

:root {
  --color-text: #1a1a1a;
  --color-bg: #faf7f0;  /* §5.7.7 warm paper (was #ffffff); AA pairs re-checked vs this bg in §5.7.1 */
  --color-muted: #555555;
  /* --color-accent (blue) is superseded for links/buttons by the §5.7.1
     brand tokens below; retained for reference. Badge/notice tokens unchanged. */
  --color-accent: #0a4fb3;
  --color-accent-text: #ffffff;
  --color-border: #cccccc;
  --color-pass-bg: #1f6f3a;
  --color-fail-bg: #a01432;
  --color-warn-bg: #815400;
  --color-badge-text: #ffffff;
  --color-notice-bg: #fff8e1;
  --color-notice-border: #a07a00;
  /* §5.7.1 brand palette — verified AA on white. Ratios live in
     architecture §5.7.1 and the keyboard-walkthrough contrast row. */
  --color-brand: #1f6f3a;       /* corporate green — wordmark outer, hero lead emphasis, links, focus */
  --color-brand-soft: #2e8b57;  /* lighter green — wordmark "Ready" ONLY (large text ≥3:1) */
  --color-btn-bg: #1a1a1a;      /* primary button background (white text) */
  --color-btn-bg-hover: #333333;/* button hover background */
  --color-row-stripe: #f0ebe0;  /* §5.7.7 warm zebra alternate-row background (was cool #f1f5f9) */
}

* { box-sizing: border-box; }

body {
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.5;
  margin: 0;
  /* §5.7.5(a) sticky footer: full-height flex column so the footer pins to
     the viewport bottom on short pages without overlapping content. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

header, main, footer {
  width: 100%;
  max-width: 48rem;
  margin: 0 auto;
  padding: 1rem;
}

/* main flex-grows to push the footer down; width:100% + margin auto keep the
   centered max-width intact inside the body flex column. It is itself a flex
   column so a page can claim the full grown height (the §5.7.7 home hero uses
   auto margins to center vertically); ordinary pages stack from the top. */
main { flex: 1 0 auto; display: flex; flex-direction: column; }
header, footer { flex: none; }

/* §5.7.7 footer: two columns — copyright left, LLMfirst brand link right;
   wraps to a stack on narrow widths. */
footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
}

footer p { margin: 0; }

/* §5.7.4 header: wordmark left, nav right, hamburger appears on narrow. */
header nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
}

header nav ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}

/* §5.7.4 two-tone wordmark — outer segments brand green, middle "Ready"
   lighter. Colors come from CSS classes (CSP forbids inline style=). */
.wordmark {
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: -0.02em;
  color: var(--color-brand);
}

.wordmark-soft { color: var(--color-brand-soft); }

/* Hamburger toggle — hidden by default so the nav is fully reachable without
   JS (links stay visible). nav.js removes [hidden] and adds .nav-enhanced,
   which the narrow-viewport media query uses to collapse the menu. */
.nav-toggle {
  display: none;
  align-items: center;
  background: none;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: 0.5rem 0.6rem;
  cursor: pointer;
  color: var(--color-brand);
}

.nav-toggle-bars,
.nav-toggle-bars::before,
.nav-toggle-bars::after {
  content: "";
  display: block;
  width: 1.25rem;
  height: 2px;
  background: currentColor;
}

.nav-toggle-bars { position: relative; }
.nav-toggle-bars::before { position: absolute; top: -0.4rem; left: 0; }
.nav-toggle-bars::after { position: absolute; top: 0.4rem; left: 0; }

a { color: var(--color-brand); text-decoration: underline; }

/* §5.7.2 link affordance — default-on, opt-out. In-prose links keep the
   underline (green-on-body-text is only ~2.8:1, below F73's 3:1). Standalone
   chrome links drop it and gain a non-color hover cue. */
.wordmark,
header nav a,
nav[aria-label="Breadcrumb"] a,
footer a,
a.cta,
h1 a, h2 a, h3 a {
  text-decoration: none;
}

.wordmark:hover,
header nav a:hover,
nav[aria-label="Breadcrumb"] a:hover,
footer a:hover,
a.cta:hover,
h1 a:hover, h2 a:hover, h3 a:hover {
  text-decoration: underline;
}

/* §5.7.8 breadcrumb presentation — the kept multi-level breadcrumbs
   (category-hub: Home › {category}; signal page: Home › Signals › {category} ›
   {signal}) render as a number-free, single horizontal row that wraps when
   narrow. Style only: the <ol>/<li> semantics, aria-label="Breadcrumb",
   aria-current="page", and the signal-page BreadcrumbList JSON-LD are untouched. */
nav[aria-label="Breadcrumb"] ol {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
}

/* Decorative `›` between crumbs — CSS-generated content, never a DOM text node,
   never a link, never inline style (CSP). Muted color + small horizontal margin
   set it apart from the crumb text without being announced by assistive tech. */
nav[aria-label="Breadcrumb"] li + li::before {
  content: "\203A"; /* › single right-pointing angle quotation mark */
  margin: 0 0.5rem;
  color: var(--color-muted);
}

/* WCAG 2.2 AA focus indicator: always-visible 2px outline. NFR-3, FR-49. */
:focus-visible {
  outline: 2px solid var(--color-brand);
  outline-offset: 2px;
}

h1 { font-size: 1.75rem; line-height: 1.25; }
h2 { font-size: 1.25rem; line-height: 1.3; }

/* §5.7.7 home hero — the lead line + scan form fill the flex `main` and center
   both axes. auto block margins absorb main's spare height (vertical centering);
   text-align + the form's own auto margins handle the horizontal axis. Only the
   home article carries .hero, so other pages keep their top-aligned flow. */
.hero {
  margin-top: auto;
  margin-bottom: auto;
  text-align: center;
}

/* The lead line is the page's only h1 (document structure) but styled as a lead,
   not a display headline (§5.7.7): regular weight, near-black body color. */
.hero-lead {
  font-size: 1.75rem;
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--color-text);
  margin: 0 auto 1.5rem;
  max-width: 32rem;
}

/* Green emphasis on "155" and "signals" — bold + slightly larger, brand green.
   Presentational only; the words live in strings.js (NFR-4) and the color comes
   from a class, never inline style= (CSP). */
.lead-em {
  font-weight: 700;
  font-size: 1.15em;
  color: var(--color-brand);
}

form p { margin: 1rem 0; }

/* §5.7.5(c) scan + email-gate forms share centered, rounded styling. */
#scan-form,
#scan-gate-form {
  max-width: 28rem;
  margin-left: auto;
  margin-right: auto;
}

label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.25rem;
}

input[type="url"],
input[type="email"] {
  width: 100%;
  font-size: 1rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: 8px;
}

/* Tint native checkboxes/radios with the corporate green (§5.7.1 --color-brand)
   instead of the browser default blue. Keeps the native control so keyboard/AT
   behavior and the focus ring stay intact (NFR-3, FR-49). */
input[type="checkbox"],
input[type="radio"] {
  accent-color: var(--color-brand);
}

button[type="submit"] {
  font-size: 1rem;
  padding: 0.6rem 1.25rem;
  background: var(--color-btn-bg);
  color: var(--color-accent-text);
  border: 1px solid var(--color-btn-bg);
  border-radius: 8px;
  cursor: pointer;
  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
}

button[type="submit"]:hover {
  background: var(--color-btn-bg-hover);
  border-color: var(--color-btn-bg-hover);
}

button[type="submit"]:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.disclaimer {
  color: var(--color-muted);
  font-size: 0.875rem;
  border-left: 3px solid var(--color-border);
  padding: 0.25rem 0.75rem;
}

#scan-cached-notice,
#scan-slow-notice {
  background: var(--color-notice-bg);
  border: 1px solid var(--color-notice-border);
  padding: 0.5rem 0.75rem;
  border-radius: 4px;
}

/* Result tables (scan + report) share cell layout and §5.7.5(b) zebra. */
#scan-results,
#report-signals-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 1rem;
}

#scan-results th,
#scan-results td,
#report-signals-table th,
#report-signals-table td {
  text-align: left;
  padding: 0.5rem;
  border-bottom: 1px solid var(--color-border);
}

#scan-results tbody tr:nth-child(even),
#report-signals-table tbody tr:nth-child(even) {
  background: var(--color-row-stripe);
}

.badge {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  color: var(--color-badge-text);
  font-size: 0.875rem;
}

.badge-pass { background: var(--color-pass-bg); }
.badge-fail { background: var(--color-fail-bg); }
.badge-skipped,
.badge-timeout,
.badge-error { background: var(--color-warn-bg); }

/* §5.7.8 hero lead single-line at desktop — once the viewport reaches the
   centered container's 48rem cap, the content column is at full width, so drop
   the 32rem wrap cap and forbid wrapping to hold "Scan any URL against 155
   AI-readiness signals" on one line. Below this width the lead keeps its 32rem
   cap and wraps naturally (no forced nowrap → no overflow / horizontal scroll
   on narrow/mobile viewports). */
@media (min-width: 48rem) {
  .hero-lead {
    max-width: none;
    white-space: nowrap;
  }
}

/* §5.7.4 narrow viewport — only when nav.js has enhanced the nav do we show
   the toggle and collapse the menu behind it. Without JS .nav-enhanced is
   absent, so the links stay visible at every width. */
@media (max-width: 40rem) {
  .hero-lead { font-size: 1.5rem; }

  .nav-enhanced .nav-toggle { display: inline-flex; }

  .nav-enhanced .nav-menu { display: none; }

  .nav-enhanced .nav-menu.nav-menu--open {
    display: flex;
    flex-direction: column;
    width: 100%;
  }
}

/* §5.7.9 motion convention (first animation). While the preview streams,
   scan.js adds .is-scanning to the H1 "Scanning" word, pulsing its color
   between the two brand greens; it removes the class on the SSE done/error
   frame so the word reverts to the normal heading color. Both greens hold AA
   at the H1 large-text size on the §5.7.1 paper bg (≥3:1 large). Default
   .scan-heading-word (no class) inherits the normal --color-text. */
@keyframes scan-heading-pulse {
  0%, 100% { color: var(--color-brand); }
  50% { color: var(--color-brand-soft); }
}

.scan-heading-word.is-scanning {
  animation: scan-heading-pulse 1.4s ease-in-out infinite;
}

/* §5.7.9 / WCAG 2.2.2 — the loop runs longer than 5s and is decorative, so
   under reduced-motion drop the animation and hold a static brand green. */
@media (prefers-reduced-motion: reduce) {
  .scan-heading-word.is-scanning {
    animation: none;
    color: var(--color-brand);
  }
}
