/* ==========================================================================
   Contact page (design system v3). Loaded after styles.css.
   Contact's colour moment is blue: Nick's portrait sits on a blue tile.
   ========================================================================== */

/* ---------- Intro ---------- */
.contact-intro__copy { display: grid; gap: 18px; align-content: center; }
.contact-intro__copy p { margin: 0; }
.contact-intro__copy > p { max-width: 46ch; }
.contact-mail { display: grid; gap: 4px; justify-items: start; margin-top: 10px; }
.contact-mail__link {
  color: var(--ink); font-weight: 650; font-size: clamp(1.6rem, 1rem + 3vw, 3.25rem); line-height: 1.15; letter-spacing: -0.02em;
  overflow-wrap: anywhere;
  text-decoration: underline; text-decoration-color: var(--yellow); text-decoration-thickness: 0.14em;
  text-underline-offset: 0.14em; text-decoration-skip-ink: none;
  background: linear-gradient(var(--yellow), var(--yellow)) no-repeat 0 92% / 0% 45%;
  transition: background-size 0.35s var(--ease), text-decoration-color 0.2s;
}
.contact-mail__link:hover { background-size: 100% 45%; text-decoration-color: var(--ink); }
.contact-intro__jump { gap: 4px 26px; margin-top: 4px; }

