/* ============================================================
   Refresh Health — contact.css
   Only what is specific to /contact/. Tokens, typography and the
   header / partner-cta / footer come from base.css + components.css.
   ============================================================ */

/* ---------- Hero ---------- */

/* The band that continues above the document when the page is overscrolled
   (see the `html` rule in base.css) — this hero's own base colour. */
:root { --band-top: var(--panel-alt); }

.hero {
  position: relative;
  overflow: hidden;
  background: var(--panel-alt);
  /* Same soft-blob recipe as the platform hero, repositioned so the
     two interior pages don't read as literal copies of one another. */
  background-image:
    radial-gradient(55% 75% at 12% 20%, var(--blue-steam) 0%, color-mix(in srgb, var(--blue-steam) 0%, transparent) 70%),
    radial-gradient(50% 70% at 88% 75%, var(--blue-steam) 0%, color-mix(in srgb, var(--blue-steam) 0%, transparent) 70%);
}

.hero__hex { opacity: var(--decor-ink); }

.hero__decor {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* Shared canonical artwork, reused at a rotation/position this page
   hasn't used yet — see platform.css for the same convention. Rotation
   stays in 90deg steps, the only increments that don't skew the source
   vector's own right angles. Both pieces sit at the hero's side edges,
   bleeding out of frame rather than floating in the middle of the band.

   --reveal-rest and --reveal-opacity are what each piece's arrival lands
   on. Both are rotated as drawn and the circuit is held under full
   strength, so an entrance ending on the primitive's defaults would
   unrotate them and print the circuit at full ink. See the .reveal
   primitive in components.css. */
.hero__circuit {
  position: absolute;
  left: -6%;
  top: 14%;
  width: clamp(160px, 20vw, 288px);
  --reveal-rest: rotate(90deg);
  --reveal-opacity: var(--decor-ink);
  transform: rotate(90deg);
  transform-origin: center;
  opacity: var(--decor-ink);
}

.hero__hex {
  position: absolute;
  right: -3%;
  bottom: 10%;
  width: clamp(64px, 7.4vw, 107px);
  --reveal-rest: rotate(180deg);
  transform: rotate(180deg);
  transform-origin: center;
}

.hero__inner {
  position: relative;
  z-index: 1;
  padding-block: clamp(56px, 9vw, 128px) clamp(48px, 7vw, 96px);
}

/* Same frosted-glass recipe as .button-bar / .site-header .logo /
   .pill-button / the home hero panel, so this bubble reads as the
   same material. */
.hero__panel {
  max-width: 640px;
  margin-inline: auto;
  padding: clamp(28px, 4vw, 48px) clamp(24px, 4.5vw, 56px);
  border-radius: var(--radius-lg);
}

.hero__title {
  font-family: var(--font-heading);
  font-size: clamp(36px, 4.4vw, 60px);
  line-height: 0.98;
  letter-spacing: 0.02em;
  color: var(--ink);
}

.hero__lead {
  max-width: 560px;
  margin-top: clamp(20px, 2.4vw, 28px);
  font-size: clamp(18px, 1.6vw, 22px);
  line-height: 1.5;
}

/* ---------- Intake band ---------- */

.intake-band {
  background: var(--surface-alt);
}

/* ---------- Form card ---------- */

/* --card-shadow is named rather than inlined because the card's arrival
   animates it and has to land back on exactly this value — see the reveal
   block at the foot of this file. */
.contact-form {
  --card-shadow: var(--shadow-md);
  padding: clamp(28px, 4vw, 48px);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--card-shadow);
}

.contact-form__heading {
  margin-bottom: clamp(24px, 3vw, 36px);
  /* Pure white rather than the grey .eyebrow ships elsewhere — this
     heading is the first thing read on the card, not a section label
     sitting beside body copy. */
  color: var(--white);
}

.field-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-md);
}

.field-grid--full {
  margin-top: var(--space-md);
}

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

.field--wide {
  grid-column: 1 / -1;
}

