/* ============================================================
   QUOTE PAGE SERVICE FORMS — form.css
   ============================================================
   The one stylesheet behind every service form on the quote page:

     services/others/form.html            (8 services)
     services/attestation/form.html
     services/dtp/form.html
     services/interpretation/steps_form.html

   The host page links this file, not those partials: each of them
   is injected into #servicesFormPanel with .html(), and a <link>
   added that way only starts downloading once the markup it styles
   is already on screen — one frame of unstyled form (FOUC) on every
   service switch. quote.html links it up front instead.

   Scoping
   -------
   The shared field anatomy is scoped to `.quote-form`, the class
   all four <form> elements carry. That deliberately stops at the
   form: every panel also holds a plans panel injected *inside* the
   same <section>, and those own their look via plan.css.

   A handful of rules keep an id scope
   (#form_panel · #attestationServiceFromPanel ·
   #interpretationServiceFromPanel) for one of two reasons:

     • they style the panel shell *around* the form (card, stepper,
       note), which `.quote-form` can't reach; or
     • they must out-rank a stylesheet that loads later in the
       document. footer.html declares .updated-prices / .staris and
       links select2.min.css, and interpretation's modal.html ships
       !important select2 overrides of its own. A class beats those
       on specificity in most cases; where it doesn't, an id does.

   Tokens
   ------
   Everything resolves against variables.css, which quote.html
   links before the forms are injected — so there are no local
   :root redeclarations and no var() fallbacks here.

   Load order (document order, which is what the cascade follows):

       variables.css · bootstrap · style.scoped.css     quote.html
       → select2-theme.css · flatpickr-theme.css ·
         native-select-theme.css · THIS FILE            quote.html, last
                                                        in that block
       → select2.min.css · flatpickr.min.css ·
         .updated-prices / .staris                      footer.html
   ============================================================ */


/* ============================================================
   PANEL SHELLS
   ============================================================
   Id-scoped: these sit outside the <form>. */
#form_panel,
#attestationServiceFromPanel,
#interpretationServiceFromPanel {
    font-family: var(--font-body);
    color: var(--color-text-primary);
}

/* .card-demo / .card are legacy #f2f5f7 wells; the inset fields
   would be invisible against them. */
#attestationServiceFromPanel .card-demo,
#form_panel .card-demo {
    background: var(--color-surface-white);
    border-radius: var(--radius-lg);
    padding: 0 40px;
}

#interpretationServiceFromPanel .card {
    background: var(--color-surface-white);
    border: 0;
    border-radius: var(--radius-lg);
    box-shadow: none;
}

/* plan.html and the discount modal land inside this section and
   carry their own styling, so this stays deliberately narrow.
   plan.css shouts back with !important where it needs to. */
#interpretationServiceFromPanel a {
    font-size: 12px;
    font-weight: 600;
    text-decoration: none;
}

/* the raw <select class="otherServiceSelect"> select2 turns into a
   shell — this just keeps it off the UA's native height for the frame
   before select2 runs. Moved out of footer.html. */
#form_panel .otherServiceSelect {
    height: 46px !important;
}


/* ============================================================
   BASE
   ============================================================ */
.quote-form button,
.quote-form input,
.quote-form select,
.quote-form textarea,
.quote-form .row__select {
    font-family: inherit;
    font-size: inherit;
    color: inherit;
}

.quote-form button {
    cursor: pointer;
    background: none;
    border: none;
}

/* the design replaces the UA outline with a box-shadow ring */
.quote-form input:focus,
.quote-form select:focus,
.quote-form textarea:focus,
.quote-form .row__select:focus {
    outline: none !important;
}

/* number spinners fight the pill's padding */
.quote-form input[type="number"]::-webkit-outer-spin-button,
.quote-form input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.quote-form input[type="number"] {
    -moz-appearance: textfield;
    appearance: textfield;
}


/* ============================================================
   FIELDS
   ============================================================
   One field = a label stacked over a control, bottom-aligned so a
   row of them lines up whatever height the labels wrap to. */
.quote-form .field {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 5px;
    min-width: 0;
}

/* attestation and interpretation wrap some labels in a .d-flex
   row; both read the same */
.quote-form .field > .d-flex,
.quote-form .form-group > .d-flex,
.quote-form [class*="col-"] > .d-flex {
    margin: 0;
}

.quote-form .field > label,
.quote-form .field > .d-flex > label,
.quote-form .form-group > label,
.quote-form [class*="col-"] > label,
.quote-form [class*="col-"] > .d-flex > label,
.quote-form .reveal-panel label {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 3px;
    font-size: 14px;
    font-weight: 400;
    line-height: 1.2;
    color: var(--color-text-primary);
}

/* .field already spaces label and control with its own gap */
.quote-form .field > label,
.quote-form .field > .d-flex > label {
    margin-bottom: 0;
}

/* the required asterisk reads as part of the label, not a warning
   (footer.html paints a bare .staris red) */
.quote-form label .staris {
    color: var(--color-status-danger) !important;
    font-size: inherit;
    font-weight: 500;
}

/* info glyphs carry the label's own colour rather than shouting */
.quote-form label .bi {
    font-size: 13px;
    color: var(--color-text-primary);
    cursor: pointer;
}

/* the currency hints: "(Currency: NZD)" and "Price in NZD" */
.quote-form .field__hint,
.quote-form .small-green {
    margin: 0;
    font-size: 12px;
    font-style: normal;
    font-weight: 500;
    color: var(--color-text-secondary);
}

/* the word-count label's trailing annotation — "words per page",
   "words per minute", CERT's "auto" — same weight as .field__hint,
   just inline with the label text instead of stacked under it */
.quote-form .PagePerWordSpan {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 2px;
    font-size: 12px;
    font-weight: 500;
    color: var(--color-text-secondary);
}

.quote-form .PagePerWordSpan i,
.quote-form .PagePerWordSpan svg {
    font-size: 16px;
    width: 16px;
    height: 16px;
}

.quote-form .field.field--add {
    gap: 0;
}

/* ── Validation ─────────────────────────────────────────── */
.quote-form .field--error > label {
    color: var(--color-status-danger);
}

.quote-form .field--error .wordcount,
.quote-form .field--error .delivery-date-btn,
.quote-form .field--error .select2-selection,
.quote-form .wordcount.is-invalid {
    box-shadow: inset 0 0 0 1.5px var(--color-status-danger);
}

/* the shared validation helper paints this on a missing field */
.quote-form .is-invalid {
    border: 0 !important;
    background-color: var(--color-status-danger-bg) !important;
    box-shadow: inset 0 0 0 1.5px var(--color-status-danger) !important;
}


