/* Xelleron scheduling enquiry form: components and layout.
   Reads only var(--…) for colour, font, radius and shadow colour; the values live in tokens.css (spec BR-17).
   Sizes with no token (an icon, a fixed control height) are copied from design/app.pen, frames S01/S02.
   Phone first (frame 390); the desktop layout (frame 1440) starts at 1100 px. */

@font-face {
  font-family: "Manrope";
  src: url("assets/fonts/manrope-latin-wght.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

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

/* Canvas text without a line height uses the face's own (Manrope: 1.366), rounded to whole pixels. Set on every
   element, not inherited: an inherited line height arrives already computed at the parent's font size (a 14 px
   hint under a 16 px body got 22 px instead of 19). Rules below set the ratio (--lh), which inherits as a number,
   so a link inside a 1.45 line gets 1.45 at its own size. */
:root { --lh: 1.366; }
* { line-height: round(calc(var(--lh) * 1em), 1px); }

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

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--background);
  color: var(--foreground);
  font-family: var(--font-primary);
  font-size: var(--text-body);
  font-weight: 500;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

h1, p, ul, fieldset, legend { margin: 0; padding: 0; }
fieldset { border: 0; min-width: 0; }
ul { list-style: none; }
a { color: var(--primary); }
img { display: block; }
[hidden] { display: none !important; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.icon {
  display: block;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

a, button, input, label, textarea { touch-action: manipulation; }

:focus-visible { outline: 3px solid var(--ring); outline-offset: 2px; }

/* ---------- Page and sky ---------- */

.page {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  background: linear-gradient(200deg, var(--sky-1), var(--sky-2));
}

.sky {
  display: flex;
  flex-direction: column;
  /* 52 below the intro plus the sheet's corner radius: the sheet sits 28 up over the band (.sheet margin-top), so the
     band's own gradient shows behind its rounded corners, as on the canvas (Form/Sky Band/Phone padding 80, frames
     gap -28; user report 2026-11-04: the page's gradient showed there and didn't match the band above it). */
  padding: var(--space-5) 22px calc(52px + var(--radius-xl));
  padding-top: max(var(--space-5), env(safe-area-inset-top));
  color: var(--on-sky);
}

.sky { position: relative; isolation: isolate; }
.sky-fill { position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%; pointer-events: none; }
.sky-stop-1 { stop-color: var(--sky-1); }
.sky-stop-2 { stop-color: var(--sky-2); }

.sky-top { display: flex; flex-direction: column; gap: 28px; }

.logo { align-self: flex-start; border-radius: var(--radius-s); }
.logo img { width: 104px; height: 38px; object-fit: contain; }

.sky-heading { display: flex; flex-direction: column; gap: 10px; }

.title {
  font-size: var(--text-h1);
  font-weight: 300;
  --lh: 1.04;
  letter-spacing: -1.2px;
}

.intro {
  font-size: var(--text-lead);
  font-weight: 500;
  --lh: 1.45;
}

.call-card { display: none; }

.sky :focus-visible { outline-color: var(--on-sky); }

/* ---------- Sheet ---------- */

.sheet {
  position: relative;
  z-index: 1; /* over the band's last 28 px */
  margin-top: calc(-1 * var(--radius-xl));
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  background: var(--card);
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  padding: var(--space-6) 18px var(--space-8);
  padding-bottom: max(var(--space-8), env(safe-area-inset-bottom));
}

.column,
.sky-top {
  width: 100%;
  max-width: 560px;
  margin-inline: auto;
}

.column { flex: 1 0 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--space-5); }

.enquiry { display: flex; flex-direction: column; gap: var(--space-5); }

.required-note {
  color: var(--muted-foreground);
  font-size: var(--text-small);
  --lh: 1.4;
}

/* ---------- Field staff: forecast strip of radio capsules ---------- */

.field-staff { display: flex; flex-direction: column; gap: var(--space-3); }

.legend {
  font-size: var(--text-lead);
  font-weight: 600;
  --lh: 1.35;
  margin-bottom: var(--space-3);
}
/* A legend is not a flex item in every engine; its margin stands in for the fieldset's gap. */

.forecast-strip { display: flex; gap: var(--space-2); }

.capsule {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  height: 124px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-1);
  background: var(--card);
  border-radius: var(--radius-l);
  box-shadow: inset 0 0 0 1px var(--input);
  cursor: pointer;
  transition: background-color 150ms ease, box-shadow 150ms ease, color 150ms ease;
}

.capsule-input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.scale-bar {
  width: 8px;
  height: 10px;
  border-radius: 4px;
  background: var(--primary);
  transition: background-color 150ms ease;
}
.capsule:nth-child(2) .scale-bar { height: 18px; }
.capsule:nth-child(3) .scale-bar { height: 26px; }
.capsule:nth-child(4) .scale-bar { height: 34px; }

.range {
  font-size: var(--text-numeral-sm);
  font-weight: 400;
  letter-spacing: -1px;
  white-space: nowrap;
}

.unit {
  color: var(--muted-foreground);
  font-size: var(--text-caption);
  font-weight: 500;
  white-space: nowrap;
  transition: color 150ms ease;
}
.unit-extra { display: none; }

.capsule:has(:checked) {
  background: var(--selected);
  color: var(--on-selected);
  box-shadow: inset 0 0 0 1px var(--selected), 0 8px 20px color-mix(in srgb, var(--selected) 25%, transparent);
}
.capsule:has(:checked) .scale-bar { background: var(--on-selected); }
.capsule:has(:checked) .unit { color: var(--on-selected); }

.capsule:has(:focus-visible) { box-shadow: inset 0 0 0 3px var(--ring); }
.capsule:has(:checked:focus-visible) {
  box-shadow: inset 0 0 0 3px var(--ring), 0 8px 20px color-mix(in srgb, var(--selected) 25%, transparent);
}
.capsule-input:focus-visible { outline: none; }

/* ---------- Fields ---------- */

.field { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }

.label {
  font-size: var(--text-body);
  font-weight: 600;
}
.field--scenario .label { --lh: 1.35; }

.hint {
  color: var(--muted-foreground);
  font-size: var(--text-small);
  font-weight: 500;
}

.input {
  display: block;
  width: 100%;
  height: 56px;
  margin: 0;
  padding: 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-m);
  background: var(--card);
  box-shadow: inset 0 0 0 1px var(--input);
  color: var(--foreground);
  caret-color: var(--ring);
  font: inherit;
  font-size: var(--text-body);
  font-weight: 500;
  appearance: none;
  transition: box-shadow 150ms ease;
}
.input::placeholder { color: var(--muted-foreground); opacity: 1; }
.input:focus-visible,
.input:focus { outline: none; box-shadow: inset 0 0 0 2px var(--ring); }
.input[aria-invalid="true"] { box-shadow: inset 0 0 0 2px var(--error); }
.input[aria-invalid="true"]:focus { box-shadow: inset 0 0 0 2px var(--error), 0 0 0 3px var(--ring); }

