/* ==== SPP base styles ====
   Sitewide primitives, loaded on every page after tokens.css and before
   components.css. Blocks in this file, top to bottom: reset, typography
   primitives, buttons, section heading block, image placeholder,
   utilities, responsive heading scale, motion.

   Two-font system: Switzer (Fontshare CDN) for headings only, via
   .display / .h1-.h6 / .card-title; Inter (Google Fonts) for everything
   else, inherited from body. IBM Plex Mono was deliberately removed
   sitewide by the designer, never reintroduce it. */

/* ---- Reset ---- */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 103px; /* sticky header height: keeps smooth anchor
     scrolls from landing under the fixed bar. If the header height changes
     in components.css, update this value (and :target below) to match. */
}

body {
  font-family: var(--font-body);
  font-size: var(--type-body);
  line-height: 1.6;
  color: var(--text-primary);
  background: var(--bg-page);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

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

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

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

ul,
ol {
  list-style: none;
}

/* Extra anchor offset, slightly larger than the 103px header for
   breathing room when a section is jumped to by fragment link. */
:target {
  scroll-margin-top: 120px;
}

/* Reduced motion: disable smooth scrolling and collapse all animation and
   transition times to near zero. The motion block at the bottom of this
   file is additionally gated behind no-preference, this rule is the
   belt-and-braces catch-all for everything else. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---- Typography primitives ---- */
/* Headings use Switzer. Semibold (600) for display + section titles,
   Medium (500) for card titles. These classes are the ONLY place Switzer
   is applied; all other text inherits Inter from body. Sizes come from
   the --type-* tokens in tokens.css, edit them there. */
.display {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--type-display);
  line-height: 1.14;
  letter-spacing: -1.6px;
  color: var(--text-primary);
}

.h1 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--type-h1);
  line-height: 1.1;
  letter-spacing: -1px;
  color: var(--text-primary);
}

.h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--type-h2);
  line-height: normal; /* Figma: leading-[normal], Switzer renders ~1.32 */
  letter-spacing: -1.2px;
  color: var(--text-primary);
}

.h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--type-h3);
  line-height: normal; /* Figma: leading-[normal] */
  letter-spacing: 0;
  color: var(--text-primary);
}

.h4 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--type-h4);
  line-height: 1.3;
  color: var(--text-primary);
}

.h5 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--type-h5);
  line-height: 1.3;
  color: var(--text-primary);
}

.h6 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--type-h6);
  line-height: 1.3;
  color: var(--text-primary);
}

/* Card / list-item title: Switzer Medium 20px */
.card-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 20px;
  line-height: 1.25;
  letter-spacing: -0.2px;
  color: var(--text-primary);
}

.lead {
  font-family: var(--font-body);
  font-size: 18px;
  line-height: 1.6;
  color: var(--text-secondary);
}

.body-sm {
  font-size: var(--type-body-sm);
  line-height: 1.55;
}

.accent {
  color: var(--accent);
}

/* Section eyebrow: Inter Medium 14px, uppercase, accent (matches Figma). */
.eyebrow {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 14px;
  line-height: 1.2;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}

/* Small uppercase label (CASE STUDIES, SUPPORTED BY, chips). Inter.
   The class NAME is historical: it was IBM Plex Mono before mono was
   removed sitewide. It renders Inter now. Keep the name so existing
   markup keeps working, and never point it back at a mono font. */
.mono-label {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 12px;
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* ---- Buttons ----
   .btn is the shared shell; combine with .btn--primary or .btn--secondary
   (and optionally .btn--block). Disabled styling responds to both the
   [disabled] attribute and aria-disabled="true". */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 16px 32px;
  border-radius: var(--radius-lg);
  font-family: var(--font-body);
  font-weight: 600; /* Figma Button component: Inter Semi Bold */
  font-size: var(--type-button);
  line-height: 1;
  text-align: center;
  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}

.btn--primary {
  background: var(--accent);
  color: #fff;
  box-shadow: var(--shadow-button);
}
.btn--primary:hover { background: var(--accent-hover); }
.btn--primary:active { background: var(--accent-active); }
.btn--primary[disabled],
.btn--primary[aria-disabled="true"] {
  background: var(--accent-disabled);
  pointer-events: none;
}

