/*
 * Virgo CMS - Contact Form module styles.
 *
 * Dynamic contact / message form. Fields flow into a responsive grid whose
 * column count is driven by the .contact-form-cols-N modifier on the <form>
 * (1-3 columns). Captcha, the error region and the submit button stay outside
 * the grid so they always span full width on their own rows below the fields.
 * The module card sits inside the content card, so its surface uses --bg-color
 * (one step up) rather than --card-bg (which would match the wrapping card and
 * disappear). Token-first throughout: text, borders and accents adapt across
 * all palettes + dark mode automatically.
 */

.contact-form-module {
    box-sizing: border-box;
    width: 100%;
}

.contact-form-module *,
.contact-form-module *::before,
.contact-form-module *::after {
    box-sizing: border-box;
}

.contact-form-title {
    color: var(--text-ink);
    font-size: var(--fs-h3);
    font-weight: 700;
    margin: 0 0 1rem;
    line-height: 1.3;
}

.contact-form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/*
 * Fields grid: N equal columns, set via the .contact-form-cols-N modifier on
 * the <form>. Items flow into the grid automatically. Captcha / error /
 * submit live outside this container and span full width below.
 */
.contact-form-fields {
    display: grid;
    gap: 1rem;
}

.contact-form-cols-1 .contact-form-fields {
    grid-template-columns: 1fr;
}

.contact-form-cols-2 .contact-form-fields {
    grid-template-columns: repeat(2, 1fr);
}

.contact-form-cols-3 .contact-form-fields {
    grid-template-columns: repeat(3, 1fr);
}

/* Responsive: collapse multi-column layouts to a single column on narrow
 * viewports so 2/3-column forms stay usable on phones. */
@media (max-width: 575.98px) {
    .contact-form-cols-2 .contact-form-fields,
    .contact-form-cols-3 .contact-form-fields {
        grid-template-columns: 1fr;
    }
}

.contact-form-field {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.contact-form-label {
    color: var(--text-color);
    font-size: var(--fs-subtitle);
    font-weight: 600;
    margin: 0;
}

/*
 * Field captions hidden via the "Show labels" setting. Uses the standard
 * visually-hidden pattern so the <label> stays in the accessibility tree
 * (screen readers still announce the field) while being removed from layout.
 */
.contact-form-label.visually-hidden {
    border: 0;
    clip: rect(0, 0, 0, 0);
    clip-path: inset(50%);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    white-space: nowrap;
    width: 1px;
}

.contact-form-required {
    color: var(--danger);
}

/*
 * Floating required badge shown over a control's top-end corner when field
 * captions are hidden (the asterisk would otherwise vanish with the caption).
 * The badge is decorative — the visually-hidden caption still carries it for
 * assistive tech — hence aria-hidden on the markup.
 */
.contact-form-input-wrap {
    display: block;
    position: relative;
}

.contact-form-required-badge {
    color: var(--danger);
    font-size: var(--fs-subtitle);
    font-weight: 700;
    line-height: 1;
    pointer-events: none;
    position: absolute;
    top: -0.1rem;
    inset-inline-end: 0.6rem;
    z-index: 1;
}

.contact-form-input {
    background-color: var(--bg-color);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    color: var(--text-color);
    font-size: var(--fs-body);
    padding: 0.5rem 0.75rem;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    width: 100%;
}

.contact-form-input:focus {
    border-color: var(--primary-color);
    box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--primary-color) 18%, transparent);
    outline: none;
}

.contact-form-input::placeholder {
    color: var(--text-muted);
}

textarea.contact-form-input {
    min-height: 120px;
    resize: vertical;
}

.contact-form-check {
    align-items: center;
    display: flex;
    flex-direction: row;
    gap: 0.5rem;
}

/*
 * Checkbox / radio controls. These intentionally do NOT use .contact-form-input
 * (which forces width:100%, padding and a text-field border and would stretch
 * the native control across the whole field). Bootstrap's .form-check-input
 * already renders the correct fixed square / circle; we only bind the native
 * control tint to the theme primary token via accent-color so checked state
 * follows the active palette + dark mode automatically.
 */
.contact-form-check-input {
    accent-color: var(--primary-color);
    flex-shrink: 0;
}

