/* ==========================================================================
   Humblebee — AI Readiness Report
   Shared stylesheet for the English (/index.html) and Swedish (/sv/index.html)
   versions of the landing page.

   Contents
     1.  Fonts
     2.  Design tokens
     3.  Reset & base
     4.  Layout primitives
     5.  Typography
     6.  Buttons, badge, eyebrow
     7.  Header
     8.  Hero
     9.  How it works
     10. What you get (dark band)
     11. Final CTA
     12. Footer
     13. Motion preferences
   ========================================================================== */


/* 1. Fonts ---------------------------------------------------------------- */
/* Inter, subset to latin + latin-ext (covers å ä ö for the Swedish version).
   Self-hosted deliberately: no third-party request means no visitor IP leaves
   our domain, which keeps the page clean under GDPR. Inter is SIL OFL 1.1 —
   see assets/fonts/LICENSE.md. */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/inter-400.woff2') format('woff2');
}

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


/* 2. Design tokens -------------------------------------------------------- */

:root {
  /* Brand palette — do not introduce colours outside this set. */
  --c-black: #000000;
  --c-dark: #161616;
  --c-blue: #1a00ff;
  --c-blue-light: #4733ff;
  --c-yellow: #fff500;
  --c-orange: #ff9d00;
  --c-orange-deep: #ff4d00;

  /* Neutrals */
  --c-white: #ffffff;
  --c-light: #f8f8f8;
  --c-gray-100: #e0e0e0;
  --c-gray-200: #cccccc;
  --c-gray-500: #6c6e74;
  --c-gray-700: #373737;

  /* Derived. Every pair below is checked against WCAG AA on its own ground. */
  --c-muted: var(--c-gray-700);                 /* body on light — 10.4:1 */
  --c-muted-on-dark: rgba(255, 255, 255, 0.78); /* body on dark  — 11:1 */
  --c-muted-on-blue: rgba(255, 255, 255, 0.88);
  --c-hairline: var(--c-gray-100);
  /* Form errors. Deep orange itself is only 3.3:1 on white, which fails AA for
     text, so this is #ff4d00 darkened until it clears it — 5.5:1. It is the
     one colour on the page outside the Humblebee palette, and it exists
     because the palette has no accessible red. */
  --c-error: #c53000;
  --c-hairline-on-dark: rgba(255, 255, 255, 0.24);
  --c-blue-hover: var(--c-blue-light);

  /* Spacing */
  --space-section: clamp(4.5rem, 9vw, 8.5rem);
  --shell-max: 1120px;
  --shell-pad: clamp(1.5rem, 4vw, 4.5rem);

  /* Radii */
  --r-card: 20px;
  --r-xl: 28px;
  --r-pill: 999px;

  /* Type ramp — fluid, so there are no awkward jumps between breakpoints. */
  --t-h1: clamp(2.25rem, 4.6vw, 4.25rem);
  --t-h2: clamp(2rem, 4.6vw, 4rem);
  --t-h3: clamp(1.25rem, 1.8vw, 1.5rem);
  --t-lead: clamp(1.0625rem, 1.5vw, 1.4375rem);
  --t-body: clamp(1rem, 0.9vw, 1.0625rem);
  --lh-body: 1.5;          /* 16/24 */
  --ls-body: -0.019em;     /* -0.3px at 16px */
  --lh-head: 1;            /* 100% */
  --ls-head: -0.03em;
  --t-small: clamp(0.9375rem, 0.9vw, 1.0625rem);
  --t-eyebrow: 0.8125rem;

  --focus-ring: 3px solid var(--c-blue);
}


/* 3. Reset & base --------------------------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--c-white);
  color: var(--c-dark);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
  font-size: var(--t-body);
  font-weight: 400;
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Inter's default figures are proportional; tabular reads better for the
     step numerals. Contextual alternates keep the arrow glyphs tidy. */
  font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1;
}

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

