/* 047 v5, Contact. Built ON theme.css, chrome.css and site.css (untouched here), and contact-wolf.css (GENERATED by
   _rig_contact/build.py from wolf.json: the figure's box per screen, the eye's place, the rake's ground).
   The opening: the words on the left in the cloth's light; on the right the wolf in the folds (044 run 2 D4, mirrored so the wolf
   faces the words: the reversed field), unframed, its black the page's own (the file's alpha), drawn at exact device pixels.
   The form on black: square fields with a control boundary of 3:1 (gun-400) and a lit top edge (the one light); labels in Mona;
   errors in a light red that reads at 4.5:1. Motion: after the opening's light the form is laid in, field by field (each rises
   into place in turn), then the three ways to reach us take the light (site.css .roll). */

/* ------------------------------------------------------------------ the opening: the wolf in the folds
   Exact pixels (the plate technique): the box is --W x --H CSS px and the <picture> picks the file whose width IS that times the
   device pixel ratio, from the same query table. Desktop: the figure's right edge is the wrap's outer edge (the screen's edge up to
   1440, where the flag's cut hoist side runs off it), its top 8 px under the header, so both land on whole pixels. Phones: centred
   on whole pixels (a 16 px step, at most 15 px short of the screen; the sides are black or feathered).
   Nothing is ever painted outside the image's own alpha: the dark is not a layer over the figure (a layer would paint the page's
   ground round the wolf, a halo, wherever the lamp has lit the air) but the image held back, by a mask that travels away from the
   lamp (.wolf__expo moves; .wolf__inner moves back by exactly as much, so the image itself never moves) and by its opacity. At rest
   both are at none and 1: the file's pixels, untouched. */