.contact-form-radio-group,
.contact-form-check-group {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.contact-form-help {
    color: var(--text-muted);
    font-size: var(--fs-meta);
    line-height: 1.4;
    margin: 0;
}

.contact-form-captcha {
    margin-top: 0.25rem;
}

.contact-form-submit-wrap {
    align-items: center;
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    margin-top: 0.25rem;
}

/*
 * Centered submit button modifier (the "Ortalı Gönder Butonu" setting). When
 * enabled the submit button aligns to the center of the form instead of the
 * start edge.
 */
.contact-form-submit-wrap.is-centered {
    justify-content: center;
}

.contact-form-submit {
    font-weight: 600;
    min-width: 140px;
}

.contact-form-submit[disabled] {
    cursor: not-allowed;
    opacity: 0.65;
}

.contact-form-submit .contact-form-spinner {
    display: inline-block;
    height: 1em;
    margin-inline-end: 0.4rem;
    vertical-align: -0.125em;
    width: 1em;
}

/* RTL: logical properties handle direction; no extra rules needed. */


/*
 * ============================================================================
 * FILE ATTACHMENT FIELD (custom selection UI)
 * ============================================================================
 *
 * The native <input type="file"> is hidden from view but kept in the DOM so
 * FormData carries the selected files on submit. A custom dropzone surface
 * opens the OS dialog and shows the invitation; selected files render as pill
 * chips below. This is the karma (modern) treatment — generous rounded dashed
 * dropzone, soft tinted icon well, chips that lift on hover. The surface uses
 * --bg-color (one step up from the wrapping content card's --card-bg) so the
 * field reads as a raised tray, not a hole punched into the card.
 */

/* The native control is never shown — it is driven programmatically. Reuses
 * the same visually-hidden clip as the label-off mode so it stays in the a11y
 * tree for assistive tech while being removed from layout. */
.contact-form-file-native {
    border: 0;
    clip: rect(0, 0, 0, 0);
    clip-path: inset(50%);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    white-space: nowrap;
    width: 1px;
}

/* Dropzone surface — a raised, rounded, dashed tray. */
.cfk-file-dropzone {
    align-items: center;
    background-color: var(--bg-color);
    border: 2px dashed var(--border-strong);
    border-radius: var(--radius-lg);
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding: 1.75rem 1rem;
    text-align: center;
    transition: border-color 0.18s ease, background-color 0.18s ease,
                transform 0.18s ease, box-shadow 0.18s ease;
}

.cfk-file-dropzone:hover {
    border-color: var(--primary-color);
}

/* Keyboard focus mirrors the regular input focus ring so the surface is
 * recognizably a control. The native input is off-screen, so the focus ring
 * is owned by the trigger surface itself. */
.cfk-file-dropzone:focus-visible {
    border-color: var(--primary-color);
    box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--primary-color) 18%, transparent);
    outline: none;
}

/* Drag-over: the dashed line firms up to solid, the tray tints toward the
 * primary, and a hair of scale sells the "drop here" affordance. */
.cfk-file-dropzone.is-dragover {
    background-color: color-mix(in srgb, var(--primary-color) 8%, transparent);
    border-color: var(--primary-color);
    border-style: solid;
    transform: scale(1.01);
}

/* Soft circular tinted well behind the upload glyph. */
.cfk-file-dropzone__icon {
    align-items: center;
    background-color: color-mix(in srgb, var(--primary-color) 12%, transparent);
    border-radius: var(--radius-pill);
    color: var(--primary-color);
    display: flex;
    font-size: 1.4rem;
    height: 3rem;
    justify-content: center;
    width: 3rem;
}

.cfk-file-dropzone__cta {
    color: var(--text-ink);
    font-size: var(--fs-subtitle);
    font-weight: 600;
}

.cfk-file-dropzone__hint {
    color: var(--text-muted);
    font-size: var(--fs-meta);
}

/* Once files are selected the invitation dims and the tray retracts slightly
 * so the chip row below takes the focus. */
.cfk-file-dropzone.is-populated {
    padding-block: 1.15rem;
}

.cfk-file-dropzone.is-populated .cfk-file-dropzone__hint {
    opacity: 0.6;
}

/*
 * Selected file chips — a wrapping row of pills. Each chip is its own raised
 * surface (--bg-color) with a hairline border; it earns a subtle lift shadow
 * only on hover (shadow-as-state, not default texture).
 */
.cfk-file-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.65rem;
}

.cfk-file-chip {
    align-items: center;
    background-color: var(--bg-color);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-pill);
    box-shadow: 0 2px 4px rgba(26, 36, 33, 0);
    color: var(--text-color);
    display: inline-flex;
    font-size: var(--fs-meta);
    gap: 0.4rem;
    max-width: 100%;
    padding-block: 0.35rem;
    padding-inline: 0.5rem 0.35rem;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.cfk-file-chip:hover {
    border-color: var(--primary-color);
    box-shadow: 0 2px 4px rgba(26, 36, 33, 0.06);
}

.cfk-file-chip__icon {
    align-items: center;
    color: var(--primary-color);
    display: flex;
    flex-shrink: 0;
}

.cfk-file-chip__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cfk-file-chip__size {
    color: var(--text-muted);
    flex-shrink: 0;
}

/* Circular remove affordance — danger on hover so the destructive intent reads. */
.cfk-file-chip__remove {
    align-items: center;
    background-color: transparent;
    border: 0;
    border-radius: var(--radius-pill);
    color: var(--text-muted);
    cursor: pointer;
    display: inline-flex;
    flex-shrink: 0;
    font-size: var(--fs-meta);
    height: 1.4rem;
    justify-content: center;
    line-height: 1;
    padding: 0;
    transition: background-color 0.15s ease, color 0.15s ease;
    width: 1.4rem;
}

.cfk-file-chip__remove:hover {
    background-color: color-mix(in srgb, var(--danger) 14%, transparent);
    color: var(--danger);
}

