/* ============================================================
   BEINC — Contact Form (Component CSS)

   Five stages stacked vertically:
     1. Basic details (4 fields, 2x2 grid on desktop, 1 col on mobile)
     2. Services (8 coloured chips with click-to-toggle)
     3. Budget range (4 boxes connected by dashed SVG tubes)
     4. Message (textarea)
     5. Submit button
   ============================================================ */

.cf-form {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 100%;
    color: var(--color-white);
}

/* Group of 4 stacked field-sections (1-4), then submit gap */
.cf-stages {
    display: flex;
    flex-direction: column;
    gap: 20px;
}
.cf-form__submit-wrap {
    margin-top: 40px;
}

/* ── STAGE BLOCK ── */
.cf-stage {
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: 100%;
    transition: opacity 0.4s var(--ease-primary);
}

.cf-stage__label {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    font-family: var(--font-heading);
    font-weight: var(--font-weight-medium);
    letter-spacing: var(--tracking-tight);
    font-size: 12px;
    line-height: 1;
    color: var(--color-greyish);
}
.cf-stage__label-text {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.cf-stage__asterisk {
    color: var(--color-greyish);
    font-size: 14px;
    line-height: 1;
    transition: color 0.3s var(--ease-primary);
}
.cf-stage__error {
    font-family: var(--font-body);
    font-size: 11px;
    color: var(--color-red-brand);
    opacity: 0;
    transition: opacity 0.3s var(--ease-primary);
}

.cf-stage.is-error .cf-stage__asterisk { color: var(--color-red-brand); }
.cf-stage.is-error .cf-stage__error { opacity: 1; }
.cf-stage.is-error .cf-field { border-color: var(--color-red-brand); }


/* ── BASIC DETAILS GRID ── */
.cf-basic {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-row-gap: 10px;
    grid-column-gap: 20px;
    width: 100%;
}
.cf-basic .cf-stage { gap: 8px; }

/* ── INPUT FIELD ── */
.cf-field {
    width: 100%;
    height: 38px;
    box-sizing: border-box;
    background: transparent;
    border: var(--guide-border);
    border-radius: var(--radius);
    padding: 0 14px;
    color: var(--color-white);
    font-family: var(--font-body);
    font-size: var(--text-xs);
    letter-spacing: var(--tracking-body);
    outline: none;
    transition: border-color 0.3s var(--ease-primary);
}
.cf-field:focus {
    border-color: var(--color-white);
}

.cf-field--message {
    height: 76px;
    padding-top: 10px;
    padding-bottom: 10px;
    resize: none;
    font-family: var(--font-body);
    line-height: var(--leading-normal);
}


/* ── SERVICES (chips) ── */
.cf-services {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.cf-chip {
    --chip-color: var(--color-greyish);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 8px 20px;
    border: 1px solid var(--chip-color);
    border-radius: var(--radius);
    background: transparent;
    color: var(--color-white);
    font-family: var(--font-body);
    font-size: var(--text-xs);
    letter-spacing: var(--tracking-body);
    line-height: 1;
    cursor: pointer;
    /* `transform-origin: center` so hover-shrink + press-pulsate scale
       symmetrically (no shift toward an edge while neighbours stay put).
       Transform transition is 0.2s — slightly longer than the previous
       0.15s — so the press-deeper → spring-back-to-hover-size pulsate
       reads as a soft cushion rather than a snap. Transforms don't
       trigger layout so neighbour chips never move during the pulse. */
    transform-origin: center;
    transition: background 0.25s var(--ease-primary), color 0.25s var(--ease-primary), transform 0.2s var(--ease-primary);
    white-space: nowrap;
}
.cf-chip[data-svc="brand"]    { --chip-color: var(--color-red-brand); }
.cf-chip[data-svc="comms"]    { --chip-color: var(--color-orange-comms); }
.cf-chip[data-svc="app"]      { --chip-color: var(--color-purple-app-platform); }
.cf-chip[data-svc="web"]      { --chip-color: var(--color-blue-web); }
.cf-chip[data-svc="pkg"]      { --chip-color: var(--color-green-packaging); }
.cf-chip[data-svc="name"]     { --chip-color: var(--color-pink-name-ideation); }
.cf-chip[data-svc="graphic"]  { --chip-color: var(--color-yellow-graphic-design); }
.cf-chip[data-svc="other"]    { --chip-color: var(--color-greyish); }

/* Active state — clicking toggles `.is-active` (in contact-form.js) which
   fills the chip with its service colour. This is the ONLY thing that
   communicates selected vs. unselected now — colour state is decoupled
   from hover. The "other" chip is grey, so its filled text needs to
   flip to dark for legibility. */
.cf-chip.is-active { background: var(--chip-color); color: var(--color-white); }
.cf-chip[data-svc="other"].is-active { color: var(--color-black2); }

/* Desktop / tablet hover + press behaviour ─ size, not colour.
     - hover: chip shrinks to 0.95 (a soft "I'm available" cue)
     - press (mouse held / Space-bar / Enter): chip shrinks further to
       0.92 — the "deeper" half of the pulsate
     - on release while still hovered: transform transitions back up
       to 0.95 because `:active` releases but `:hover` is still true →
       the pulse reads as press-deeper → cushion-back-to-hover, with
       the colour swap (driven by JS toggling `.is-active`) landing
       right in the dip.
   Wrapped in `min-width: 768px` so mobile keeps its existing design
   (transparent chip with the small inner colour swatch box toggling
   on `.is-active`). Touch hover doesn't apply, so a hover-shrink on
   mobile would either flicker on tap or never fire. */
@media (min-width: 768px) {
    .cf-chip:hover { transform: scale(0.95); }
    /* The "press" pulse is a CSS animation, not a `:active` transition.
       Why: `:active` only fires while the mouse button is physically
       held down (typically 50–100 ms for a normal click). A 0.2 s
       transform transition can't reach scale(0.85) in that window —
       the chip dips ~halfway and snaps back when the user releases,
       so the press barely registers visually. A class-driven keyframe
       animation runs its full duration regardless of how long the
       click is held, so every click pulses to scale(0.85) at peak,
       no matter how brief. The class is added on the `click` event
       by contact-form-chip-pulse.js (a tiny visual-only file — does
       NOT touch the form's logic in contact-form.js). */
    .cf-chip--pulsing { animation: cf-chip-pulse 0.35s var(--ease-primary); }
}
/* Pulse keyframes live outside the @media so the animation rule can
   reference them on any viewport (currently only used at ≥768 px,
   but trivial to extend later). The dip lands at 40 % of the timeline
   — a touch past midway — so the press feels deliberate but the
   spring-back-to-hover-size has more room to breathe and ease out. */
@keyframes cf-chip-pulse {
    0%   { transform: scale(0.95); }
    40%  { transform: scale(0.85); }
    100% { transform: scale(0.95); }
}

/* Mobile: chip is bordered (in service color) AND has the checkbox-square inside.
   Each chip is its own bordered cell with a small coloured square + label. */
@media (max-width: 767px) {
    .cf-services {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 10px 12px;
    }
    .cf-chip {
        justify-content: flex-start;
        padding: 12px 14px;
        border: 1px solid var(--chip-color);
        border-radius: var(--radius);
        background: transparent !important;
        color: var(--color-white) !important;
        gap: 10px;
        min-height: 44px;
    }
    .cf-chip__box {
        width: 10px;
        height: 10px;
        border: 1px solid var(--chip-color);
        border-radius: 1px;
        flex-shrink: 0;
        transition: background 0.2s var(--ease-primary);
    }
    .cf-chip.is-active .cf-chip__box { background: var(--chip-color); }
    /* Subtle tap feedback — a small scale-down while the chip is being
       tapped gives a tactile "you pressed me" cue. Lighter than the
       desktop press (0.97 vs 0.92) since the chip is full-width on
       mobile and a deep shrink reads exaggerated next to the inner
       swatch box. */
    .cf-chip:active { transform: scale(0.97); }
}
.cf-chip__box { display: none; }
@media (max-width: 767px) { .cf-chip__box { display: inline-block; } }


/* ── BUDGET BOXES ── */
.cf-budget {
    position: relative;
    width: 100%;
}

.cf-budget__grid {
    position: relative;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    column-gap: 36px;        /* room for the SVG tubes */
    width: 100%;
    z-index: 2;
}

.cf-budget__box {
    position: relative;
    height: 78px;
    /* No border — the entire dashed outline is owned by the SVG layer
       (.cf-budget__tubes) which traces all four boxes + the inter-box
       tube cutouts as a single continuous path. Per-box borders would
       collide with that frame and destroy the "connected via tubes"
       visual. The boxes are otherwise just transparent click targets. */
    border-radius: var(--radius);
    background: transparent;
    color: var(--color-white);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-heading);
    font-weight: var(--font-weight-medium);
    letter-spacing: var(--tracking-tight);
    font-size: 16px;
    line-height: 1;
    /* Same press-shrink as the service chips — keeps the form's click
       feedback consistent across all clickable controls. */
    transform-origin: center;
    transition: color 0.25s var(--ease-primary), background 0.25s var(--ease-primary), transform 0.15s var(--ease-primary);
    overflow: hidden;
    z-index: 2;
}
.cf-budget__box:active { transform: scale(0.96); }

/* Hover plate — a centred dark capsule that fades in on hover, sized
   to match the active pill (so hover and active geometries align).
   Active state is now driven by the SHARED `.cf-budget__active-pill`
   element (the one that travels through the tubes), so this `::before`
   is purely the hover indicator. On the active box the hover plate is
   suppressed via the rule below — otherwise hovering the active box
   would stack a dark plate over the white travelling pill. */
.cf-budget__box::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: calc(100% - 32px);
    height: 44px;
    background: var(--color-black);
    border-radius: 4px;
    opacity: 0;
    transition: opacity 0.25s var(--ease-primary);
    z-index: -1;
}
.cf-budget__box:not(.is-active):hover::before { opacity: 1; }
.cf-budget__box:not(.is-active):hover { color: var(--color-white); }