/* Material Symbols are drawn as filled paths, so they inherit text colour. */
use {
  fill: currentColor;
}

/* Every interactive element gets the same visible focus treatment. */
a:focus-visible,
button:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Skip link — visible only once focused. */
.skip-link {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--c-dark);
  color: var(--c-light);
  border-radius: var(--r-pill);
  font-size: var(--t-small);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-160%);
}

.skip-link:focus-visible {
  transform: translateY(0);
}

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


/* 4. Layout primitives ---------------------------------------------------- */

.shell {
  width: 100%;
  /* The pad sits outside the cap, so the content column is --shell-max wide on
     a big screen and the gutters grow instead of the measure. */
  max-width: calc(var(--shell-max) + 2 * var(--shell-pad));
  margin-inline: auto;
  padding-inline: var(--shell-pad);
}

.section {
  padding-block: var(--space-section);
}

.section--dark {
  background: var(--c-dark);
  color: var(--c-light);
}

/* Thin grey rules between page sections. */
main > section + section,
.cta {
  border-top: 1px solid var(--c-hairline);
}

/* Clears the sticky header when the "See how it works" anchor jumps here. */
[id] {
  scroll-margin-top: 6rem;
}


/* 5. Typography ----------------------------------------------------------- */

/* Headings wrap greedily against an explicit em-based measure rather than
   using text-wrap: balance. Balance redistributes words evenly, which fights
   the specific line breaks in the design; em units keep those breaks
   identical at every viewport size because the measure scales with the type. */
h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 900;
  line-height: var(--lh-head);
  letter-spacing: var(--ls-head);
}

h1 {
  font-size: var(--t-h1);
  max-width: 11.2em;
}

/* Keeps a hyphenated word whole so the headline never breaks mid-word. */
.nowrap {
  white-space: nowrap;
}

h2 {
  font-size: var(--t-h2);
}

h3 {
  font-size: var(--t-h3);
}

p {
  margin: 0;
}

.lead {
  font-size: var(--t-lead);
  line-height: var(--lh-body);
  max-width: 34em;
}

.section--dark .lead,
.section--dark .item__body {
  color: var(--c-muted-on-dark);
}


/* 6. Buttons, badge, eyebrow ---------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  height: 3.5rem;              /* 56px */
  padding: 0 1.625rem;
  border: 1.5px solid transparent;
  border-radius: var(--r-pill);
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: var(--ls-head);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease,
              border-color 0.18s ease, transform 0.18s ease;
}

.btn--primary {
  background: var(--c-blue);
  color: var(--c-light);
}

.btn--primary:hover {
  background: var(--c-blue-hover);
}

.btn--secondary {
  background: transparent;
  border-color: var(--c-dark);
  color: var(--c-dark);
}

.btn--secondary:hover {
  background: var(--c-dark);
  color: var(--c-light);
}

/* Header buttons sit on a 40px height so they line up with the language switch. */
.btn--sm {
  height: 2.5rem;              /* 40px */
  padding-inline: 1.125rem;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.875rem;
}

/* Yellow pill above the h1. Yellow is a background here, never a text colour
   on light — per the brand accessibility rules. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4375rem 1.125rem;
  background: var(--c-yellow);
  color: var(--c-dark);
  border-radius: var(--r-pill);
  font-size: var(--t-small);
  font-weight: 600;
  line-height: 1.3;
}

.badge svg {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
}

.eyebrow {
  margin: 0 0 1.125rem;
  color: var(--c-blue);
  font-size: var(--t-eyebrow);
  font-weight: 600;
  letter-spacing: 0.09em;
  line-height: 1.4;
}

.section--dark .eyebrow {
  color: var(--c-yellow);
}


/* 7. Header --------------------------------------------------------------- */

