@font-face {
    font-family: "Acumin Pro Wide";
    src: url("assets/fonts/Acumin Pro Wide Book.otf") format("opentype");
    /* Single physical weight (Book ≈ 400). Declaring a full range maps any
       requested weight (the CSS uses 400 and 500) onto this one file with
       no faux-bold synthesis, so all text renders in Book. */
    font-weight: normal;
    font-style: normal;
    /* swap (not optional): always apply Book once it loads, showing the
       metric-matched fallback only briefly first. optional could skip the
       custom font entirely on uncached loads (e.g. first hit on index),
       falling back to Arial and reading heavier. */
    font-display: swap;
}

/* Metric-matched fallback: makes Arial occupy the same line box and width
   as Acumin Pro Wide, so swapping between them causes no layout/baseline
   shift. Overrides derived from Acumin's metrics (1000 upem, asc 735,
   desc 265, gap 200, avg width 581) against Arial. */
@font-face {
    font-family: "Acumin Fallback";
    src: local("Arial");
    size-adjust: 131.60%;
    ascent-override: 55.85%;
    descent-override: 20.14%;
    line-gap-override: 15.20%;
}

:root {
    --fg: #ffffff;
    --font-sans: "Acumin Pro Wide", "Acumin Fallback", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

::selection {
    background-color: #bfbfbf;
    color: inherit;
}

::-moz-selection {
    background-color: #bfbfbf;
    color: inherit;
}

html, body {
    height: 100%;
    /* Remove the translucent grey overlay mobile browsers paint over a
       link/button when it's tapped. This property is inherited, so setting
       it on the root clears it for every tappable element on the site
       (nav links, logo, gallery zones, form controls). */
    -webkit-tap-highlight-color: transparent;
}

body {
    color: var(--fg);
    font-family: var(--font-sans);
    font-weight: 400;
    /* Only the Book (≈400) weight is loaded. font-synthesis: none stops the
       browser faux-bolding any element that asks for 500/700 (e.g. nav,
       labels) — without it they render heavier than the 400 body text. */
    font-synthesis: none;
    -webkit-font-smoothing: antialiased;
    overflow: hidden;
}

.bg-video {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: -1;
}

.landing {
    position: relative;
    height: 100vh;
    width: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    padding: 4rem 2rem;
    text-align: center;
}

.wordmark {
    line-height: 0;
}

.wordmark img {
    display: block;
    width: clamp(160px, 22vw, 320px);
    height: auto;
}

.tagline {
    font-size: 0.65rem;
    font-weight: 300;
    letter-spacing: normal;
}

.landing-link {
    color: inherit;
    text-decoration: none;
    display: block;
}

.page-light {
    background-color: #f3efe8;
    color: #1a1a1a;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
}

.work {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    scrollbar-width: none;
    overscroll-behavior: contain;
}

.work::-webkit-scrollbar {
    display: none;
}

.project {
    height: 100%;
    padding: 0 4rem 1.5rem;
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
}

.site-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    padding: 1.5rem 4rem;
}

.logo-link {
    display: inline-block;
    line-height: 0;
    padding: 1.5rem 1.75rem;
    margin: -1.5rem -1.75rem;
}

.logo-mark {
    display: block;
    height: 15px;
    width: auto;
    aspect-ratio: 1188 / 208;
}

.primary-nav {
    display: flex;
    gap: 2.5rem;
}

.nav-link {
    color: inherit;
    text-decoration: none;
    font-size: 0.65rem;
    line-height: 1;
    letter-spacing: normal;
    padding: 1.5rem 1.75rem;
    margin: -1.5rem -1.75rem;
}

.nav-link:hover {
    text-decoration: underline;
    text-underline-offset: 0.25em;
}


.work-feature {
    margin: 0;
    flex: 1;
    min-height: 0;
    position: relative;
}

.slide {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    pointer-events: none;
}

.slide.is-active {
    opacity: 1;
}

.slide--bedroom {
    object-position: center 69%;
}

.slide--bathroom,
.slide--kitchen,
.slide--study {
    object-position: center 60%;
}

.slide--bright-hero {
    object-position: center 85%;
}

.slide--bright-entry {
    object-position: center 55%;
}

