component Captcha {
    props {
        provider = "self-hosted"
        siteKey = ""
        type = "alphanumeric"
        action = "form-submit"
        presentation = "visual"
        difficulty = "normal"
        disturbance = 50
        imageStyle = "random"
        allowedStyles = ""
        excludedStyles = ""
        randomizeStyle = false
        locale = "en"
        size = "normal"
        color = "primary"
        class = ""

        id = ""
        name = "wrn-captcha-response"
        endpoint = "/__wrnexus/captcha/challenge"
        verifyEndpoint = "/__wrnexus/captcha/verify"
        responseField = "wrn-captcha-response"

        label = "Security verification"
        description = "Complete the challenge to continue."
        helpText = ""
        requiredMessage = "Please complete the security check."
        incorrectMessage = "That answer was not correct. Try again."
        expiredMessage = "This challenge expired. Load a new one."
        networkMessage = "The verification service is unavailable. Try again."

        autoLoad = true
        autoVerify = false
        showVerify = true
        showRefresh = true
        showAudio = true
        showListen = true
        showStatus = true
        disabled = false
        required = true
        resetOnError = true
        compact = false
        layout = "vertical"

        @event ready = function
        @event challenge = function
        @event input = function
        @event verify = function
        @event success = function
        @event failure = function
        @event expired = function
        @event refresh = function
        @event audioStart = function
        @event audioEnd = function
        @event error = function
    }

    view {
        <section
            {...attrs}
            id='{id}'
            data-wrn-captcha
            data-wrnexus-runtime="captcha"
            data-captcha-provider='{provider}'
            data-captcha-site-key='{siteKey}'
            data-captcha-type='{type}'
            data-captcha-action='{action}'
            data-captcha-presentation='{presentation}'
            data-captcha-difficulty='{difficulty}'
            data-captcha-disturbance='{disturbance}'
            data-captcha-image-style='{imageStyle}'
            data-captcha-allowed-styles='{allowedStyles}'
            data-captcha-excluded-styles='{excludedStyles}'
            data-captcha-randomize-style='{randomizeStyle}'
            data-captcha-locale='{locale}'
            data-captcha-size='{size}'
            data-captcha-color='{color}'
            data-captcha-endpoint='{endpoint}'
            data-captcha-verify-endpoint='{verifyEndpoint}'
            data-captcha-response-field='{responseField}'
            data-captcha-name='{name}'
            data-captcha-auto-load='{autoLoad}'
            data-captcha-auto-verify='{autoVerify}'
            data-captcha-show-verify='{showVerify}'
            data-captcha-show-refresh='{showRefresh}'
            data-captcha-show-audio='{showAudio}'
            data-captcha-show-listen='{showListen}'
            data-captcha-show-status='{showStatus}'
            data-captcha-disabled='{disabled}'
            data-captcha-required='{required}'
            data-captcha-reset-on-error='{resetOnError}'
            data-captcha-compact='{compact}'
            data-captcha-layout='{layout}'
            data-captcha-required-message='{requiredMessage}'
            data-captcha-incorrect-message='{incorrectMessage}'
            data-captcha-expired-message='{expiredMessage}'
            data-captcha-network-message='{networkMessage}'
            data-captcha-status="idle"
            data-server-verification-required="true"
            aria-busy="false"
            class='group/captcha relative flex w-full max-w-lg flex-col gap-3 rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface)] p-4 text-[var(--wire-color-text)] shadow-[var(--wire-shadow-1)] [--captcha-accent:var(--wire-color-primary)] data-[captcha-color=secondary]:[--captcha-accent:var(--wire-color-secondary)] data-[captcha-color=success]:[--captcha-accent:var(--wire-color-success)] data-[captcha-color=warning]:[--captcha-accent:var(--wire-color-warning)] data-[captcha-color=danger]:[--captcha-accent:var(--wire-color-danger)] data-[captcha-color=info]:[--captcha-accent:var(--wire-color-info)] data-[captcha-size=compact]:max-w-xs data-[captcha-size=compact]:gap-1.5 data-[captcha-size=compact]:p-2 data-[captcha-size=big]:max-w-2xl data-[captcha-size=big]:gap-4 data-[captcha-size=big]:p-5 data-[captcha-compact=true]:max-w-xs data-[captcha-compact=true]:gap-1.5 data-[captcha-compact=true]:p-2 data-[captcha-layout=horizontal]:max-w-2xl data-[captcha-layout=horizontal]:grid data-[captcha-layout=horizontal]:grid-cols-1 sm:data-[captcha-layout=horizontal]:grid-cols-[minmax(0,1fr)_minmax(12rem,0.8fr)] sm:data-[captcha-layout=horizontal]:items-start data-[captcha-type=not-robot]:max-w-sm data-[captcha-type=not-robot]:gap-0 data-[captcha-type=not-robot]:p-0 data-[captcha-disabled=true]:pointer-events-none data-[captcha-disabled=true]:opacity-60 data-[captcha-status=verified]:border-[var(--wire-color-success)] data-[captcha-status=incorrect]:border-[var(--wire-color-danger)] data-[captcha-status=expired]:border-[var(--wire-color-danger)] data-[captcha-status=network-error]:border-[var(--wire-color-danger)] data-[captcha-status=provider-error]:border-[var(--wire-color-danger)] {class}'
        >
            <header data-captcha-header class='flex items-start justify-between gap-3 group-data-[captcha-size=compact]/captcha:gap-1.5 group-data-[captcha-layout=horizontal]/captcha:col-span-full group-data-[captcha-type=not-robot]/captcha:hidden'>
                <div class='min-w-0'>
                    <div class='flex items-center gap-2 group-data-[captcha-size=compact]/captcha:gap-1.5'>
                        <span
                            aria-hidden="true"
                            class='icon-[lucide--shield-check] size-5 shrink-0 text-[var(--captcha-accent)] group-data-[captcha-size=compact]/captcha:size-4'
                        ></span>
                        <h3 class='m-0 text-sm font-semibold leading-5 text-[var(--wire-color-text)] group-data-[captcha-size=compact]/captcha:text-[11px] group-data-[captcha-size=compact]/captcha:leading-4 group-data-[captcha-size=big]/captcha:text-base'>
                            {label}
                        </h3>
                    </div>
                    <p class='m-0 mt-1 text-xs leading-5 text-[var(--wire-color-muted)] group-data-[captcha-size=compact]/captcha:hidden group-data-[captcha-size=big]/captcha:text-sm'>
                        {description}
                    </p>
                </div>

                <span
                    data-captcha-verified-badge
                    hidden
                    class='shrink-0 items-center gap-1 rounded-full bg-[color-mix(in_srgb,var(--wire-color-success)_12%,transparent)] px-2 py-1 text-xs font-semibold text-[var(--wire-color-success)] group-data-[captcha-size=compact]/captcha:gap-0.5 group-data-[captcha-size=compact]/captcha:px-1.5 group-data-[captcha-size=compact]/captcha:py-0.5 group-data-[captcha-size=compact]/captcha:text-[10px]'
                >
                    <span aria-hidden="true" class='icon-[lucide--circle-check] size-3.5 group-data-[captcha-size=compact]/captcha:size-3'></span>
                    Verified
                </span>
            </header>

            <div
                data-captcha-provider-mount
                hidden
                class='flex min-h-16 w-full items-center justify-center overflow-hidden rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-surface-2)] p-2 group-data-[captcha-size=compact]/captcha:min-h-12 group-data-[captcha-size=compact]/captcha:p-1.5'
            ></div>

            <div
                data-captcha-loading
                hidden
                class='flex min-h-28 items-center justify-center gap-2 rounded-[var(--wire-radius-sm)] bg-[var(--wire-color-surface-2)] text-sm text-[var(--wire-color-muted)] group-data-[captcha-size=compact]/captcha:min-h-14 group-data-[captcha-size=compact]/captcha:gap-1.5 group-data-[captcha-size=compact]/captcha:text-[11px] group-data-[captcha-size=compact]/captcha:leading-4 group-data-[captcha-size=big]/captcha:min-h-36 group-data-[captcha-type=not-robot]/captcha:m-3 group-data-[captcha-type=not-robot]/captcha:min-h-16'
            >
                <span aria-hidden="true" class='icon-[lucide--loader-circle] size-5 animate-spin group-data-[captcha-size=compact]/captcha:size-4'></span>
                Loading challenge…
            </div>

            <div data-captcha-challenge hidden class='flex min-w-0 flex-col gap-3 group-data-[captcha-size=compact]/captcha:gap-1.5 group-data-[captcha-size=big]/captcha:gap-4 group-data-[captcha-type=not-robot]/captcha:p-3'>
                <div data-captcha-prompt-row class='flex items-start justify-between gap-3 group-data-[captcha-size=compact]/captcha:gap-2'>
                    <p data-captcha-prompt class='m-0 text-sm font-medium text-[var(--wire-color-text)] group-data-[captcha-size=compact]/captcha:text-[11px] group-data-[captcha-size=compact]/captcha:leading-4'></p>
                    <span data-captcha-countdown hidden class='shrink-0 text-xs tabular-nums text-[var(--wire-color-muted)] group-data-[captcha-size=compact]/captcha:text-[10px]'></span>
                </div>

                <div data-captcha-not-robot hidden class='w-full'>
                    <button
                        data-captcha-not-robot-button
                        type="button"
                        aria-pressed="false"
                        class='flex min-h-20 w-full items-center gap-3 rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface-2)] px-4 py-3 text-left transition-[border-color,box-shadow,background-color] hover:border-[var(--captcha-accent)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--captcha-accent)] disabled:cursor-wait disabled:opacity-80 group-data-[captcha-size=compact]/captcha:min-h-16 group-data-[captcha-size=compact]/captcha:gap-2.5 group-data-[captcha-size=compact]/captcha:px-3 group-data-[captcha-size=compact]/captcha:py-2.5 group-data-[captcha-size=big]/captcha:min-h-24 group-data-[captcha-size=big]/captcha:px-5 group-data-[captcha-size=big]/captcha:py-4'
                    >
                        <span
                            data-captcha-not-robot-control
                            aria-hidden="true"
                            class='inline-flex size-7 shrink-0 items-center justify-center rounded-md border-2 border-[var(--wire-color-border)] bg-[var(--wire-color-surface)] text-white transition-colors data-[verified=true]:border-[var(--wire-color-success)] data-[verified=true]:bg-[var(--wire-color-success)] group-data-[captcha-size=compact]/captcha:size-6 group-data-[captcha-size=big]/captcha:size-8'
                        >
                            <span data-captcha-not-robot-empty class='size-full'></span>
                            <span data-captcha-not-robot-spinner hidden class='icon-[lucide--loader-circle] size-4 animate-spin text-[var(--captcha-accent)]'></span>
                            <span data-captcha-not-robot-check hidden class='icon-[lucide--check] size-5'></span>
                        </span>

                        <span data-captcha-not-robot-label class='min-w-0 flex-1 text-sm font-semibold text-[var(--wire-color-text)] group-data-[captcha-size=compact]/captcha:text-[11px] group-data-[captcha-size=compact]/captcha:leading-4 group-data-[captcha-size=big]/captcha:text-base'>
                            I'm not a robot
                        </span>

                        <span class='flex shrink-0 flex-col items-center gap-0.5 text-[10px] leading-none text-[var(--wire-color-muted)]'>
                            <span aria-hidden="true" class='icon-[lucide--shield-check] size-6 text-[var(--captcha-accent)] group-data-[captcha-size=compact]/captcha:size-5 group-data-[captcha-size=big]/captcha:size-7'></span>
                            <span>WRNexus</span>
                        </span>
                    </button>
                </div>

                <div
                    data-captcha-image-wrap
                    hidden
                    class='overflow-hidden rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-white'
                >
                    <img
                        data-captcha-image
                        src=""
                        alt="CAPTCHA challenge"
                        draggable="false"
                        class='block h-auto min-h-20 w-full select-none object-contain group-data-[captcha-size=compact]/captcha:max-h-24 group-data-[captcha-size=compact]/captcha:min-h-12 group-data-[captcha-size=big]/captcha:min-h-28'
                    />
                </div>

                <div
                    data-captcha-items
                    hidden
                    role="group"
                    class='grid grid-cols-2 gap-2 group-data-[captcha-size=compact]/captcha:gap-1 sm:grid-cols-3 group-data-[captcha-size=big]/captcha:gap-3'
                ></div>

                <template data-captcha-item-template>
                    <button
                        type="button"
                        aria-pressed="false"
                        class='group relative overflow-hidden rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-white p-1 group-data-[captcha-size=compact]/captcha:p-0.5 transition-[border-color,box-shadow,transform] duration-[var(--wire-motion-fast)] hover:border-[var(--captcha-accent)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--captcha-accent)] aria-[pressed=true]:border-[var(--captcha-accent)] aria-[pressed=true]:ring-2 aria-[pressed=true]:ring-[var(--captcha-accent)]'
                    >
                        <img
                            data-captcha-item-image
                            src=""
                            alt=""
                            draggable="false"
                            class='aspect-[4/3] w-full select-none object-cover'
                        />
                        <span
                            data-captcha-item-check
                            hidden
                            aria-hidden="true"
                            class='absolute right-1.5 top-1.5 inline-flex size-5 group-data-[captcha-size=compact]/captcha:right-1 group-data-[captcha-size=compact]/captcha:top-1 group-data-[captcha-size=compact]/captcha:size-4 items-center justify-center rounded-full bg-[var(--captcha-accent)] text-white shadow-sm'
                        >
                            <span class='icon-[lucide--check] size-3.5'></span>
                        </span>
                    </button>
                </template>

                <input
                    data-captcha-honeypot
                    type="text"
                    name=""
                    value=""
                    tabindex="-1"
                    autocomplete="off"
                    aria-hidden="true"
                    class='pointer-events-none absolute -left-[10000px] top-auto h-px w-px overflow-hidden opacity-0'
                />
            </div>

            <div data-captcha-response-panel class='flex min-w-0 flex-col gap-2 group-data-[captcha-layout=horizontal]/captcha:self-stretch'>
            <label data-captcha-answer-wrap hidden class='flex min-w-0 flex-col gap-1.5 group-data-[captcha-size=compact]/captcha:gap-1'>
                <span class='text-xs font-semibold text-[var(--wire-color-text)] group-data-[captcha-size=compact]/captcha:text-[10px]'>Your answer</span>
                <input
                    data-captcha-answer
                    type="text"
                    inputmode="text"
                    autocomplete="off"
                    autocapitalize="characters"
                    spellcheck="false"
                    class='h-11 w-full rounded-[var(--wire-radius-sm)] border border-[var(--wire-color-border)] bg-[var(--wire-color-surface)] px-3 text-base font-semibold tracking-[0.18em] text-[var(--wire-color-text)] outline-none transition-[border-color,box-shadow] placeholder:tracking-normal focus:border-[var(--captcha-accent)] focus:ring-2 focus:ring-[var(--captcha-accent)] disabled:cursor-not-allowed disabled:bg-[var(--wire-color-surface-2)] aria-[invalid=true]:border-[var(--wire-color-danger)] aria-[invalid=true]:ring-2 aria-[invalid=true]:ring-[var(--wire-color-danger)] group-data-[captcha-size=compact]/captcha:h-8 group-data-[captcha-size=compact]/captcha:px-2 group-data-[captcha-size=compact]/captcha:text-xs group-data-[captcha-size=compact]/captcha:tracking-[0.12em] group-data-[captcha-size=big]/captcha:h-12 group-data-[captcha-size=big]/captcha:px-4 group-data-[captcha-size=big]/captcha:text-lg'
                    placeholder="Enter the answer"
                />
            </label>

            <div data-captcha-success hidden role="status" aria-live="polite" class='flex items-start gap-1.5 text-xs leading-5 text-[var(--wire-color-success)] group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-size=compact]/captcha:text-[10px] group-data-[captcha-size=compact]/captcha:leading-4 group-data-[captcha-type=not-robot]/captcha:hidden'>
                <span aria-hidden="true" class='icon-[lucide--circle-check] mt-0.5 size-3.5 shrink-0'></span>
                <span data-captcha-success-message>Verification completed.</span>
            </div>

            <div data-captcha-error hidden role="alert" aria-live="polite" class='flex items-start gap-1.5 text-xs leading-5 text-[var(--wire-color-danger)] group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-size=compact]/captcha:text-[10px] group-data-[captcha-size=compact]/captcha:leading-4 group-data-[captcha-type=not-robot]/captcha:mx-3 group-data-[captcha-type=not-robot]/captcha:mb-3'>
                <span aria-hidden="true" class='icon-[lucide--circle-alert] mt-0.5 size-3.5 shrink-0'></span>
                <span data-captcha-error-message></span>
            </div>

            <p data-captcha-help class='m-0 text-xs leading-5 text-[var(--wire-color-muted)] group-data-[captcha-size=compact]/captcha:text-[10px] group-data-[captcha-size=compact]/captcha:leading-4 group-data-[captcha-type=not-robot]/captcha:hidden'>
                {helpText}
            </p>

            <footer data-captcha-footer class='flex flex-wrap items-center justify-between gap-2 group-data-[captcha-size=compact]/captcha:flex-nowrap group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-type=not-robot]/captcha:hidden'>
                <div class='flex flex-wrap items-center gap-1.5 group-data-[captcha-size=compact]/captcha:flex-nowrap group-data-[captcha-size=compact]/captcha:gap-0.5'>
                    <button
                        data-captcha-audio
                        hidden
                        type="button"
                        class='inline-flex h-9 items-center justify-center gap-1.5 rounded-[var(--wire-radius-sm)] px-2.5 text-xs group-data-[captcha-size=compact]/captcha:h-8 group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-size=compact]/captcha:px-1.5 group-data-[captcha-size=compact]/captcha:text-[10px] font-semibold text-[var(--wire-color-muted)] transition-colors hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--captcha-accent)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--captcha-accent)] disabled:cursor-not-allowed disabled:opacity-50'
                    >
                        <span aria-hidden="true" class='icon-[lucide--volume-2] size-4 group-data-[captcha-size=compact]/captcha:size-3.5'></span>
                        Listen
                    </button>

                    <button
                        data-captcha-audio-alternative
                        hidden
                        type="button"
                        class='inline-flex h-9 items-center justify-center gap-1.5 rounded-[var(--wire-radius-sm)] px-2.5 text-xs group-data-[captcha-size=compact]/captcha:h-8 group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-size=compact]/captcha:px-1.5 group-data-[captcha-size=compact]/captcha:text-[10px] font-semibold text-[var(--wire-color-muted)] transition-colors hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--captcha-accent)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--captcha-accent)] disabled:cursor-not-allowed disabled:opacity-50'
                    >
                        <span aria-hidden="true" class='icon-[lucide--ear] size-4 group-data-[captcha-size=compact]/captcha:size-3.5'></span>
                        Use audio
                    </button>

                    <button
                        data-captcha-refresh
                        type="button"
                        class='inline-flex h-9 items-center justify-center gap-1.5 rounded-[var(--wire-radius-sm)] px-2.5 text-xs group-data-[captcha-size=compact]/captcha:h-8 group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-size=compact]/captcha:px-1.5 group-data-[captcha-size=compact]/captcha:text-[10px] font-semibold text-[var(--wire-color-muted)] transition-colors hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--captcha-accent)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--captcha-accent)] disabled:cursor-not-allowed disabled:opacity-50'
                    >
                        <span aria-hidden="true" class='icon-[lucide--refresh-cw] size-4 group-data-[captcha-size=compact]/captcha:size-3.5'></span>
                        New challenge
                    </button>
                </div>

                <button
                    data-captcha-verify
                    type="button"
                    class='inline-flex h-9 items-center justify-center gap-1.5 rounded-[var(--wire-radius-sm)] bg-[var(--captcha-accent)] px-3 text-xs group-data-[captcha-size=compact]/captcha:h-8 group-data-[captcha-size=compact]/captcha:gap-1 group-data-[captcha-size=compact]/captcha:px-2.5 group-data-[captcha-size=compact]/captcha:text-[10px] font-semibold text-white shadow-sm transition-[filter,transform] hover:brightness-95 active:translate-y-px focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--captcha-accent)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--wire-color-surface)] disabled:cursor-not-allowed disabled:opacity-50'
                >
                    <span data-captcha-verify-icon aria-hidden="true" class='icon-[lucide--shield-check] size-4 group-data-[captcha-size=compact]/captcha:size-3.5'></span>
                    <span data-captcha-verify-spinner hidden aria-hidden="true" class='icon-[lucide--loader-circle] size-4 animate-spin group-data-[captcha-size=compact]/captcha:size-3.5'></span>
                    <span data-captcha-verify-label>Verify</span>
                </button>
            </footer>

            <input
                data-captcha-response
                type="hidden"
                name='{responseField}'
                value=""
            />

            <p data-captcha-credit class='m-0 text-[11px] leading-4 text-[var(--wire-color-muted)] group-data-[captcha-size=compact]/captcha:hidden group-data-[captcha-type=not-robot]/captcha:hidden'>
                Protected by WRNexus CAPTCHA. Server-side verification is required.
            </p>
            </div>
        </section>
    }

    style {
        /*
         * Compact image challenges read as a single sequence: challenge,
         * secondary actions, answer, then verification. Flattening the footer
         * lets Listen/New challenge move directly beneath the image without
         * changing the DOM or the client runtime selectors.
         */
        [data-wrn-captcha]:is([data-captcha-compact="true"], [data-captcha-size="compact"])[data-captcha-layout="horizontal"] {
            grid-template-columns: minmax(0, 1fr);
        }

        [data-wrn-captcha]:is([data-captcha-compact="true"], [data-captcha-size="compact"])
            [data-captcha-response-panel]
            [data-captcha-footer] {
            display: contents;
        }

        [data-wrn-captcha]:is([data-captcha-compact="true"], [data-captcha-size="compact"])
            [data-captcha-footer]
            > div:first-child {
            order: -1;
            justify-content: flex-start;
        }

        [data-wrn-captcha]:is([data-captcha-compact="true"], [data-captcha-size="compact"])
            [data-captcha-verify] {
            align-self: flex-start;
        }
    }
}