.header {
  position: sticky;
  top: 0;
  z-index: 50;
  /* Opaque, and no backdrop-filter: the header used to blur its backdrop, but
     re-sampling it every frame over the counter SVG and the marquee made the
     bar flicker on scroll. Every surface underneath is near-white, so the blur
     was never visible anyway. */
  background: var(--c-white);
  border-bottom: 1px solid var(--c-hairline);
  /* Keep the bar on its own compositor layer. Dropping backdrop-filter also
     dropped the promotion it forced, which left the header repainting on the
     main thread on every scroll frame — and its wordmark is a <use> reference
     into the sprite, so each repaint re-rasterises ~60 paths. */
  transform: translateZ(0);
  will-change: transform;
  backface-visibility: hidden;
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 4.5rem;
}

.header__brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}

.wordmark {
  flex: none;
  width: auto;
  height: 24px;
  color: currentColor;
}

.header__actions {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}

/* Language switch: EN / SV pair, current language de-emphasised. */
.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  height: 2.5rem;              /* 40px, matching .btn--sm */
  margin-right: 1rem;          /* 16px gap before the CTA */
  font-size: 0.75rem;          /* 12px */
  letter-spacing: 0.02em;
}

.lang-switch__sep {
  color: var(--c-gray-200);
  font-weight: 400;
}

.lang-switch a,
.lang-switch span {
  text-decoration: none;
  transition: color 0.18s ease;
}

.lang-switch [aria-current="true"] {
  color: var(--c-dark);
  font-weight: 600;
}

.lang-switch a:not([aria-current="true"]) {
  color: var(--c-gray-500);
  font-weight: 400;
}

.lang-switch a:not([aria-current="true"]):hover {
  color: var(--c-dark);
}


/* 8. Hero ----------------------------------------------------------------- */

.hero {
  padding-block: 3rem var(--space-section);
}

.hero .badge {
  margin-bottom: clamp(1.5rem, 3vw, 2rem);
}

.hero h1 {
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
}

