/* ==========================================================================
   Contact Page — dedicated stylesheet
   Isolated from index.html styling; only relies on the design tokens
   defined in style.css (:root variables + reset).

   Interaction model:
   - Default: cream background (var(--bg)) + dark ink content
   - Hovering `.contact-details` (desktop) or tapping it (touch) flips
     the whole page to dark: <body> gains .is-flipped which swaps colour
     tokens via CSS variables and flips the headline + subhead with a
     rotateX card flip so new copy is revealed.
   ========================================================================== */

/* Scoped CSS variables so the whole page transitions in sync. */
body.contact-body {
  --page-bg:  #fff3eb;   /* homepage cream */
  --page-fg:  #0d0d0d;   /* homepage ink */
  --page-muted: rgba(13, 13, 13, 0.62);
  --page-rule:  rgba(13, 13, 13, 0.14);
  --flip-ease: var(--ease-in-out);

  background-color: var(--page-bg) !important;
  color: var(--page-fg);
  min-height: 100vh;
  overflow-x: hidden;
  transition: background-color 0.6s var(--flip-ease),
              color 0.6s var(--flip-ease);
  cursor: auto !important;
}

/* Neutralise the site-wide dark breathing gradient + paper grain so this
   page stays clean and readable. */
body.contact-body::after { display: none !important; }
body.contact-body::before { opacity: 0 !important; }

/* Override the site-wide <main> cream background so it participates in
   the flip. */
body.contact-body main.contact-main {
  background-color: var(--page-bg) !important;
  transition: background-color 0.6s var(--flip-ease);
}

/* No custom cursor on this page — override any global cursor helpers. */
body.contact-body,
body.contact-body a,
body.contact-body button,
body.contact-body select,
body.contact-body input,
body.contact-body textarea,
body.contact-body [role="button"],
body.contact-body [data-cursor] { cursor: auto !important; }
body.contact-body .custom-cursor,
body.contact-body .custom-cursor-follower { display: none !important; }

/* Flipped state — activated when .contact-details is hovered / tapped. */
body.contact-body.is-flipped {
  --page-bg:  #0d0d0d;
  --page-fg:  #fff3eb;
  --page-muted: rgba(255, 243, 235, 0.6);
  --page-rule:  rgba(255, 243, 235, 0.16);
}

/* ── Header colour sync ─────────────────────────────────────────────────── */
/* Restore a soft top-of-viewport backdrop under the fixed header so page
   content doesn't bleed up through it while scrolling. We use a SOLID
   background-color (transitions in perfect lockstep with the body) and a
   pure `mask-image` gradient for the fade-out — the mask itself isn't a
   colour, so it can't drift out of sync during the flip. */
body.contact-body header.thread-nav-container::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: var(--page-bg) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  /* Fade to transparent over the header's bottom third so the edge feels
     soft, not a hard band. */
  -webkit-mask-image: linear-gradient(180deg, #000 60%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 60%, transparent 100%);
  transition: background-color 0.6s var(--flip-ease);
}
body.contact-body header.thread-nav-container {
  background: transparent !important;
}

body.contact-body .thread-nav-links .nav-link,
body.contact-body .nav-logo-text,
body.contact-body .mobile-nav-toggle,
body.contact-body .mobile-nav-toggle-text {
  color: var(--page-fg);
  transition: color 0.6s var(--flip-ease);
}
/* Preserve the homepage's hover-pill behaviour (higher specificity was
   defeating it). Cream text on the dark pill; on the flipped state the
   pill becomes cream and the text dark so it stays legible. */
body.contact-body .thread-nav-links .nav-link:hover,
body.contact-body .thread-nav-links .nav-link:focus-visible {
  background-color: var(--page-fg);
  color: var(--page-bg);
  outline: none;
}
body.contact-body .mobile-nav-toggle-line {
  background: var(--page-fg);
  transition: background-color 0.6s var(--flip-ease);
}
/* Logo image: match the treatment used inside the "Start a Project" contact
   modal so the flipped state has a pure-white lockup instead of an inverted
   hue. Preserve the header logo's native width / height. */
body.contact-body .nav-logo-img,
body.contact-body .mobile-menu-logo-img {
  transition: filter 0.6s var(--flip-ease);
}
body.contact-body.is-flipped .nav-logo-img,
body.contact-body.is-flipped .mobile-menu-logo-img {
  filter: brightness(0) invert(1);
}
/* Contact-us pill CTA — inverted colours on flip so it stays visible. */
body.contact-body .nav-cta {
  transition: background-color 0.6s var(--flip-ease),
              color 0.6s var(--flip-ease);
}
body.contact-body.is-flipped .nav-cta {
  background: var(--page-fg);
  color: var(--page-bg);
}

