/* Singlespot contact page. Its own stylesheet for the same reason as kura.css:
   page-specific rules carrying their own global resets, so folding them into
   styles.css would tax every other page.

   This page is the merge of two forms that used to exist side by side — the
   gradient card inlined in index.html and the old kura-contact.html — so it
   carries the union of their fields and, unlike either, re-themes itself around
   the product the visitor is asking about. */

:root{
  --field-bg: rgba(255,255,255,0.025);
  --field-border: rgba(255,255,255,0.1);
  /* Both are KURA-local tokens (see kura.css) rather than design-system ones,
     and this page does not load kura.css — so they are redeclared here. */
  --border-subtle: rgba(255,255,255,0.08);
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ── Product theming ──────────────────────────────────────────────────────
   Everything accent-coloured on this page reads these custom properties, and
   nothing else hardcodes a product colour. body[data-interest] is switched by
   contact.js.

   The gradients are built out of their stop colours rather than written
   literally, because `transition: background-image` does nothing —
   background-image is not an animatable property. An *unregistered* custom
   property is not animatable either: it has no type, so the browser can only
   swap it. Registering each stop as a <color> below gives it one, so the
   `transition` on body interpolates the stops and the gradients built from them
   follow. Everything else here resolves to a plain colour, which the ordinary
   transitions on each element animate.

   Colours come from the design system — see _ds/.../colors_and_type.css. The
   @property initial-values are the one place a literal is unavoidable:
   initial-value must be a computationally independent value, so it cannot read
   a var(). They are only a pre-registration fallback; every real value below
   goes through a token. */
@property --g1 { syntax: '<color>'; inherits: true; initial-value: #7F5AF0; }
@property --g2 { syntax: '<color>'; inherits: true; initial-value: #09A5E9; }
@property --g3 { syntax: '<color>'; inherits: true; initial-value: #2CB67D; }
@property --h1 { syntax: '<color>'; inherits: true; initial-value: transparent; }
@property --h2 { syntax: '<color>'; inherits: true; initial-value: transparent; }

body{
  /* House default: no product chosen yet, so the title wears the tri-gradient. */
  --g1: var(--kura-purple);
  --g2: var(--atlas-cyan);
  --g3: var(--ss-mint);
  --h1: color-mix(in srgb, var(--kura-purple) 13%, transparent);
  --h2: color-mix(in srgb, var(--atlas-cyan) 6%, transparent);
  --accent:       var(--kura-purple);
  --accent-soft:  var(--overlay-purple);
  --accent-glow:  var(--shadow-glow-purple);
  --accent-line:  color-mix(in srgb, var(--kura-purple) 50%, transparent);
  --accent-hover: #9171F5;   /* hover tint; the design system has no token for it */

  --accent-grad: linear-gradient(90deg, var(--g1) 0%, var(--g2) 50%, var(--g3) 100%);
  --accent-halo: radial-gradient(60% 60% at 50% 0%, var(--h1) 0%, var(--h2) 55%, transparent 100%);
  transition: --g1 .6s ease, --g2 .6s ease, --g3 .6s ease, --h1 .6s ease, --h2 .6s ease;
}
body[data-interest="kura"]{
  --g1: var(--ss-mint);
  --g2: #5FE3AE;
  --g3: var(--ss-mint);
  --h1: color-mix(in srgb, var(--ss-mint) 20%, transparent);
  --h2: color-mix(in srgb, var(--ss-mint) 7%, transparent);
  --accent:       var(--ss-mint);
  --accent-soft:  var(--overlay-mint);
  --accent-glow:  var(--shadow-glow-mint);
  --accent-line:  color-mix(in srgb, var(--ss-mint) 50%, transparent);
  --accent-hover: #3ACE91;
}
body[data-interest="atlas"]{
  --g1: var(--kura-purple);
  --g2: #A78BFA;             /* mid-stop highlight; no token */
  --g3: var(--kura-purple);
  --h1: color-mix(in srgb, var(--kura-purple) 20%, transparent);
  --h2: color-mix(in srgb, var(--kura-purple) 7%, transparent);
  --accent:       var(--kura-purple);
  --accent-soft:  var(--overlay-purple);
  --accent-glow:  var(--shadow-glow-purple);
  --accent-line:  color-mix(in srgb, var(--kura-purple) 50%, transparent);
  --accent-hover: #9171F5;
}
body[data-interest="platforms"]{
  --g1: var(--atlas-cyan);
  --g2: #5CCDF7;
  --g3: var(--atlas-cyan);
  --h1: color-mix(in srgb, var(--atlas-cyan) 20%, transparent);
  --h2: color-mix(in srgb, var(--atlas-cyan) 7%, transparent);
  --accent:       var(--atlas-cyan);
  --accent-soft:  var(--overlay-cyan);
  --accent-glow:  var(--shadow-glow-cyan);
  --accent-line:  color-mix(in srgb, var(--atlas-cyan) 50%, transparent);
  --accent-hover: #2BB9F5;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { height: 100%; background: var(--bg-deep); }
body {
  font-family: var(--ff-body);
  background: var(--bg-deep);
  color: var(--fg-1);
  min-height: 100%;
  -webkit-font-smoothing: antialiased;
}

canvas#bg {
  position: fixed;
  top: 0; left: 0;
  width: 100%; height: 100%;
  z-index: 0;
  pointer-events: none;
}

/* Layout */
.page {
  position: relative;
  z-index: 1;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 40px 48px 0;
}

/* The header is the shared Singlespot nav (markup in contact.html, styles in
   nav.css) — the old page's logo-top-left/back-top-right rules went with the
   elements they styled. */

/* ── Form column ───────────────────────────────────────────────────────── */
.form-wrapper {
  margin-top: 140px;
  width: 100%;
  max-width: 560px;
  opacity: 0;
  animation: fadeUp 0.9s var(--ease-out-expo) 0.3s forwards;
}

.form-title {
  font-family: var(--ff-display);
  font-size: clamp(2rem, 4.5vw, 2.75rem);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1.12;
  margin-bottom: 12px;
  color: var(--fg-1);
}
/* The two halves crossfade independently when the product changes: contact.js
   adds .is-swapping, waits out this transition, swaps the text, then removes it. */
.form-title span {
  display: inline-block;
  transition: opacity .22s ease, transform .22s var(--ease-out-expo);
}
.form-title.is-swapping .title-lead   { opacity: 0; transform: translateY(-6px); }
.form-title.is-swapping .title-accent { opacity: 0; transform: translateY(-6px); transition-delay: .04s; }

.title-accent {
  background-image: var(--accent-grad);
  background-size: 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: gradientShift 8s ease infinite;
  transition: opacity .22s ease, transform .22s var(--ease-out-expo);
}
@keyframes gradientShift {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

.form-sub {
  font-size: 0.9375rem;
  color: var(--fg-3);
  font-weight: 400;
  line-height: 1.6;
  margin-bottom: 32px;
  transition: opacity .25s ease;
}
.form-sub.is-swapping { opacity: 0; }

/* ── The card ──────────────────────────────────────────────────────────────
   A restrained dark panel with an accent hairline and halo, rather than the
   full-bleed gradient the home page's inline form wears — at this size a
   gradient that loud swamps the fields sitting on it. */
.contact-card {
  position: relative;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: rgba(255,255,255,0.018);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  padding: 34px 32px 32px;
  overflow: hidden;
  transition: border-color .6s ease;
}
.contact-card::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: var(--accent-halo);
  pointer-events: none;
}
.contact-card > * { position: relative; }
/* The accent hairline across the top edge — the page's clearest product tell. */
.card-rule {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background-image: var(--accent-grad);
  background-size: 200% 100%;
  animation: gradientShift 8s ease infinite;
}

/* Fields */
.form-row {
  display: flex;
  gap: 12px;
  margin-bottom: 14px;
}

.field {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.field.full {
  width: 100%;
  margin-bottom: 14px;
}

.field label {
  font-family: var(--ff-mono);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--fg-4);
  font-weight: 400;
  margin-bottom: 6px;
}

.field input,
.field select,
.field textarea {
  background: var(--field-bg);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-md);
  padding: 13px 16px;
  font-family: var(--ff-body);
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--fg-1);
  outline: none;
  transition: border-color 0.5s ease, background 0.3s ease, box-shadow 0.5s ease;
  width: 100%;
}
.field input::placeholder,
.field textarea::placeholder {
  color: rgba(255,255,255,0.22);
}
.field input:hover,
.field select:hover,
.field textarea:hover {
  border-color: rgba(255,255,255,0.16);
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--accent-line);
  background: rgba(255,255,255,0.04);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.field select {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none'%3E%3Cpath d='M1 1.5l5 5 5-5' stroke='%2361616C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  padding-right: 40px;
}
.field select option {
  background: #1a1525;
  color: var(--fg-1);
}
.field textarea {
  resize: vertical;
  min-height: 110px;
  line-height: 1.55;
  font-family: var(--ff-body);
}
/* Invalid-field flag, set by contact.js instead of inline styles. */
.field .is-invalid {
  border-color: color-mix(in srgb, var(--negative) 70%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--negative) 12%, transparent);
}

/* ── "Add more detail" disclosure ─────────────────────────────────────────
   Industry is the field most visitors skip, so it is collapsed by default and
   the form reads short. Height is animated via max-height because the content
   is a single known-size field. */
.more { margin-bottom: 14px; }
.more-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: 0;
  padding: 2px 0 8px;
  cursor: pointer;
  font-family: var(--ff-mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-4);
  transition: color 0.3s ease;
}
.more-toggle:hover { color: var(--fg-2); }
.more-chevron { transition: transform .3s var(--ease-out-expo); }
.more-toggle[aria-expanded="true"] { color: var(--fg-3); }
.more-toggle[aria-expanded="true"] .more-chevron { transform: rotate(180deg); }
.more-fields {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  /* visibility, not just height: without it the Industry select stays in the
     tab order and is announced by screen readers while collapsed — a field the
     toggle has just reported as aria-expanded="false". Held until the collapse
     finishes, then flipped instantly. */
  visibility: hidden;
  transition: max-height .35s var(--ease-out-expo), opacity .25s ease, visibility 0s linear .35s;
}
.more-fields.is-open {
  max-height: 160px;
  opacity: 1;
  visibility: visible;
  transition: max-height .35s var(--ease-out-expo), opacity .25s ease, visibility 0s;
}