/* Active — text flips to dark to read against the white travelling
   pill. Box itself stays transparent (no full-box fill); the hover
   plate is hidden so it doesn't stack on top of the travelling pill. */
.cf-budget__box.is-active { color: var(--color-black2); }
.cf-budget__box.is-active::before { opacity: 0; }

/* The travelling active pill — a single shared element that GSAP
   positions and sizes per `animatePillTransition` in contact-form.js.
   `top: 0; left: 0` + `transform: translate3d(x, y, 0)` lets us animate
   via GSAP's `x`/`y` (faster than animating `left`/`top`).
   Z-index 1 sits ABOVE the SVG outline (z-index 1 too, but later in
   DOM order means it paints on top — though our pill geometry is
   always inside the channel so it doesn't visually cover the dashes)
   and BELOW the boxes (z-index 2 in the grid stacking) so the box's
   text reads clearly over the pill when at rest in a box.
   Initial state: width/height 0 + opacity 0 — invisible until the
   first `setActiveBudget(idx)` populates it. */
.cf-budget__active-pill {
    position: absolute;
    top: 0;
    left: 0;
    width: 0;
    height: 0;
    background: var(--color-white);
    border-radius: 4px;
    opacity: 0;
    z-index: 1;
    pointer-events: none;
    will-change: transform, width, height, opacity;
}