/* ── Main contact layout ────────────────────────────────────────────────── */
/* Two columns on desktop: [sidebar 320px] [content flexible].
   The sidebar hosts the address / phone / email / social + acts as the flip
   trigger. The content column holds the headline, subhead, form + submit. */
.contact-main {
  position: relative;
  z-index: 1;
  min-height: calc(100vh - 120px);
  padding: clamp(104px, 11vh, 140px) clamp(24px, 5vw, 72px) clamp(60px, 8vh, 100px);
  display: grid;
  grid-template-columns: minmax(240px, 300px) minmax(0, 1fr);
  column-gap: clamp(40px, 6vw, 96px);
  row-gap: clamp(48px, 8vh, 100px);
  align-items: start;
}

/* ── Sidebar (flip trigger) ─────────────────────────────────────────────── */
.contact-sidebar {
  grid-column: 1;
  position: sticky;
  top: clamp(104px, 11vh, 140px);
  /* Nudge the sidebar down so its top edge visually aligns with the
     baseline-top of the huge headline (which has ascender space above it).
     Without this the sidebar looks like it's floating too high, especially
     near the fading top edge of the fixed header. */
  margin-top: clamp(24px, 4vh, 56px);
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 1.8vh, 22px);
  padding: clamp(18px, 1.8vw, 26px);
  border-radius: clamp(20px, 2.4vw, 32px);
  border: 1px solid var(--page-rule);
  color: var(--page-fg);
  transition: border-color 0.6s var(--flip-ease);
  cursor: default;
  outline: none;
}
.contact-sidebar__globe {
  width: 48px;
  height: 48px;
  color: var(--page-fg);
  transition: color 0.6s var(--flip-ease);
}
.contact-sidebar__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--page-fg);
  opacity: 0.9;
  transition: background-color 0.6s var(--flip-ease);
}
.contact-sidebar__block { display: flex; flex-direction: column; gap: 8px; }
.contact-sidebar__label {
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--page-muted);
  transition: color 0.6s var(--flip-ease);
}
.contact-sidebar__value {
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-style: normal;
  font-weight: 500;
  font-size: 14px;
  line-height: 1.55;
  color: var(--page-fg);
  transition: color 0.6s var(--flip-ease);
}
.contact-sidebar__value--link {
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 0.35s ease, color 0.6s var(--flip-ease);
}
.contact-sidebar__value--link:hover,
.contact-sidebar__value--link:focus-visible {
  border-bottom-color: currentColor;
  outline: none;
}
.contact-sidebar__deck {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  align-self: flex-start;
  padding: 12px 18px 12px 16px;
  border-radius: 999px;
  border: none;
  background: var(--page-fg);
  color: var(--page-bg);
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background-color 0.6s var(--flip-ease),
              color 0.6s var(--flip-ease),
              transform 0.25s var(--flip-ease);
}
.contact-sidebar__deck:hover { transform: translateY(-2px); }
.contact-social {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.contact-social__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--page-rule);
  color: var(--page-fg);
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-decoration: none;
  transition: background-color 0.35s var(--flip-ease),
              color 0.35s var(--flip-ease),
              border-color 0.6s var(--flip-ease);
}
.contact-social__link:hover,
.contact-social__link:focus-visible {
  background: var(--page-fg);
  color: var(--page-bg);
  outline: none;
}
.contact-sidebar__hint {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--page-muted);
  transition: color 0.6s var(--flip-ease);
}
.contact-sidebar__hint::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent, #ff914d);
  animation: contact-pulse 2.2s ease-in-out infinite;
}
@keyframes contact-pulse {
  0%, 100% { transform: scale(1);   opacity: 1; }
  50%      { transform: scale(1.6); opacity: 0.4; }
}

/* ── Content column ─────────────────────────────────────────────────────── */
.contact-content {
  grid-column: 2;
  display: flex;
  flex-direction: column;
  gap: clamp(28px, 4vh, 48px);
  min-width: 0;
}

/* ── Headline ──────────────────────────────────────────────────────────── */
.contact-headlines {
  position: relative;
  perspective: 1400px;
}