.slide--bright-bathroom {
    object-position: center 65%;
}

.slide--bright-penthouse-living {
    object-position: center 65%;
}

.slide--bright-penthouse-dining {
    object-position: center 57%;
}

.slide--baie-bar {
    object-position: center 52%;
}

.slide--baie-kitchen {
    object-position: center 78%;
}

.slide--baie-study {
    object-position: center 70%;
}

.slide--vetro-kitchen-vig {
    object-position: center 35%;
}

.slide--vetro-hero {
    object-position: center 35%;
}

.slide--ombroso-hero {
    object-position: center 80%;
}

.slide--ombroso-kitchen-vig {
    object-position: center 60%;
}

.slide--ombroso-living {
    object-position: center 55%;
}

.slide--preston-entry {
    object-position: center 70%;
}

.slide--sydney-laneway {
    object-position: center 80%;
}

.slide--albion-entry {
    object-position: center 65%;
}

.slide-zone {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 50%;
    background: transparent;
    border: 0;
    padding: 0;
    z-index: 2;
    -webkit-tap-highlight-color: transparent;
}

.slide-zone--prev {
    left: 0;
}

.slide-zone--next {
    right: 0;
}

/* Bottom-quarter zone (desktop/hover only): hovering shows a down arrow and
   clicking goes to the next project. Sits above the full-height prev/next
   zones (z-index 3 > 2) so the bottom strip navigates between projects
   rather than between images. Hidden on touch so it doesn't change tap
   behaviour there. */
.slide-zone--down {
    top: auto;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 25%;
    z-index: 3;
    display: none;
}

@media (hover: hover) {
    .slide-zone--down {
        display: block;
    }
}

.slide-zone:focus-visible {
    outline: 2px solid rgba(0, 0, 0, 0.4);
    outline-offset: -4px;
}

.info-control {
    position: absolute;
    right: 1.25rem;
    top: 1.25rem;
}

.info-button {
    position: relative;
    z-index: 4;
    width: 48px;
    height: 48px;
    border: 0;
    background: transparent;
    color: #ffffff;
    mix-blend-mode: difference;
    padding: 0;
    cursor: pointer;
    display: grid;
    place-items: center;
}

.info-button__icon {
    display: block;
    width: 100%;
    height: 100%;
    transition: transform 250ms ease;
}

.info-button[aria-expanded="true"] .info-button__icon {
    transform: rotate(45deg);
}

.info-panel {
    position: absolute;
    right: 0;
    top: calc(100% + 0.75rem);
    z-index: 4;
    min-width: 12rem;
    max-width: 14rem;
    padding: 1.1rem 1.25rem;
    background: #f3efe8;
    color: #1a1a1a;
    opacity: 0;
    transform: translateY(6px);
    pointer-events: none;
    transition: opacity 220ms ease, transform 220ms ease;
}

.info-panel.is-open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.info-panel__title {
    font-family: inherit;
    font-weight: 500;
    font-size: 0.8rem;
    letter-spacing: 0.1em;
    line-height: 1.3;
    margin: 0 0 0.9rem;
    text-transform: uppercase;
}

.info-panel__credits {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.6rem;
    margin: 0;
}