.textarea {
  height: auto;
  min-height: 132px;
  padding: var(--space-4);
  --lh: 1.5;
  resize: none;
  overflow: hidden;
  field-sizing: content;
}

.counter-line {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  height: 22px;
}
.counter {
  color: var(--muted-foreground);
  font-size: var(--text-small);
  --lh: 1.45;
}

.error-line {
  display: flex;
  gap: 6px;
  min-height: 19px;
  color: var(--error);
  font-size: var(--text-small);
  font-weight: 600;
}
.error-line .icon { width: 16px; height: 16px; margin-top: 1px; }

/* A hint and the error line share one slot under the field; an error hides the hint and keeps its room. */
.below { display: grid; }
.below > * { grid-area: 1 / 1; }
.field:has(.error-line:not(:empty)) .hint { visibility: hidden; }
.error-line--group { min-height: 0; align-items: center; }
.error-line--group:empty { display: none; }

.name-mobile { display: flex; flex-direction: column; gap: var(--space-5); }

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

.consent {
  position: relative;
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 10px 0;
  cursor: pointer;
}
.consent-input {
  position: absolute;
  left: 0;
  top: 10px;
  width: 24px;
  height: 24px;
  margin: 0;
  opacity: 0;
  z-index: 1;
}
.box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 7px;
  background: var(--card);
  box-shadow: inset 0 0 0 1.5px var(--input);
  color: var(--on-selected);
  transition: background-color 150ms ease, box-shadow 150ms ease;
}
.box .icon { width: 18px; height: 18px; opacity: 0; pointer-events: none; transition: opacity 150ms ease; }
.consent:has(:checked) .box { background: var(--selected); box-shadow: inset 0 0 0 1.5px var(--selected); }
.consent:has(:checked) .box .icon { opacity: 1; }
.consent:has(:focus-visible) .box { box-shadow: inset 0 0 0 3px var(--ring); }
.consent-input:focus-visible { outline: none; }
.consent-label { --lh: 1.45; }

