/*
  The Lawneds, base layer
  Reset, typography, layout primitives, band rhythm, focus, reduced motion.
  Authority: plans/lawneds-brand-system.md
*/

/* ---------- Reset ---------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body,
h1, h2, h3, h4, h5, h6,
p, figure, blockquote, dl, dd {
  margin: 0;
}

ul[class], ol[class] { list-style: none; margin: 0; padding: 0; }

img, picture, svg, video {
  display: block;
  max-width: 100%;
}

input, button, textarea, select { font: inherit; color: inherit; }

button { background: none; border: 0; padding: 0; cursor: pointer; }

/* ---------- Document ---------- */

body {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  color: var(--charcoal);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ---------- Typography (section 5.2) ----------
   Headings are navy. Body is charcoal, and charcoal is the only body colour
   on light backgrounds (section 4.3 rule 5). */

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  color: var(--navy);
  text-wrap: balance;
}

h1 { font-size: var(--fs-h1); line-height: var(--lh-h1); letter-spacing: var(--ls-h1); font-weight: 700; }
h2 { font-size: var(--fs-h2); line-height: var(--lh-h2); letter-spacing: var(--ls-h2); font-weight: 700; }
h3 { font-size: var(--fs-h3); line-height: var(--lh-h3); font-weight: 700; }

/* H4 is the one heading at Inter 600, per the scale in section 5.2. */
h4 {
  font-family: var(--font-body);
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  font-weight: 600;
}

p { text-wrap: pretty; }

.lead      { font-size: var(--fs-lead);    line-height: var(--lh-lead); }
.body-lg   { font-size: var(--fs-body-lg); line-height: var(--lh-body); }
.small     { font-size: var(--fs-small);   line-height: var(--lh-small); }
.caption   { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--slate); }

/* Prose. Left aligned in a centred column. Never justified (section 5.3). */
.prose {
  max-width: var(--measure-prose);
  text-align: left;
}
.prose > * + * { margin-top: var(--space-24); }

/* A prose block is one type size. Where a block opens with a lead-in paragraph
   it reads large throughout, rather than stepping down paragraph by paragraph:
   19px then 17px then 15px inside one run is what "it deforms the website" was
   describing. Set on the container, so it inherits to paragraphs, lists and
   inline elements alike, and keyed on :has so it also reaches the Solution and
   Sector body copy, which lives in post content and carries the same markup.
   Blocks with no lead-in are untouched, which is what keeps the small byline
   and share row on an Insight article small. */
.prose:has(> p.body-lg) { font-size: var(--fs-body-lg); }

/* ---------- Links (section 4.3 rule 2) ----------
   Inline links are --accent-strong. Never --accent. */

a {
  color: var(--accent-strong);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* Link hover: underline appears, 150ms (section 10.2) */
.link-inline {
  text-decoration: none;
  font-weight: 500;
  transition: text-decoration-color var(--dur-link) var(--ease);
  text-decoration: underline;
  text-decoration-color: transparent;
}
.link-inline:hover { text-decoration-color: currentColor; }

/* ---------- Focus (section 12.1, 11.1). 3px ring, never removed. ----------

   Composite ring: 2px white inner offset, then a 3px accent-strong outline.
   Section 11.1 asks for exactly this, and it is what makes one ring work on
   every background:

     on white  the accent-strong outline carries it            5.78:1
     on navy   the WHITE INNER RING carries it                11.60:1
               (accent-strong alone on navy is 2.01:1, and WCAG 2.2 SC 1.4.11
                requires 3:1 of a focus indicator: a hard failure)

   Do NOT reduce this to a bare `outline` with an offset. The offset gap then
   shows whatever is behind it, so on any navy surface the emerald ring sits
   directly on navy at 2.01:1. An earlier draft did that and scoped a white
   override to an opt-in `.on-navy` class, which meant every template that used
   .band--navy and forgot the extra class shipped an AA failure. The ring must
   not depend on the author remembering anything. */

:focus-visible {
  outline: var(--focus-ring) solid var(--accent-strong);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--white);   /* the 2px white inner offset */
}

/* Skip link (section 12.1) */
.skip-link {
  position: absolute;
  left: var(--space-8);
  top: var(--space-8);
  z-index: 100;
  padding: var(--space-8) var(--space-16);
  background: var(--navy);
  color: var(--white);
  border-radius: var(--radius-sm);
  transform: translateY(-200%);
}
.skip-link:focus { transform: translateY(0); }