.contact-title {
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-weight: 900;
  font-size: clamp(3rem, 9vw, 9rem);
  line-height: 0.95;
  letter-spacing: -0.04em;
  margin: 0;
  color: var(--page-fg);
  transform-origin: center center;
  backface-visibility: hidden;
  transition: transform 0.75s var(--flip-ease),
              opacity 0.5s var(--flip-ease),
              color 0.6s var(--flip-ease);
}
/* Serif italic accent on the second word — editorial like the reference. */
.contact-title em {
  font-family: var(--font-serif, 'Instrument Serif'), serif;
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.01em;
}

.contact-title--back {
  position: absolute;
  inset: 0;
  transform: rotateX(90deg);
  opacity: 0;
  pointer-events: none;
}

body.contact-body.is-flipped .contact-title--front {
  transform: rotateX(-90deg);
  opacity: 0;
}
body.contact-body.is-flipped .contact-title--back {
  transform: rotateX(0deg);
  opacity: 1;
}

/* ── Subhead ───────────────────────────────────────────────────────────── */
.contact-sub-wrap {
  position: relative;
  max-width: 640px;
  min-height: 3.4em;
}
.contact-sub {
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-weight: 400;
  font-size: clamp(14px, 1vw, 17px);
  line-height: 1.55;
  color: var(--page-muted);
  margin: 0;
  transition: opacity 0.55s var(--flip-ease),
              transform 0.55s var(--flip-ease),
              color 0.6s var(--flip-ease);
}
.contact-sub--back {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
}
body.contact-body.is-flipped .contact-sub--front {
  opacity: 0;
  transform: translateY(-12px);
}
body.contact-body.is-flipped .contact-sub--back {
  opacity: 1;
  transform: translateY(0);
}

/* ==========================================================================
   Form
   3×2 grid on desktop:
   [name    ][project][contact ]
   [company ][project][brief   ]
   ========================================================================== */
.contact-form {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(14px, 1.2vw, 20px);
  margin-top: clamp(8px, 2vh, 20px);
}
.ff--name    { grid-column: 1; grid-row: 1; }
.ff--company { grid-column: 1; grid-row: 2; }
.ff--project { grid-column: 2; grid-row: 1 / span 2; }
.ff--contact { grid-column: 3; grid-row: 1; }
.ff--brief   { grid-column: 3; grid-row: 2; }

/* Field card — rounded pill container that inherits the flip colours. */
.ff {
  position: relative;
  padding: clamp(18px, 2vw, 24px) clamp(20px, 2vw, 28px);
  border-radius: clamp(20px, 1.8vw, 28px);
  border: 1px solid var(--page-rule);
  background: transparent;
  color: var(--page-fg);
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 118px;
  transition: border-color 0.35s ease, box-shadow 0.35s ease;
}
.ff:focus-within {
  border-color: var(--accent, #ff914d);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent, #ff914d) 22%, transparent);
}
.ff__label {
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--page-muted);
  transition: color 0.6s var(--flip-ease);
}
.ff__sublabel {
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--page-muted);
  margin-top: 4px;
  transition: color 0.6s var(--flip-ease);
}
.ff__input,
.ff__textarea {
  width: 100%;
  border: none;
  outline: none;
  background: transparent;
  color: var(--page-fg);
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 16px;
  font-weight: 500;
  line-height: 1.45;
  padding: 0;
  transition: color 0.6s var(--flip-ease);
  min-width: 0;
}
.ff__input--sub { font-size: 15px; }
.ff__input::placeholder,
.ff__textarea::placeholder {
  color: var(--page-muted);
  opacity: 0.7;
}
.ff__textarea {
  resize: vertical;
  min-height: 100%;
  flex: 1 1 auto;
  font-size: 16px;
}
.ff__divider {
  height: 1px;
  background: var(--page-rule);
  margin: 6px 0;
  transition: background-color 0.6s var(--flip-ease);
}
.ff--project { min-height: 260px; }
.ff--project .ff__textarea { min-height: 200px; }