/* ---------- Alerts ---------- */

.error-summary {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-m);
  background: var(--error-bg);
  box-shadow: inset 0 0 0 2px var(--error);
}
.error-summary:focus-visible { outline: 3px solid var(--ring); outline-offset: 2px; }
.error-summary:focus:not(:focus-visible) { outline: none; }
.error-summary-head { display: flex; align-items: center; gap: var(--space-2); }
.error-summary-head .icon { width: 20px; height: 20px; color: var(--error); }
.error-summary-title { font-weight: 700; --lh: 1.45; }
.error-summary-list { display: flex; flex-direction: column; gap: var(--space-3); }
.error-summary-list a {
  color: var(--error);
  text-decoration: none;
  font-size: var(--text-small);
  font-weight: 600;
  --lh: 1.75;
}

.alert {
  display: flex;
  gap: 10px;
  padding: 14px var(--space-4);
  border-radius: var(--radius-m);
  background: var(--error-bg);
  box-shadow: inset 0 0 0 1px var(--error);
}
.alert:target { display: flex !important; }
.alert .icon { width: 20px; height: 20px; color: var(--error); }
.alert-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: var(--text-small);
  --lh: 1.45;
}
.alert-message { font-weight: 600; }
.alert-phone { align-self: flex-start; font-weight: 700; text-decoration: none; }

/* ---------- Button ---------- */

.button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  height: 60px;
  margin: 0;
  padding: 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-m);
  background: var(--primary);
  color: var(--primary-foreground);
  font: inherit;
  font-size: var(--text-lead);
  font-weight: 600;
  --lh: 1.45;
  cursor: pointer;
  transition: opacity 150ms ease, box-shadow 150ms ease;
}
.button:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ring); }
.button .spinner { display: none; width: 20px; height: 20px; }
.button[aria-disabled="true"] { opacity: 0.85; cursor: progress; }
.button[aria-disabled="true"] .spinner { display: block; animation: spin 800ms linear infinite; }

@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- Privacy line and footer ---------- */

.privacy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  color: var(--muted-foreground);
  font-size: var(--text-small);
  --lh: 1.45;
}
.privacy-link { font-weight: 600; text-decoration: none; }

/* Links keep their drawn size; the padding makes a 44 px tall tap target without moving anything (the logo is
   38 tall on the phone; the text links 20). */
.privacy-link,
.footer-number,
.alert-phone,
.logo {
  padding-block: var(--space-3);
  margin-block: calc(-1 * var(--space-3));
}

.footer-call {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: var(--space-4) 0;
  color: var(--muted-foreground);
  font-size: var(--text-small);
  --lh: 1.45;
}
.footer-call .icon { width: 18px; height: 18px; color: var(--primary); }
.footer-number { font-weight: 700; text-decoration: none; }

/* ---------- S02: confirmation ---------- */

.confirmation { display: flex; flex-direction: column; gap: var(--space-4); }
.confirmation:not(:target):not(.is-shown) { display: none; }
.confirmation:focus { outline: none; }

.tick-badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 28px;
  background: var(--success-bg);
  color: var(--success);
}
.tick-badge .icon { width: 28px; height: 28px; }

.confirmation-heading {
  /* The visitor's first name is in it: a long unbroken one (e.g. 35 letters) breaks inside the word rather than
     pushing the page sideways (worst-case check, tests/worst-case.spec.mjs). */
  overflow-wrap: anywhere;
  font-size: var(--text-h1);
  font-weight: 300;
  --lh: 1.1;
  letter-spacing: -1px;
}
.confirmation-heading:focus { outline: none; }
.confirmation-heading:focus-visible { outline: 3px solid var(--ring); outline-offset: 4px; }

.next-step {
  color: var(--muted-foreground);
  font-size: var(--text-lead);
  --lh: 1.45;
}

.demo-label {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: var(--space-3) 14px;
  border-radius: var(--radius-s);
  background: var(--muted);
  font-size: var(--text-small);
  --lh: 1.45;
}
.demo-label .icon { width: 18px; height: 18px; color: var(--muted-foreground); }