.btn--secondary {
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--accent);
}
.btn--secondary:hover { background: var(--accent-soft); }
.btn--secondary:active { background: var(--accent-light); }

.btn--block {
  width: 100%;
}

/* Inline text link with trailing arrow */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 4px; /* Figma renders "Read more →" as one text run, word-space wide */
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 16px;
  color: var(--accent);
}
.link-arrow:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---- Section heading block (eyebrow + title + intro), centered ---- */
.section-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-5);
  max-width: 842px;
  margin-inline: auto;
}
.section-head .intro {
  color: var(--text-secondary);
  font-family: var(--font-body);
  font-size: 18px;
  line-height: 1.6;
  /* No own max-width: fills the .section-head 842px block, as in Figma. */
}
.section-head--left {
  align-items: flex-start;
  text-align: left;
  margin-inline: 0;
}

/* ---- Image placeholder (until client supplies real photos) ----
   Convention: a striped block with an "IMG/... (replace)" label marks a
   slot awaiting real photography (current images are Figma exports). To
   swap in a real photo, replace the placeholder element in the HTML with
   an <img> (WebP, run through scripts/convert-images.sh) and remove the
   __label span. Leave these rules in place while any slot still uses
   the placeholder. */
.img-placeholder {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    repeating-linear-gradient(
      45deg,
      var(--accent-soft),
      var(--accent-soft) 12px,
      var(--accent-subtle) 12px,
      var(--accent-subtle) 24px
    );
  border: 1px solid var(--border);
  color: var(--accent);
  overflow: hidden;
}
.img-placeholder__label {
  font-family: var(--font-body);
  font-size: var(--type-mono-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  background: rgba(255, 255, 255, 0.75);
  padding: 6px 10px;
  border-radius: var(--radius-md);
}

/* ---- Utilities ----
   .visually-hidden keeps text available to screen readers while hiding
   it visually. Currently unused in the markup; kept for icon-only
   controls or skip links when they are added. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Responsive heading scale. Desktop sizes come from tokens.css; these
   phone overrides are hand-tuned here, so a token change alone will not
   move headings below 768px. */
@media (max-width: 768px) {
  .display { font-size: clamp(34px, 9vw, 42px); letter-spacing: -1px; }
  .h1 { font-size: clamp(30px, 8vw, 36px); }
  .h2 { font-size: clamp(28px, 7.5vw, 32px); }
  .h3 { font-size: 26px; }
  .h4 { font-size: 22px; }
}

/* ---- Motion: hero entrance + scroll reveals ----
   Subtle and cheap (opacity/transform only). Everything sits behind
   prefers-reduced-motion: no-preference, so reduced-motion users see
   the page fully static and nothing is ever hidden without JS
   (.reveal is added by main.js before first paint).
   No-JS guarantee: because ONLY main.js adds .reveal, a broken or
   blocked script means no element ever gets the hidden start state,
   the page just renders without the effect. Per-element stagger comes
   from the --reveal-delay custom property, set inline in the HTML
   (e.g. style="--reveal-delay: 120ms"). */
@media (prefers-reduced-motion: no-preference) {
  /* Hero entrance: eyebrow, headline, subhead, CTAs rise in sequence. */
  .hero__copy-wrap > * {
    animation: rise-in 650ms cubic-bezier(0.22, 1, 0.36, 1) both;
  }
  .hero__copy-wrap > :nth-child(2) { animation-delay: 90ms; }
  .hero__copy-wrap > :nth-child(3) { animation-delay: 180ms; }
  .hero__copy-wrap > :nth-child(4) { animation-delay: 270ms; }
  .hero__media {
    animation: fade-in 900ms ease-out both;
  }

  /* Scroll reveal: hidden start state, released by .is-visible. */
  .reveal {
    opacity: 0;
    transform: translateY(18px);
    transition:
      opacity 650ms cubic-bezier(0.22, 1, 0.36, 1),
      transform 650ms cubic-bezier(0.22, 1, 0.36, 1);
    transition-delay: var(--reveal-delay, 0ms);
  }
  .reveal.is-visible {
    opacity: 1;
    transform: none;
  }
}

@keyframes rise-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