/* ============================================================
   TEXT CONTROLS
   ============================================================
   .tall-input is interpretation's alias for the same thing. */
.quote-form .form-control,
.quote-form .tall-input {
    width: 100%;
    height: var(--field-h);
    min-height: var(--field-h);
    padding: 0 16px;
    background: var(--color-surface-inset);
    border: 0;
    border-radius: var(--field-radius) !important;
    box-shadow: none;
    font-family: inherit;
    font-size: 16px;
    font-weight: 400;
    line-height: normal;
    color: var(--color-text-primary);
    transition: background var(--transition-fast), box-shadow var(--transition-fast);
}

.quote-form textarea.form-control {
    height: auto;
    padding: 13px 16px;
    line-height: 1.45;
    resize: none;
}

.quote-form .form-control::placeholder,
.quote-form input::placeholder,
.quote-form textarea::placeholder {
    font-size: 14px;
    font-weight: 400;
    color: var(--color-text-placeholder);
    opacity: 1;
}

.quote-form .form-control:hover {
    background: var(--color-surface-subtle);
}

.quote-form .form-control:focus {
    outline: none;
    background: var(--color-surface-white);
    border: 0;
    box-shadow: var(--focus-ring-gold);
}

/* Fallback for any <select> select2 hasn't taken over — the frame
   before loadSpeakersTemplate() inits the injected Gender field, or
   a page where select2 failed to load. Same chevron select2-theme.css
   draws on the select2 shells; the stroke colour is
   --color-text-secondary's real hex (#71717a) hardcoded, because
   var() can't be used inside an SVG data URI. The !importants beat
   the :hover shorthand above, which would otherwise reset
   background-image to none. */
.quote-form select.form-control:not(.select2-hidden-accessible),
.quote-form .row__select {
    appearance: none;
    -webkit-appearance: none;
    padding-right: 42px;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2371717a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") !important;
    background-repeat: no-repeat !important;
    background-position: right 16px center !important;
    background-size: 13px 13px !important;
}


/* ============================================================
   FILLED PILL
   ============================================================
   One control holding a count, a hairline divider, a file tally
   and an upload trigger. Three templates, three class names, one
   component:

     .wordcount   others      — the count is typed
     .fake-input  attestation — the count is filled in by the modal
     .dtp-pill    dtp         — ditto
   ============================================================ */
.quote-form .wordcount,
.quote-form .fake-input,
.quote-form .dtp-pill {
    display: flex;
    align-items: center;
    width: 100%;
    height: var(--field-h);
    min-height: var(--field-h);
    background: var(--color-surface-inset);
    border: 0;
    border-radius: var(--field-radius);
    box-shadow: none;
    transition: box-shadow var(--transition-fast);
}

/* the typed variant lets its input take the slack; the read-only
   variants park it against a fixed-width count */
.quote-form .wordcount {
    gap: 0;
    padding: 0 12px;
}

.quote-form .fake-input,
.quote-form .dtp-pill {
    padding: 0 6px 0 16px;
}

.quote-form .wordcount:focus-within,
.quote-form .fake-input:focus-within,
.quote-form .dtp-pill:focus-within {
    box-shadow: var(--focus-ring-gold);
}

/* The read-only counts stay disabled — hence the explicit
   text-fill-color, which webkit would otherwise grey out. */
.quote-form .wordcount input,
.quote-form #totalDocumentPlaceHolder,
.quote-form #dtp_pages_show {
    min-width: 0;
    border: 0;
    outline: none;
    background: transparent;
    box-shadow: none;
    font: inherit;
    font-size: 14px;
    font-weight: 500;
    color: var(--color-text-primary);
    -webkit-text-fill-color: var(--color-text-primary);
    opacity: 1;
    font-variant-numeric: tabular-nums;
}

.quote-form .wordcount input {
    flex: 1 1 44px;
    padding: 0 12px 0 0;
}

.quote-form #totalDocumentPlaceHolder,
.quote-form #dtp_pages_show {
    flex: 0 1 auto;
    width: 62px;
    min-width: 40px;
    padding: 0;
    cursor: default;
}

.quote-form .wordcount input::placeholder {
    color: var(--color-text-placeholder);
    opacity: 1;
}

/* .left-border draws its line with a border in style.css; a
   background keeps it a crisp hairline at any device pixel ratio */
.quote-form .wordcount__divider,
.quote-form .fake-input .left-border,
.quote-form .dtp-pill .left-border {
    flex: none;
    width: 1px;
    height: 32px;
    margin: 0;
    padding: 0;
    border: 0;
    background: var(--color-divider);
    opacity: 1;
}

/* margin-left:auto parks the slack between the divider and the
   tally, the way the mockup spaces them */
.quote-form .fake-input .span-wrap,
.quote-form .dtp-pill .span-wrap {
    flex: 0 1 auto;
    display: flex;
    align-items: center;
    min-width: 0;
    margin: 0 16px 0 auto;
}

.quote-form .wordcount__files,
.quote-form .fake-input .span-wrap > span,
.quote-form .dtp-pill .span-wrap > span {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    line-height: 1;
    color: var(--color-text-muted);
    white-space: nowrap;
}

.quote-form .wordcount__files {
    margin: 0 20px 0 25px;
}

.quote-form .wordcount__files svg,
.quote-form .fake-input .span-wrap svg,
.quote-form .dtp-pill .span-wrap svg {
    width: 14px;
    height: 14px;
}

.quote-form .wordcount__suffix {
    margin-left: 6px;
    font-size: 13px;
    color: var(--color-text-secondary);
    white-space: nowrap;
}

/* ── Upload trigger, inside the pill ────────────────────── */
.quote-form .upload-btn,
.quote-form #attestationUploadText {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 32px;
    padding: 0 14px;
    border: 0;
    border-radius: var(--radius-sm);
    background: var(--color-brand-gold);
    font: inherit;
    font-size: 12px;
    font-weight: 400;
    color: #fff;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: background var(--transition-fast);
}

.quote-form .upload-btn:hover,
.quote-form .upload-btn:focus,
.quote-form #attestationUploadText:hover,
.quote-form #attestationUploadText:focus {
    background: var(--color-brand-gold-hover);
    color: #fff;
    text-decoration: none;
}


/* ============================================================
   DATE FIELDS
   ============================================================ */
/* attestation / dtp — a flatpickr-backed text field */
.quote-form #delivery_date {
    padding-right: 44px;
    cursor: pointer;
}

.quote-form #delivery_date.active {
    background: var(--color-surface-white);
    box-shadow: var(--focus-ring-gold);
}