.credit {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.credit dt {
    font-size: 0.55rem;
    letter-spacing: 0.18em;
    color: #888;
}

.credit dd {
    margin: 0;
    font-size: 0.7rem;
    color: #1a1a1a;
}

.slide-chevron {
    display: none;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 18px;
    height: 18px;
    color: #ffffff;
    mix-blend-mode: difference;
    pointer-events: none;
    z-index: 3;
}

.slide-chevron--prev { left: 0.5rem; }
.slide-chevron--next { right: 0.5rem; }


@media (hover: hover) {
    .page-light,
    .page-light a,
    .page-light button {
        cursor: none;
    }
    /* The open info panel keeps cursor:none (inherited) so the custom
       cursor stays visible over it — the JS points it NE there, matching
       the info button. */
    .page-light input,
    .page-light textarea {
        cursor: text;
    }
    /* Each blank gets a small invisible buffer above and below itself
       (see .field-underline::before) so the native text cursor stays
       visible when the mouse moves from one input to another that's on a
       different line — no flicker back to the custom arrow in the gap. */
    .page-light .field-underline {
        cursor: text;
    }
}

.cursor-arrow {
    position: fixed;
    top: 0;
    left: 0;
    width: 48px;
    height: 48px;
    pointer-events: none;
    z-index: 10;
    color: #ffffff;
    mix-blend-mode: difference;
    opacity: 0;
    will-change: transform;
}

.cursor-arrow.is-visible {
    opacity: 1;
}

.cursor-arrow.is-suppressed {
    opacity: 0;
}

.cursor-arrow__icon {
    display: block;
    width: 100%;
    height: 100%;
    transition: transform 200ms ease;
}

/* Cursor rotation is driven by JS (inline transform) so it can take the
   shortest angular path between successive directions. The transition rule
   on .cursor-arrow__icon above animates the change. */

@media (hover: none) {
    .cursor-arrow {
        display: none;
    }
}

.about {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    scrollbar-width: none;
    overscroll-behavior: contain;
    padding: 6rem 4rem 6rem;
    display: flex;
    flex-direction: column;
    gap: 6rem;
    align-items: stretch;
}

.about::-webkit-scrollbar {
    display: none;
}

.about-section {
    width: 100%;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    column-gap: 3rem;
    align-items: start;
    box-sizing: border-box;
}

@media (prefers-reduced-motion: no-preference) {
    .about-section {
        opacity: 0;
        transform: translateY(12px);
        transition: opacity 600ms cubic-bezier(0.22, 1, 0.36, 1),
                    transform 600ms cubic-bezier(0.22, 1, 0.36, 1);
        will-change: opacity, transform;
    }

    .about-section.is-revealed {
        opacity: 1;
        transform: translateY(0);
    }
}

.about-section__label {
    font-family: inherit;
    font-weight: 500;
    font-size: 0.65rem;
    line-height: 1.55;
    letter-spacing: normal;
    color: #1a1a1a;
    margin: 0;
    text-transform: uppercase;
    align-self: start;
}

.about-section:has(.about-lede) .about-section__label {
    margin-top: 0.5rem;
}

.about-section__body {
    max-width: 60rem;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

.about-section__body a {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 0.25em;
    position: relative;
}

.about-section__body a[href^="tel:"] {
    white-space: nowrap;
}

.about-section__body a::before {
    content: '';
    position: absolute;
    inset: -1.25rem -1rem;
}

.about-section__body a:hover {
    text-decoration: none;
}

.about-section__body--profile {
    display: grid;
    grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);
    column-gap: 2.5rem;
    align-items: start;
    max-width: none;
}

.about-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    font-size: clamp(1.1rem, 1.6vw, 1.45rem);
    line-height: 1.4;
    letter-spacing: 0.01em;
}

.about-list--columns {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 2.5rem;
    row-gap: 0.85rem;
}

.about-lede {
    font-size: clamp(1.25rem, 2vw, 1.65rem);
    line-height: 1.55;
    font-weight: 500;
    letter-spacing: 0.01em;
    margin: 0;
}

.profile-portrait {
    margin: 0;
    line-height: 0;
    width: 100%;
    max-width: 18rem;
    justify-self: start;
}

.profile-portrait img {
    display: block;
    width: 100%;
    height: auto;
}

.profile-bio {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    align-items: flex-start;
    padding-top: 0.25rem;
    max-width: 22rem;
}

.profile-name {
    font-family: inherit;
    font-weight: 500;
    font-size: 1.05rem;
    letter-spacing: 0.05em;
    margin: 0;
}

.profile-role {
    font-size: 0.65rem;
    letter-spacing: normal;
    text-transform: uppercase;
    color: #1a1a1a;
    margin: 0;
}

.profile-copy {
    font-size: 0.85rem;
    line-height: 1.7;
    letter-spacing: 0.02em;
    margin: 0;
}

/* ---------- Contact page ---------- */