.cfk-file-chip__remove:focus-visible {
    box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--primary-color) 22%, transparent);
    outline: none;
}

/* Respect users who prefer less motion — drop the scale/transform flourishes. */
@media (prefers-reduced-motion: reduce) {
    .cfk-file-dropzone,
    .cfk-file-dropzone.is-dragover,
    .cfk-file-chip,
    .cfk-file-chip__remove,
    .contact-form-range-input,
    .cf-rating-star {
        transition: none;
        transform: none;
    }
}


/*
 * ============================================================================
 * RANGE (SLIDER) FIELD
 * ============================================================================
 *
 * A native <input type="range"> with a live value indicator (<output>) that
 * shows prefix + value + suffix as the thumb moves. The slider track and thumb
 * are tinted via accent-color so they follow the active palette + dark mode
 * automatically. The output reads as a small chip to the right of the track.
 */

.contact-form-range-field {
    align-items: center;
    display: flex;
    flex-direction: row;
    gap: 0.75rem;
}

.contact-form-range-input {
    accent-color: var(--primary-color);
    cursor: pointer;
    flex: 1 1 auto;
    /* The native range control carries its own height; give it vertical room
     * so the thumb is comfortably grabbable on touch devices. */
    min-height: 1.75rem;
    width: 100%;
}

.contact-form-range-input:focus {
    outline: none;
}

.cf-range-prefix {
    color: var(--text-muted);
    flex: 0 0 auto;
    font-size: var(--fs-meta);
    font-weight: 600;
}

.cf-range-value {
    background-color: var(--surface-sunken);
    border-radius: var(--radius-pill);
    color: var(--text-ink);
    flex: 0 0 auto;
    font-size: var(--fs-meta);
    font-weight: 600;
    min-width: 3rem;
    padding-block: 0.2rem;
    padding-inline: 0.6rem;
    text-align: center;
}


/*
 * ============================================================================
 * RATING (STAR) FIELD
 * ============================================================================
 *
 * A pure-CSS star rating backed by a radio group. The radios + labels are
 * rendered high→low in the DOM (N, N-1, ... 1) and the row is visually
 * reversed with flex-direction: row-reverse below. row-reverse is
 * direction-aware, so the scale always starts at the reading edge: LTR shows
 * the stars 1..N from the left, RTL shows them 1..N from the right. Reversing
 * the visual order but not the DOM order is what makes the sibling
 * combinators fill the correct prefix: a checked/hovered star fills itself
 * and every star that follows it in DOM order (the lower values), which the
 * reversed row paints as the first N stars from the reading edge. Dropping
 * the row-reverse would mirror the widget and make it fill from the end edge.
 *
 * The radios themselves are visually hidden (kept in the a11y tree); the labels
 * carry the star glyphs. Filled stars use the accent, empty stars stay muted.
 */

.contact-form-rating {
    display: flex;
    /* Reverse the visual order (DOM is high→low, display is low→high) so the
     * sibling combinators below fill a prefix. row-reverse is direction-aware:
     * LTR reads 1..N from the left edge, RTL reads 1..N from the right edge. */
    flex-direction: row-reverse;
    /* Anchor to the reading edge. `start` is the logical inline start (left in
     * LTR, right in RTL); flex-start would follow the reversed main axis and
     * push the group to the opposite side. */
    justify-content: start;
    gap: 0.15rem;
}

.cf-rating-input {
    /* Visually hidden but focusable/operable: the label forwards clicks, and
     * keyboard :focus-within on the group still shows a focus ring. */
    height: 1px;
    opacity: 0;
    position: absolute;
    width: 1px;
}

.cf-rating-star {
    color: var(--text-muted);
    cursor: pointer;
    display: inline-flex;
    font-size: var(--fs-h3);
    line-height: 1;
    transition: color 0.12s ease, transform 0.12s ease;
}

/* Fill the hovered star and every star that FOLLOWS it in DOM order. The DOM is
 * high→low, so "following" = lower values, which the reversed row paints as the
 * stars from the reading edge up to the hovered position. This keeps the hover
 * preview in sync with the checked fill without any JS preview state. */
.cf-rating-star:hover,
.cf-rating-star:hover ~ .cf-rating-star {
    color: var(--accent-color);
    transform: scale(1.08);
}

/* Fill the checked star and every star that follows it in DOM order (the prefix
 * up to the selected value). Uses the accent so the active rating reads strongly. */
.cf-rating-input:checked ~ .cf-rating-star {
    color: var(--accent-color);
}

/* Keyboard focus ring on the group when a radio inside it has focus, so the
 * control is recognizably operable from the keyboard (native radio is hidden). */
.contact-form-rating:focus-within {
    outline: 2px solid color-mix(in srgb, var(--primary-color) 55%, transparent);
    outline-offset: 0.2rem;
    border-radius: var(--radius-sm);
}

@media (prefers-reduced-motion: reduce) {
    .cf-rating-star {
        transition: none;
        transform: none;
    }
}