/* interpretation — Tempus Dominus. The addon span is the picker's
   toggle (data-td-toggle), so it has to stay in the markup; it just
   moves inside the pill. The whole pill opens the picker: clicks
   elsewhere in the group are forwarded to it by steps_form.html's
   handler, so the pointer cursor covers the group. */
.quote-form .input-group {
    position: relative;
    display: block;
    width: 100%;
    cursor: pointer;
}

.quote-form .input-group > .form-control {
    width: 100%;
    padding-right: 48px;
    border-radius: var(--field-radius);
    cursor: pointer;
}

.quote-form .input-group > .input-group-text {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: var(--field-h);
    margin: 0;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: 0;
    font-size: 15px;
    color: var(--color-text-secondary);
    cursor: pointer;
}

/* the calendar glyph, pinned from the bottom so it centres inside
   the 48px control however tall the label above it wraps */
.quote-form .field--delivery .icon-date,
.quote-form .icon-date-custom {
    position: absolute;
    top: auto;
    right: 16px;
    bottom: 0;
    display: flex;
    align-items: center;
    height: var(--field-h);
    font-size: 15px;
    color: var(--color-text-secondary);
    opacity: 1;
    pointer-events: none;
}

/* the speakers' date-of-birth field clears its own glyph */
.quote-form .speaker-dob {
    padding-right: 44px;
}

/* the delivery-date control on the others form — a button that
   opens .dd-modal rather than a picker */
.quote-form .delivery-date-btn {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: var(--field-h);
    padding: 0 12px;
    background: var(--color-surface-inset);
    border: 0;
    border-radius: var(--field-radius);
    font: inherit;
    font-size: 16px;
    font-weight: 400;
    color: var(--color-text-primary);
    text-align: left;
    cursor: pointer;
    transition: background var(--transition-fast), box-shadow var(--transition-fast);
}

.quote-form .delivery-date-btn:hover {
    background: var(--color-surface-subtle);
}

.quote-form .delivery-date-btn:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring-gold);
}

.quote-form .delivery-date-btn__text {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}


/* ============================================================
   PRIMARY CTA
   ============================================================
   footer.html paints a bare .updated-prices with a blue border and
   a 49.6px min-height; two classes out-rank it. */
.quote-form .btn-price,
.quote-form #attestationShowPriceBtn,
.quote-form #interpretationShowPriceBtn,
.quote-form #nextBtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: var(--field-h);
    min-height: var(--field-h);
    padding: 0 22px;
    background: var(--color-brand-navy);
    border: 0;
    border-radius: var(--field-radius);
    box-shadow: none;
    font: inherit;
    font-size: 16px;
    font-weight: 500;
    color: #fff;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--transition-fast), transform var(--transition-fast);
}

.quote-form .btn-price:hover:not(:disabled):not([data-wc-blocked]),
.quote-form #attestationShowPriceBtn:hover:not(:disabled):not([data-wc-blocked]),
.quote-form #interpretationShowPriceBtn:hover:not(:disabled):not([data-wc-blocked]),
.quote-form #nextBtn:hover:not(:disabled):not([data-wc-blocked]) {
    background: var(--color-brand-navy-hover);
    border-color: transparent;
    color: #fff;
}

.quote-form .btn-price:active:not(:disabled):not([data-wc-blocked]),
.quote-form #attestationShowPriceBtn:active:not(:disabled):not([data-wc-blocked]),
.quote-form #interpretationShowPriceBtn:active:not(:disabled):not([data-wc-blocked]),
.quote-form #nextBtn:active:not(:disabled):not([data-wc-blocked]) {
    transform: translateY(1px);
}

.quote-form .btn-price:focus-visible,
.quote-form #attestationShowPriceBtn:focus-visible,
.quote-form #interpretationShowPriceBtn:focus-visible,
.quote-form #nextBtn:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring-navy);
}

/* [data-wc-blocked]: same look as :disabled, but click still lands -
   see services/price_button_guard.html. */
.quote-form .btn-price:disabled,
.quote-form #attestationShowPriceBtn:disabled,
.quote-form #interpretationShowPriceBtn:disabled,
.quote-form #nextBtn:disabled,
.quote-form .btn-price[data-wc-blocked],
.quote-form #attestationShowPriceBtn[data-wc-blocked],
.quote-form #interpretationShowPriceBtn[data-wc-blocked],
.quote-form #nextBtn[data-wc-blocked] {
    background: var(--color-brand-navy);
    opacity: 0.6;
    cursor: not-allowed;
}


/* ============================================================
   LANGUAGE ROWS  ·  others
   ============================================================ */
.quote-form .rows {
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.quote-form .rows:has(~ .rows) {
    margin-bottom: 20px;
}

.quote-form .lang-row {
    position: relative;
}

.quote-form .row__fields {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 52px;
    gap: 24px var(--field-gap);
    align-items: end;
}

.quote-form .row__fields--professional .field--source,
.quote-form .row__fields--professional .field--targets {
    grid-column: 1 / -1;
}

.quote-form .row__fields--professional .field--wordcount {
    grid-column: 1;
}

.quote-form .row__fields--professional .field--add {
    grid-column: 2;
}

/* ── Add / remove row buttons (the trailing grid column) ── */
.quote-form .row-action {
    flex: none;
    width: 52px;
    height: var(--field-h);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: var(--field-radius);
    background: var(--color-surface-inset);
    color: var(--color-text-primary);
    box-shadow: none;
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast);
}

/* keep the icon optically centred and stop the SVG being squashed */
.quote-form .row-action svg {
    flex: none;
    width: 14px;
    height: 14px;
}

.quote-form .row-action:hover,
.quote-form .row-action:focus-visible {
    background: var(--color-surface-subtle);
}

.quote-form .row-action:focus-visible {
    outline: 2px solid var(--color-brand-gold);
    outline-offset: 2px;
}

.quote-form .lang-row .field--add {
    flex-direction: row;
    align-items: flex-end;
    gap: 0;
}

.quote-form .lang-row .field--add .row-action {
    display: flex;
}

.quote-form .field--add .add__label {
    display: none;
    font-size: 14px;
    font-weight: 500;
    color: var(--color-text-primary);
}

/* ── Remove-this-row control ─────────────────────────────── */
.quote-form .lang-row > .row__remove {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 2;
    width: 20px;
    height: 20px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: var(--radius-xs);
    background: transparent;
    color: var(--color-text-muted);
    box-shadow: none;
    cursor: pointer;
    transition:
        background var(--transition-fast),
        color var(--transition-fast),
        opacity var(--transition-fast);
}

.quote-form .lang-row > .row__remove svg {
    flex: none;
    width: 12px;
    height: 12px;
}