.contact-page {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    scrollbar-width: none;
    padding: 6rem 4rem 1.5rem;
    display: flex;
    flex-direction: column;
    --prose-size: clamp(1.5rem, 2.8vw, 2rem);
    --form-line: rgba(26, 24, 21, 0.35);
    --form-text-muted: #6a6862;
    --form-text-faint: #8a8780;
    --form-accent: #c4621a;
    --form-serif: Georgia, "Times New Roman", serif;
}

.contact-page::-webkit-scrollbar {
    display: none;
}

.greeting {
    font-size: var(--prose-size);
    font-weight: 400;
    line-height: 1.2;
    letter-spacing: normal;
    color: inherit;
    /* margin-top: auto pushes the greeting — and the form + footer below
       it — down to the bottom of the contact-page flex column, so the
       empty space collects at the TOP and the whole brief sits near the
       footer. Applies on both desktop and mobile. */
    margin: auto 0 3.5rem;
}

.brief-form {
    max-width: 58rem;
    margin-bottom: 4.5rem;
}

@media (prefers-reduced-motion: no-preference) {
    .contact-page > .greeting,
    .contact-page > .brief-form,
    .contact-page > .contact-footer {
        opacity: 0;
        transform: translateY(18px);
        transition: opacity 850ms cubic-bezier(0.16, 1, 0.3, 1),
                    transform 850ms cubic-bezier(0.16, 1, 0.3, 1);
        transition-delay: 80ms;
    }

    .contact-page.is-active > .greeting,
    .contact-page.is-active > .brief-form,
    .contact-page.is-active > .contact-footer {
        opacity: 1;
        transform: translateY(0);
    }
}

.prose {
    font-family: inherit;
    font-size: var(--prose-size);
    line-height: 1.65;
    color: inherit;
    font-weight: 400;
    margin: 0 0 2rem;
}

/* On desktop each clause of the brief becomes its own block-level no-wrap
   line so the underline can extend rightward into the page padding as a
   field grows, instead of jumping the field down to a new visual line. On
   mobile (≤ 600px) the prose-line spans stay inline and the paragraph
   wraps normally — the desktop has the horizontal real estate; mobile
   doesn't. */
@media (min-width: 601px) {
    .prose-line {
        display: block;
        white-space: nowrap;
    }
}

.field-wrap {
    display: inline-block;
    position: relative;
    vertical-align: baseline;
}

.field-sizer {
    display: inline-block;
    visibility: hidden;
    white-space: pre;
    font-family: inherit;
    font-size: var(--prose-size);
    padding: 0 2px;
    min-width: 4em;
}

.field-input {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    border: none;
    background: transparent;
    font-family: inherit;
    font-size: var(--prose-size);
    color: inherit;
    padding: 0 2px;
    outline: none;
    line-height: inherit;
    -webkit-appearance: none;
    border-radius: 0;
}

.field-input::placeholder {
    color: transparent;
    transition: color 200ms ease;
}

.field-input:focus::placeholder {
    color: rgba(26, 26, 26, 0.35);
}

/* Suppress Chrome / Safari autofill's pale blue background and yellow tint.
   The browsers won't let us simply set background-color, so we paint over
   them with a huge inset box-shadow that matches the page colour, and lock
   the text fill colour to inherit so the typed value stays the form's
   regular ink. The 9999s transition keeps the autofill animation from ever
   completing if a future browser draws a different default. */
.field-input:-webkit-autofill,
.field-input:-webkit-autofill:hover,
.field-input:-webkit-autofill:focus,
.field-input:-webkit-autofill:active {
    -webkit-box-shadow: 0 0 0 1000px #f3efe8 inset !important;
            box-shadow: 0 0 0 1000px #f3efe8 inset !important;
    -webkit-text-fill-color: inherit !important;
    caret-color: inherit;
    transition: background-color 9999s ease-in-out 0s;
}

.field-underline {
    display: inline-block;
    border-bottom: 0.5px solid var(--form-line);
    padding-bottom: 2px;
    transition: border-color 0.25s ease;
    position: relative;
}

/* Transparent buffer that extends each blank's hit area ~0.6rem above
   and below its visible footprint. Catches the cursor a moment earlier
   on entry and holds it a moment longer on exit, so moving between two
   inputs on adjacent lines never flickers through the custom arrow. The
   ::before has no visible content; it just absorbs pointer events. */
