/* ─── Widget container ───────────────────────────────────────────────────────
   No chrome of its own. The container is layout only — the box the challenge
   occupies — so nothing here has to be undone before it can be styled.

   It used to ship a 1px border, an 8px radius, a white background and 5px of
   padding, on the reasoning that the challenge should read as one of the
   form's fields. That is a decision the site makes, not this file: in Elementor
   it is the form's own Field section and the Cloudflare Turnstile section
   beside it, and everywhere else it is the surface's own stylesheet. A default
   that looks deliberate is the hardest kind to override, because it has to be
   discovered first.

   Alignment is done with margins rather than flex: a flex container would
   stretch past the widget and the loading placeholder would no longer line up
   with it.                                                                    */

.bzs-turnstile {
    /* The challenge itself. The slot below reserves exactly this, so the box
       never shifts when the placeholder is swapped for the real widget. */
    --bzs-turnstile-w: 300px;
    --bzs-turnstile-h: 65px;

    position: relative;
    box-sizing: border-box;

    /* Shrink-wraps the slot plus whatever padding and border are set around
       it, so a wider box is always the styling asking for it and never the
       challenge being squeezed. */
    width: fit-content;
    max-width: 100%;
    margin: 0;
    overflow: hidden;
}

/* What the provider renders into. Holding the fixed size here rather than on
   the container is what lets the two be independent: the iframe always gets
   its 300x65 and the box around it is free to carry any padding, border or
   radius that is set on it. */
.bzs-turnstile__slot {
    display: block;
    box-sizing: border-box;
    min-width: var(--bzs-turnstile-w);
    min-height: var(--bzs-turnstile-h);
    max-width: 100%;
    border-radius: inherit;
    overflow: hidden;
}

.bzs-turnstile[data-size="compact"] {
    --bzs-turnstile-w: 150px;
    --bzs-turnstile-h: 140px;
}

/* Told to fill its column, the box is measured from the outside in — padding
   stays inside the column — and the slot gives up its own minimum so it can
   follow. */
.bzs-turnstile[data-size="flexible"],
.bzs-turnstile--full {
    width: 100%;
}

.bzs-turnstile[data-size="flexible"] .bzs-turnstile__slot,
.bzs-turnstile--full .bzs-turnstile__slot {
    min-width: 0;
    width: 100%;
}

/* A second challenge in one form is dropped at render, which would otherwise
   leave the form widget's own field group behind as an empty gap. */
.bzs-turnstile-duplicate {
    display: none !important;
}

/* The slot clips to its own corners, so the iframe keeps the widget's shape
   rather than the container's. */
.bzs-turnstile__slot iframe {
    display: block;
    max-width: 100%;
}

/* ─── Editor stand-in ────────────────────────────────────────────────────────
   The canvas shows the box at the exact size and chrome the visitor will see,
   and names it. It is deliberately not a live challenge: the widget re-renders
   on every keystroke in the editor, and each render would take a fresh
   challenge from Cloudflare to be thrown away a moment later.               */

.bzs-turnstile[data-bzs-preview] .bzs-turnstile__slot {
    display: flex;
    align-items: center;
}

.bzs-turnstile[data-bzs-preview] .bzs-turnstile__slot::before,
.bzs-turnstile[data-bzs-preview] .bzs-turnstile__slot::after {
    content: none;
}

.bzs-turnstile__preview {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1 1 auto;
    align-self: stretch;
    min-width: 0;
    box-sizing: border-box;
    padding: 0 12px;
    border-radius: inherit;
    background: #fafafa;
    color: #313131;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    font-size: 14px;
    font-weight: 400;
    line-height: 1.4;
}

.bzs-turnstile__preview-check {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    border: 1px solid #b7b7b7;
    border-radius: 3px;
    background: #fff;
}

.bzs-turnstile__preview-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bzs-turnstile__preview-brand {
    flex: 0 0 auto;
    color: #7a7a7a;
    font-size: 11px;
    letter-spacing: 0.02em;
}

.bzs-turnstile[data-size="compact"] .bzs-turnstile__preview {
    flex-direction: column;
    justify-content: center;
    gap: 8px;
    text-align: center;
}

.bzs-turnstile[data-theme="dark"] .bzs-turnstile__preview {
    background: #232323;
    color: #f5f5f5;
}

.bzs-turnstile[data-theme="dark"] .bzs-turnstile__preview-check {
    border-color: #5a5a5a;
    background: #2b3039;
}

.bzs-turnstile[data-theme="dark"] .bzs-turnstile__preview-brand {
    color: #9e9e9e;
}

/* ─── Alignment ──────────────────────────────────────────────────────────── */

.bzs-turnstile--align-left {
    margin-right: auto;
}