.quote-form .lang-row > .row__remove:hover:not(:disabled),
.quote-form .lang-row > .row__remove:focus-visible:not(:disabled) {
    background: var(--color-status-danger-bg);
    color: var(--color-status-danger);
}

.quote-form .lang-row > .row__remove:focus-visible {
    outline: 2px solid var(--color-brand-gold);
    outline-offset: 2px;
}

/* a single row has nothing to remove */
.quote-form .lang-row > .row__remove:disabled {
    display: none;
}

/* ── Row enter / collapse-on-remove ──────────────────────── */
@keyframes row-in {
    from {
        opacity: 0;
        transform: translateY(-6px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.quote-form .lang-row--entering {
    animation: row-in 240ms ease both;
}

.quote-form .lang-row--removing {
    overflow: hidden;
    /* cancel row-in's `both` fill mode */
    animation: none;
    pointer-events: none;
    opacity: 0;
    height: 0 !important;
    margin-bottom: -24px;
    transition:
        height 220ms ease,
        opacity 160ms ease,
        margin-bottom 220ms ease;
}

.quote-form .lang-row--removing select {
    display: none !important;
}

/* ── Only the latest row needs "Add another source" ──────────
   Non-last rows hide it and let the word-count field reclaim its
   column. */
.quote-form .lang-row:not(:last-child) .field--add {
    display: none;
}

.quote-form .lang-row:not(:last-child) .row__fields--professional .field--wordcount {
    grid-column: 1 / -1;
}

/* very small screens: the word-count pill needs the full width */
@media (max-width: 479px) {
    .quote-form .row__fields--professional .field--wordcount {
        grid-column: 1 / -1;
    }

    .quote-form .row__fields--professional .field--add {
        grid-column: 1 / -1;
        width: 100%;
        justify-self: end;
    }

    .quote-form .field.field--add .add-row-btn {
        width: 100%;
    }

    .quote-form .field.field--add .add__label {
        display: inline;
    }
}

@media (min-width: 640px) {
    .quote-form .row__fields--professional {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 52px;
    }

    .quote-form .row__fields--professional .field--source {
        grid-column: 1;
    }

    .quote-form .row__fields--professional .field--targets {
        grid-column: 2 / span 2;
    }

    .quote-form .row__fields--professional .field--wordcount {
        grid-column: 1 / span 2;
    }

    .quote-form .row__fields--professional .field--add {
        grid-column: 3;
    }

    .quote-form .lang-row:not(:last-child) .row__fields--professional .field--wordcount {
        grid-column: 1 / -1;
    }
}

@media (min-width: 1024px) {
    .quote-form .row__fields--professional {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(232px, 270px) 52px;
    }

    .quote-form .row__fields--professional .field--targets {
        grid-column: 2;
    }

    .quote-form .row__fields--professional .field--wordcount {
        grid-column: 3;
    }

    .quote-form .row__fields--professional .field--add {
        grid-column: 4;
    }

    .quote-form .lang-row:not(:last-child) .row__fields--professional .field--wordcount {
        grid-column: 3 / -1;
    }
}


/* ============================================================
   CERTIFIED: COUNTRY + CERTIFICATION  ·  others
   ============================================================
   Same field anatomy as the language rows, but two equal columns. */
.quote-form .cert-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 24px var(--field-gap);
    align-items: end;
    margin: 24px 0;
}

.quote-form .cert-row > .field {
    min-width: 0;
}

@media (min-width: 640px) {
    .quote-form .cert-row {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}


/* ============================================================
   OPTIONAL TOGGLES  ·  others
   ============================================================ */
.quote-form .toggle-block {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.quote-form .toggle-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 28px;
}

/* the caption is a <label for> (keeps click-to-toggle), so it needs
   the browser/Bootstrap label margin knocked off */
.quote-form .toggle-row label.toggle-row__label {
    margin: 0;
    font-size: 15px;
    font-weight: 500;
    color: var(--color-text-primary);
    cursor: pointer;
}

.quote-form .toggle-row__info {
    font-size: 13px;
    color: var(--color-text-secondary);
    cursor: pointer;
    transition: color var(--transition-fast);
}

.quote-form .toggle-row__info:hover {
    color: var(--color-link);
}

.quote-form .switch {
    position: relative;
    display: inline-block;
    flex-shrink: 0;
    margin: 0 !important;
}

.quote-form .switch input {
    position: absolute;
    width: 40px;
    height: 22px;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}

.quote-form .switch__track {
    display: block;
    position: relative;
    width: 40px;
    height: 22px;
    border-radius: var(--radius-full);
    background: #cfcabb;
    transition: background var(--transition-base);
}

.quote-form .switch__thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 18px;
    height: 18px;
    border-radius: var(--radius-full);
    background: var(--color-surface-white);
    box-shadow: var(--shadow-sm);
    transition: transform var(--transition-base);
}

.quote-form .switch input:checked + .switch__track {
    background: var(--color-brand-gold);
}

.quote-form .switch input:checked + .switch__track .switch__thumb {
    transform: translateX(18px);
}

.quote-form .switch input:focus-visible + .switch__track {
    outline: 2.5px solid var(--color-brand-navy);
    outline-offset: 2px;
}

.quote-form .toggle-reveal {
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    transition: max-height var(--transition-base), opacity var(--transition-base);
}

.quote-form .toggle-reveal.open {
    opacity: 1;
}

.quote-form .toggle-reveal[hidden] {
    display: none;
}

/* Only clipped while it moves — once open, a dropdown inside the
   panel has to be able to hang outside it. toggleReveal() owns
   this class. */
.quote-form .toggle-reveal.is-settled {
    overflow: visible;
}

.quote-form .toggle-reveal .wordcount {
    background: var(--color-surface-white);
}


/* ============================================================
   REVEAL PANEL  ·  others
   ============================================================
   The well of fields a .toggle-reveal opens. Generic — one direct
   child per field; --2 / --3 / --4 pick the column count on wide screens.

   (The DTP block predates this and keeps its own .dtp-field-grid,
   whose two columns are deliberately uneven — leave it be.) */
.quote-form .reveal-panel,
.quote-form .dtp-field-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
    padding: 16px;
    background: var(--color-surface-page);
    border-radius: var(--field-radius);
    animation: row-in var(--transition-base) ease both;
}

.quote-form .dtp-field-grid {
    transition: border-color var(--transition-fast);
}

.quote-form .dtp-field-grid:hover {
    border-color: color-mix(in srgb, var(--color-border) 55%, var(--color-brand-gold) 45%);
}

/* Each cell stacks like a .field. The second rule is for cells that
   need an inner positioning wrapper (e.g. to anchor a dropdown to
   the input). */
.quote-form .reveal-panel > div,
.quote-form .reveal-panel > div > .position-relative {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 5px;
    min-width: 0;
}

/* these two wells sit on --color-surface-page, so their fields lift
   back to white to stay legible */
.quote-form .reveal-panel .form-control,
.quote-form .dtp-field-grid .field .form-control {
    background-color: var(--color-surface-white);
}

.quote-form .reveal-panel .form-control:disabled,
.quote-form .reveal-panel .form-control[readonly] {
    background-color: var(--color-surface-subtle);
    color: var(--color-text-secondary);
    cursor: not-allowed;
}

@media (min-width: 640px) {
    .quote-form .reveal-panel--2,
    .quote-form .reveal-panel--3,
    .quote-form .reveal-panel--4 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .quote-form .dtp-field-grid--2 {
        grid-template-columns: minmax(0, 0.62fr) minmax(0, 1.6fr);
    }
}

@media (min-width: 1024px) {
    .quote-form .reveal-panel--3 {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .quote-form .reveal-panel--4 {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    /* Courier: the only thing it needs beyond the generic panel is a
       wider middle column, because the address runs much longer than
       the other two. */
    .quote-form #courier_reveal .reveal-panel--3 {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr) minmax(0, 1fr);
    }
}

/* Address autocomplete list */
#addressSuggestions {
    top: 100%;
    left: 0;
    margin-top: 6px;
    padding: 6px;
    background: var(--color-surface-white);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    z-index: 300;
}

#addressSuggestions .dropdown-item {
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    font-size: 13px;
    line-height: 1.4;
    color: var(--color-text-primary);
    /* long addresses wrap instead of overflowing */
    white-space: normal;
}