.field-underline::before {
    content: '';
    position: absolute;
    top: -0.6rem;
    bottom: -0.6rem;
    left: 0;
    right: 0;
}

.field-underline:focus-within {
    border-bottom-color: #1a1a1a;
}

.field-underline.error {
    border-bottom-color: var(--form-accent);
}

.attach-trigger {
    display: inline-block;
    position: relative;
    cursor: pointer;
    font-family: inherit;
    font-size: var(--prose-size);
    color: inherit;
    padding: 0 2px 2px;
    border-bottom: 0.5px solid var(--form-line);
    transition: border-color 0.25s ease;
    user-select: none;
}

.attach-trigger::before {
    content: '';
    position: absolute;
    inset: -0.75rem -1rem;
}

.attach-trigger:hover,
.attach-trigger:focus {
    border-bottom-color: #1a1a1a;
    outline: none;
}

.attach-trigger.has-files {
    color: var(--form-text-muted);
    border-bottom-color: var(--form-text-muted);
}

.attach-clear {
    display: inline-block;
    position: relative;
    margin-left: 0.4em;
    border: 0;
    background: transparent;
    color: var(--form-text-muted);
    font-family: inherit;
    font-size: 0.7em;
    line-height: 1;
    padding: 0.25em 0.45em;
    vertical-align: 0.25em;
}

.attach-clear::before {
    content: '';
    position: absolute;
    inset: -0.6rem -0.6rem;
}

.attach-clear[hidden] {
    display: none;
}

@media (hover: hover) {
    .page-light .attach-clear {
        cursor: pointer;
    }
}

.attach-icon {
    display: inline-block;
    width: 12px;
    height: 12px;
    margin-left: 6px;
    vertical-align: 2px;
    transform: rotate(-45deg);
}

.bottom {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 2rem;
    margin-top: 0;
}

.file-info-label {
    color: var(--form-text-faint);
    font-size: 0.6rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
}

.send-btn {
    background: transparent;
    border: 0;
    padding: 1rem 1.25rem;
    margin: -1rem -1.25rem;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: normal;
    color: inherit;
    font-family: inherit;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.3em;
    display: inline-flex;
    align-items: center;
    -webkit-appearance: none;
    border-radius: 0;
    transition: text-decoration-thickness 180ms ease;
}

.send-btn:hover {
    text-decoration-thickness: 2px;
}

.send-btn:disabled {
    opacity: 0.5;
}

.send-btn.sending .send-label__dot {
    display: none;
}

.send-btn.sending .send-label::after {
    content: 'ing…';
}

/* When chunk-upload progress is being shown, JS sets the full label
   text ("Sending… 42%"), so the CSS ::after that would otherwise
   append "ing…" must be suppressed — otherwise the rendered text
   becomes "Sending… 42%ing…". */
.send-btn.sending.with-progress .send-label::after {
    content: '';
}

.send-arrow {
    font-size: 0.85rem;
    letter-spacing: 0;
}

/* Shown in place of the form sentence after a successful send (the form's
   .prose is hidden via .brief-form.sent below). Matches the prose's size and
   spacing so it occupies the same area; JS also sets its min-height to the
   sentence's height so the Send button and footer don't shift. */
.thank-you-msg {
    font-family: inherit;
    font-size: var(--prose-size);
    line-height: 1.65;
    color: inherit;
    font-weight: 400;
    margin: 0 0 2rem;
    animation: contactFadeIn 0.4s ease;
}

.brief-form.sent .prose {
    display: none;
}


/* Inline error banner shown when /api/contact returns an error (network
   failure, Resend rejection, etc.). Hidden by default via the [hidden]
   attribute; populated and revealed by contact.js. */
.form-error {
    margin: 1.25rem 0 0;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--form-accent);
    max-width: 36rem;
}

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

.contact-footer {
    /* No margin-top:auto here — the greeting's auto-margin already pushes
       the whole group (greeting + form + footer) to the bottom, and the
       footer being the last child lands it at the very bottom. Same on
       desktop and mobile. */
    padding-top: 2rem;
    border-top: 0.5px solid var(--form-line);
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 2rem;
    font-size: 0.75rem;
    line-height: 1.7;
    letter-spacing: 0.01em;
    align-items: start;
}

