101 lines
3.7 KiB
Plaintext
101 lines
3.7 KiB
Plaintext
---
|
|
import { t, type Lang } from '../../i18n/ui';
|
|
interface Props { lang: Lang }
|
|
const { lang } = Astro.props;
|
|
const ui = t(lang);
|
|
const f = ui.contact.form;
|
|
---
|
|
<section class="section contact" id="contact" aria-labelledby="contact-title">
|
|
<div class="container grid">
|
|
<div class="contact__text">
|
|
<h2 id="contact-title" class="h2">{ui.contact.title}</h2>
|
|
<p class="contact__body">{ui.contact.body}</p>
|
|
<address class="contact__address">
|
|
<p>{ui.contact.address[0]}<br />{ui.contact.address[1]}</p>
|
|
<p><a href={ui.contact.phoneHref}>{ui.contact.phone}</a><br /><a href={`mailto:${ui.contact.email}`}>{ui.contact.email}</a></p>
|
|
</address>
|
|
</div>
|
|
|
|
<form class="contact__form" action="/contact" method="post" lang={lang}>
|
|
<p class="visually-hidden" aria-hidden="true">
|
|
<label for="website">{f.honeypot}</label>
|
|
<input type="text" id="website" name="website" tabindex="-1" autocomplete="off" />
|
|
</p>
|
|
<div class="field">
|
|
<label for="first_name">{f.firstName} <span aria-hidden="true">*</span></label>
|
|
<input id="first_name" name="first_name" type="text" autocomplete="given-name" required />
|
|
</div>
|
|
<div class="field">
|
|
<label for="last_name">{f.lastName} <span aria-hidden="true">*</span></label>
|
|
<input id="last_name" name="last_name" type="text" autocomplete="family-name" required />
|
|
</div>
|
|
<div class="field field--full">
|
|
<label for="email">{f.email} <span aria-hidden="true">*</span></label>
|
|
<input id="email" name="email" type="email" autocomplete="email" required />
|
|
</div>
|
|
<div class="field field--full">
|
|
<label for="message">{f.message} <span aria-hidden="true">*</span></label>
|
|
<textarea id="message" name="message" rows="5" required></textarea>
|
|
</div>
|
|
<div class="field--full contact__actions">
|
|
<button class="button" type="submit">{f.submit}</button>
|
|
<p class="small muted"><span aria-hidden="true">* </span>{f.required}</p>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</section>
|
|
|
|
<style>
|
|
.contact { border-top: var(--hairline) solid var(--line); }
|
|
.contact__text {
|
|
grid-column: 1 / -1;
|
|
display: grid;
|
|
gap: var(--space-6);
|
|
align-content: start;
|
|
}
|
|
.contact__body { max-width: 28em; color: var(--ink-muted); }
|
|
.contact__address { font-style: normal; display: grid; gap: var(--space-4); }
|
|
.contact__address a { text-decoration: none; }
|
|
.contact__address a:hover { text-decoration: underline; }
|
|
|
|
.contact__form {
|
|
grid-column: 1 / -1;
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: var(--space-6) var(--gap);
|
|
align-content: start;
|
|
}
|
|
.field { display: grid; gap: var(--space-2); }
|
|
.field--full { grid-column: 1 / -1; }
|
|
.field label { font-size: var(--step-small); line-height: var(--leading-small); color: var(--ink-muted); }
|
|
.field input, .field textarea {
|
|
width: 100%;
|
|
background: transparent;
|
|
border: 0;
|
|
border-bottom: var(--hairline) solid var(--line);
|
|
padding: var(--space-2) 0 var(--space-3);
|
|
border-radius: 0;
|
|
transition: border-color var(--dur-fast) var(--ease);
|
|
}
|
|
.field input:focus-visible, .field textarea:focus-visible {
|
|
border-bottom-color: currentColor;
|
|
}
|
|
.field textarea { resize: vertical; min-height: 8rem; }
|
|
.contact__actions {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
gap: var(--space-5);
|
|
margin-top: var(--space-2);
|
|
}
|
|
|
|
@media (min-width: 48rem) {
|
|
.contact__text { grid-column: 1 / span 5; }
|
|
.contact__form { grid-column: 7 / span 6; }
|
|
}
|
|
@media (max-width: 30rem) {
|
|
.contact__form { grid-template-columns: 1fr; }
|
|
.field { grid-column: 1 / -1; }
|
|
}
|
|
</style>
|