#addressSuggestions .dropdown-item:hover,
#addressSuggestions .dropdown-item:focus,
#addressSuggestions .dropdown-item:active {
    background: var(--color-surface-subtle);
    color: var(--color-text-primary);
}

#addressSuggestions .spinner-border {
    color: var(--color-brand-gold);
}


/* ============================================================
   DELIVERY DATE + SHOW PRICES BAR  ·  others
   ============================================================ */
.quote-form .delivery-bar {
    display: grid;
    /* mobile-first: stacked */
    grid-template-columns: minmax(0, 1fr);
    gap: 24px var(--field-gap);
    margin-top: 28px;
    align-items: end;
}

/* From 640px up the bar reuses the *same* track list as
   .row__fields--professional, so "Delivery date" sits in column 1
   and ends up exactly as wide as "Source". The CTA takes the
   trailing tracks (270 + 18 + 52 = 340px on desktop) and stays
   pinned right. */
@media (min-width: 640px) {
    .quote-form .delivery-bar {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 52px;
    }

    .quote-form .delivery-bar .field--delivery {
        grid-column: 1;
    }

    .quote-form .delivery-bar .btn-price {
        grid-column: 2 / -1;
        justify-self: end;
        width: 340px;
        max-width: 100%;
    }
}

@media (min-width: 1024px) {
    .quote-form .delivery-bar {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(232px, 270px) 52px;
    }

    .quote-form .delivery-bar .btn-price {
        grid-column: 3 / -1;
    }
}


/* ============================================================
   ATTESTATION GRID
   ============================================================
   Mobile-first: one column. 640px: two — Document Count/Type, the
   two fees, then Delivery date/CTA pair up. 1024px: the
   three-across layout from the mockup, same field order. */
.quote-form .atts-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 24px var(--field-gap);
    align-items: end;
}

@media (min-width: 640px) {
    .quote-form .atts-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1024px) {
    .quote-form .atts-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}


/* ============================================================
   DTP BAR
   ============================================================
   Mobile-first: one column. 640px: two. 1024px: the single line
   from the mockup — Source and Delivery date share the slack, the
   pill and the CTA are capped. */
.quote-form .dtp-bar {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 24px var(--field-gap);
    align-items: end;
}

@media (min-width: 640px) {
    .quote-form .dtp-bar {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }
}

@media (min-width: 1024px) {
    .quote-form .dtp-bar {
        grid-template-columns:
            minmax(0, 1fr) minmax(0, 1fr) minmax(250px, 288px) minmax(148px, 178px);
    }
}


/* ============================================================
   INTERPRETATION — STEPPER
   ============================================================
   Id-scoped: the strip is a sibling of the <form>, not inside it.

   The markup is Bootstrap's tab strip and stays that way —
   changeTab() drives it by toggling .active on the nth .nav-link,
   and nothing else. So the three visual states are derived in CSS
   instead:

     completed → sits before the active item
                 (:has(~ .nav-item .nav-link.active))
     current   → carries .active
     upcoming  → the default

   The step number is a CSS counter, so the buttons keep holding
   only their label. Browsers without :has() simply render the
   completed steps as upcoming — nothing breaks.
   ============================================================ */
#interpretationServiceFromPanel #stepTabs {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    margin: 0;
    padding: 0;
    border-bottom: 0;
    counter-reset: intstep;
    list-style: none;
}

#interpretationServiceFromPanel #stepTabs .nav-item {
    position: relative;
    display: flex;
    justify-content: center;
    min-width: 0;
    counter-increment: intstep;
}

/* the two connector halves, drawn behind the circles */
#interpretationServiceFromPanel #stepTabs .nav-item::before,
#interpretationServiceFromPanel #stepTabs .nav-item::after {
    content: "";
    position: absolute;
    top: 15px;
    height: 2px;
    background: var(--color-border);
}

#interpretationServiceFromPanel #stepTabs .nav-item::before { left: 0; right: 50%; }
#interpretationServiceFromPanel #stepTabs .nav-item::after { left: 50%; right: 0; }
#interpretationServiceFromPanel #stepTabs .nav-item:first-child::before,
#interpretationServiceFromPanel #stepTabs .nav-item:last-child::after { display: none; }

/* the button holds the label; ::before is the numbered circle */
#interpretationServiceFromPanel #stepTabs .nav-link {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-width: 0;
    margin: 0;
    padding: 0 2px;
    background: none;
    border: 0;
    border-radius: 0;
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 400;
    line-height: 1.3;
    text-align: center;
    overflow-wrap: break-word;
    color: var(--color-text-secondary);
    opacity: 1;
    cursor: default;
    transition: color var(--transition-fast);
}