/* Opt-in — carried over from the home page's inline form, which is the only one
   of the two that asked. */
.optin {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 4px;
  font-size: 0.75rem;
  line-height: 1.6;
  color: var(--fg-3);
  cursor: pointer;
}
.optin input {
  margin-top: 2px;
  flex: none;
  accent-color: var(--accent);
  transition: accent-color .6s ease;
}
.optin a {
  color: var(--fg-2);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(255,255,255,0.25);
}
.optin a:hover { color: var(--accent); }

/* Submit */
.submit-btn {
  display: inline-block;
  margin-top: 22px;
  padding: 14px 40px;
  font-family: var(--ff-body);
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--fg-1);
  background: var(--accent);
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background .6s ease, box-shadow .4s ease, transform .3s var(--ease-out-expo), opacity .3s ease;
  width: 100%;
  position: relative;
  overflow: hidden;
}
.submit-btn::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(135deg, transparent 40%, rgba(255,255,255,0.22) 50%, transparent 60%);
  background-size: 200% 100%;
  animation: btnShine 3s ease infinite;
  pointer-events: none;
}
@keyframes btnShine { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
.submit-btn:hover:not(:disabled) {
  background: var(--accent-hover);
  box-shadow: var(--accent-glow);
  transform: translateY(-1px);
}
.submit-btn:disabled { opacity: 0.6; cursor: wait; }
/* No product picked yet: wear the same house tri-gradient as the headline
   accent and the card hairline, instead of a single flat accent colour. */
body[data-interest=""] .submit-btn {
  background-image: var(--accent-grad);
  background-size: 200% 100%;
  animation: gradientShift 8s ease infinite;
}
body[data-interest=""] .submit-btn:hover:not(:disabled) {
  background-image: var(--accent-grad);
  box-shadow: var(--accent-glow);
}
/* Same crossfade the headline uses, so the label and the title change together. */
.submit-btn span.label { display: inline-block; transition: opacity .2s ease; }
.submit-btn.is-swapping span.label { opacity: 0; }

/* Privacy note */
.privacy-note {
  margin-top: 18px;
  font-family: var(--ff-mono);
  font-size: 0.6875rem;
  color: var(--fg-4);
  line-height: 1.6;
  letter-spacing: 0.01em;
}
.privacy-note a {
  color: var(--fg-3);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(255,255,255,0.2);
  transition: color 0.3s;
}
.privacy-note a:hover { color: var(--accent); }

/* Success state */
.success-msg {
  display: none;
  text-align: center;
  padding: 60px 0;
}
.success-msg.active { display: block; animation: fadeUp 0.6s var(--ease-out-expo) forwards; }
.success-msg .check {
  width: 56px; height: 62px;
  margin: 0 auto 20px;
  position: relative;
  display: grid; place-items: center;
}
.success-msg .check::before {
  content: '';
  position: absolute; inset: 0;
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-line);
}
.success-msg .check svg {
  position: relative; z-index: 1;
  width: 22px; height: 22px;
  stroke: var(--accent);
}
.success-msg h3 {
  font-family: var(--ff-display);
  font-size: 1.375rem;
  font-weight: 500;
  margin-bottom: 8px;
  letter-spacing: -0.01em;
}
.success-msg p {
  font-size: 0.875rem;
  color: var(--fg-3);
  font-weight: 400;
}