/* ── File upload ────────────────────────────────────────────────────────── */
.ff__file {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border: 1.5px dashed var(--page-rule);
  border-radius: 999px;
  cursor: pointer;
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--page-fg);
  transition: border-color 0.35s ease, background-color 0.35s ease;
  align-self: flex-start;
  max-width: 100%;
}
.ff__file:hover { border-color: var(--accent, #ff914d); }
.ff__file svg { flex: 0 0 auto; }
.ff__file-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ff__file-input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  border: 0;
}
.ff__file.has-file { border-style: solid; border-color: var(--accent, #ff914d); }

/* ── Consent ────────────────────────────────────────────────────────────── */
.ff-consent {
  grid-column: 1 / -1;
  grid-row: 3;
  margin-top: 6px;
}
.ff-consent__row {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--page-fg);
  cursor: pointer;
  user-select: none;
  transition: color 0.6s var(--flip-ease);
}
.ff-consent__input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.ff-consent__box {
  width: 18px;
  height: 18px;
  border-radius: 4px;
  border: 1.5px solid var(--page-rule);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: transparent;
  transition: background-color 0.25s ease,
              border-color 0.25s ease,
              color 0.25s ease;
  flex: 0 0 auto;
}
.ff-consent__box svg {
  width: 12px;
  height: 12px;
}
.ff-consent__input:checked + .ff-consent__box {
  background: var(--accent, #ff914d);
  border-color: var(--accent, #ff914d);
  color: #fff3eb;
}
.ff-consent__input:focus-visible + .ff-consent__box {
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent, #ff914d) 22%, transparent);
}
.ff-consent__text a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Field error state (red-tinted stroke via CSS custom property) */
.ff.is-invalid { border-color: #d64f3d; }

/* ── Submit ────────────────────────────────────────────────────────────── */
.contact-submit {
  grid-column: 1 / -1;
  grid-row: 4;
  margin-top: clamp(10px, 2vh, 22px);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  width: 100%;
  padding: clamp(18px, 2.2vh, 24px) 28px;
  border: none;
  border-radius: 999px;
  background: var(--page-fg);
  color: var(--page-bg);
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 0.6s var(--flip-ease),
              color 0.6s var(--flip-ease),
              transform 0.25s ease,
              opacity 0.25s ease;
}
.contact-submit:hover { transform: translateY(-2px); }
.contact-submit:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }

/* ── Toast ─────────────────────────────────────────────────────────────── */
.contact-toast {
  position: fixed;
  left: 50%;
  bottom: 32px;
  transform: translate(-50%, 120%);
  z-index: 10000;
  max-width: min(440px, calc(100vw - 32px));
  opacity: 0;
  pointer-events: none;
  transition: transform 0.5s var(--flip-ease), opacity 0.4s var(--flip-ease);
}
.contact-toast[aria-hidden="false"] {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
}
.contact-toast__inner {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 16px 18px 16px 20px;
  border-radius: 20px;
  background: #0d0d0d;
  color: #fff3eb;
  box-shadow: 0 20px 60px -20px rgba(0,0,0,0.5);
}
.contact-toast__icon {
  color: var(--accent, #ff914d);
  flex: 0 0 auto;
  margin-top: 2px;
}
.contact-toast__title {
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.contact-toast__body {
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 13px;
  font-weight: 400;
  color: rgba(255, 243, 235, 0.72);
  margin-top: 2px;
  line-height: 1.45;
}
.contact-toast__close {
  margin-left: auto;
  background: transparent;
  border: none;
  color: rgba(255, 243, 235, 0.6);
  font-size: 20px;
  line-height: 1;
  padding: 2px 6px;
  cursor: pointer;
  transition: color 0.25s ease;
}
.contact-toast__close:hover { color: #fff3eb; }

/* ── Outro section — colour sync so it reads on any body colour ─────────── */
body.contact-body #outro.outro-section {
  transition: background-color 0.6s var(--flip-ease);
}

/* ==========================================================================
   First-visit nudge — soft accent breathing on the first field so new
   visitors know the form is interactive (and by extension discover the
   focus-flip). Auto-dismissed on first focus by JS.
   ========================================================================== */
body.contact-body.first-visit .ff--name {
  border-color: color-mix(in oklab, var(--accent, #ff914d) 70%, transparent);
  animation: ff-breathe 2.6s ease-in-out infinite;
}
body.contact-body.first-visit .ff--name::after {
  content: "";
  position: absolute;
  top: -6px;
  right: 14px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent, #ff914d);
  box-shadow: 0 0 0 6px color-mix(in oklab, var(--accent, #ff914d) 22%, transparent);
  animation: ff-nudge-pulse 1.4s ease-in-out infinite;
  pointer-events: none;
}
body.contact-body.first-visit .ff--name .ff__nudge {
  opacity: 1;
  transform: translateY(0);
}

/* The small caption that appears above the first field. Hidden by default;
   revealed only during first-visit and only until the field is focused. */
.ff__nudge {
  position: absolute;
  top: -28px;
  left: 4px;
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent, #ff914d);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.4s var(--flip-ease),
              transform 0.4s var(--flip-ease);
  pointer-events: none;
  white-space: nowrap;
}

@keyframes ff-breathe {
  0%, 100% {
    border-color: color-mix(in oklab, var(--accent, #ff914d) 70%, transparent);
    box-shadow: 0 0 0 0 color-mix(in oklab, var(--accent, #ff914d) 0%, transparent);
  }
  50% {
    border-color: var(--accent, #ff914d);
    box-shadow: 0 0 0 5px color-mix(in oklab, var(--accent, #ff914d) 14%, transparent);
  }
}
@keyframes ff-nudge-pulse {
  0%, 100% { transform: scale(1);   opacity: 1; }
  50%      { transform: scale(1.35); opacity: 0.55; }
}

/* ==========================================================================
   Success screen — replaces the form after a valid submit.
   Sits in the same column as the form; `body.is-submitted` hides the
   headline / subhead / form.
   ========================================================================== */
body.contact-body.is-submitted .contact-headlines,
body.contact-body.is-submitted .contact-sub-wrap,
body.contact-body.is-submitted #contactForm { display: none; }

.contact-success {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(20px, 3vh, 32px);
  padding: clamp(16px, 3vh, 40px) 0;
  max-width: 720px;
  color: var(--page-fg);
  animation: ff-success-in 0.6s var(--flip-ease) both;
}
/* The `display: flex` above is a class selector, which outranks the browser's
   default `[hidden] { display: none }` — so the success screen rendered under
   the form on load, before any submit. This restores the hidden state (JS
   clears the attribute in showSuccess()). Class + attribute beats class alone. */
.contact-success[hidden] {
  display: none;
}
@keyframes ff-success-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
.contact-success__badge {
  position: relative;
  width: clamp(96px, 12vw, 140px);
  height: clamp(96px, 12vw, 140px);
  color: var(--page-fg);
  transition: color 0.6s var(--flip-ease);
  overflow: visible;
}
.contact-success__badge svg {
  width: 100%;
  height: 100%;
  display: block;
  position: relative;
  z-index: 1;
}

/* ── Confetti burst — spawned in JS on submit success. Pieces are
   absolutely positioned at the badge's centre and animate outward via
   CSS custom properties (--dx, --dy, --rot, --dur, --delay) set inline.
   Fully declarative — no rAF loop. ────────────────────────────────── */
.contact-confetti {
  position: absolute;
  inset: -60%;         /* extends beyond the badge for the burst radius */
  pointer-events: none;
  z-index: 0;
  overflow: visible;
}
.contact-confetti__piece {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 10px;
  height: 4px;
  border-radius: 2px;
  transform: translate(-50%, -50%) scale(0);
  opacity: 0;
  animation: contact-confetti-burst var(--dur, 1s) var(--ease-out) var(--delay, 0s) forwards;
}
@keyframes contact-confetti-burst {
  0%   { opacity: 0; transform: translate(-50%, -50%) rotate(0deg) scale(0.4); }
  20%  { opacity: 1; transform: translate(calc(-50% + calc(var(--dx) * 0.35)), calc(-50% + calc(var(--dy) * 0.35))) rotate(calc(var(--rot) * 0.35)) scale(1); }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) rotate(var(--rot)) scale(0.9); }
}
@media (prefers-reduced-motion: reduce) {
  .contact-confetti { display: none; }
}
.contact-success__title {
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-weight: 900;
  font-size: clamp(2.6rem, 8vw, 7.2rem);
  line-height: 0.95;
  letter-spacing: -0.04em;
  margin: 0;
  color: var(--page-fg);
  transition: color 0.6s var(--flip-ease);
}
.contact-success__title em {
  font-family: var(--font-serif, 'Instrument Serif'), serif;
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.01em;
}
.contact-success__body {
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: clamp(15px, 1.1vw, 18px);
  line-height: 1.6;
  color: var(--page-muted);
  margin: 0;
  max-width: 560px;
  transition: color 0.6s var(--flip-ease);
}
.contact-success__body a {
  color: var(--page-fg);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
  transition: color 0.6s var(--flip-ease);
}
.contact-success__again {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  padding: 14px 22px 14px 18px;
  border-radius: 999px;
  border: 1px solid var(--page-rule);
  background: transparent;
  color: var(--page-fg);
  font-family: var(--font-sans, 'Onest'), sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 0.35s var(--flip-ease),
              color 0.35s var(--flip-ease),
              border-color 0.6s var(--flip-ease),
              transform 0.25s ease;
}
.contact-success__again:hover {
  background: var(--page-fg);
  color: var(--page-bg);
  transform: translateY(-2px);
}
.contact-success__again:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent, #ff914d) 30%, transparent);
}

/* ==========================================================================
   Responsive
   ========================================================================== */

/* Small laptops / tablets landscape (992–1199) — tighter grid gaps. */
@media (max-width: 1199.98px) {
  .contact-main {
    grid-template-columns: minmax(220px, 260px) minmax(0, 1fr);
    column-gap: clamp(28px, 3.6vw, 56px);
  }
  .contact-form { gap: 12px; }
  .ff { padding: 16px 20px; min-height: 108px; }
  .ff--project { min-height: 236px; }
  .ff--project .ff__textarea { min-height: 180px; }
}

/* Tablets (768–991) — sidebar drops below the content, becomes full width. */
@media (max-width: 991.98px) {
  .contact-main {
    grid-template-columns: 1fr;
    padding: clamp(96px, 10vh, 128px) clamp(20px, 5vw, 40px) clamp(56px, 8vh, 80px);
    row-gap: clamp(40px, 6vh, 64px);
  }
  .contact-content { grid-column: 1; grid-row: 1; }
  .contact-sidebar {
    grid-column: 1;
    grid-row: 2;
    position: static;
    top: auto;
    margin-top: 0;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
    gap: clamp(18px, 3vw, 28px);
  }
  .contact-sidebar__globe { grid-column: 1 / -1; }
  .contact-sidebar__dot { display: none; } /* separators unnecessary in the grid */
  .contact-sidebar__deck { grid-column: 1 / -1; }
  .contact-sidebar__hint { grid-column: 1 / -1; }
  .contact-title { font-size: clamp(2.8rem, 10vw, 6.4rem); }
  .contact-form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ff--name    { grid-column: 1; grid-row: 1; }
  .ff--company { grid-column: 2; grid-row: 1; }
  .ff--project { grid-column: 1 / -1; grid-row: 2; min-height: 200px; }
  .ff--contact { grid-column: 1; grid-row: 3; }
  .ff--brief   { grid-column: 2; grid-row: 3; }
  .ff-consent  { grid-row: 4; }
  .contact-submit { grid-row: 5; }
}

/* Phones (≤767) — everything single column. */
@media (max-width: 767.98px) {
  .contact-main {
    padding: 92px 20px 60px;
    row-gap: 40px;
  }
  .contact-title { font-size: clamp(2.4rem, 12vw, 4.4rem); }
  .contact-sub { font-size: 14px; }
  .contact-form { grid-template-columns: 1fr; }
  .ff--name, .ff--company, .ff--project, .ff--contact, .ff--brief {
    grid-column: 1;
  }
  .ff--name    { grid-row: 1; }
  .ff--company { grid-row: 2; }
  .ff--project { grid-row: 3; min-height: 180px; }
  .ff--contact { grid-row: 4; }
  .ff--brief   { grid-row: 5; }
  .ff-consent  { grid-row: 6; }
  .contact-submit { grid-row: 7; }
  .contact-sidebar {
    grid-template-columns: 1fr;
    padding: 22px;
  }
  .contact-sidebar__deck { align-self: stretch; justify-content: center; }
}

/* Very small phones (<380) */
@media (max-width: 379.98px) {
  .contact-title { font-size: clamp(2rem, 12.5vw, 3rem); }
  .ff { padding: 14px 16px; }
  .ff__input, .ff__textarea { font-size: 15px; }
}

/* Reduced motion — instant crossfade, no rotate. */
@media (prefers-reduced-motion: reduce) {
  .contact-title,
  .contact-title--back,
  .contact-sub,
  .contact-sub--back {
    transition-duration: 0.001s;
    transform: none !important;
  }
  .contact-title--back,
  .contact-sub--back {
    opacity: 0;
  }
  body.contact-body.is-flipped .contact-title--front,
  body.contact-body.is-flipped .contact-sub--front { opacity: 0; }
  body.contact-body.is-flipped .contact-title--back,
  body.contact-body.is-flipped .contact-sub--back  { opacity: 1; }
  .contact-toast { transition-duration: 0.001s; }
}