#interpretationServiceFromPanel #stepTabs .nav-link::before {
    content: counter(intstep);
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: 2px solid var(--color-border);
    border-radius: var(--radius-full);
    background: var(--color-surface-page);
    font-size: 13px;
    font-weight: 500;
    line-height: 1;
    color: var(--color-text-secondary);
    transition: background var(--transition-fast), border-color var(--transition-fast),
                color var(--transition-fast), box-shadow var(--transition-fast);
}

/* ── current ────────────────────────────────────────────── */
#interpretationServiceFromPanel #stepTabs .nav-link.active {
    background: none;
    font-weight: 500;
    color: var(--color-brand-navy);
}

#interpretationServiceFromPanel #stepTabs .nav-link.active::before {
    border-color: var(--color-brand-navy);
    background: var(--color-surface-white);
    color: var(--color-brand-navy);
    box-shadow: 0 0 0 4px rgba(149, 128, 73, 0.16);
}

#interpretationServiceFromPanel #stepTabs .nav-item:has(> .nav-link.active)::before {
    background: var(--color-brand-navy);
}

/* ── completed ──────────────────────────────────────────── */
#interpretationServiceFromPanel #stepTabs .nav-item:has(~ .nav-item .nav-link.active) .nav-link {
    color: var(--color-text-muted);
}

#interpretationServiceFromPanel #stepTabs .nav-item:has(~ .nav-item .nav-link.active) .nav-link::before {
    content: "";
    border-color: var(--color-brand-navy);
    background: var(--color-brand-navy) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m20 6-11 11-5-5'/%3E%3C/svg%3E") no-repeat center / 14px 14px;
}

#interpretationServiceFromPanel #stepTabs .nav-item:has(~ .nav-item .nav-link.active)::before,
#interpretationServiceFromPanel #stepTabs .nav-item:has(~ .nav-item .nav-link.active)::after {
    background: var(--color-brand-navy);
}


/* ============================================================
   INTERPRETATION — STEP PANELS
   ============================================================
   The !importants here out-rank Bootstrap's spacing utilities
   (.mt-3 / .mt-4 / .mt-5), which the markup still carries and
   which ship as !important themselves. */
#interpretationServiceFromPanel .tab-content {
    height: auto;
    margin: 30px 0 0 !important;
    padding-top: 30px;
    border-top: 1px solid var(--color-border);
    overflow: visible;
}

.quote-form .tab-pane {
    white-space: normal;
    word-wrap: break-word;
}

/* ── Rows ───────────────────────────────────────────────────
   Bootstrap's .row / .col-lg-* stay in the markup (addCharge() in
   main.html and speakerTemp.html both emit them), but the row
   becomes a 12-track grid so the columns can be re-flowed at the
   two breakpoints below. At ≥992px each col-lg-N keeps exactly the
   width Bootstrap gave it. */
.quote-form .tab-content .row {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 22px var(--field-gap);
    align-items: end;
    margin: 0 !important;
}

.quote-form .tab-content .row + .row {
    margin-top: 22px !important;
}

.quote-form .tab-content .row > [class*="col-"] {
    width: auto;
    max-width: none;
    flex: none;
    min-width: 0;
    padding: 0;
    /* mobile: one field per line */
    grid-column: span 12;
}

/* tablet: two */
@media (min-width: 576px) {
    .quote-form .tab-content .row > .col-lg-2,
    .quote-form .tab-content .row > .col-lg-3,
    .quote-form .tab-content .row > .col-lg-4,
    .quote-form .tab-content .row > .col-lg-6 { grid-column: span 6; }
}

/* desktop: the layout the markup already asks for */
@media (min-width: 992px) {
    .quote-form .tab-content .row > .col-lg-2 { grid-column: span 2; }
    .quote-form .tab-content .row > .col-lg-3 { grid-column: span 3; }
    .quote-form .tab-content .row > .col-lg-4 { grid-column: span 4; }
    .quote-form .tab-content .row > .col-lg-6 { grid-column: span 6; }
    .quote-form .tab-content .row > .col-lg-8 { grid-column: span 8; }
}

/* ── Speakers step (speakerTemp.html, injected) ─────────────
   One card per target language; the fields inside sit on white so
   they read against the card's inset fill. */
.quote-form #step4 .targetSpeakers {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    padding: 18px 20px 20px;
    background: var(--color-surface-inset);
    border-radius: var(--radius-md);
}

.quote-form #step4 .targetSpeakers > [class*="col-"] {
    grid-column: span 1;
}

.quote-form #step4 .targetSpeakers .form-control {
    background: var(--color-surface-white);
}

.quote-form #step4 .targetSpeakers .form-control:hover {
    background: var(--color-surface-subtle);
}

.quote-form .tab-content #step4 .targetSpeakers + .targetSpeakers {
    margin-top: 14px !important;
}

@media (max-width: 991.98px) {
    .quote-form #step4 .targetSpeakers { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 575.98px) {
    .quote-form #step4 .targetSpeakers { grid-template-columns: minmax(0, 1fr); }
}

/* ── Additional charges ─────────────────────────────────────
   #chargesContainer is itself a .row but only ever holds rows, so
   it opts out of the grid above. Its children get the description /
   price / action template — addCharge() emits the same
   col-lg-6 · col-lg-4 · col-lg-2 trio. */
.quote-form #chargesContainer {
    display: block;
    margin-top: 22px;
}

.quote-form #chargesContainer > .row {
    grid-template-columns: minmax(0, 1fr) minmax(110px, 180px) 56px;
    margin: 0 !important;
    padding: 0;
}

.quote-form #chargesContainer > .row + .row {
    margin-top: 12px !important;
    padding: 0;
}

.quote-form #chargesContainer > .row > .col-lg-6 { grid-column: 1; }
.quote-form #chargesContainer > .row > .col-lg-4 { grid-column: 2; }

.quote-form #chargesContainer > .row > .col-lg-2 {
    grid-column: 3;
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;
    gap: 8px;
}


/* below 768 the description takes its own line and the price keeps
   the button company, rather than the two fighting over one row */
@media (max-width: 767.98px) {
    .quote-form #chargesContainer > .row { grid-template-columns: minmax(0, 1fr) 56px; }
    .quote-form #chargesContainer > .row > .col-lg-6 { grid-column: 1 / -1; }
    .quote-form #chargesContainer > .row > .col-lg-4 { grid-column: 1; max-width: 220px; }
    .quote-form #chargesContainer > .row > .col-lg-2 { grid-column: 2; }
}