/* SVG tube layer — sits BEHIND the boxes visually but routes between them.
   `overflow: visible` matters: the path geometry runs along the SVG's
   viewBox edges (top/bottom/left/right), and the 1 px stroke extends
   ~0.5 px outside the geometry on each side. Default `overflow: hidden`
   on inline SVG would clip those half-pixels, leaving truncated dashes
   along the four outer edges. */
.cf-budget__tubes {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 1;
    overflow: visible;
}
/* Dashed stroke calibrated to match the rest of the page's CSS
   `border: 1px dashed` pattern. Chrome renders a 1 px CSS dashed
   border as roughly 2×2 px alternating segments — `stroke-dasharray:
   2 2` mirrors that, so the budget outline reads identical to the
   guide lines, hero rails, and the address-pill borders elsewhere on
   the contact page. (Was 4 4, which was visibly chunkier.) */
.cf-budget__tubes path {
    fill: none;
    stroke: var(--color-grid);
    stroke-width: 1;
    stroke-dasharray: 2 2;
    stroke-linecap: butt;
    stroke-linejoin: round;
}


/* ── SUBMIT BUTTON ── */
.cf-submit {
    position: relative;
    width: 100%;
    height: 60px;
    background: var(--color-white);
    color: var(--color-black2);
    border: 1px solid transparent;
    border-radius: var(--radius);
    font-family: var(--font-heading);
    font-weight: var(--font-weight-medium);
    letter-spacing: var(--tracking-btn);
    font-size: var(--text-btn);
    cursor: pointer;
    /* Subtler press-shrink (2 %) than the chips/budget boxes — the submit
       is a much larger target so the same 4 % shrink would look exaggerated. */
    transform-origin: center;
    transition: background 0.3s var(--ease-primary), color 0.3s var(--ease-primary), border-color 0.3s var(--ease-primary), transform 0.15s var(--ease-primary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
}
/* Press feedback — gated with `:not(.is-submitted)` so the post-submit
   state (which has cursor:default and is no longer interactive) does
   not visually depress on click. */
.cf-submit:not(.is-submitted):active { transform: scale(0.98); }
.cf-submit:hover {
    background: var(--color-black);
    color: var(--color-white);
}
.cf-submit.is-submitted {
    background: transparent;
    color: var(--color-white);
    border: var(--guide-border);
    cursor: default;
}
.cf-submit__reset {
    display: none;
    width: 18px;
    height: 18px;
    color: var(--color-white);
    cursor: pointer;
    transition: transform 0.4s var(--ease-primary);
}
.cf-submit__reset svg { width: 100%; height: 100%; display: block; fill: currentColor; }
.cf-submit.is-submitted .cf-submit__reset { display: inline-block; }
.cf-submit__reset:hover { animation: cfResetSpin 1.2s linear infinite; }

@keyframes cfResetSpin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}


/* ── RESPONSIVE ── */
@media (max-width: 767px) {
    .cf-stages { gap: 20px; }
    .cf-form__submit-wrap { margin-top: 20px; }

    .cf-basic { grid-template-columns: 1fr; }

    /* Taller, more touch-friendly fields. font-size:16px prevents iOS
       Safari from zooming in on focus (any input <16px triggers it). */
    .cf-field {
        height: 50px;
        font-size: 16px;
        padding: 0 16px;
    }
    .cf-field--message {
        height: 110px;
        padding-top: 14px;
        padding-bottom: 14px;
        font-size: 16px;
    }

    .cf-budget__grid { column-gap: 20px; }
    .cf-budget__box { height: 64px; font-size: 15px; }

    /* Bigger, more tappable submit button on mobile */
    .cf-submit { height: 64px; }
}
