/* KG's & INCH's - reset, typography, layout primitives */

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

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

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

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

/* Editor content can carry a YouTube or Maps embed, and an <iframe> has a
   default width of 300px that does not shrink with the column it sits in. */
iframe, embed, object { max-width: 100%; }

h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.02em;
  color: var(--navy);
  margin: 0;
  text-wrap: balance;
}

/* The scale steps down clearly at every level. h2 was set nearly as large as
   h1, so a section title beside a page title read as the louder of the two. */
h1 { font-size: clamp(1.9rem, 3.6vw, 3rem); }
h2 { font-size: clamp(1.4rem, 2.4vw, 1.9rem); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }

p { margin: 0; }

a { color: var(--green-deep); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
  outline: 2px solid var(--green-deep);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

ul, ol { margin: 0; padding-left: 1.25rem; }

/* ---------- layout ---------- */

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

.container-narrow { max-width: var(--container-narrow); }

/* Section rhythm.
   A page alternates ground so it has a pulse instead of reading as one long
   scroll of white. .section-alt is not a flat fill - it carries a wash of the
   brand green off one corner, and hairlines top and bottom so the change of
   ground looks intended rather than like a rendering seam. */
.section { padding-block: clamp(var(--sp-6), 4.5vw, var(--sp-7)); }
.section-tight { padding-block: clamp(var(--sp-5), 3.5vw, var(--sp-6)); }

.section-alt {
  position: relative;
  background:
    radial-gradient(80% 120% at 100% 0%, rgba(113, 169, 48, .10), rgba(113, 169, 48, 0) 62%),
    radial-gradient(70% 110% at 0% 100%, rgba(26, 66, 120, .05), rgba(26, 66, 120, 0) 60%),
    var(--surface-2);
  border-block: 1px solid var(--line);
}

.stack { display: flex; flex-direction: column; }
.stack-2 { gap: var(--sp-2); }
.stack-3 { gap: var(--sp-3); }
.stack-4 { gap: var(--sp-4); }
.stack-5 { gap: var(--sp-5); }
.stack-6 { gap: var(--sp-6); }
.stack-7 { gap: var(--sp-7); }

.row { display: flex; align-items: center; gap: var(--sp-4); }
.row-between { justify-content: space-between; }
.wrap { flex-wrap: wrap; }

.grid { display: grid; gap: var(--sp-5); }
/* The track minimum is capped at the width of the grid itself. Without the
   min() a 280px track stays 280px inside a 272px column - which is all a
   320px phone leaves once the container and a card's padding are taken off -
   and the whole page picks up a sideways scroll. */
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fill, minmax(min(230px, 100%), 1fr)); }

.center { text-align: center; }
.mx-auto { margin-inline: auto; }
.measure { max-width: 62ch; }

/* ---------- section heading ---------- */

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--green-deep);
  margin: 0;
}

.section-head { display: flex; flex-direction: column; gap: var(--sp-3); }
.section-head p.lede { color: var(--ink-2); font-size: var(--step-1); max-width: 60ch; }
.section-head.center { align-items: center; }

/* A heading with an action beside it. This is a separate class rather than
   .section-head.row because .row does not set flex-direction, so .section-head
   would keep winning with column and the two would fight. */
.section-head-inline {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-4);
}
.section-head.center p.lede { text-align: center; }

.rule {
  width: 56px; height: 3px; border: 0; border-radius: 2px;
  background: var(--green); margin: 0;
}
.section-head.center .rule { margin-inline: auto; }

/* ---------- utility ---------- */

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: var(--sp-4); top: -100px;
  background: var(--navy); color: #fff;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-sm); z-index: 200;
  transition: top .15s var(--ease);
}
.skip-link:focus { top: var(--sp-4); }

.scroll-x { overflow-x: auto; }

/* ---------- body copy ----------
   Paragraph colour and size used to be set inline on each <p>, which is how
   the first paragraph on About ended up a step larger than the ones under it.
   One class now governs a whole block of running text. */

.body-copy { display: flex; flex-direction: column; gap: var(--sp-4); }
.body-copy p { color: var(--ink-2); font-size: var(--step-0); }
.body-copy strong { color: var(--navy); font-weight: 600; }


/* ---------- motion ----------
   Two kinds of movement, and nothing else moves on its own:

   1. the inner-page header animates in on load, so a page arrives rather than
      appears;
   2. the blocks below the fold fade up the first time they are scrolled to.

   The reveal list here has to match REVEAL_SELECTOR in main.js - the CSS hides
   the elements and the script is what brings them back. Both are behind .js,
   which is set by an inline script in <head>, so a browser that never runs the
   script shows the page as plain, fully-visible HTML. */

@keyframes kgs-rise {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

.js .page-hero .eyebrow { animation: kgs-rise .5s var(--ease) both; }
.js .page-hero h1       { animation: kgs-rise .55s .07s var(--ease) both; }
.js .page-hero .lede    { animation: kgs-rise .6s .14s var(--ease) both; }

.js [data-reveal],
.js .section-head,
.js .card,
.js .value-card,
.js .step,
.js .clinic-card,
.js .quote,
.js .contact-row,
.js .aside-card,
.js .product-figure,
.js .enquiry-box {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .55s var(--ease), transform .55s var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}

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

/* A card that has arrived hands its transition back to its own hover rules,
   or the lift would inherit the slow reveal timing. */
.js .card.is-in,
.js .value-card.is-in {
  transition: box-shadow .2s var(--ease), transform .2s var(--ease),
              border-color .2s var(--ease);
}

.link-more {
  display: inline-block;
  transition: transform .18s var(--ease), color .18s var(--ease);
}
.link-more:hover { transform: translateX(3px); }

/* The header tightens and lifts off the page once you scroll past the top. */
.site-header {
  transition: box-shadow .25s var(--ease), background-color .25s var(--ease);
}
.site-header.is-stuck {
  box-shadow: 0 1px 0 rgba(27, 33, 25, .06), 0 10px 30px -22px rgba(27, 33, 25, .45);
}
.site-header .header-inner {
  transition: min-height .25s var(--ease);
}
.site-header.is-stuck .header-inner { min-height: 74px; }
.site-header .brand img { transition: height .25s var(--ease); }
.site-header.is-stuck .brand img { height: 46px; }

@media (prefers-reduced-motion: reduce) {
  .js .page-hero .eyebrow,
  .js .page-hero h1,
  .js .page-hero .lede { animation: none; }

  .js [data-reveal],
  .js .section-head,
  .js .card,
  .js .value-card,
  .js .step,
  .js .clinic-card,
  .js .quote,
  .js .contact-row,
  .js .aside-card,
  .js .product-figure,
  .js .enquiry-box {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .link-more:hover { transform: none; }
  .site-header,
  .site-header .header-inner,
  .site-header .brand img { transition: none; }
}

/* A short green rule leads every eyebrow, so the label above a heading reads
   as part of one system across all the pages. */
.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.6em;
}
.eyebrow::before {
  content: "";
  width: 18px;
  height: 2px;
  border-radius: 1px;
  background: var(--green);
  flex: none;
}
.section-head.center .eyebrow { justify-content: center; }