/* ── Additional-charge buttons and confirm popover ───────────
   addCharge() · askRemoveCharge() · removeCharge()
   (services/interpretation/main.html) build this markup by hand,
   so it never appears in a template. Moved here from an inline
   <style> in that partial, beside the charge-row grid above, so
   the whole row lives in one file.

   The #interpretationServiceFromPanel scope is load-bearing, for
   the second reason listed at the top of this file: removeCharge()
   builds the trash button as `remove-charge updated-prices`, and
   footer.html declares .updated-prices after this stylesheet
   loads. An id out-ranks that single class, so these rules no
   longer depend on being declared late in the document. */

/* Add / remove a charge row — a --field-h square, so the buttons
   line up with the fields they sit beside */
#interpretationServiceFromPanel .add-charge,
#interpretationServiceFromPanel .remove-charge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: var(--field-h);
    height: var(--field-h);
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: var(--field-radius);
    box-shadow: none;
    font-size: 17px;
    /* removeCharge() writes `display: inline-block` straight onto these,
       so the glyph is centred by line-height as well as by the flexbox */
    line-height: var(--field-h);
    text-align: center;
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast),
                box-shadow var(--transition-fast), transform var(--transition-fast);
}

#interpretationServiceFromPanel .add-charge {
    background-color: var(--color-brand-navy);
    color: var(--color-surface-white);
}
#interpretationServiceFromPanel .add-charge:hover {
    background-color: var(--color-brand-navy-hover);
    color: var(--color-surface-white);
}

#interpretationServiceFromPanel .remove-charge {
    background-color: var(--color-surface-white);
    box-shadow: inset 0 0 0 1px var(--color-border);
    color: var(--color-text-secondary);
}
#interpretationServiceFromPanel .remove-charge:hover {
    background-color: var(--color-status-danger-bg);
    box-shadow: inset 0 0 0 1px var(--color-status-danger);
    color: var(--color-status-danger);
}
/* the glyph inherits the button's state colour */
#interpretationServiceFromPanel .remove-charge .fa,
#interpretationServiceFromPanel .remove-charge .bi { color: inherit; }
#interpretationServiceFromPanel .remove-charge svg { color: inherit; margin-bottom: 4px; }

#interpretationServiceFromPanel .add-charge:active,
#interpretationServiceFromPanel .remove-charge:active { transform: translateY(1px); }

/* the trash stays lit in its danger state while its popover is open */
#interpretationServiceFromPanel .remove-charge.is-confirming {
    background-color: var(--color-status-danger-bg);
    box-shadow: inset 0 0 0 1px var(--color-status-danger);
    color: var(--color-status-danger);
}

/* ── "Remove this charge?" popover ──────────────────────────
   askRemoveCharge() builds this above the trash button. It is
   positioned out of flow: the action column is only 56px wide and
   the row's grid must not reflow around it. */
#interpretationServiceFromPanel #chargesContainer > .row > .col-lg-2 { position: relative; }

#interpretationServiceFromPanel .charge-confirm {
    position: absolute;
    right: 0;
    bottom: calc(var(--field-h) + 8px);   /* clears the button, plus a gap */
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 10px 9px 14px;
    background: var(--color-surface-white);
    border: 1px solid var(--color-border);
    border-radius: 14px;
    /* not --shadow-pop: this sits tighter to its button than a
       select2 panel or a calendar does */
    box-shadow: 0 12px 30px rgba(34, 30, 27, .16);
    font-family: var(--font-body);
    font-size: 13px;
    line-height: 1;
    white-space: nowrap;
    color: var(--color-text-primary);
    animation: charge-confirm-in .16s ease-out;
}

/* the caret, pointing back down at the button it belongs to */
#interpretationServiceFromPanel .charge-confirm::after {
    content: "";
    position: absolute;
    right: 18px;
    bottom: -6px;
    width: 10px;
    height: 10px;
    background: var(--color-surface-white);
    border-right: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
    transform: rotate(45deg);
}

@keyframes charge-confirm-in {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: none; }
}

#interpretationServiceFromPanel .charge-confirm-text { font-weight: 500; }

#interpretationServiceFromPanel .charge-btn-mini {
    height: 28px;
    padding: 0 13px;
    border: 0;
    border-radius: 9px;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 500;
    line-height: 28px;
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast),
                box-shadow var(--transition-fast);
}

#interpretationServiceFromPanel .charge-btn-mini.is-yes {
    background: var(--color-status-danger);
    color: var(--color-surface-white);
}
/* a darker red than --color-status-danger; --color-status-danger-hover
   is a pale background tint, not a hover for a filled button */
#interpretationServiceFromPanel .charge-btn-mini.is-yes:hover { background: #b91c1c; }

#interpretationServiceFromPanel .charge-btn-mini.is-no {
    background: var(--color-surface-white);
    box-shadow: inset 0 0 0 1px var(--color-border);
    color: var(--color-text-secondary);
}
#interpretationServiceFromPanel .charge-btn-mini.is-no:hover {
    background: var(--color-surface-subtle);
    color: var(--color-text-primary);
}

/* the field focus rings are gold and navy; this is the danger
   equivalent, which has no token of its own */
#interpretationServiceFromPanel .charge-btn-mini:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(220, 38, 38, .28);
}

/* a confirmed row collapses instead of vanishing, so the rows
   below slide up rather than jump */
#interpretationServiceFromPanel #chargesContainer > .row.is-leaving { pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
    #interpretationServiceFromPanel .charge-confirm { animation: none; }
    #interpretationServiceFromPanel .charge-btn-mini { transition: none; }
}


/* ── Wizard actions ─────────────────────────────────────────
   changeTab() writes `style.display = "block"` straight onto
   #prevBtn / #nextBtn, so these can't rely on a flex display of
   their own — the label is centred with line-height instead. */
.quote-form .form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin: 28px 0 0 !important;
    padding-top: 22px;
    border-top: 1px solid var(--color-border);
}

.quote-form .form-actions > button {
    height: var(--field-h);
    /* footer.html gives a bare .updated-prices min-height:49.6px, which
       would otherwise stretch #prevBtn past its 48px sibling */
    min-height: var(--field-h);
    min-width: 120px;
    padding: 0 26px;
    border: 0;
    border-radius: var(--field-radius);
    box-shadow: none;
    font-family: inherit;
    font-size: 15px;
    font-weight: 500;
    line-height: var(--field-h);
    text-align: center;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast),
                box-shadow var(--transition-fast), transform var(--transition-fast);
}

.quote-form .form-actions > button:active:not(:disabled) {
    transform: translateY(1px);
}

.quote-form .form-actions > button:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring-navy);
}

.quote-form .form-actions > button:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* the CTA rules above give #nextBtn / #interpretationShowPriceBtn a
   width:100%; inside the actions row they size to their label */
.quote-form .form-actions > #nextBtn,
.quote-form .form-actions > #interpretationShowPriceBtn {
    width: auto;
}