.contact-col__label {
    font-family: inherit;
    font-size: 0.55rem;
    font-weight: 500;
    letter-spacing: normal;
    text-transform: uppercase;
    color: var(--form-text-muted);
    margin: 0 0 0.75rem;
}

.contact-col__item {
    margin: 0;
    font-style: normal;
}

.contact-col__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
}

.contact-col a {
    color: inherit;
    text-decoration: none;
    display: inline-block;
    padding: 1.5rem 1.75rem;
    margin: -1.5rem -1.75rem;
}

.contact-col a:hover {
    text-decoration: underline;
    text-underline-offset: 0.25em;
}

/* The Follow column stacks two links (Instagram / LinkedIn). The full
   1.5rem vertical hit-area padding from .contact-col a would extend far
   past the gap between them and overlap, so their clickable zones — and
   the custom-cursor direction calc — interfered. Trim the vertical
   padding here (keeping the horizontal catchment) and let the larger
   list gap above give clear separation. */
.contact-col__list a {
    padding-top: 0.35rem;
    padding-bottom: 0.35rem;
    margin-top: -0.35rem;
    margin-bottom: -0.35rem;
}

/* ---------- Fee proposal page (unlinked) ---------- */

.fp-page {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    scrollbar-width: none;
    padding: 5rem 4rem 1.5rem;
    display: flex;
    flex-direction: column;
    --form-line: rgba(26, 24, 21, 0.35);
    --form-text-muted: #6a6862;
    --form-text-faint: #8a8780;
    --form-accent: #c4621a;
}

.fp-page::-webkit-scrollbar {
    display: none;
}

@media (prefers-reduced-motion: no-preference) {
    .fp-page > * {
        animation: fpReveal 800ms cubic-bezier(0.16, 1, 0.3, 1) both;
    }
    .fp-sub { animation-delay: 60ms; }
    .fp-form { animation-delay: 120ms; }
    .fp-page > .contact-footer { animation-delay: 180ms; }
}

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

.fp-intro {
    font-size: clamp(1.5rem, 2.6vw, 2.25rem);
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: 0.02em;
    margin: 0 0 0.6rem;
}

.fp-sub {
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--form-text-muted);
    margin: 0 0 3rem;
    max-width: 38rem;
}

.fp-sub .req,
.fp-label .req {
    color: var(--form-accent);
}

.fp-form {
    max-width: 62rem;
    margin-bottom: 3rem;
}

.fp-form.sent {
    display: none;
}

.fp-group {
    border: 0;
    padding: 0;
    margin: 0 0 2.75rem;
}

.fp-legend {
    display: block;
    font-size: 0.55rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--form-text-muted);
    margin: 0 0 1.5rem;
    padding: 0;
}

.fp-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.75rem 3rem;
}

.fp-grid--spaced {
    margin-top: 1.75rem;
}

.fp-field {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.fp-field--full {
    grid-column: 1 / -1;
}

.fp-label {
    font-size: 0.6rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--form-text-faint);
    margin-bottom: 0.6rem;
}

.fp-input,
.fp-select,
.fp-textarea {
    width: 100%;
    border: 0;
    border-bottom: 0.5px solid var(--form-line);
    background: transparent;
    font-family: inherit;
    font-size: 1rem;
    color: inherit;
    padding: 0.4rem 0;
    outline: none;
    border-radius: 0;
    -webkit-appearance: none;
    appearance: none;
    transition: border-color 0.25s ease;
}

.fp-textarea {
    resize: vertical;
    min-height: 5.5rem;
    line-height: 1.55;
}

.fp-input::placeholder,
.fp-textarea::placeholder {
    color: var(--form-text-faint);
    opacity: 0.7;
}

.fp-input:focus,
.fp-select:focus,
.fp-textarea:focus {
    border-bottom-color: #1a1a1a;
}

.fp-field.error .fp-input,
.fp-field.error .fp-select,
.fp-field.error .fp-textarea {
    border-bottom-color: var(--form-accent);
}

/* Custom dropdown chevron (native arrow suppressed by appearance:none). */
.fp-select {
    cursor: pointer;
    padding-right: 1.5rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236a6862' stroke-width='1'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.1rem center;
}

