/* IconCaptcha, dressed as one of the contact form's own rows.

   The library ships a single hard-coded look — 330px box, blue accent, uppercase titles — that
   reads as a foreign widget dropped into the form. It exposes no custom properties, so the only
   way to reskin it is to re-declare its own selectors.

   ONE RULE THAT LOOKS LIKE A MISTAKE AND IS NOT: this file is NOT wrapped in `@layer components`,
   unlike every other stylesheet here. The library's CSS is unlayered, and unlayered rules beat
   layered ones outright — putting these in a layer would lose every override to a stylesheet with
   *lower* specificity. They win on source order instead, which is why assets/app.js has to keep
   importing this file after '@fabianwennink/iconcaptcha/css/iconcaptcha.min.css'.

   BOTH THEMES ARE SKINNED, and which one applies is decided in the browser, not here: the
   challenge icons are PNGs the server picks per theme (light = black glyphs, dark = white ones),
   so the CSS palette and the icon palette have to agree or the challenge becomes unreadable.
   assets/controllers/captcha_theme_controller.js is what makes them agree. Never style one theme
   and let the other inherit it.

   The geometry of the challenge strip is load-bearing and deliberately untouched: click
   coordinates are mapped back to an icon using the element width, so resizing it breaks
   selection. */

.iconcaptcha-row {
    /* The bundle renders its own row block, so .contact__form's `gap` reaches it but the label
       spacing its sibling rows get does not. */
    display: flex;
    flex-direction: column;
    gap: var(--space-2xs, 0.25rem);
}

.iconcaptcha-widget {
    /* Every accented pixel in the widget — the pulsing circle, the loader, the selection dot —
       comes from these. Declared unconditionally so the light theme needs no overrides of its
       own; the dark block below re-points them. */
    --captcha-accent: var(--clr-brand-700);
    --captcha-accent-dim: var(--clr-brand-800);
    --captcha-ink: var(--clr-slate-800);
    --captcha-ink-muted: var(--clr-slate-500);
    --captcha-line: var(--clr-slate-200);
    --captcha-surface: var(--clr-white);
    --captcha-surface-hover: var(--clr-slate-50);
    --captcha-negative: var(--clr-rose-500);

    /* The library caps the widget at 330px; the rest of the form is full width and the captcha
       is just another row in it. */
    width: 100%;
    max-width: 100%;
    border-radius: var(--radius-m);
}

.iconcaptcha-widget.iconcaptcha-theme-dark {
    /* The page's dark tokens, hardcoded to the primitives rather than to --color-*: the theme is
       chosen by prefers-color-scheme in JS, and if the two ever disagreed (JS blocked, controller
       removed) a widget whose colours followed the media query while its icons followed the
       attribute would be unreadable. Tying the palette to the class the icons agree with keeps
       the two in step by construction. */
    --captcha-accent: var(--clr-brand-300);
    --captcha-accent-dim: var(--clr-brand-400);
    --captcha-ink: var(--clr-slate-50);
    --captcha-ink-muted: var(--clr-slate-300);
    --captcha-line: var(--clr-slate-700);
    --captcha-surface: var(--clr-slate-900);
    --captcha-surface-hover: var(--clr-slate-800);
    --captcha-negative: var(--clr-rose-400);
}

.iconcaptcha-widget.iconcaptcha-theme-light,
.iconcaptcha-widget.iconcaptcha-theme-dark {
    /* Matches the form's inputs: a plain field on a hairline border, not the library's grey. */
    background: var(--captcha-surface);
    border: 1px solid var(--captcha-line);
}

.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-init:hover,
.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-init:hover {
    background: var(--captcha-surface-hover);
}

/* ===== Idle state ("Overte, že nie ste robot.") ===== */

.iconcaptcha-widget.iconcaptcha-init .iconcaptcha-modal__body-circle {
    border-width: 5px;
    border-color: var(--captcha-accent);
}

/* Same name as the library's, redeclared so the animation stops repainting the circle blue on
   every keyframe. */
@keyframes captcha-breathing {
    0%,
    100% {
        transform: scale(1) translateZ(0);
        border-color: var(--captcha-accent);
    }
    25% {
        transform: scale(0.8) translateZ(0);
        border-color: var(--captcha-accent-dim);
    }
    50% {
        transform: scale(1) translateZ(0);
        border-color: var(--captcha-accent);
    }
    75% {
        transform: scale(0.8) translateZ(0);
        border-color: var(--captcha-accent-dim);
    }
}