.wolf { position: relative; width: var(--W); height: var(--H); margin: 0; isolation: isolate; pointer-events: none; }
.wolf span, .wolf i { position: absolute; display: block; pointer-events: none; }
.wolf__expo { left: -200%; top: -200%; width: 500%; height: 500%;
  -webkit-mask-image: linear-gradient(to bottom left, #000 0%, #000 64%, transparent 80%); mask-image: linear-gradient(to bottom left, #000 0%, #000 64%, transparent 80%); }
.wolf__inner { left: 40%; top: 40%; width: 20%; height: 20%; isolation: isolate; }       /* exactly the figure's box: 40% of 5 W is 2 W */
.wolf picture, .wolf img { display: block; width: var(--W); height: var(--H); max-width: none; }
/* the rake: one band of the lamp's light crossing the cloth from the top right; overlay lifts what is lit (the folds, the stars,
   the fur) and leaves the shadows dark. It travels inside .wolf__light, which holds still, carries the silhouette's interior as
   its mask and does the blending (a blended layer paints wherever its backdrop is transparent: it must stay on the cloth) */
.wolf__light { inset: 0; overflow: hidden; mix-blend-mode: overlay; -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; }
.wolf__rake { left: -100%; top: -100%; width: 300%; height: 300%; opacity: 0;
  background: linear-gradient(to bottom left, rgba(254, 254, 253, 0) 44%, rgba(254, 254, 253, .5) 49.4%, rgba(254, 254, 253, .62) 50%, rgba(254, 254, 253, .5) 50.6%, rgba(254, 254, 253, 0) 56%); }
/* the eye: unlit (its colour taken out, then darkened) until the end; then it lights and a little of its red glows on */
.wolf__lid, .wolf__dim, .wolf__glow { left: var(--ex); top: var(--ey); width: var(--er); height: var(--er); margin: calc(var(--er) / -2) 0 0 calc(var(--er) / -2); border-radius: 50%; opacity: 0; }
.wolf__lid { mix-blend-mode: saturation; background: radial-gradient(closest-side, #808080 0%, #808080 66%, rgba(128, 128, 128, 0) 100%); }
.wolf__dim { mix-blend-mode: multiply; background: radial-gradient(closest-side, rgba(34, 34, 36, 1) 0%, rgba(34, 34, 36, .92) 50%, rgba(34, 34, 36, 0) 100%); }
.wolf__glow { --g: 2.6; width: calc(var(--er) * var(--g)); height: calc(var(--er) * var(--g)); margin: calc(var(--er) * var(--g) / -2) 0 0 calc(var(--er) * var(--g) / -2);
  mix-blend-mode: screen; opacity: .3;                                                      /* at rest a little of the eye's red glows on (reduced motion too) */
  background: radial-gradient(closest-side, rgba(219, 14, 35, .62) 0%, rgba(219, 14, 35, .3) 26%, rgba(219, 14, 35, .08) 60%, rgba(219, 14, 35, 0) 100%); }

@media (prefers-reduced-motion: no-preference) {
  /* armed: until the pixels are decoded the figure stands in the dark (held back, the eye unlit). A fail-safe: were the ready
     class never to come, the finished image stands after 4 s */
  .motion .wolf:not(.is-ready) .wolf__expo { animation: wolf-hold-expo 4s steps(1, end) both; }
  .motion .wolf:not(.is-ready) .wolf__inner { animation: wolf-hold-inner 4s steps(1, end) both; }
  .motion .wolf:not(.is-ready) .wolf__lid, .motion .wolf:not(.is-ready) .wolf__dim { animation: wolf-hold-lid 4s steps(1, end) both; }
  .motion .wolf:not(.is-ready) .wolf__glow { animation: wolf-hold-glow 4s steps(1, end) both; }
  @keyframes wolf-hold-expo { from { transform: translate(40%, -40%); } to { transform: none; } }
  @keyframes wolf-hold-inner { from { transform: translate(-200%, 200%); opacity: 0; } to { transform: none; opacity: 1; } }
  @keyframes wolf-hold-lid { from { opacity: 1; } to { opacity: 0; } }
  @keyframes wolf-hold-glow { from { opacity: 0; } to { opacity: .3; } }
  /* played (2.4 s from ready, with the hero's light): the image comes up out of the dark (its opacity over the black: an exposure,
     the highlights arrive first) while the held-back edge travels from the lamp's corner to the far one; the rake crosses the folds;
     the eye lights last. expo and inner share one duration, delay and curve, so their two moves cancel at every frame */
  .light .wolf.is-ready .wolf__expo { animation: wolf-expo 1.45s cubic-bezier(.33, 0, .3, 1) .05s both; }
  .light .wolf.is-ready .wolf__inner { animation: wolf-inner 1.45s cubic-bezier(.33, 0, .3, 1) .05s both, wolf-expose 1.3s cubic-bezier(.25, 0, .35, 1) .05s both; }
  .light .wolf.is-ready .wolf__rake { animation: wolf-rake .95s cubic-bezier(.45, 0, .3, 1) .85s both; }
  .light .wolf.is-ready .wolf__lid, .light .wolf.is-ready .wolf__dim { animation: wolf-lid .3s cubic-bezier(.3, 0, .2, 1) 1.72s both; }
  .light .wolf.is-ready .wolf__glow { animation: wolf-glow .7s cubic-bezier(.2, .6, .2, 1) 1.72s both; }
  @keyframes wolf-expo { from { transform: translate(40%, -40%); } to { transform: none; } }
  @keyframes wolf-inner { from { transform: translate(-200%, 200%); } to { transform: none; } }
  @keyframes wolf-expose { from { opacity: 0; } to { opacity: 1; } }
  @keyframes wolf-rake { from { opacity: 1; transform: translate(30%, -30%); } 82% { opacity: 1; } to { opacity: 0; transform: translate(-30%, 30%); } }
  @keyframes wolf-lid { from { opacity: 1; } to { opacity: 0; } }
  @keyframes wolf-glow { from { opacity: 0; transform: scale(.55); } 34% { opacity: 1; transform: scale(1.06); } to { opacity: .3; transform: none; } }
}

/* desktop: words left in the cloth's light, the figure right; the opening as tall as the figure (it fills the half that was black) */
@media (min-width: 900px) {
  .phead--contact .hero__stage { grid-template-columns: minmax(0, 1fr) calc(var(--W) - var(--gutter)); column-gap: var(--gap); --hh: calc(var(--H) + 16px); }
  .phead--contact .hero__words { grid-area: 1 / 1; }
  .phead--contact .wolf { grid-area: 1 / 2; align-self: start; justify-self: end; margin: 8px calc(-1 * var(--gutter)) 0 0; }
  /* the cloth stands behind the words (its light near the headline's end), not mid-page beside the wolf: two star fields side by side
     read as two flags */
  .phead--contact .cloth { right: auto; width: min(500px, 44%); }
}
/* phones and narrow windows: the label, the heading, the figure (full width: the head and the flag around it), the line, then the
   form. The words block dissolves into the stage's grid (display: contents) so the figure stands between the heading and the line;
   the label and the heading are rounded up to whole pixels (and the heading's line box too: WebKit has no calc-size()), so the
   figure lands on a whole device pixel (theme.css's own phone hero does the same for the plate) */
@media (max-width: 899.98px) {
  .phead--contact .hero__stage { row-gap: 22px; padding-top: calc(var(--nav-h) + 64px); padding-bottom: 16px; }
  .phead--contact .hero__words { display: contents; }
  .phead--contact .hero__words > * { justify-self: start; }
  .phead--contact .hero__words > .badge { order: 1; height: calc-size(auto, round(up, size, 1px)); }
  .phead--contact .hero__words > h1 { order: 2; height: calc-size(auto, round(up, size, 1px)); line-height: round(up, 1.06em, 1px); }
  .phead--contact .wolf { order: 3; justify-self: start; margin: 2px 0 0 round(down, (100% - var(--W)) / 2, 1px); }
  .phead--contact .hero__words > .lead { order: 4; }
  /* the cloth: full width behind the label and the heading, gone before the figure (it showed a cut edge at 30% from the right) */
  .phead--contact .cloth { right: 0; height: calc(var(--nav-h) + 150px);
    -webkit-mask-image: linear-gradient(180deg, #000 45%, transparent 100%); mask-image: linear-gradient(180deg, #000 45%, transparent 100%); }
}

.contact { padding-top: 24px; }
.contact__in { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); column-gap: calc(var(--gap) * 1.4); row-gap: 56px; align-items: start; }

/* ------------------------------------------------------------------ the form */
.form { display: grid; gap: 26px; max-width: 760px; }
.field { display: grid; gap: 10px; align-content: start; }
.field__row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 26px; }
.field label { font: 500 .9375rem/1.3 var(--sans); color: var(--bw-silver); letter-spacing: .01em; }
.req { font: 400 .8125rem/1 var(--sans); color: var(--bw-gun-300); margin-left: 4px; }
.req.is-hidden { display: none; }
.help { font: 400 .875rem/1.45 var(--sans); color: var(--bw-gun-300); }
.input { width: 100%; min-height: 52px; padding: 13px 16px; border: 1px solid var(--bw-gun-400); border-radius: 0; background: #0e0f10;
  box-shadow: inset 0 1px 0 rgba(254, 254, 253, .1); color: var(--bw-white); font: 400 1.0625rem/1.45 var(--sans); -webkit-appearance: none; appearance: none;
  transition: border-color .2s, box-shadow .2s; }
.input:hover { border-color: var(--bw-gun-300); }
.input:focus-visible { outline: 2px solid var(--bw-white); outline-offset: 2px; border-color: var(--bw-gun-300); }
textarea.input { min-height: 156px; resize: vertical; }
.input[aria-invalid="true"] { border-color: #ff7a85; }
.select { position: relative; display: block; }
.select .input { padding-right: 44px; cursor: pointer; }
.select::after { content: ""; position: absolute; right: 18px; top: 50%; width: 7px; height: 7px; margin-top: -6px; pointer-events: none;
  border: solid var(--bw-silver); border-width: 0 1.5px 1.5px 0; transform: rotate(45deg); }
select.input option { background: #111213; color: var(--bw-white); }
#field-role.is-hidden { display: none; }
.error { display: none; font: 500 .875rem/1.4 var(--sans); color: #ff7a85; }
.error.is-on { display: block; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form__foot { display: grid; gap: 16px; justify-items: start; margin-top: 8px; }
.form__under { font: 400 .875rem/1.55 var(--sans); color: var(--bw-gun-300); max-width: 46ch; }
.form-status { font: 500 1rem/1.5 var(--sans); color: var(--bw-silver); min-height: 1.5em; }
.form-status.ok { color: var(--bw-white); }
.form-status.err { color: #ff7a85; }
.form-status a { color: inherit; text-decoration: underline; text-underline-offset: .2em; }
.btn[disabled] { opacity: .6; cursor: progress; }

/* ------------------------------------------------------------------ reach us */
.reach { display: grid; gap: 22px; align-content: start; padding-top: 4px; }
.reach__list li { padding: 18px 0; display: grid; gap: 8px; }
.reach__list li::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: linear-gradient(90deg, rgba(254, 254, 253, .2), rgba(254, 254, 253, .05)); }
.reach__list a { display: inline-flex; align-items: center; min-height: 32px; font: 400 1.25rem/1.3 var(--sans); color: var(--bw-white); text-decoration: none; transition: color .2s; }
.reach__list a:hover { text-decoration: underline; text-underline-offset: .22em; text-decoration-thickness: 1px; }
.reach__loc { font: 400 1.25rem/1.3 var(--sans); color: var(--bw-white); }
.reach__sec { margin-top: 18px; font: 400 .9375rem/1.55 var(--sans); color: var(--bw-gun-300); }

/* ------------------------------------------------------------------ the form is laid in, field by field */
.field--1 { --i: 0; } .field--2 { --i: 1; } .field__row { --i: 1; } .field--5 { --i: 2; } .field--6 { --i: 3; } .form__foot { --i: 4; }
@media (prefers-reduced-motion: no-preference) {
  /* the form and the contact details never wait to appear: shown at full strength from the start (Forge, 2026-10-20) */
  .form.is-on > .field, .form.is-on > .field__row, .form.is-on > .form__foot { animation: lay-in .55s var(--ease-light) calc(.55s + var(--i, 0) * .12s) both; }
  @keyframes lay-in { from { opacity: .12; transform: translateY(18px); } to { opacity: 1; transform: none; } }
  .reach.is-on .roll__i { animation-delay: calc(1.05s + var(--i, 0) * .14s); }
  .reach.is-on .roll__i::before { animation-delay: calc(1.1s + var(--i, 0) * .14s); }
}

@media (max-width: 899.98px) {
  .contact { padding-top: 16px; }
  .contact__in { grid-template-columns: minmax(0, 1fr); }
  .field__row { grid-template-columns: minmax(0, 1fr); }
}
.motion .reach.roll:not(.is-on) .roll__i { opacity: 1; }
.motion .reach.roll:not(.is-on) .roll__i::before { transform: none; }