/* ── Footer ────────────────────────────────────────────────────────────────
   The same footer every other page carries. Its own rules rather than the
   shared hv30–hv35 hover classes, which live in styles.css — a stylesheet this
   page does not load. */
.site-footer {
  width: 100%;
  margin-top: 110px;
  border-top: 1px solid rgba(255,255,255,0.06);
}
.site-footer a { text-decoration: none; }
.footer-pad { max-width: 1000px; margin: 0 auto; padding: 64px 48px 48px; }
.footer-grid {
  display: grid;
  grid-template-columns: 1.2fr 1fr 1fr 1fr;
  gap: 40px;
  align-items: start;
}
.footer-logo { height: 22px; width: auto; display: block; }
.footer-heading {
  font-family: var(--ff-mono);
  font-size: 10px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--fg-4);
}
.footer-col { display: flex; flex-direction: column; gap: 12px; margin-top: 18px; }
.footer-col a { font-size: 13px; color: var(--fg-3); transition: color .3s ease; }
.footer-col a:hover { color: var(--fg-1); }
.footer-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  font-family: var(--ff-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-4);
  margin-top: 64px;
  border-top: 1px solid rgba(255,255,255,0.06);
  padding-top: 24px;
}

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (max-width: 768px) {
  .page { padding: 32px 24px 0; }
  .form-wrapper { margin-top: 110px; }
  .contact-card { padding: 28px 22px 26px; }
  .footer-pad { padding: 48px 24px 40px; }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 32px; }
}
@media (max-width: 480px) {
  .page { padding: 24px 16px 0; }
  .form-wrapper { margin-top: 90px; }
  /* Stacked, each field owns its own 14px gap — otherwise the row's own
     margin-bottom lands on top of the last field's and doubles that one gap. */
  .form-row { flex-direction: column; gap: 0; margin-bottom: 0; }
  .form-row .field { margin-bottom: 14px; }
  .contact-card { padding: 24px 18px 22px; }
  .footer-grid { grid-template-columns: 1fr; gap: 28px; }
}

/* Motion is decorative throughout: the gradient drifts, the button shine and the
   entrance are all safe to drop. The colour transitions stay — they carry meaning. */
@media (prefers-reduced-motion: reduce) {
  .title-accent, .card-rule { animation: none; }
  .submit-btn::before { animation: none; opacity: 0; }
  .form-wrapper { animation: none; opacity: 1; }
  .success-msg.active { animation: none; }
}