.fp-select option {
    color: #1a1a1a;
}

/* Mirror the contact form's autofill paint-over so Chrome/Safari don't
   tint the field blue/yellow. Selects are intentionally excluded: an inset
   box-shadow large enough to cover the autofill colour also paints over
   their dropdown chevron, and they hold no autofillable data anyway. */
.fp-input:-webkit-autofill,
.fp-input:-webkit-autofill:hover,
.fp-input:-webkit-autofill:focus,
.fp-input:-webkit-autofill:active,
.fp-textarea:-webkit-autofill,
.fp-textarea:-webkit-autofill:hover,
.fp-textarea:-webkit-autofill:focus,
.fp-textarea:-webkit-autofill:active {
    -webkit-box-shadow: 0 0 0 1000px #f3efe8 inset !important;
            box-shadow: 0 0 0 1000px #f3efe8 inset !important;
    -webkit-text-fill-color: inherit !important;
    caret-color: inherit;
    transition: background-color 9999s ease-in-out 0s;
}

/* Service selection — toggle chips. */
.fp-checks {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem 0.7rem;
}

.fp-check {
    position: relative;
    display: inline-flex;
}

.fp-check input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
}

.fp-check span {
    display: inline-block;
    padding: 0.5rem 1rem;
    border: 0.5px solid var(--form-line);
    font-size: 0.8rem;
    color: var(--form-text-muted);
    cursor: pointer;
    user-select: none;
    transition: color 0.2s ease, background-color 0.2s ease, border-color 0.2s ease;
}

.fp-check input:checked + span {
    background-color: #1a1a1a;
    border-color: #1a1a1a;
    color: #f3efe8;
}

.fp-check input:focus-visible + span {
    outline: 1px solid #1a1a1a;
    outline-offset: 2px;
}

/* Attachment control. */
.fp-attach-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem 1.25rem;
    margin-bottom: 0.6rem;
}

.fp-attach-btn,
.fp-attach-clear {
    background: transparent;
    border: 0;
    padding: 0;
    font-family: inherit;
    color: inherit;
    font-size: 0.85rem;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.3em;
    transition: text-decoration-thickness 180ms ease;
}

.fp-attach-clear {
    color: var(--form-text-muted);
    font-size: 0.75rem;
}

.fp-attach-btn:hover,
.fp-attach-clear:hover {
    text-decoration-thickness: 2px;
}

@media (hover: hover) {
    .page-light .fp-attach-btn,
    .page-light .fp-attach-clear {
        cursor: pointer;
    }
}

.fp-attach-list {
    font-size: 0.85rem;
    color: var(--form-text-muted);
}

.fp-attach-list[hidden],
.fp-attach-clear[hidden] {
    display: none;
}

.fp-attach .file-info-label {
    display: block;
}

.fp-actions {
    margin-top: 0.5rem;
}