.hero .lead {
  /* Narrower than the default measure so the wrap matches the design. */
  max-width: 31em;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

/* The lead runs to two paragraphs; keep them closer to each other than to
   the button below. */
.hero .lead--tight {
  margin-bottom: 0.85em;
}


/* 9. How it works --------------------------------------------------------- */

/* The heading sits on a deliberately narrow measure, as drawn. */
.steps__intro h2 {
  max-width: 8.2em; /* "Four steps. A / couple of / questions. Real / answers." */
  margin-bottom: clamp(1.25rem, 2.5vw, 1.75rem);
}

.steps__intro .lead {
  max-width: 22em;
}

.steps {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(2rem, 3.5vw, 2.75rem);
  margin-top: clamp(3rem, 6vw, 5rem);
  padding: 0;
  list-style: none;
}

.step__number {
  display: block;
  margin-bottom: 0.75rem;
  color: var(--c-blue);
  font-style: italic;
  font-size: clamp(2.25rem, 3.4vw, 3rem);
  font-weight: 900;
  line-height: var(--lh-head);
  letter-spacing: var(--ls-head);
}

/* Step numbers mirror the counter animation palette. */
.step:nth-child(2) .step__number { color: #FF4D00; }
.step:nth-child(3) .step__number { color: #FF9D00; }
.step:nth-child(4) .step__number { color: #00FF09; }

.step__title {
  margin: 0 0 0.625rem;
  font-size: 1.1875rem;
}

.step__body {
  color: var(--c-muted);
  font-size: var(--t-small);
  line-height: var(--lh-body);
}


/* 10. What you get (dark band) -------------------------------------------- */

.get__intro h2 {
  max-width: 9em; /* "Something you can / act on Monday / morning" */
  padding-bottom: 0.06em; /* descenders, now that leading is 100% */
}

.get__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2.5rem, 5vw, 4.5rem);
  align-items: start;
  margin-top: clamp(3rem, 6vw, 4.5rem);
}

/* Left column: the list, with the grey card beneath it. */
.get__col {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem);
}

.get__visual {
  display: block;
  width: 100%;
  height: auto;
}

.item-list {
  display: grid;
  gap: clamp(1.75rem, 3vw, 2.5rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.5rem 1rem;
}

/* Icon-less items (the "What you get" list) collapse to a single column. */
.item:not(:has(.item__icon)) {
  grid-template-columns: minmax(0, 1fr);
}

.item__icon {
  flex: none;
  grid-row: span 2;
  width: 1.5rem;
  height: 1.5rem;
  margin-top: 0.2em;
  color: var(--c-blue);
}

.item__title {
  margin: 0;
  font-size: 1.125rem;
}

.item__body {
  color: var(--c-muted);
  font-size: var(--t-small);
  line-height: var(--lh-body);
}

/* Blue "In your hands" card. */
.card--blue {
  max-width: 600px;
  background: var(--c-light);
  color: var(--c-dark);
  border-radius: 0;
  padding: clamp(1.75rem, 3.5vw, 2.75rem);
}

.card--blue h3 {
  color: var(--c-blue);
  margin-bottom: clamp(1.25rem, 2.5vw, 1.75rem);
}

.card--blue .item-list {
  gap: 0;
}

.card--blue .item {
  align-items: start;
  padding-block: clamp(1.25rem, 2.5vw, 1.625rem);
}

.card--blue .item + .item {
  border-top: 1px solid var(--c-hairline);
}

.card--blue .item:last-child {
  padding-bottom: 0;
}

.card--blue .item__icon {
  color: var(--c-blue);
  width: 2rem;
  height: 2rem;
  margin-top: -0.375rem;
}

.card--blue .item__body {
  color: var(--c-muted);
}


/* 10b. Counter animation -------------------------------------------------- */

.counter {
  padding-block: 0;
  background: #fafafa;
  border-top: 0;
  border-bottom: 0;
}

.counter + section {
  border-top: 0;
}

.counter .shell {
  max-width: none;
  padding-inline: 0;
}

.counter__stage {
  width: 100%;
  aspect-ratio: 16 / 9;
  /* counter-1-4.js rewrites transforms on ~25 SVG nodes every frame; keep that
     raster work from invalidating the rest of the page. */
  contain: paint;
}

.counter__stage svg {
  width: 100%;
  height: 100%;
}


/* 11. Final CTA ----------------------------------------------------------- */

.cta {
  padding-block: clamp(5rem, 11vw, 10rem);
  background: var(--c-white);
}

/* The final CTA is the one centred section on a page that is left-aligned
   everywhere else. There is nothing to scan here and one thing to do, so the
   whole thing — heading, price, offer, button, small print — sits on a single
   axis and reads as the climax rather than one more column of copy. */
.cta__inner {
  display: grid;
  gap: clamp(3rem, 7vw, 8rem);
  justify-items: center;
  text-align: center;
}

.cta__head,
.cta__action {
  width: 100%;
}

.cta__title {
  max-width: 14ch;
  margin: 0 auto;
  font-size: clamp(3rem, 9.5vw, 8rem);
  font-weight: 900;
  line-height: 0.92;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.cta__accent {
  color: var(--c-blue);
}

/* Orange is what sets the final CTA apart now that it is sized like every
   other button on the page. */
.btn--accent {
  background: #FF4D00;
  border-color: #FF4D00;
  color: var(--c-light);
}

.btn--accent:hover,
.btn--accent:focus-visible {
  background: #e64500;
  border-color: #e64500;
}

/* Price sits under the CTA heading, one step down in size so the heading still
   leads. */
.cta__price {
  margin-top: clamp(0.75rem, 2vw, 1.25rem);
  color: var(--c-dark);
  font-size: clamp(1.25rem, 2.6vw, 2rem);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.cta__vat {
  color: var(--c-gray-500);
  font-size: 0.6em;
  font-weight: 400;
  letter-spacing: 0;
}

/* Waiting-list copy around the big button. The offer reads first, the terms
   sit quietly below. */
.cta__offer,
.cta__note-lead,
.cta__fine {
  max-width: 42em;
  margin-inline: auto;
  line-height: var(--lh-body);
}

/* The offer sits under the price, set a step down from it, so the two read as
   one statement: the list price, then what it costs right now. */
.cta__offer {
  margin-top: clamp(0.5rem, 1.4vw, 0.875rem);
  color: var(--c-dark);
  font-size: clamp(1rem, 1.9vw, 1.375rem);
  font-weight: 600;
  letter-spacing: -0.02em;
}

/* Set like the offer, so the reassurance under the button sits a step below
   the numbers above it without disappearing. */
.cta__note-lead {
  margin-top: clamp(1.25rem, 3vw, 2rem);
  color: var(--c-dark);
  font-size: clamp(1rem, 1.9vw, 1.375rem);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.cta__fine {
  margin-top: 0.75rem;
  color: var(--c-gray-500);
  font-size: 0.75rem;
}


/* 11b. Marquee ------------------------------------------------------------ */

.marquee {
  overflow: hidden;
  /* The track animates forever; containment stops its repaints escaping. */
  contain: paint;
  padding-block: clamp(2.5rem, 6vw, 4.5rem);
  background: var(--c-white);
  border-top: 1px solid var(--c-hairline);
}

.marquee__viewport {
  display: flex;
  width: max-content;
  animation: marquee-scroll 68s linear infinite;
  will-change: transform;
}

.marquee__track {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding-right: 1.5rem;
}

.marquee__item,
.marquee__dot {
  font-size: 64px;
  font-weight: 900;
  line-height: 1;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.marquee__dot {
  color: #ff4d00;
}

@keyframes marquee-scroll {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

@media (max-width: 768px) {
  .marquee__item,
  .marquee__dot {
    font-size: clamp(2rem, 9vw, 4rem);
  }
}


/* 12. Footer -------------------------------------------------------------- */

.footer {
  border-top: 1px solid var(--c-hairline);
  padding-block: 2.5rem;
}

.footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 1.5rem;
  color: var(--c-muted);
  font-size: 0.75rem;
}

.footer__wordmark-link {
  display: block;
  line-height: 0;
  text-decoration: none;
}

.footer__wordmark {
  display: block;
  height: 1rem;              /* 16px */
  width: auto;
}

.footer__inner > div:first-child {
  flex: 1;
  max-width: 34em;
}

.footer__disclosure {
  margin-top: 0.5rem;
  color: var(--c-gray-500);
}

.footer__links {
  flex: 1;
  justify-content: flex-end;
}

.footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
}

/* Underlined so links never rely on colour alone. */
.footer a {
  color: var(--c-dark);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.footer a:hover {
  color: var(--c-blue);
}

.footer .wordmark {
  margin-bottom: 0.5rem;
  color: var(--c-dark);
}


/* 13. Responsive ---------------------------------------------------------- */

@media (max-width: 1024px) {
  .steps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .get__grid {
    grid-template-columns: 1fr;
  }

  /* Visual sits between the heading and the list on narrow screens. */
  .get__visual {
    order: -1;
  }

  .get__intro h2,
  .steps__intro h2 {
    max-width: 12em;
  }
}

@media (max-width: 768px) {
  h1 {
    max-width: 100%;
  }

  .header__inner {
    /* Tall enough to clear the 56px CTA with a little air around it. */
    min-height: 4.25rem;
  }
}

@media (max-width: 640px) {
  /* The lockup is a wide two-line mark; 18px keeps it legible next to a
     40px CTA at phone widths. */
  .header .wordmark {
    height: 18px;
  }

  .header .btn {
    padding-inline: 0.8125rem;
  }

  .lang-switch {
    gap: 0.5rem;
  }

  /* Buttons keep their intrinsic size; they stack when the row runs out of
     width, with a tighter 8px gap. */
  .btn-row {
    gap: 8px;
  }

  .steps {
    grid-template-columns: minmax(0, 1fr);
    gap: 2.25rem;
  }

  .steps__intro h2,
  .get__intro h2,
  .cta__title {
    max-width: 100%;
  }

  .footer__inner {
    flex-direction: column;
    align-items: flex-start;
  }
}


/* 14. Motion preferences -------------------------------------------------- */

/* Pre-hide animated elements only while the GSAP package is booting.
   The `anim` class is set inline in <head> and dropped once tweens exist (or
   if GSAP never loads), so no-JS visitors always see full content. */
html.anim .header__inner > *,
html.anim .hero h1,
html.anim .hero .lead,
html.anim .hero .btn-row,
html.anim .steps__intro > *,
html.anim .get__intro > *,
html.anim .step,
html.anim .get__col .item,
html.anim .card--blue > *,
html.anim .get__visual,
html.anim .cta__inner > *,
html.anim .footer__inner > * {
  visibility: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .marquee__viewport {
    animation: none;
  }

  html.anim .header__inner > *,
  html.anim .hero h1,
  html.anim .hero .lead,
  html.anim .hero .btn-row,
  html.anim .steps__intro > *,
  html.anim .get__intro > *,
  html.anim .step,
  html.anim .get__col .item,
  html.anim .card--blue > *,
  html.anim .get__visual,
  html.anim .cta__inner > *,
  html.anim .footer__inner > * {
    visibility: visible;
  }
}

@media (prefers-reduced-motion: reduce) {
  .marquee__viewport {
    animation: none;
  }

  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}


/* 15. Booking form (book.html, thanks.html) -------------------------------- */

/* The form page runs without the GSAP entrance package, so nothing here is
   ever hidden waiting on JavaScript. */

.form-page {
  padding-block: clamp(3rem, 6vw, 5.5rem);
}

/* The site is full-bleed and hugs the left edge everywhere; the form keeps
   that alignment rather than centring, which would read as a different page.
   The measure is capped so input lines never grow uncomfortably long. */
.form-page__inner {
  max-width: 42rem;
}

.form-page__title {
  /* Breaks after "where to look." at every size — em measure, as elsewhere. */
  max-width: 16em;
  margin-bottom: 1.25rem;
}

.form-page__intro .lead {
  max-width: 32em;
}

.form-page__reassure {
  list-style: none;
  margin: 2rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.875rem;
}

.form-page__reassure li {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  color: var(--c-muted);
  font-size: var(--t-small);
}

.form-page__reassure svg {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  color: var(--c-blue);
}

/* -- Notes: the no-JS error banner and the JS success panel --------------- */

.form-note {
  margin-top: 2.5rem;
  padding: 1.5rem 1.625rem;
  border-radius: var(--r-card);
}

.form-note__title {
  font-size: var(--t-h3);
  margin-bottom: 0.5rem;
}

.form-note__action {
  margin-top: 1.5rem;
}

.form-note--ok {
  background: var(--c-blue);
  color: var(--c-white);
}

.form-note--ok .btn--secondary {
  border-color: var(--c-white);
  color: var(--c-white);
}

.form-note--ok .btn--secondary:hover {
  background: var(--c-white);
  color: var(--c-blue);
}

/* The bar is a non-text indicator, where 3:1 is the AA threshold, so the
   palette's deep orange is fine here. Error *text* uses --c-error. */
.form-note--error {
  display: none;
  background: var(--c-light);
  border-left: 4px solid var(--c-orange-deep);
}

/* The server bounces a no-JS submit back to #form-error; :target reveals it
   with no script involved. form.js hides it again on a live submit. */
.form-note--error:target {
  display: block;
}

.form-note--error[data-shown="true"] {
  display: block;
}

/* -- The form itself ------------------------------------------------------ */

.form {
  margin-top: 2.75rem;
}

.form[hidden] {
  display: none;
}

.form__group {
  margin: 0 0 2.5rem;
  padding: 0;
  border: 0;
  border-top: 1px solid var(--c-hairline);
  padding-top: 1.75rem;
  display: grid;
  gap: 1.5rem;
}

.form__legend {
  /* A grid parent ignores legend placement, so it is positioned as a normal
     grid item rather than floated into the border. */
  padding: 0;
  font-size: var(--t-eyebrow);
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--c-gray-500);
}

.field {
  display: grid;
  gap: 0.5rem;
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
}

.field__label {
  font-size: var(--t-small);
  font-weight: 600;
  letter-spacing: var(--ls-body);
}

.field__req {
  color: var(--c-error);
}

.field__input {
  width: 100%;
  min-height: 3.25rem;              /* 52px — comfortable touch target */
  padding: 0.875rem 1rem;
  background: var(--c-white);
  border: 1.5px solid var(--c-gray-200);
  border-radius: 12px;
  font: inherit;
  font-size: var(--t-body);
  color: var(--c-dark);
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
  -webkit-appearance: none;
  appearance: none;
}

.field__input::placeholder {
  color: var(--c-gray-500);
}

.field__input:hover {
  border-color: var(--c-gray-500);
}

.field__input:focus-visible {
  outline: none;
  border-color: var(--c-blue);
  box-shadow: 0 0 0 3px rgba(26, 0, 255, 0.18);
}

/* Native select needs its own chevron once appearance is stripped. */
.field__select {
  padding-right: 2.75rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 -960 960 960' fill='%23373737'%3E%3Cpath d='M480-360 280-560h400L480-360Z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.875rem center;
  cursor: pointer;
}

.field__textarea {
  min-height: 7rem;
  line-height: var(--lh-body);
  resize: vertical;
}

.field__hint,
.field__error {
  margin: 0;
  font-size: var(--t-small);
}

.field__hint {
  color: var(--c-muted);
}

.field__error {
  color: var(--c-error);
  font-weight: 600;
}

.field__error[hidden] {
  display: none;
}

.field--invalid .field__input {
  border-color: var(--c-error);
}

/* -- Consent checkbox ---------------------------------------------------- */

.field--consent {
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: 0.75rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--c-hairline);
}

.field__check {
  width: 1.375rem;
  height: 1.375rem;
  margin: 0.0625rem 0 0;
  accent-color: var(--c-blue);
  flex: none;
}

.field__check:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 2px;
}

.field__label--inline {
  font-weight: 400;
  color: var(--c-muted);
}

.field--consent .field__error {
  grid-column: 1 / -1;
}

.field--consent.field--invalid .field__label--inline {
  color: var(--c-error);
}

/* -- Actions ------------------------------------------------------------- */

.form__status {
  margin-top: 1.75rem;
  font-size: var(--t-small);
  font-weight: 600;
  color: var(--c-error);
}

.form__status:empty {
  display: none;
}

.form__actions {
  margin-top: 2rem;
  display: grid;
  gap: 1rem;
  justify-items: start;
}

.btn--wide {
  min-width: 14rem;
}

.btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: progress;
}

.form__smallprint {
  font-size: var(--t-small);
  color: var(--c-muted);
}

/* Inline links in the notes are underlined; a .btn inside one is not. */
.form__smallprint a,
.form-note a:not(.btn) {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.form-note--ok a:not(.btn) {
  color: var(--c-white);
}

/* Honeypot: out of the layout and out of the tab order, but not
   display:none, which some bots know to skip. */
.form__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* -- thanks.html --------------------------------------------------------- */

.thanks {
  padding-block: clamp(4rem, 10vw, 8rem);
}

.thanks__inner {
  max-width: 40rem;
}

.thanks h1 {
  max-width: 14em;
  margin-bottom: 1.25rem;
}

.thanks .btn-row {
  margin-top: 2.5rem;
}

@media (max-width: 640px) {
  .field-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
  }

  .form-page__title,
  .thanks h1 {
    max-width: 100%;
  }

  .form__actions .btn {
    width: 100%;
  }
}