.field__label {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.04em;
  /* --text-muted only clears 4.5:1 at the larger sizes .eyebrow uses; at
     13px this needs the darker blue instead. */
  color: var(--blue-accent);
}

.field__input {
  width: 100%;
  padding: 12px var(--space-sm);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--text);
  transition: border-color var(--transition), box-shadow var(--transition);
}

.field__input::placeholder {
  color: var(--text-subtle);
}

.field__input:hover {
  border-color: var(--blue-primary);
}

.field__input:focus-visible {
  border-color: var(--blue-accent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue-accent) 14%, transparent);
}

textarea.field__input {
  min-height: 140px;
  resize: vertical;
}

.field__select-wrap {
  position: relative;
}

select.field__input {
  appearance: none;
  padding-right: var(--space-xl);
  color: var(--text);
}

select.field__input:invalid {
  color: var(--text-placeholder);
}

.field__chevron {
  position: absolute;
  right: var(--space-sm);
  top: 50%;
  transform: translateY(-50%);
  color: var(--ink-muted);
  pointer-events: none;
}

.contact-form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
  margin-top: clamp(28px, 3.4vw, 40px);
}

.contact-form__submit {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  padding: 14px clamp(26px, 3vw, 36px);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  /* Three layers, and the middle one is load-bearing: the sheen on top is
     translucent, so without an opaque fill under it the border-box
     gradient shows through the whole button instead of just the 1px rim.
     On the white theme the sheen was near-opaque and hid that; on black
     it is not. Same fill + sheen + rim stack as .pill-button. */
  background:
    linear-gradient(180deg, var(--sheen-strong-top), var(--sheen-strong-bottom)) padding-box,
    linear-gradient(var(--panel), var(--panel)) padding-box,
    var(--gradient-brand-edge) border-box;
  box-shadow:
    inset 0 1px 0 var(--sheen-highlight),
    var(--shadow-sm);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 16px;
  letter-spacing: 0.02em;
  color: var(--blue-accent);
  cursor: pointer;
  transition: transform var(--transition), box-shadow var(--transition);
}

.contact-form__submit:hover {
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 var(--sheen-highlight-hover),
    var(--shadow-md);
}

.contact-form__submit:active { transform: translateY(0); }

.contact-form__note {
  color: var(--text-subtle);
}

/* ---------- Submit, mid-flight ---------- */

/* The button is the only thing on the card that reports the send is in
   progress, so it has to stop looking pressable while it is. No spinner:
   the label already says "Sending…", and a second moving thing on a card
   that is otherwise still would be the loudest element on the page. */
.contact-form__submit:disabled {
  cursor: progress;
  opacity: 0.65;
  transform: none;
}

.contact-form__submit:disabled:hover {
  transform: none;
  box-shadow:
    inset 0 1px 0 var(--sheen-highlight),
    var(--shadow-sm);
}

/* ---------- What the form says back ---------- */

/* One line, three tones. Empty it collapses entirely — no reserved gap
   under the button waiting for a message that may never come. */
.contact-form__status {
  margin-top: var(--space-md);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
  color: var(--text-muted);
}

.contact-form__status:empty {
  display: none;
}

/* Green and gold are the site's two accent inks; neither carried a state
   meaning before this. Refusal takes gold — the palette has no red, and
   inventing one for a line of text would put a hue on the page that
   appears nowhere else. Gold still reads as "stop and look" against this
   ground, which is the whole job. */
.contact-form__status[data-tone="error"]   { color: var(--gold-ink); }
.contact-form__status[data-tone="working"] { color: var(--text-muted); }

/* ---------- The card, once it has been sent ---------- */

/* `hidden` is how the script holds this back, and a display rule of any
   kind beats the UA stylesheet's [hidden] { display: none } — so the
   attribute has to be honoured explicitly or the panel ships visible,
   sitting under the form telling everyone their message was sent. */
.contact-form__done[hidden] { display: none; }

.contact-form__done {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding: clamp(20px, 2.6vw, 28px) 0 var(--space-2xs);
}