/* ---------- Layout (section 6.2, 6.3) ---------- */

.container {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--outer-margin);
}

.content { max-width: var(--content-max); margin-inline: auto; }

/* Band: the vertical rhythm unit. Padding per section 6.4. */
.band {
  padding-block: var(--band-padding);
}

/* ---------- Background rhythm (section 4.4) ----------
   White, off-white, white, off-white. Two adjacent bands of the same colour
   is the most common way this breaks and it is instantly visible. The
   styleguide prints a check for it; see styleguide.html. */

.band--white     { background: var(--white); }
.band--off-white { background: var(--off-white); }

/* The two documented exceptions. */
.band--navy {
  background: var(--navy);
  color: var(--white);
}
.band--navy h1, .band--navy h2, .band--navy h3, .band--navy h4 { color: var(--white); }

/* ---------- Grid (section 6.3) ---------- */

.grid {
  display: grid;
  gap: var(--gutter);
  grid-template-columns: repeat(12, 1fr);
}

/* Common patterns from 6.3. Single column below 640px.
   cols-4 carries the four value cards and the four stat blocks; section 6.3
   does not name a 3/3/3/3 pattern, but the 12 column grid divides by four
   exactly and both bands are specified as four across. */
.cols-3 { display: grid; gap: var(--gutter); grid-template-columns: 1fr; }
.cols-2 { display: grid; gap: var(--gutter); grid-template-columns: 1fr; }
.cols-4 { display: grid; gap: var(--gutter); grid-template-columns: 1fr; }

@media (min-width: 640px) {
  .cols-3 { grid-template-columns: repeat(2, 1fr); }
  .cols-2 { grid-template-columns: repeat(2, 1fr); }
  .cols-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .cols-3 { grid-template-columns: repeat(3, 1fr); }
  .cols-4 { grid-template-columns: repeat(4, 1fr); }
}

/* Full band intro: 8 columns, offset 2, centred (section 6.3) */
.band-intro { max-width: var(--measure-prose); margin-inline: auto; text-align: center; }

/* Section header: 7 columns, left aligned (section 6.3) */
.section-header-wrap { max-width: 62ch; }

/* ---------- Icons (section 8.1) ----------
   Lucide, outline only, 1.5px stroke, never filled, never multicolour,
   never in a coloured circle or square (section 8.2). Stroke is set here
   centrally rather than per icon, so it cannot drift. */

.icon-sprite { display: none; }

.icon {
  width: var(--icon-size);
  height: var(--icon-size);
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icon-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--slate);
}
.icon--inline  { width: var(--icon-size-inline);  height: var(--icon-size-inline); }
.icon--feature { width: var(--icon-size-feature); height: var(--icon-size-feature); }
.icon--accent  { color: var(--accent-strong); }
.icon--on-navy { color: var(--white); }

/* ---------- Motion (section 10.1) ----------
   Three animations exist: fade up, fade left, fade right. 400 to 600ms,
   ease-out, on scroll into view, once, never repeating. Applied by js/reveal.js,
   which adds .is-revealed. No library.

   .reveal IS A WRAPPER. Never put it on an element that carries its own
   transition, and in practice that means never on .card. Both set the
   transition shorthand, components.css loads after this file, so .card would
   win and the reveal would silently run at 200ms: outside the permitted 400 to
   600ms band, and undetectable by reading the markup. Wrap instead:

     <div class="reveal reveal--up"><div class="card">...</div></div>          */

/* The opacity: 0 start state is applied ONLY when JS is running, via the .js
   class that reveal.js stamps on <html> before paint. Without this guard, a
   blocked, failed or slow-to-error script leaves every .reveal element
   permanently invisible: the content is simply gone. Script blocking is
   routine on the NHS, local-authority and school estates this firm sells to.
   No JS, no hiding: content renders at final state. */
.js .reveal {
  opacity: 0;
  transition:
    opacity var(--dur-reveal) var(--ease),
    transform var(--dur-reveal) var(--ease);
}
.js .reveal--up    { transform: translateY(24px); }
.js .reveal--left  { transform: translateX(-24px); }
.js .reveal--right { transform: translateX(24px); }

.js .reveal.is-revealed {
  opacity: 1;
  transform: none;
}

/* ---------- Reduced motion (section 10.4) ----------
   Disables every entrance animation and every transform. Content appears at
   final state and opacity 1 immediately. WCAG requirement, cheap, and
   routinely forgotten. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal {
    opacity: 1 !important;
    transform: none !important;
  }
}