.iconcaptcha-widget.iconcaptcha-init .iconcaptcha-modal__body-title,
.iconcaptcha-widget.iconcaptcha-success .iconcaptcha-modal__body-title {
    font-family: var(--font-sans);
    font-size: 0.95rem;
    font-weight: 500;
    /* The library shouts these in uppercase; the labels above it do not. */
    text-transform: none;
}

.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-init .iconcaptcha-modal__body-title,
.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-init .iconcaptcha-modal__body-title {
    color: var(--captcha-ink);
}

/* ===== Challenge state ===== */

/* The instruction bar above the icons. */
.iconcaptcha-widget .iconcaptcha-modal__header span {
    padding: 9px 12px;
    font-family: var(--font-sans);
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.4;
}

.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__header,
.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__header {
    border-bottom: 1px solid var(--captcha-line);
}

.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__header span,
.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__header span {
    color: var(--captcha-ink);
}

/* The library emphasises the important word ("najmenej") with a <u>. */
.iconcaptcha-widget .iconcaptcha-modal__header span u {
    color: var(--captcha-accent);
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
}

.iconcaptcha-widget .iconcaptcha-modal__body-selection > i {
    background: var(--captcha-accent);
}

.iconcaptcha-widget .iconcaptcha-modal__body .captcha-loader {
    border-width: 5px;
    border-color: var(--captcha-accent);
}

/* ===== Result states ===== */

.iconcaptcha-widget .iconcaptcha-modal__body-title {
    top: 10px;
    font-family: var(--font-sans);
    font-size: 1rem;
    font-weight: 600;
    text-transform: none;
}

.iconcaptcha-widget .iconcaptcha-modal__body-subtitle {
    top: 33px;
    font-family: var(--font-sans);
    font-size: 0.75rem;
}

.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__body-subtitle,
.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__body-subtitle {
    color: var(--captcha-ink-muted);
}

.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-error .iconcaptcha-modal__body-title,
.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-error .iconcaptcha-modal__body-title {
    color: var(--captcha-negative);
}

/* The palette has no green, and inventing one for a single checkmark would put a fourth hue on
   the page. Solved reads as brand-coloured. */
.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-success .iconcaptcha-modal__body-title,
.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-success .iconcaptcha-modal__body-title {
    color: var(--captcha-accent);
}

.iconcaptcha-widget.iconcaptcha-theme-light.iconcaptcha-success .iconcaptcha-modal__body-checkmark svg,
.iconcaptcha-widget.iconcaptcha-theme-dark.iconcaptcha-success .iconcaptcha-modal__body-checkmark svg {
    stroke: var(--captcha-accent);
}

/* ===== Attribution footer ===== */

.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__footer,
.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__footer {
    padding-top: 5px;
    padding-bottom: 5px;
    border-top: 1px solid var(--captcha-line);
}

.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__footer > span a,
.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__body-info a,
.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__footer > span a,
.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__body-info a {
    /* The library prints the credit link in bold uppercase blue, louder than the instruction it
       sits under. Attribution stays, the shouting does not. */
    color: var(--captcha-ink-muted);
    font-family: var(--font-sans);
    font-weight: 500;
    text-transform: none;
}

.iconcaptcha-widget.iconcaptcha-theme-light .iconcaptcha-modal__footer > span a:hover,
.iconcaptcha-widget.iconcaptcha-theme-dark .iconcaptcha-modal__footer > span a:hover {
    color: var(--captcha-accent);
}

/* ===== Validation error ===== */

/* An unsolved captcha fails validation like any other field. Symfony's default form theme renders
   the violation as a bare <ul>, which would otherwise arrive with browser bullets and margins in
   the middle of a hand-styled form. */
.iconcaptcha-row ul {
    margin: 0;
    padding: 0;
    list-style: none;
    color: var(--color-negative);
    font-size: 0.85rem;
}

/* The widget is not an input, so the form theme's error marking never reaches it — the red frame
   has to be inferred from the error list rendered next to it. */
.iconcaptcha-row:has(ul) .iconcaptcha-widget.iconcaptcha-theme-light,
.iconcaptcha-row:has(ul) .iconcaptcha-widget.iconcaptcha-theme-dark {
    border-color: var(--captcha-negative);
}