.quote-form #interpretationShowPriceBtn {
    display: inline-block;
    min-width: 176px;
}

.quote-form #prevBtn {
    background: var(--color-surface-white);
    box-shadow: inset 0 0 0 1px var(--color-border);
    color: var(--color-text-primary);
}

.quote-form #prevBtn:hover {
    background: var(--color-surface-subtle);
    box-shadow: inset 0 0 0 1px var(--color-border-hover);
    color: var(--color-text-primary);
}

/* ============================================================
   LEGACY CONTROLS
   ============================================================
   Kept for the markup clean.html still emits. */
.quote-form .row__select {
    display: unset !important;
    height: var(--field-h);
}

.quote-form .multiselect {
    position: relative;
}

.quote-form .multiselect__trigger {
    width: 100%;
    min-height: var(--field-h);
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0.4em 0.6em;
    background: var(--color-surface-white);
    border: 1.5px solid var(--color-border);
    border-radius: var(--radius-sm);
    text-align: left;
    transition: border-color var(--transition-fast);
}

.quote-form .multiselect__trigger:hover,
.quote-form .multiselect__trigger[aria-expanded="true"] {
    border-color: var(--color-brand-gold);
}

.quote-form .multiselect__trigger[aria-expanded="true"] .multiselect__chevron {
    transform: rotate(180deg);
}

.quote-form .multiselect__chips {
    flex: 1;
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.quote-form .multiselect__placeholder {
    font-size: 15px;
    color: var(--color-text-secondary);
}

.quote-form .multiselect__chevron {
    flex-shrink: 0;
    margin-left: auto;
    color: var(--color-text-secondary);
    transition: transform var(--transition-fast);
}

.quote-form .icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    color: currentColor;
}

.quote-form .icon--sm {
    width: 16px;
    height: 16px;
}

.quote-form .icon--xs {
    width: 13px;
    height: 13px;
}


/* ============================================================
   NOTE UNDER THE FORM
   ============================================================
   Outside the <form>, so these stay unscoped. */
.note {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    width: auto;
    max-width: 100%;
    height: auto;
    margin: 42px 0;
    padding: 12px 13.5px;
    background: var(--color-surface-subtle);
    border: 0;
    border-radius: 24px;
    font-family: var(--font-body);
    font-size: 14px;
    font-weight: 400;
    line-height: 1;
    color: var(--color-text-muted);
}

.wc-modal .note {
    margin: 8px 0;
}

.note > svg {
    flex: none;
    width: 16px;
    height: 16px;
    margin: 0;
    color: var(--color-text-primary);
}

.note .note__body {
    line-height: 1.5;
}

/* attestation / dtp use a plain paragraph instead of the pill */
.atts-note,
.dtp-note {
    margin: 32px 0 0;
    font-size: 14px;
    line-height: 1.5;
    color: var(--color-text-muted);
}

.note strong,
.atts-note strong,
.dtp-note strong {
    font-weight: 500;
    color: var(--color-text-primary);
}

.note a,
.atts-note a,
.dtp-note a {
    font-weight: 500;
    color: var(--color-text-primary);
    text-decoration: none !important;
    white-space: nowrap;
}

.note a:hover,
.atts-note a:hover,
.dtp-note a:hover {
    text-decoration: underline !important;
}


/* ============================================================
   RESPONSIVE
   ============================================================ */

/* style.css hard-codes `.card-demo { padding: 30px 0 !important }`
   under 600px, so these need !important to land. */
@media (max-width: 991.98px) {
    #attestationServiceFromPanel .card-demo,
    #form_panel .card-demo { padding: 28px 24px !important; }

    #interpretationServiceFromPanel .tab-content { min-height: 0; }
}

@media (max-width: 575.98px) {
    #attestationServiceFromPanel .card-demo,
    #form_panel .card-demo { padding: 24px 14px !important; }

    .quote-form .atts-grid,
    .quote-form .dtp-bar { gap: 20px; }

    #interpretationServiceFromPanel .tab-content {
        margin-top: 24px !important;
        padding-top: 24px;
    }

    .quote-form .tab-content .row { gap: 18px var(--field-gap); }
}

/* narrow phones: tighten the pill so the count, the file tally and
   the upload button all stay on one line */
@media (max-width: 479.98px) {
    .quote-form .fake-input,
    .quote-form .dtp-pill { padding: 0 6px 0 12px; }

    .quote-form #totalDocumentPlaceHolder,
    .quote-form #dtp_pages_show { width: 52px; min-width: 34px; }

    .quote-form .fake-input .span-wrap,
    .quote-form .dtp-pill .span-wrap { margin: 0 10px 0 auto; }

    .quote-form .fake-input .span-wrap > span,
    .quote-form .dtp-pill .span-wrap > span { font-size: 12px; gap: 5px; }

    .quote-form .upload-btn,
    .quote-form #attestationUploadText { padding: 0 10px; }
}

/* five stepper labels have to share the strip, so they shrink
   rather than collide — "Purpose and Setting" is the one that
   decides this */
@media (max-width: 767.98px) {
    #interpretationServiceFromPanel #stepTabs .nav-link { font-size: 11px; gap: 9px; }
}

@media (max-width: 575.98px) {
    #interpretationServiceFromPanel #stepTabs .nav-link { font-size: 10px; gap: 8px; }
}

@media (max-width: 399.98px) {
    #interpretationServiceFromPanel #stepTabs .nav-link { font-size: 9.5px; }
    #interpretationServiceFromPanel #stepTabs .nav-link::before { width: 28px; height: 28px; }
    #interpretationServiceFromPanel #stepTabs .nav-item::before,
    #interpretationServiceFromPanel #stepTabs .nav-item::after { top: 13px; }
}

/* the wizard actions stack and go full width where two no longer fit */
@media (max-width: 419.98px) {
    .quote-form .form-actions > button { flex: 1 1 100%; min-width: 0; }
}


/* ============================================================
   REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
    .quote-form .lang-row,
    .quote-form .lang-row--entering,
    .quote-form .reveal-panel,
    .quote-form .dtp-field-grid {
        animation: none;
    }

    .quote-form .lang-row--removing,
    .quote-form .toggle-reveal,
    .quote-form .field *,
    .quote-form .form-control,
    .quote-form .form-actions > button,
    .quote-form .btn-price,
    .quote-form #attestationShowPriceBtn,
    .quote-form #interpretationShowPriceBtn,
    #interpretationServiceFromPanel #stepTabs .nav-link,
    #interpretationServiceFromPanel #stepTabs .nav-link::before {
        transition: none;
    }
}