.contact-form__done-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(20px, 2.2vw, 26px);
  letter-spacing: 0.01em;
  color: var(--green-ink);
}

.contact-form__done-copy {
  max-width: 46ch;
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-muted);
}

/* The panel is focused when it appears, so that a keyboard visitor whose
   focus was on the now-hidden Send button is not dropped back to the top
   of the document. It is not interactive and cannot be tabbed to, so the
   global focus ring would be pointing at something nobody can act on —
   the heading colour is what marks the arrival instead. */
.contact-form__done:focus,
.contact-form__done:focus-visible {
  outline: none;
}

/* ---------- Fields that failed ---------- */

/* Driven by aria-invalid rather than :invalid or :user-invalid, and the
   script is what sets it. :invalid is true for every empty required
   field from first paint, which would outline a form nobody has filled
   in yet; :user-invalid is the pseudo-class for "and the visitor has
   had their turn", but the browser only flips it for validation IT ran,
   and this form carries `novalidate` precisely so that the reporting is
   ours. So the attribute the script already owes assistive tech is the
   same signal the stylesheet keys off — one source of truth, set the
   moment a submit is refused and cleared as each field is fixed. */
.field__input[aria-invalid="true"] {
  border-color: var(--gold-ink);
}

.field__input[aria-invalid="true"]:focus-visible {
  border-color: var(--gold-ink);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--gold-ink) 16%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  .contact-form__submit:hover { transform: none; }
}

@media (max-width: 560px) {
  .field-grid { grid-template-columns: 1fr; }
  .field--wide { grid-column: auto; }
}

/* ============================================================
   Arrival — what lands, and in what order

   The primitive is .reveal in components.css. The hero is the same
   sequence the other two pages open on: the pane lands and frosts, its
   two lines rise inside it, and the artwork drifts in at the edges.

   Below the hero the page parts company with them, deliberately.

   /  and /platform/ are pages to be read, and they are choreographed
   section by section as a reader reaches them. This page is a page to
   be USED: the form is the reason anyone is here, and a task surface
   that assembles itself in front of someone who came to type is
   theatre charged to the visitor. So nothing inside the card animates.
   No field-by-field stagger, no label rising after its input, no
   delay between arriving and being able to fill it in. The card
   arrives as one object and it arrives ready.

   What it does do is land: it rises the last two dozen pixels while
   its shadow opens from --shadow-sm to the --shadow-md it is drawn
   with, so the card reads as coming to rest above the band rather than
   fading up out of it. Shadow, not scale, because this card is opaque
   paper on a tinted band — the glass panes elsewhere on the site scale
   because glass sits ON a surface, and paper settles ONTO one.
   ============================================================ */

/* ---------- Hero ---------- */

.reveals-armed .hero__title { --reveal-delay: 140ms; }
.reveals-armed .hero__lead  { --reveal-delay: 220ms; }

/* Authored in each piece's own rotated frame — a few degrees of turn and
   a hair of scale, so neither slides in from anywhere. */
.reveals-armed .hero__circuit,
.reveals-armed .hero__hex {
  --reveal-duration: var(--reveal-long);
}

.reveals-armed .hero__circuit {
  --reveal-from: rotate(-8deg) scale(0.95);
  --reveal-delay: 300ms;
}

.reveals-armed .hero__hex {
  --reveal-from: rotate(10deg) scale(0.9);
  --reveal-delay: 400ms;
}

/* ---------- The intake band ---------- */

.reveals-armed .contact-form {
  --reveal-from: translateY(26px);
  --reveal-duration: var(--reveal-long);
  box-shadow: var(--shadow-sm);
  transition-property: opacity, transform, box-shadow;
}

.reveals-armed .contact-form.is-revealed {
  box-shadow: var(--card-shadow);
}

/* Paper has no viewport to arrive into, and a stated preference for
   stillness is a preference for the page as drawn. */
@media (prefers-reduced-motion: reduce), print {
  .reveals-armed .contact-form { box-shadow: var(--card-shadow); }
}
