/* ============================================================
   Hosted form stylesheet.

   Completely organisation-agnostic: every value that varies per
   org comes in as a --ft-* custom property from _ThemeStyle.cshtml,
   which is why one cacheable file can serve every tenant.

   The layout follows the shared form design: a banner-topped
   header card, a rounded white form card with numbered sections,
   roomy controls and a soft page-level glow tinted by the org's
   primary colour.

   Derived values (tints, focus rings, the card radius) are
   computed HERE from the handful of tokens form_theme actually
   stores, so nothing new has to be added to the table.

   The same token names drive the admin live preview in
   WebConsole/wwwroot/css/site.css, so the preview cannot drift
   away from what a visitor actually sees. Change a token here,
   change it there.
   ============================================================ */

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

html {
    scroll-behavior: smooth;
}

.ft-page {
    /* ── Derived tokens ──────────────────────────────────────
       Static values first, then the color-mix() versions. A
       browser without color-mix() simply drops the second
       declaration and keeps the neutral fallback, so the page
       degrades to a plain — never broken — theme. */
    --ft-primary-soft: #edf6ff;
    --ft-primary-ring: rgba(15, 111, 222, .14);
    --ft-primary-dark: #0854ad;
    --ft-primary-glow: rgba(15, 111, 222, .09);
    --ft-primary-soft: color-mix(in srgb, var(--ft-primary, #0f6fde) 9%, #fff);
    --ft-primary-ring: color-mix(in srgb, var(--ft-primary, #0f6fde) 18%, transparent);
    --ft-primary-dark: color-mix(in srgb, var(--ft-primary, #0f6fde) 78%, #000);

    /* The page tint only — 9%, half the strength of the focus ring. They used to
       share --ft-primary-ring, which made the background pools twice as heavy as
       form.html's. */
    --ft-primary-glow: color-mix(in srgb, var(--ft-primary, #0f6fde) 9%, transparent);

    /* The warm pool in the bottom-right corner, fixed amber rather than the org's
       secondary — form.html's rgba(255,193,7,.08). Same reasoning as --ft-star:
       it is part of the design's lighting, not of the palette, and derived from
       the palette it just reads as a second, muddier copy of the first pool. */
    --ft-warm-glow: rgba(255, 193, 7, .08);

    /* A filled star is gold regardless of the org's palette, exactly as in
       form.html. Tying it to --ft-primary made a red-branded form's rating
       indistinguishable from its error state. */
    --ft-star: #f5a623;
    --ft-star-empty: #d7dbe0;

    --ft-surface: #fff;
    --ft-field-bg: #fbfdff;
    --ft-muted: #667085;
    --ft-input-border: #dce5ef;
    --ft-hairline: #edf0f2;

    /* form_theme carries ONE border_radius_px. The card reads as a
       panel rather than a chip, so it takes that radius plus a
       fixed step instead of needing a second stored column. */
    --ft-card-radius: calc(var(--ft-radius, 12px) + 10px);
    --ft-input-radius: var(--ft-radius, 12px);
    --ft-btn-radius: var(--ft-radius, 12px);

    --ft-shadow: 0 22px 60px rgba(29, 64, 110, .11);
    --ft-max-width: 840px;

    font-family: var(--ft-font-family, system-ui, sans-serif);
    font-size: var(--ft-font-size, 14px);
    line-height: 1.5;
    color: var(--ft-font, #172033);
    min-height: 100vh;
    padding: 48px 20px;

    /* Two faint pools over the flat background — cool top-left in the org's
       primary, warm bottom-right — the only place the page tints itself.
       Positions, sizes and opacities are form.html's body background verbatim. */
    background:
        radial-gradient(circle at 10% 15%, var(--ft-primary-glow), transparent 27rem),
        radial-gradient(circle at 92% 88%, var(--ft-warm-glow), transparent 23rem),
        var(--ft-bg, #eef4fa);
}

/* Status-page shell: flat background, card centred in the viewport.
   A form page is top-aligned because it scrolls; a short status message
   does not, so leaving it pinned to the top just strands it above a
   large empty area. The page tint goes with it — with no form to frame,
   it reads as decoration. */
.ft-page-status {
    display: flex;
    background: var(--ft-bg, #eef4fa);
}

.ft-container {
    width: 100%;
    max-width: var(--ft-max-width, 840px);
    margin: 0 auto;
}

/* Narrower than a form: a heading and two short lines set across 840px
   read as a banner rather than a message.

   margin:auto rather than align-items:center on the parent — auto margins
   centre both axes without the overflow-clipping that centre alignment
   causes when the content is taller than a short viewport. */
.ft-page-status .ft-container {
    max-width: 560px;
    margin: auto;
}

button,
input,
textarea,
select {
    font: inherit;
}

/* ── Header card ────────────────────────────────────────── */

/* The header and the form card are two elements that read as one
   panel: the header rounds only its top corners, the card only
   its bottom. */
/* The line that used to show just under the progress bar is this shadow, not a
   border: the header is positioned and the card is not, so the header paints
   LAST and its drop shadow lands on the card's top edge instead of behind it.
   (The card is clipped the same way for the mirror-image reason — see
   .ft-card:not(.ft-card-solo).) Clipping the header to its own bottom edge
   removes it; the negative insets leave the other three sides untouched. */
.ft-header {
    position: relative;
    background: var(--ft-surface);
    border-radius: var(--ft-card-radius) var(--ft-card-radius) 0 0;
    box-shadow: var(--ft-shadow);
    overflow: hidden;
    clip-path: inset(-80px -80px 0 -80px);
}

/* The 7px gradient strip that used to top a header with no banner image is gone;
   that panel is now plain white. banner_bg_color is not orphaned by this — it
   still tints .ft-header-overlay whenever a banner image IS set — but it no
   longer shows on a header without one. */

/* form.html's split header: the copy holds the left, the logo sits hard right.
   A single row rather than the stacked block this used to be, which is why the
   logo no longer needs a position modifier. */
.ft-header-content {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 32px;
    padding: 24px 30px;
}

.ft-header-copy {
    min-width: 0;
    max-width: 590px;
}

/* form.html's .brand: a flex box that pins the mark to the right and centres it
   vertically against the copy. It used to be `flex: 0 0 auto` alone, which left
   the alignment to whatever the image's own baseline happened to be — visible as
   soon as the mark was shorter than the heading block beside it. */
.ft-header-brand {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex: 0 0 auto;
}

/* Banner image variant: the image fills the header and an overlay
   in the banner colour keeps the text readable over it. */
.ft-header-hero {
    background-size: cover;
    background-position: center;
}

.ft-header-hero .ft-header-overlay {
    position: absolute;
    inset: 0;
    background: var(--ft-banner-bg, #0f6fde);
    opacity: var(--ft-banner-overlay, .6);
}

.ft-header-hero .ft-header-content {
    min-height: var(--ft-banner-height, 120px);
}

.ft-header-hero .ft-title,
.ft-header-hero .ft-subtitle {
    color: #fff;
}

.ft-header-hero .ft-subtitle {
    color: rgba(255, 255, 255, .85);
}

/* The org's banner_title, above the form's own heading. Set small and in the
   primary colour so it reads as the organisation's standing line rather than
   competing with the title of the form the visitor actually opened. */
.ft-eyebrow {
    margin-bottom: 5px;
    color: var(--ft-primary, #0f6fde);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

.ft-header-hero .ft-eyebrow {
    color: rgba(255, 255, 255, .9);
}

/* 28px / 16px / 1.65, exactly as form.html sets .form-title and
   .form-description. Expressed in rem — relative to the ROOT font size, not to
   the org's --ft-font-size — so the heading keeps the design's proportions
   whatever body size the theme asks for. */
.ft-title {
    margin-bottom: 8px;
    font-size: 1.75rem;
    line-height: 1.25;
    font-weight: 700;
    letter-spacing: -.3px;
}

.ft-subtitle {
    max-width: 650px;
    color: var(--ft-muted);
    font-size: 1rem;
    line-height: 1.65;
}

/* ── Logo ───────────────────────────────────────────────── */

/* No margin-bottom and no position modifiers: the logo is a flex sibling of the
   copy now, not a block stacked above it.

   Sized from the WIDTH — a fixed 100px with the height left to follow the mark's
   own aspect ratio. Fixing one axis and freeing the other is what stops two orgs'
   headers coming out at different optical weights; driving it from the width
   rather than the height keeps every mark to the same column beside the copy,
   whatever its proportions. */
.ft-logo {
    display: block;
    width: auto;
    height: 90px;
    max-width: var(--ft-logo-max-width, 210px);
    object-fit: contain;
}

.ft-logo-text {
    color: var(--ft-primary, #0f6fde);
    font-size: .8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .08em;
    white-space: nowrap;
}

/* Banner image AND logo are independent settings, so both render — the image
   fills the panel and the mark sits on it. A logo dropped straight onto a photo
   is a coin flip though: the overlay rescues white TEXT, but it cannot rescue a
   dark logo on a dark image, and a washed-out mark reads as "the logo did not
   apply". So over an image the mark gets its own light panel. */
.ft-header-hero .ft-header-brand {
    padding: 10px 14px;
    background: rgba(255, 255, 255, .94);
    border-radius: calc(var(--ft-radius, 12px) + 2px);
    box-shadow: 0 8px 22px rgba(15, 23, 42, .18);
}

/* Capped on the hero: the chip adds its own bulk, and the hero panel is only
   120px tall, so a tall mark rendering at its natural height for a 100px width
   would fill the panel edge to edge. A max-height rather than a height, because
   the base rule leaves the height auto — a wide mark stays shorter than this. */
.ft-header-hero .ft-logo {
    max-height: 56px;
}

/* The text fallback rides the same chip, so it keeps the brand colour rather
   than being set white and disappearing into a light photo. */
.ft-header-hero .ft-logo-text {
    color: var(--ft-primary, #0f6fde);
}

/* ── Progress ───────────────────────────────────────────────
   Driven by form.js. The track is rendered empty and the bar is
   sized from script, so a visitor with JS disabled sees an empty
   rail rather than a bar frozen at a number that means nothing. */

/* No bottom padding, as in form.html's .progress-wrapper: the rail sits flush on
   the seam between the header panel and the card, which is what makes the two
   read as one panel with a rule across it. */
.ft-progress {
    padding: 0 30px;
}

/* With the banner switched off the bar sits inside the card, which already
   supplies the horizontal padding. */
.ft-progress-inline {
    padding: 0 0 22px;
}

.ft-progress-info {
    display: flex;
    justify-content: space-between;
    margin-bottom: 8px;
    font-size: .8125rem;
    color: var(--ft-muted);
}

.ft-progress-track {
    width: 100%;
    height: 7px;
    overflow: hidden;
    background: #e9ecef;
    border-radius: 20px;
}

.ft-progress-bar {
    width: 0;
    height: 100%;
    background: linear-gradient(90deg,
        var(--ft-primary-dark),
        var(--ft-primary, #0f6fde));
    border-radius: 20px;
    transition: width .3s ease;
}

/* ── Form card ──────────────────────────────────────────── */

.ft-card {
    display: block;
    background: var(--ft-surface);
    border-radius: 0 0 var(--ft-card-radius) var(--ft-card-radius);
    box-shadow: var(--ft-shadow);
    padding: 30px;
}

/* The line across the header/card seam.

   Neither element has a border — it is the CARD's own shadow. --ft-shadow blurs
   60px and is offset only 22px down, so roughly 8px of it sits ABOVE the card's
   top edge, and the card paints after the header, so that band lands on the
   header's bottom edge and reads as a rule between the two.

   Clipping the card to its own top edge removes it; the negative insets leave
   the other three sides free so the drop shadow underneath is untouched. Only
   when a header is actually above — a solo card has nothing to cast onto and
   keeps its shadow all the way round. */
.ft-card:not(.ft-card-solo) {
    clip-path: inset(0 -80px -80px -80px);
}

/* Corners are composed, not overwritten: .ft-card assumes a header above
   and nothing below, and each modifier only touches the pair it owns —
   so solo + footer still comes out right. */
.ft-card-solo {
    border-top-left-radius: var(--ft-card-radius);
    border-top-right-radius: var(--ft-card-radius);
}

/* The form card carries no header row of its own — form.html's .form-card opens
   straight onto the first field, and the heading/logo live in the header panel
   above it. (There used to be a .ft-card-head here for the banner-off case.) */

/* Centred variant, for the confirmation and status cards: those are centred
   layouts with no copy beside the mark. */
.ft-card-brand {
    display: flex;
    justify-content: center;
    margin-bottom: 18px;
}

.ft-centered {
    text-align: center;
}

.ft-lead {
    max-width: 520px;
    margin: 0 auto 12px;
    color: var(--ft-muted);
    line-height: 1.7;
}

/* ── Sections ───────────────────────────────────────────── */

.ft-section {
    margin-bottom: 26px;
}

.ft-section:last-of-type {
    margin-bottom: 0;
}

.ft-section-head {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 18px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--ft-hairline);
}

.ft-section-number {
    flex: 0 0 34px;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--ft-primary-soft);
    color: var(--ft-primary, #0f6fde);
    border-radius: calc(var(--ft-radius, 12px) + 5px);
    font-size: .85rem;
    font-weight: 700;
}

.ft-section-title {
    font-size: 1.2rem;
    font-weight: 700;
}

/* ── Fields ─────────────────────────────────────────────── */

.ft-field {
    margin-bottom: 20px;
}

.ft-field:last-child {
    margin-bottom: 0;
}

/* The exclusions matter: .ft-check and .ft-choice-clear are both direct-child
   labels that lay themselves out as flex rows, and a bare `.ft-field > label`
   rule out-specifies a single class — it would silently flatten them back to
   bold block headings. Any new label added directly under .ft-field has to be
   listed here too. */
.ft-field > label:not(.ft-check):not(.ft-choice-clear) {
    display: block;
    font-size: .95rem;
    font-weight: 600;
    margin-bottom: 9px;
}

.ft-required {
    color: #dc3545;
    margin-left: 3px;
}

/* Every input type _Field.cshtml can render has to be listed here, minus the
   radios and the checkbox, which are painted on their own further down. A type
   left off this list is not "slightly unstyled" — it falls all the way back to
   the browser's default box, which is the one control on the page that looks
   like it belongs to another site. */
.ft-field input[type="text"],
.ft-field input[type="email"],
.ft-field input[type="tel"],
.ft-field input[type="number"],
.ft-field input[type="date"],
.ft-field input[type="file"],
.ft-field textarea,
.ft-field select {
    width: 100%;
    min-height: 50px;
    padding: 12px 15px;
    font-family: inherit;
    font-size: inherit;
    color: inherit;
    background: var(--ft-field-bg);
    border: 1.5px solid var(--ft-input-border);
    border-radius: var(--ft-input-radius);
    outline: none;
    transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
}

.ft-field select {
    cursor: pointer;
}

.ft-field textarea {
    resize: vertical;
    min-height: 128px;
    line-height: 1.6;
}

/* A file input's own button supplies the left padding, and the control sits
   taller than the shorthand above allows. */
.ft-field input[type="file"] {
    padding: 9px 15px;
    cursor: pointer;
}

.ft-field input[type="file"]::file-selector-button {
    margin-right: 12px;
    padding: 8px 14px;
    font-family: inherit;
    font-size: .85rem;
    font-weight: 600;
    color: #fff;
    background: var(--ft-primary, #0f6fde);
    border: 0;
    border-radius: calc(var(--ft-input-radius) * .7);
    cursor: pointer;
}

/* :not([type="radio"]) throughout — the rating's radios are visually hidden,
   so a border or ring on them would be both invisible and misleading. */
.ft-field input:not([type="radio"]):hover,
.ft-field textarea:hover,
.ft-field select:hover {
    border-color: #b8c0c8;
}

.ft-field input:not([type="radio"]):focus,
.ft-field textarea:focus,
.ft-field select:focus {
    background: #fff;
    border-color: var(--ft-primary, #0f6fde);
    box-shadow: 0 0 0 4px var(--ft-primary-ring);
}

.ft-field select:disabled {
    background: #f2f5f9;
    color: #8a97a4;
    cursor: not-allowed;
}

/* A checkbox reads as a selectable card rather than a bare box,
   matching the option tiles in the design. */
.ft-check {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 52px;
    padding: 10px 15px;
    background: var(--ft-field-bg);
    border: 1.5px solid var(--ft-input-border);
    border-radius: var(--ft-input-radius);
    cursor: pointer;
    font-weight: 400 !important;
    transition: border-color .15s ease, background .15s ease;
}

.ft-check:hover {
    border-color: var(--ft-primary, #0f6fde);
}

.ft-check:focus-within {
    border-color: var(--ft-primary, #0f6fde);
    box-shadow: 0 0 0 4px var(--ft-primary-ring);
}

.ft-check input[type="checkbox"] {
    width: 18px;
    height: 18px;
    accent-color: var(--ft-primary, #0f6fde);
    cursor: pointer;
}

.ft-hint {
    display: block;
    font-size: .8rem;
    color: var(--ft-muted);
    margin-top: 5px;
}

/* ── Option tiles ───────────────────────────────────────────
   A Radio field, and a Select short enough to be worth showing in
   full (FormChoiceLayout.MaxTileOptions). Pure CSS: the radio is
   hidden and its label is the tile, so this needs no script.

   auto-fit rather than a fixed 4 columns — three options should
   fill the row, not leave a gap where a fourth would go. */

.ft-options {
    position: relative; /* anchors the absolutely-positioned radios below */
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px;
}

/* Visually hidden, NOT display:none — the radio has to stay focusable
   and reachable by a screen reader. */
.ft-options input[type="radio"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.ft-option-label {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 52px;
    padding: 10px 14px;
    background: var(--ft-field-bg);
    border: 1.5px solid var(--ft-input-border);
    border-radius: var(--ft-input-radius);
    font-size: .95rem;
    font-weight: 600;
    text-align: center;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, color .15s ease;
}

.ft-option-label:hover {
    border-color: var(--ft-primary, #0f6fde);
}

.ft-options input[type="radio"]:checked + .ft-option-label {
    background: var(--ft-primary-soft);
    border-color: var(--ft-primary, #0f6fde);
    color: var(--ft-primary, #0f6fde);
    box-shadow: inset 0 0 0 1px var(--ft-primary, #0f6fde);
}

/* The input is invisible, so the focus ring has to be drawn on the
   label or keyboard users get no indication at all. */
.ft-options input[type="radio"]:focus-visible + .ft-option-label {
    outline: 3px solid var(--ft-primary-ring);
    outline-offset: 2px;
}

.ft-field-error .ft-option-label {
    border-color: #dc3545;
    background: #fffafa;
}

/* ── Rating ─────────────────────────────────────────────────
   Entirely CSS: the page is served under script-src 'none'.

   The stars are emitted HIGHEST first and the row is reversed
   visually, which is the whole trick — `input:checked ~ label`
   can only match LATER siblings, so "fill everything below the
   chosen star" only works if the lower stars come after it in
   the markup. */
.ft-rating {
    position: relative; /* anchors the absolutely-positioned radios below */
    display: flex;
    flex-direction: row-reverse;
    justify-content: flex-end;
    gap: 4px;
}

/* Each star carries its value beneath it, as in form.html. The column is the
   label itself so the number is part of the same click target. */
.ft-rating label {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-width: 54px;
    min-height: 72px;
    /* On the label, not the star — the number underneath is part of the same
       click target and should say so. */
    cursor: pointer;
}

.ft-rating-number {
    font-size: .8rem;
    font-weight: 600;
    line-height: 1;
    color: var(--ft-muted);
}

/* Visually hidden, NOT display:none — the radios must stay
   focusable and reachable by a screen reader. */
.ft-rating input[type="radio"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.ft-rating-star {
    font-size: 1.75rem;
    line-height: 1;
    color: var(--ft-star-empty, #d7dbe0);
    cursor: pointer;
    transition: color .12s ease, transform .12s ease;
}

.ft-rating input[type="radio"]:checked ~ label .ft-rating-star,
.ft-rating label:hover .ft-rating-star,
.ft-rating label:hover ~ label .ft-rating-star {
    color: var(--ft-star, #f5a623);
}

.ft-rating label:hover .ft-rating-star {
    transform: scale(1.08);
}

/* The input itself is invisible, so the focus ring has to be drawn
   on its label or keyboard users get no indication at all. */
.ft-rating input[type="radio"]:focus-visible + label {
    outline: 2px solid var(--ft-primary, #0f6fde);
    outline-offset: 3px;
    border-radius: 3px;
}

/* Shared by the rating and the option tiles: a radio group cannot be unset once
   clicked, so an optional one needs an explicit way back to "no answer". */
.ft-choice-clear {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-top: 8px;
    font-size: .82rem;
    color: var(--ft-muted);
    cursor: pointer;
}

.ft-choice-clear input[type="radio"] {
    width: 15px;
    height: 15px;
    accent-color: var(--ft-primary, #0f6fde);
    cursor: pointer;
}

/* Screen-reader-only text, so each star announces its value. */
.ft-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ── Errors ─────────────────────────────────────────────── */

/* Radios excluded alongside checkboxes: the rating's inputs are visually
   hidden, so a red box would land on nothing while the stars themselves
   stayed unmarked. .ft-rating gets its own treatment below. */
.ft-field-error input:not([type="checkbox"]):not([type="radio"]),
.ft-field-error textarea,
.ft-field-error select,
.ft-field-error .ft-check {
    border-color: #dc3545;
    background: #fffafa;
}

.ft-field-error .ft-rating .ft-rating-star {
    color: #f0a9b0;
}

.ft-error {
    display: block;
    font-size: .85rem;
    color: #dc3545;
    margin-top: 5px;
}

/* No .ft-error-summary: a failed submit is reported inline on each field and
   nowhere else, so there is no panel at the top of the form to style. */

/* The "choose your file again" line under an Attachment input. */
.ft-error-note {
    margin: 6px 0 0;
    font-size: .85rem;
    font-style: italic;
    color: #b91c1c;
}

/* ── Actions ────────────────────────────────────────────── */

.ft-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
    margin-top: 32px;
    padding-top: 24px;
    border-top: 1px solid var(--ft-hairline);
}

.ft-required-note {
    color: var(--ft-muted);
    font-size: .85rem;
}

.ft-action-buttons {
    display: flex;
    align-items: center;
    gap: 10px;
}

/* A real <button type="reset">, so it clears the form with no script at all.
   form.js takes the click over and empties every control outright. */
.ft-reset {
    min-height: 48px;
    padding: 11px 20px;
    font-family: inherit;
    font-size: inherit;
    font-weight: 600;
    color: var(--ft-muted);
    background: transparent;
    border: none;
    border-radius: var(--ft-btn-radius);
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}

.ft-reset:hover {
    color: #dc3545;
    background: #fff5f5;
}

/* ── Character count ────────────────────────────────────────
   Written by form.js. Rendered empty so it collapses to nothing
   rather than showing a stale "0 / 500" when script is blocked. */

.ft-count {
    display: block;
    margin-top: 5px;
    color: var(--ft-muted);
    font-size: .75rem;
    text-align: right;
}

.ft-count:empty {
    display: none;
}

.ft-submit {
    min-height: 48px;
    padding: 11px 24px;
    font-family: inherit;
    font-size: inherit;
    font-weight: 600;
    color: #fff;
    background: var(--ft-primary, #0f6fde);
    border: none;
    border-radius: var(--ft-btn-radius);
    box-shadow: 0 10px 22px var(--ft-primary-ring);
    cursor: pointer;
    transition: background .15s ease, transform .15s ease, box-shadow .15s ease;
}

.ft-submit:hover {
    background: var(--ft-primary-dark);
    transform: translateY(-1px);
}

.ft-submit:active {
    transform: translateY(0);
}

/* form.js disables the button for the duration of the post, so a double click
   cannot send two submissions. */
.ft-submit:disabled {
    opacity: .65;
    cursor: wait;
    transform: none;
}

/* Honeypot: off-screen rather than display:none, since some bots
   skip hidden inputs but not positioned ones. */
.ft-hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* ── Unavailable ────────────────────────────────────────────
   Its own block rather than borrowing .ft-success: these pages
   share a centred layout but not a meaning, and the success
   palette is green.

   Three tones, set per failure reason by the view model. A
   closed or unpublished form is a normal state of affairs and
   gets a calm amber; an unresolvable link is neutral; only a
   genuine server fault is red. Alarming a visitor over a stale
   link someone else sent them would be the wrong call. */

.ft-status {
    padding: 20px 0 4px;
    text-align: center;
}

.ft-status-icon {
    width: 78px;
    height: 78px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 20px;
    border-radius: 50%;
    font-size: 34px;
    line-height: 1;
}

.ft-status-neutral .ft-status-icon {
    background: linear-gradient(145deg, #eef2f7, #e3e9f1);
    box-shadow: 0 12px 28px rgba(71, 85, 105, .13);
    color: #475569;
}

.ft-status-warn .ft-status-icon {
    background: linear-gradient(145deg, #fff5e6, #ffecd1);
    box-shadow: 0 12px 28px rgba(180, 120, 20, .14);
    color: #b45309;
}

.ft-status-error .ft-status-icon {
    background: linear-gradient(145deg, #fdeceb, #fbdedd);
    box-shadow: 0 12px 28px rgba(185, 28, 28, .13);
    color: #b91c1c;
}

.ft-status .ft-title {
    font-size: 1.7rem;
    letter-spacing: -.025em;
}

/* The one actionable line on the page, so it is set apart from the
   explanation above it rather than reading as a third paragraph. */
.ft-status-advice {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    max-width: 480px;
    margin: 24px auto 6px;
    padding: 13px 16px;
    border-radius: var(--ft-input-radius);
    text-align: left;
    font-size: .88rem;
    line-height: 1.6;
}

.ft-status-neutral .ft-status-advice {
    background: #f4f7fa;
    color: #45556b;
}

.ft-status-warn .ft-status-advice {
    background: #fffaf0;
    color: #8a5a0b;
}

.ft-status-error .ft-status-advice {
    background: #fef5f4;
    color: #9b2c2c;
}

.ft-status-advice-icon {
    flex-shrink: 0;
    font-size: 1rem;
    line-height: 1.5;
    opacity: .75;
}

/* ── Confirmation ───────────────────────────────────────── */

.ft-success {
    padding: 20px 0 4px;
    text-align: center;
}

.ft-tick {
    width: 78px;
    height: 78px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 20px;
    background: linear-gradient(145deg, #e9f9ef, #dff6e8);
    border-radius: 50%;
    box-shadow: 0 12px 28px rgba(25, 135, 84, .13);
    color: #198754;
}

/* The tick is an SVG, so the circle centres a box with known bounds instead of a
   glyph whose position depends on whichever fallback font supplied it.
   display:block stops the inline baseline gap from pushing it up. */
.ft-tick svg {
    display: block;
    width: 38px;
    height: 38px;
}

.ft-kicker {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 12px;
    padding: 7px 12px;
    background: #eef9f2;
    border-radius: 999px;
    color: #157347;
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.ft-kicker::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #198754;
}

.ft-success .ft-title {
    font-size: 1.7rem;
    letter-spacing: -.025em;
}

.ft-summary {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin: 26px 0 24px;
    text-align: left;
}

.ft-summary-item {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    padding: 15px;
    background: var(--ft-field-bg);
    border: 1px solid var(--ft-input-border);
    border-radius: calc(var(--ft-radius, 12px) + 8px);
}

.ft-summary-icon {
    flex: 0 0 32px;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--ft-primary-soft);
    color: var(--ft-primary, #0f6fde);
    border-radius: calc(var(--ft-radius, 12px) + 3px);
}

.ft-summary-icon svg {
    display: block;
    width: 17px;
    height: 17px;
}

.ft-summary-item strong {
    display: block;
    margin-bottom: 3px;
    font-size: .88rem;
}

/* Scoped to the text column, not `.ft-summary-item span`: the icon is a span too,
   and the bare selector outranked .ft-summary-icon (0,1,1 beats 0,1,0, and it is
   declared later), which dropped the icon back to display:block in the muted text
   colour and parked the glyph in the tile's top-left corner. */
.ft-summary-item div span {
    display: block;
    color: var(--ft-muted);
    font-size: .82rem;
    line-height: 1.45;
}

/* The confirmation's "submit another" is a link that has to read
   as the page's one button. */
.ft-link-btn {
    display: inline-block;
    min-height: 48px;
    padding: 12px 24px;
    background: var(--ft-primary, #0f6fde);
    border-radius: var(--ft-btn-radius);
    box-shadow: 0 10px 22px var(--ft-primary-ring);
    color: #fff;
    font-weight: 600;
    text-decoration: none;
    transition: background .15s ease, transform .15s ease;
}

.ft-link-btn:hover {
    background: var(--ft-primary-dark);
    transform: translateY(-1px);
}

.ft-link {
    color: var(--ft-primary, #0f6fde);
}

/* ── Footer ─────────────────────────────────────────────── */

/* form.html's .form-footer verbatim: centred muted text under the card, not a
   panel and not a bar closing it — no padding, no surface, no shadow. That is
   why form_theme.footer_bg_color no longer renders and the Footer Background
   field has been retired from the admin page; a footer with no box has nowhere
   to put a background, and a setting that renders nowhere is worse than one that
   is not offered. The column and the stored value stay (see the hidden input in
   WebConsole's _FormThemeFormFields.cshtml). */
.ft-footer {
    margin-top: 20px;
    text-align: center;
    font-size: .75rem;
    color: var(--ft-muted);
}

/* Website / support email / support phone. Wraps rather than scrolls, and the
   separators are drawn with a pseudo-element so no punctuation has to be
   rendered between optional items that may or may not be there. */
.ft-footer-contact {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 6px 18px;
    margin-top: 8px;
}

.ft-footer-link {
    color: var(--ft-primary, #0f6fde);
    font-weight: 600;
    text-decoration: none;
    word-break: break-word;
}

.ft-footer-link:hover {
    text-decoration: underline;
}

/* The rule that used to separate this from the lines above it is gone with the
   panel: a hairline drawn across 840px of open page background reads as a stray
   divider, not as part of a three-line footer. Spacing does the same job. */
.ft-copyright {
    margin-top: 6px;
    opacity: .85;
}

/* Nothing above it to space away from when the footer is copyright only. */
.ft-copyright:only-child {
    margin-top: 0;
}

/* ── Responsive ─────────────────────────────────────────── */

@media (max-width: 600px) {

    .ft-page {
        padding: 14px;
    }

    /* Still a row here, as in form.html: the copy gives up the gap rather than
       the layout. It only stacks at 430px, further down. */
    .ft-header-content {
        gap: 0;
        padding: 24px 22px 21px;
    }

    .ft-header-copy {
        text-align: center;
    }

    .ft-progress {
        padding: 0 22px 25px;
    }

    /* Restated inside the query: the rule above is one class too, and it comes
       later in the file, so without this the in-card bar would pick up 22px of
       side padding on top of the card's own. */
    .ft-progress-inline {
        padding: 0 0 22px;
    }

    .ft-card {
        padding: 24px 22px;
    }

    .ft-title {
        font-size: 1.55rem;
    }

    .ft-subtitle {
        font-size: 1rem;
    }

    /* The chip has to give up some bulk on a phone. */
    .ft-header-hero .ft-header-brand {
        padding: 7px 10px;
    }

    .ft-header-hero .ft-logo {
        max-height: 40px;
    }

    /* One per row: two tiles side by side at this width leave the labels
       wrapping mid-word. */
    .ft-options {
        grid-template-columns: 1fr;
        gap: 8px;
    }

    .ft-rating {
        gap: 2px;
    }

    .ft-rating label {
        min-width: 0;
        min-height: 62px;
    }

    .ft-rating-star {
        font-size: 1.4rem;
    }

    .ft-actions {
        flex-direction: column-reverse;
        align-items: stretch;
        gap: 14px;
    }

    .ft-action-buttons {
        display: grid;
        gap: 8px;
    }

    .ft-submit,
    .ft-reset,
    .ft-link-btn {
        width: 100%;
        text-align: center;
    }

    .ft-required-note {
        text-align: center;
    }

    .ft-summary {
        grid-template-columns: 1fr;
    }

    /* The icon is decorative once the card is this narrow, so it gives up
       space to the message rather than pushing it below the fold. */
    .ft-status-icon {
        width: 64px;
        height: 64px;
        margin-bottom: 16px;
        font-size: 28px;
    }

    .ft-status-advice {
        margin-top: 20px;
        padding: 12px 14px;
    }
}

/* form.html's second header breakpoint: only now does the split header stack,
   logo first — on a screen this narrow the mark reads as the page's identity and
   the heading follows it. */
@media (max-width: 430px) {

    .ft-header-content {
        flex-direction: column-reverse;
        align-items: center;
        gap: 14px;
    }

    .ft-header-brand {
        justify-content: center;
    }
}

/* A 10-point rating still has to fit across the narrowest phones, so the stars
   shrink once more rather than wrapping onto a second row. */
@media (max-width: 380px) {

    .ft-rating label {
        min-height: 54px;
    }

    .ft-rating-star {
        font-size: 1.2rem;
    }

    .ft-rating-number {
        font-size: .7rem;
    }
}