/* Sent: the confirmation replaces the form; the sky keeps only the logo (S02 frames). */
.page:has(#sent:target) .enquiry,
.page.is-sent .enquiry,
.page:has(#sent:target) .sky-heading,
.page.is-sent .sky-heading { display: none; }

.page:has(#sent:target) .sheet,
.page.is-sent .sheet { padding: var(--space-8) 22px; padding-bottom: max(var(--space-8), env(safe-area-inset-bottom)); }
.page:has(#sent:target) .column,
.page.is-sent .column { justify-content: space-between; gap: var(--space-6); }

/* ---------- Hover (pointer devices only) ---------- */

@media (hover: hover) and (pointer: fine) {
  .capsule:hover:not(:has(:checked)) { box-shadow: inset 0 0 0 2px var(--input); }
  .button:hover:not([aria-disabled="true"]) { opacity: 0.92; }
  .privacy-link:hover, .footer-number:hover, .alert-phone:hover, .error-summary-list a:hover { text-decoration: underline; }
}

/* ---------- Desktop (frame S01-enquiry@1440) ---------- */

@media (min-width: 1100px) {
  .page {
    display: grid;
    /* The panel grows by half of every pixel above 1440: 600 at 1440, 840 at 1920, never past 860 (spec §5). */
    grid-template-columns: clamp(600px, calc(50vw - 120px), 860px) 1fr;
    background: var(--background);
  }

  .sky {
    position: sticky;
    top: 0;
    height: 100dvh;
    min-height: 640px;
    justify-content: space-between;
    padding: var(--space-12) 56px;
    overflow: hidden;
    background:
      linear-gradient(180deg, var(--sky-1) 0%, var(--sky-2) 36%, var(--sky-2-clear) 62%),
      image-set(url("assets/sky-photo.webp") 1x, url("assets/sky-photo-2x.webp") 2x) center / cover no-repeat,
      linear-gradient(200deg, var(--sky-1), var(--sky-2));
  }

  .sky-fill { display: none; } /* the photo and its blend cover the panel; their base layer stays as it was */

  .sky-top { gap: 56px; margin: 0; max-width: none; }
  .logo img { width: 140px; height: 51px; }
  .sky-heading { gap: 14px; max-width: 488px; } /* the panel's 1440 text width: the title stays on two lines when it grows */
  .title {
    font-size: var(--text-display);
    --lh: 1.02;
    letter-spacing: -2px;
  }

  .call-card {
    display: flex;
    align-self: flex-start;
    align-items: flex-end;
    gap: var(--space-5);
    padding: var(--space-4) var(--space-5);
    border-radius: var(--radius-l);
    background: var(--scrim);
    color: var(--on-sky);
    text-decoration: none;
  }
  .call-text { display: flex; flex-direction: column; gap: var(--space-1); }
  .call-lead { font-size: var(--text-small); --lh: 1.45; }
  .call-number { font-size: var(--text-numeral); font-weight: 600; --lh: 1.45; }
  .call-mark { width: 48px; height: 56px; }

  /* The column is centred in its area at any width (it sat 120 px from the panel, so wide windows were lopsided). */
  .sheet {
    margin-top: 0;
    justify-content: center;
    align-items: center;
    padding: var(--space-16) 0;
    border-radius: 0;
    background: transparent;
  }
  /* 560 up to 1440, then 600 by 1920 and no wider (spec §5; a 600 column at 18 px is ~60 characters a line). */
  .column { flex: 0 0 auto; margin: 0; max-width: none; width: clamp(560px, calc(560px + (100vw - 1440px) / 12), 600px); }
  .enquiry { gap: 22px; }

  .forecast-strip { gap: 10px; }
  .capsule { height: 132px; }
  .range { font-size: var(--text-numeral); font-weight: 300; }
  .unit-extra { display: inline; }

  .name-mobile { flex-direction: row; align-items: flex-start; gap: var(--space-4); }
  .name-mobile .field { flex: 1 1 0; }

  .footer-call { display: none; }

  .page:has(#sent:target) .sheet,
  .page.is-sent .sheet { padding: var(--space-16) 0; }
}

/* ---------- Reduced motion: no motion at all ---------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0s !important;
    animation-duration: 0s !important;
    animation-iteration-count: 1 !important;
  }
}