.bzs-turnstile--align-center {
    margin-left: auto;
    margin-right: auto;
}

.bzs-turnstile--align-right {
    margin-left: auto;
}

.bzs-turnstile--full {
    width: 100%;
}

/* ─── Loading skeleton ───────────────────────────────────────────────────────
   Two pseudo-elements on the container itself: a resting surface and a sweep
   over it. Using pseudo-elements means the swap is a style recalculation, not
   a DOM insertion — nothing re-renders and the widget is never reloaded.      */

.bzs-turnstile__slot::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: #f1f3f7;
}

.bzs-turnstile__slot::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(
        90deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 0.65) 50%,
        rgba(255, 255, 255, 0) 100%
    );
    transform: translateX(-100%);
    animation: bzs-turnstile-shimmer 1.4s ease-in-out infinite;
}

@keyframes bzs-turnstile-shimmer {
    100% {
        transform: translateX(100%);
    }
}

/* The widget is up: drop the placeholder. */
.bzs-turnstile[data-bzs-rendered] .bzs-turnstile__slot::before,
.bzs-turnstile[data-bzs-rendered] .bzs-turnstile__slot::after {
    content: none;
}

/* ...and drop the reserved height with it. It exists to hold the box open
   while the challenge loads so the form does not jump; once the iframe is
   there the iframe is the height, and keeping the floor leaves a strip of
   background below the widget whenever Cloudflare renders shorter than the
   65px it documents. */
.bzs-turnstile[data-bzs-rendered] {
    min-height: 0;
}

/* Nothing is coming — a blocked or unreachable provider script. Stop the
   animation and collapse the box so the form is not left holding a shimmering
   rectangle that will never resolve; the status line explains why. */
/* Nothing will ever render here, and an empty bordered field would just look
   broken. Remove it and let the status line carry the explanation. */
/* Scoped away from the editor: on a public page a dead box helps nobody, but
   hiding it on the canvas would leave the field impossible to select or
   style. */
body:not(.elementor-editor-active) .bzs-turnstile[data-bzs-state="error"]:not([data-bzs-rendered]) {
    display: none;
}

.bzs-turnstile[data-bzs-state="error"]:not([data-bzs-rendered]) .bzs-turnstile__slot::before,
.bzs-turnstile[data-bzs-state="error"]:not([data-bzs-rendered]) .bzs-turnstile__slot::after {
    content: none;
}

/* ─── Dark surfaces ──────────────────────────────────────────────────────── */

.bzs-turnstile[data-theme="dark"] .bzs-turnstile__slot::before {
    background: #2b3039;
}

.bzs-turnstile[data-theme="dark"] .bzs-turnstile__slot::after {
    background: linear-gradient(
        90deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 0.09) 50%,
        rgba(255, 255, 255, 0) 100%
    );
}

@media (prefers-color-scheme: dark) {
    .bzs-turnstile[data-theme="auto"] .bzs-turnstile__slot::before {
        background: #2b3039;
    }

    .bzs-turnstile[data-theme="auto"] .bzs-turnstile__slot::after {
        background: linear-gradient(
            90deg,
            rgba(255, 255, 255, 0) 0%,
            rgba(255, 255, 255, 0.09) 50%,
            rgba(255, 255, 255, 0) 100%
        );
    }
}

@media (prefers-reduced-motion: reduce) {
    .bzs-turnstile__slot::after {
        animation: none;
    }
}

/* ─── Surface placement ──────────────────────────────────────────────────────
   Position only. What the box looks like is the surface's business: in
   Elementor the form's Field section and the Cloudflare Turnstile section
   beside it, and on wp-login.php the login stylesheet.                       */

#loginform .bzs-turnstile,
#registerform .bzs-turnstile,
#lostpasswordform .bzs-turnstile {
    margin: 16px auto;
}

/* ─── Messages ───────────────────────────────────────────────────────────── */

.bzs-turnstile-notice {
    margin: 0 0 16px;
    padding: 10px 12px;
    border-left: 4px solid #d63638;
    border-radius: 6px;
    background: #fcf0f1;
    color: #1d2327;
    font-size: 13px;
    line-height: 1.5;
}

.bzs-turnstile-status {
    margin: 8px 0 0;
    font-size: 13px;
    line-height: 1.5;
    color: #b32d2e;
}

/* ─── Submit gating ──────────────────────────────────────────────────────────
   The control is genuinely disabled; this only makes that legible, and blocks
   pointer events on themes that restyle :disabled away. */

.bzs-submit-locked,
form[data-bzs-gate="locked"] .bzs-submit-locked {
    opacity: 0.55;
    cursor: not-allowed;
    pointer-events: none;
}