/* Portrait on a blue tile; a softer disc sits behind his head */
.contact-intro__photo { width: 100%; max-width: 500px; justify-self: center; }
.contact-tile {
  position: relative; overflow: hidden; aspect-ratio: 1; border-radius: var(--r-lg);
  background: radial-gradient(circle at 50% 44%, #2F80FF 0 31%, transparent 31.4%), var(--blue);
  box-shadow: var(--shadow);
}
.contact-tile img { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: auto; scale: 1.1; transform-origin: 50% 100%; }
@media (max-width: 899px) { .contact-intro__photo { max-width: 330px; } }

/* ---------- Statement + airport photo ---------- */
.contact-statement .lit { max-width: 24ch; font-size: clamp(1.9rem, 1.3rem + 1.9vw, 3rem); line-height: 1.12; letter-spacing: -0.02em; }
/* "Like meeting you." gets the highlighter; it draws itself once the reading reaches it */
.contact-statement__like {
  background: linear-gradient(transparent 58%, var(--yellow) 58%, var(--yellow) 90%, transparent 90%) no-repeat 0 0 / 100% 100%;
}
.contact-statement__photo { width: 100%; max-width: 560px; justify-self: end; rotate: 1.5deg; }
/* native shape, so the photo's own "Airport Rides" lettering is never cropped */
.contact-statement__photo .photo { aspect-ratio: 960 / 502; box-shadow: var(--shadow); }
.contact-statement { padding-top: clamp(28px, 4vw, 56px); }
@media (max-width: 899px) { .contact-statement__photo { justify-self: start; rotate: 0deg; } }

/* ---------- Phone + DMs ---------- */
.contact-dms { display: grid; gap: 12px; padding-top: 4px; }
@media (min-width: 520px) { .contact-dms { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.contact-dms a {
  display: flex; align-items: center; gap: 14px; padding: 16px 18px;
  border-radius: 16px; background: var(--white); box-shadow: 0 1px 2px rgba(42, 46, 49, 0.08);
  color: var(--ink); text-decoration: none; transition: transform 0.3s var(--bounce);
}
.contact-dms a:hover { transform: translateY(-3px) rotate(-1deg); }
.contact-dms__icon { display: grid; place-items: center; flex: none; width: 44px; height: 44px; border-radius: 50%; background: var(--ink); color: var(--yellow); }
.contact-dms__icon svg { width: 19px; height: 19px; }
.contact-dms b { display: block; font-weight: 650; line-height: 1.25; }
.contact-dms small { display: block; color: var(--muted); font-size: 0.95rem; line-height: 1.3; }

.contact-call { width: 100%; max-width: 500px; justify-self: center; }
.contact-call__note { display: block; width: fit-content; margin: 0 8px 12px auto; transition: opacity 0.3s; }
.contact-call:has(.callme[open]) .contact-call__note { opacity: 0; }
.contact-call__card {
  padding: clamp(24px, 3vw, 36px); border-radius: var(--r-lg); box-shadow: var(--shadow);
  rotate: -1.5deg; transition: rotate 0.4s var(--bounce);
}
.contact-call__card:hover, .contact-call__card:has(.callme[open]) { rotate: 0deg; }
.contact-call__top { display: flex; align-items: center; gap: 14px; margin-bottom: 22px; }
.contact-call__icon { display: grid; place-items: center; flex: none; width: 52px; height: 52px; border-radius: 50%; background: var(--yellow); color: var(--ink); }
.contact-call__icon svg { width: 24px; height: 24px; }

/* The details element: when it's open, the "hide" button drops below the number */
.contact-call .callme { display: flex; flex-direction: column; gap: 18px; }
.contact-call .callme[open] > summary { order: 2; }
.contact-call__closed { display: grid; gap: 22px; justify-items: start; }
.contact-call__mask { color: var(--white); font-weight: 700; font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.4rem); line-height: 1.1; letter-spacing: -0.01em; white-space: nowrap; }
.contact-call__mask span { display: inline-block; color: var(--yellow); font-size: 0.42em; letter-spacing: 0.22em; vertical-align: 0.35em; }
.contact-call .callme summary:focus-visible { outline: none; }
.contact-call .callme summary:focus-visible .btn { outline: 3px solid var(--yellow); outline-offset: 3px; }
.contact-call__body { display: grid; gap: 10px; }
.contact-call__body p { margin: 0; }
.contact-call .callme__num { justify-self: start; margin: 0 0 4px; color: var(--yellow); line-height: 1.1; text-decoration: none; white-space: nowrap; }
.contact-call .callme__num:hover { text-decoration: underline; text-decoration-thickness: 3px; text-underline-offset: 6px; }

@keyframes contact-ring {
  0%, 100% { rotate: 0deg; }
  10%, 30%, 50% { rotate: -16deg; }
  20%, 40%, 60% { rotate: 16deg; }
  70% { rotate: 0deg; }
}
@media (prefers-reduced-motion: no-preference) {
  .contact-call:has(.callme[open]) .contact-call__icon svg { animation: contact-ring 1.1s 0.1s ease-in-out 2; }
  .contact-call:has(.callme:not([open])) .contact-call__card:hover .contact-call__icon svg { animation: contact-ring 1.1s ease-in-out; }
}

/* ---------- Work with me ---------- */
/* The form uses the full width: who you are + topic on the left, the message on the right */
.contact-work__head { margin-bottom: clamp(22px, 3vw, 32px); }
.contact-work__form { padding: clamp(22px, 3.5vw, 44px); }
@media (min-width: 960px) {
  .contact-form { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: auto auto 1fr; gap: 24px clamp(28px, 3.5vw, 48px); }
  .contact-form > .form__row { grid-area: 1 / 1; }
  .contact-form > fieldset { grid-area: 2 / 1; }
  .contact-form > .contact-form__msg { grid-area: 1 / 2 / 4 / 3; grid-template-rows: auto 1fr; }
  .contact-form__msg textarea { height: 100%; min-height: 220px; }
  .contact-form > .contact-form__send { grid-area: 3 / 1; align-self: end; }
}

/* ---------- Motion ----------
   Same rules as motion.css: the static styles above are the finished state,
   load animations sit behind prefers-reduced-motion, and every scroll-driven
   effect also sits behind @supports (animation-timeline: view()).
   Only individual translate / rotate / scale / opacity / clip-path / filter
   properties are animated, so the card's hover tilt and the form still work. */
@keyframes c-iris { from { clip-path: circle(0% at 50% 44%); } to { clip-path: circle(75% at 50% 44%); } }
@keyframes c-popup { from { translate: 0 34%; } to { translate: 0 0; } }
@keyframes c-drift { to { translate: 0 -80px; } }
@keyframes c-sink { to { translate: 0 9%; } }
@keyframes c-draw { from { background-size: 0% 100%; } to { background-size: 100% 100%; } }
/* the phone card swings up into place and settles */
@keyframes c-wiggle {
  0%   { opacity: 0; translate: 0 120px; rotate: 8deg; scale: 0.9; filter: blur(6px); }
  38%  { opacity: 1; translate: 0 0; rotate: -5deg; scale: 1; filter: blur(0); }
  56%  { rotate: 3.5deg; }
  72%  { rotate: -2deg; }
  86%  { rotate: 0.8deg; }
  100% { opacity: 1; translate: 0 0; rotate: 0deg; scale: 1; filter: blur(0); }
}
/* the phone icon rings once the card has landed */
@keyframes c-ring {
  0%, 100% { rotate: 0deg; }
  12%, 36%, 60% { rotate: -18deg; }
  24%, 48%, 72% { rotate: 18deg; }
  84% { rotate: 0deg; }
}
/* the Sharpie note writes itself in, left to right */
@keyframes c-write { from { clip-path: inset(-40% 100% -40% -8%); } to { clip-path: inset(-40% -8% -40% -8%); } }
/* the airport photo tips in from a steeper angle */
@keyframes c-tip { from { opacity: 0; rotate: 7deg; translate: 0 60px; } to { opacity: 1; rotate: 1.5deg; translate: 0 0; } }

@media (prefers-reduced-motion: no-preference) {
  /* Intro: the headline words rise (motion.css .words), the copy follows,
     the blue tile opens like a camera iris and Nick pops up into it */
  .contact-intro__copy > p.load-in-2 { animation-delay: 0.3s; }
  .contact-mail.load-in-2 { animation-delay: 0.42s; }
  .contact-intro__jump.load-in-2 { animation-delay: 0.54s; }
  .contact-tile { animation: c-iris 1.1s 0.15s cubic-bezier(0.65, 0, 0.35, 1) both; }
  .contact-tile img { animation: c-popup 0.9s 0.55s var(--bounce) both; }
  .contact-intro__photo figcaption { animation: rise 0.6s 1.1s var(--ease) both; }

  @supports (animation-timeline: view()) {
    /* The whole portrait floats up and away as you scroll on, while Nick
       sinks a little inside his tile. The hero is on screen from the start,
       so the sink runs off the page scroll. */
    .contact-intro__photo { animation: c-drift linear both; animation-timeline: view(); animation-range: exit -10% exit 100%; }
    .contact-tile img {
      animation: c-popup 0.9s 0.55s var(--bounce) both, c-sink linear both;
      animation-timeline: auto, scroll(root); animation-range: normal, 0px 90vh;
      animation-composition: replace, add;
    }

    /* Statement: lights up word by word (.lit), then the highlighter draws
       under "Like meeting you." once the reading reaches it. The airport
       photo tips in beside it. */
    .contact-statement__like { animation: c-draw linear both; animation-timeline: --lit; animation-range: cover 52% cover 60%; }
    .contact-statement__photo { animation: c-tip linear both; animation-timeline: view(); animation-range: entry 0% entry 80%; }
    /* On wide, tall screens the statement and photo rise, pin in the middle
       of the screen while the words light up, then move on. The section is
       taller than the screen, and its scroll is the timeline. */
    @media (min-width: 900px) and (min-height: 560px) {
      .contact-statement { height: 170vh; padding-block: clamp(40px, 6vw, 80px); view-timeline-name: --lit; }
      .contact-statement__stage { position: sticky; top: max(96px, calc(50vh - 170px)); top: max(96px, calc(50svh - 170px)); }
      .contact-statement .lit { view-timeline-name: none; }
      .contact-statement .lit .w { animation-range: cover calc(24% + var(--i) * var(--step)) cover calc(29% + var(--i) * var(--step)); }
      .contact-statement__like { animation-range: cover 59% cover 66%; }
      .contact-statement__photo { animation-timeline: --lit; animation-range: cover 12% cover 30%; }
    }

    /* Phone card: swings up and wiggles into place, the note writes itself, the phone rings */
    .contact-call { view-timeline-name: --call; transform-origin: 50% 60%; animation: c-wiggle linear both; animation-timeline: --call; animation-range: entry 0% cover 48%; }
    .contact-call__note { animation: c-write linear both; animation-timeline: --call; animation-range: cover 30% cover 44%; }
    .contact-call__icon { animation: c-ring linear both; animation-timeline: --call; animation-range: cover 40% cover 56%; }

    /* Form: the card rises (.reveal), then each field rises in turn, timed off
       the card itself so they arrive one by one while the card is on screen */
    .contact-work__form { view-timeline-name: --form; }
    .contact-work__form .stagger > * { animation-timeline: --form; animation-range: cover 3% cover 17%; }
    .contact-work__form .stagger > .form__row { animation: none; }
    .contact-work__form .form__row > .field { animation: m-up linear both; animation-timeline: --form; animation-range: cover 3% cover 17%; }
    .contact-work__form .form__row > .field + .field { animation-range: cover 8.5% cover 22.5%; }
    .contact-work__form .stagger > :nth-child(2) { animation-range: cover 14% cover 28%; }
    .contact-work__form .stagger > :nth-child(3) { animation-range: cover 19.5% cover 33.5%; }
    .contact-work__form .stagger > :nth-child(4) { animation-range: cover 25% cover 39%; }
  }
}

/* ---------- Footer ---------- */
/* The email and number are already on this page (the number is the reveal
   above), so the shared footer skips that row here. */
.footer__top > :first-child { display: none; }