@media (max-width: 600px) {
    .landing {
        padding: 2.5rem 1.5rem;
    }
    .tagline {
        font-size: 0.6rem;
        letter-spacing: normal;
    }
    .site-header {
        padding: 1rem 1.5rem;
    }
    .primary-nav {
        gap: 1.5rem;
    }
    .nav-link {
        font-size: 0.6rem;
    }
    .project {
        height: auto;
        padding: 0 1.5rem;
    }
    .project + .project {
        margin-top: 1.5rem;
    }
    .work-feature {
        flex: none;
        aspect-ratio: 3 / 2;
    }
    .info-control {
        right: 0.75rem;
        top: 0.75rem;
    }
    .info-button {
        width: 32px;
        height: 32px;
    }
    .info-panel {
        min-width: 0;
        width: min(11rem, calc(100vw - 3rem));
        max-width: none;
        padding: 0.7rem 0.85rem;
        top: calc(100% + 0.5rem);
    }
    .info-panel__title {
        font-size: 0.62rem;
        margin-bottom: 0.5rem;
    }
    .info-panel__credits {
        gap: 0.32rem;
    }
    .credit {
        gap: 0.08rem;
    }
    .credit dt {
        font-size: 0.46rem;
    }
    .credit dd {
        font-size: 0.6rem;
    }
    .slide-chevron {
        display: block;
    }
    .about {
        padding: 4rem 1.5rem 4rem;
        gap: 3.5rem;
    }
    .about-section {
        grid-template-columns: 1fr;
        column-gap: 0;
        row-gap: 0.75rem;
    }
    .about-section__label {
        position: static;
    }
    .about-list--columns {
        grid-template-columns: 1fr;
    }
    .about-section__body--profile {
        grid-template-columns: 1fr;
        row-gap: 1.5rem;
    }
    .profile-portrait {
        max-width: 16rem;
    }
    .contact-page {
        padding: 4rem 1.5rem 1.5rem;
        /* Smaller form text on mobile so the whole brief + footer fit
           within the viewport without scrolling. --prose-size drives the
           prose copy and every inline field (line-height scales with it),
           so lowering it shrinks the entire form's height. */
        --prose-size: clamp(1.15rem, 4.6vw, 1.4rem);
    }
    .greeting {
        /* Inherit the desktop margin-top:auto so the brief is anchored to
           the footer on mobile too; just tighten the gap to the form.
           Font size inherits var(--prose-size) to match the form. */
        margin-bottom: 2.25rem;
    }
    .prose {
        margin-bottom: 2.5rem;
    }
    .bottom {
        flex-direction: column;
        align-items: stretch;
        gap: 1.25rem;
    }
    .send-btn {
        align-self: flex-start;
        font-size: 0.7rem;
    }
    .contact-footer {
        /* No margin-top:auto needed — the greeting's auto-margin pushes the
           whole group down and the footer (last child) lands at the bottom,
           same as desktop. */
        padding-top: 1.5rem;
        grid-template-columns: 1fr 1fr;
        gap: 1.75rem 1.25rem;
    }

    .fp-page {
        padding: 3.5rem 1.5rem 1.5rem;
    }
    .fp-grid {
        grid-template-columns: 1fr;
        gap: 1.5rem;
    }
    .fp-sub {
        margin-bottom: 2.25rem;
    }
    .fp-group {
        margin-bottom: 2.25rem;
    }
}

/* ----- work-v2: splash overlay on the work page ----- */

.splash-stage {
    position: fixed;
    inset: 0;
    z-index: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 6.5rem 2rem 6rem;
    text-align: center;
    color: #ffffff;
    background-color: #000;
    pointer-events: none;
}

.splash-stage .splash-content {
    flex: 1;
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
}

.splash-stage .bg-video {
    z-index: -1;
}

.splash-stage .wordmark img {
    display: block;
    width: clamp(160px, 22vw, 320px);
    height: auto;
}

.splash-stage .tagline {
    font-size: 0.65rem;
    font-weight: 300;
    letter-spacing: normal;
}

.page-light:has(.work--with-splash) {
    background-color: #f3efe8;
    display: block;
    height: 100vh;
}

.site-header--overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 10;
    will-change: transform;
    transform: translateY(100vh);
}

.page-splash .site-header--overlay {
    pointer-events: none;
}

.work--with-splash {
    position: fixed;
    inset: 0;
    z-index: 5;
    background: transparent;
}

.splash-spacer {
    height: 100%;
    background: transparent;
    pointer-events: auto;
}

.work--with-splash .project {
    height: 100%;
    background-color: #f3efe8;
    padding: 4rem 4rem 2rem;
}

@media (max-width: 600px) {
    .splash-stage {
        padding: 4.25rem 1.5rem 4rem;
    }
    .splash-stage .tagline {
        font-size: 0.6rem;
        letter-spacing: normal;
    }
    .work--with-splash .project {
        height: auto;
        padding: 0 1.5rem 1.5rem;
    }
    .work--with-splash .project + .project {
        margin-top: 0;
    }
    .work--with-splash .work-feature {
        flex: none;
        aspect-ratio: 3 / 2;
    }
    .work--with-splash .splash-spacer + .project,
    .work--with-splash .project:first-of-type {
        padding-top: 2.9375rem;
    }
    body:not(.page-splash) .site-header--overlay {
        background-color: #f3efe8;
    }
}

