/*
 * Alertify portal theme — light/dark via .portal-page-themed[data-bs-theme].
 * Uses --portal-c-* tokens from portal-components.css.
 */

/* ── Alertify-specific tokens (inherit portal component palette) ─── */
body:has(.portal-page-themed[data-bs-theme="dark"]) {
    --portal-alert-dimmer-opacity: 0.65;
    --portal-alert-input-bg: var(--portal-c-input-bg, rgba(0, 0, 0, 0.25));
    /* One accent per state drives BOTH the glass tint and the icon. It rides
       the BRIGHTER hover ramp on dark: the icon sits on a surface already
       carrying 18% of its own colour, so the resting #c92a2a danger would be
       reading against a red-cast backdrop. #e03131 keeps the glyph clear of
       its own tint. Success/warning follow suit so the three read as a family. */
    --portal-toast-success: var(--portal-c-btn-success-bg-hover);
    --portal-toast-danger: var(--portal-c-btn-danger-bg-hover);
    --portal-toast-warning: var(--portal-c-btn-warning-bg-hover);
}

body:has(.portal-page-themed[data-bs-theme="light"]) {
    --portal-alert-dimmer-opacity: 0.35;
    --portal-alert-input-bg: var(--portal-c-input-bg, #fff);
    /* Resting ramp is already the darker end — correct against a white toast. */
    --portal-toast-success: var(--portal-c-btn-success-bg);
    --portal-toast-danger: var(--portal-c-btn-danger-bg);
    --portal-toast-warning: var(--portal-c-btn-warning-bg);
}

/* ── Dimmer ───────────────────────────────────────────────────────── */
body:has(.portal-page-themed) .alertify .ajs-dimmer {
    background-color: #000;
    opacity: var(--portal-alert-dimmer-opacity);
    backdrop-filter: var(--portal-blur-dim);
    -webkit-backdrop-filter: var(--portal-blur-dim);
    /* Same cold-start fix as the portal modal/search dialogs: without this
       the blur's compositing surface gets allocated the instant the fade
       starts, so the first frame(s) show the page still sharp underneath. */
    will-change: backdrop-filter;
}

/* The rule above outranks the vendor's hidden state (0,3,1 vs 0,3,0), which
   silently pinned the dimmer at full opacity for its whole lifecycle — it
   appeared and vanished as a snap, never a fade. Restate the hidden state
   at the same specificity so the fade can actually happen. */
body:has(.portal-page-themed) .alertify.ajs-hidden .ajs-dimmer {
    opacity: 0;
}

/* ── Dialog shell ─────────────────────────────────────────────────── */
body:has(.portal-page-themed) .alertify .ajs-dialog {
    /* Overlay glass: translucent shell + blur; xl = dialog tier. isolation
       clips the blur cleanly to the rounded box (Safari corner halo). */
    background-color: var(--portal-c-overlay);
    border: 1px solid var(--portal-c-border);
    border-radius: var(--bs-border-radius-xl);
    backdrop-filter: var(--portal-blur-overlay);
    -webkit-backdrop-filter: var(--portal-blur-overlay);
    will-change: backdrop-filter;
    box-shadow: var(--portal-c-edge-dialog), var(--portal-c-elev-overlay, var(--portal-c-shadow));
    color: var(--portal-c-text);
    overflow: hidden;
    isolation: isolate;
    padding: 0 !important;
    max-width: 32rem;
}

body:has(.portal-page-themed) .alertify .ajs-header {
    color: var(--portal-c-text);
    background-color: var(--portal-c-surface-header);
    border-bottom: 1px solid var(--portal-c-border);
    border-radius: 0;
    font-size: var(--portal-text-base);
    font-weight: var(--portal-weight-label);
    padding: 1rem 1.25rem;
    margin: 0;
}

/* Body/content stay transparent — an opaque repaint inside the glass shell
   would tile visibly against the blurred backdrop. */
body:has(.portal-page-themed) .alertify .ajs-body {
    color: var(--portal-c-text-muted);
    background-color: transparent;
    padding: 0;
}

body:has(.portal-page-themed) .alertify .ajs-body .ajs-content {
    color: var(--portal-c-text-muted);
    background-color: transparent;
    padding: 1rem 1.25rem;
}

/* ── Close (X) button ────────────────────────────────────────────── */
body:has(.portal-page-themed) .alertify .ajs-commands {
    position: absolute;
    top: 0;
    right: 0;
    margin: 0;
    padding: 0;
    z-index: 2;
}

body:has(.portal-page-themed) .alertify .ajs-commands button.ajs-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    margin: 0.35rem 0.35rem 0 0;
    padding: 0;
    border: none;
    border-radius: var(--bs-border-radius);
    background: transparent;
    cursor: pointer;
    transition: background-color var(--portal-dur-1) var(--portal-ease-out);
}

body:has(.portal-page-themed) .alertify .ajs-commands button.ajs-close {
    background-image: none;
    font-size: 0;
    line-height: 1;
}

body:has(.portal-page-themed) .alertify .ajs-commands button.ajs-close::after {
    content: '\00d7';
    font-size: var(--portal-text-2xl);
    font-weight: 300;
    line-height: 1;
}

body:has(.portal-page-themed[data-bs-theme="dark"]) .alertify .ajs-commands button.ajs-close {
    filter: none;
    color: #fff;
    opacity: 0.65;
}

body:has(.portal-page-themed[data-bs-theme="dark"]) .alertify .ajs-commands button.ajs-close:hover {
    opacity: 1;
    background-color: rgba(255, 255, 255, 0.08);
}

body:has(.portal-page-themed[data-bs-theme="light"]) .alertify .ajs-commands button.ajs-close {
    filter: none;
    color: #000;
    opacity: 0.45;
}

body:has(.portal-page-themed[data-bs-theme="light"]) .alertify .ajs-commands button.ajs-close:hover {
    opacity: 0.75;
    background-color: rgba(0, 0, 0, 0.06);
}

/* ── Footer ──────────────────────────────────────────────────────── */
body:has(.portal-page-themed) .alertify .ajs-footer {
    background-color: var(--portal-c-surface-header);
    border-top: 1px solid var(--portal-c-border);
    border-radius: 0 0 var(--bs-border-radius-xl) var(--bs-border-radius-xl);
    padding: 0.875rem 1.25rem;
    margin: 0 !important;
}

body:has(.portal-page-themed) .alertify .ajs-footer .ajs-auxiliary {
    display: none;
}

body:has(.portal-page-themed) .alertify .ajs-footer .ajs-buttons {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.5rem;
    padding: 0;
    margin: 0;
}

body:has(.portal-page-themed) .alertify .ajs-footer .ajs-buttons .ajs-button {
    margin: 0;
}

/* ── Footer buttons — shared ─────────────────────────────────────── */
body:has(.portal-page-themed) .alertify .ajs-footer .btn {
    font-weight: var(--portal-weight-label);
    font-size: var(--portal-text-sm);
    border-radius: var(--bs-border-radius);
    padding: 0.45rem 1rem;
    transition: transform var(--portal-dur-1) var(--portal-ease-out),
                box-shadow var(--portal-dur-1) var(--portal-ease-out),
                background-color var(--portal-dur-1) var(--portal-ease-out),
                border-color var(--portal-dur-1) var(--portal-ease-out),
                color var(--portal-dur-1) var(--portal-ease-out);
}

/* Mirrors portal-components: buttons do not lift, they PRESS. This pair
   lagged one design behind after the interaction composition landed. */
body:has(.portal-page-themed) .alertify .ajs-footer .btn:not(:disabled):active {
    transform: scale(0.97);
}

body:has(.portal-page-themed) .alertify .ajs-footer .btn:focus-visible {
    outline: 2px solid var(--portal-c-accent);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    body:has(.portal-page-themed) .alertify .ajs-footer .btn { transition: none; }
    body:has(.portal-page-themed) .alertify .ajs-footer .btn:not(:disabled):active { transform: none; }
}

/* Primary (used for alert OK, non-destructive confirms) */
body:has(.portal-page-themed) .alertify .ajs-footer .btn-primary {
    background-color: var(--portal-c-btn-primary-bg);
    background-image: none;
    border-color: var(--portal-c-btn-primary-border);
    box-shadow: var(--portal-c-btn-primary-shadow);
    color: #fff;
}

body:has(.portal-page-themed) .alertify .ajs-footer .btn-primary:hover:not(:disabled),
body:has(.portal-page-themed) .alertify .ajs-footer .btn-primary:focus-visible:not(:disabled) {
    background-color: var(--portal-c-btn-primary-bg-hover);
    border-color: var(--portal-c-btn-primary-border-hover);
    box-shadow: var(--portal-c-btn-primary-shadow-hover);
    color: #fff;
}

/* Outline secondary (cancel buttons) */
body:has(.portal-page-themed) .alertify .ajs-footer .btn-outline-secondary {
    background-color: transparent;
    background-image: none;
    border-color: var(--portal-c-btn-outline-border);
    color: var(--portal-c-btn-outline-color);
    box-shadow: none;
}

body:has(.portal-page-themed) .alertify .ajs-footer .btn-outline-secondary:hover:not(:disabled),
body:has(.portal-page-themed) .alertify .ajs-footer .btn-outline-secondary:focus-visible:not(:disabled) {
    background-color: var(--portal-c-btn-outline-hover-bg);
    border-color: var(--portal-c-btn-outline-hover-border);
    color: var(--portal-c-btn-outline-hover-color);
}

/* Danger (destructive confirms — revoke, delete, unregister) */
body:has(.portal-page-themed) .alertify .ajs-footer .btn-danger {
    background-color: var(--portal-c-btn-danger-bg);
    background-image: none;
    border-color: var(--portal-c-btn-danger-border);
    box-shadow: var(--portal-c-btn-danger-shadow);
    color: #fff;
}

body:has(.portal-page-themed) .alertify .ajs-footer .btn-danger:hover:not(:disabled),
body:has(.portal-page-themed) .alertify .ajs-footer .btn-danger:focus-visible:not(:disabled) {
    background-color: var(--portal-c-btn-danger-bg-hover);
    border-color: var(--portal-c-btn-danger-border-hover);
    box-shadow: var(--portal-c-btn-danger-shadow-hover);
    color: #fff;
}

/* Outline info (used inside alert body — copy button, etc.) */
body:has(.portal-page-themed) .alertify .ajs-body .btn-outline-info {
    border-color: var(--portal-c-accent);
    color: var(--portal-c-accent);
    background: transparent;
    font-size: var(--portal-text-sm);
    font-weight: var(--portal-weight-label);
    border-radius: var(--bs-border-radius);
    padding: 0.3rem 0.75rem;
}

body:has(.portal-page-themed) .alertify .ajs-body .btn-outline-info:hover {
    background-color: var(--portal-c-accent-muted);
    color: var(--portal-c-accent);
}

/* ── Form inputs in prompts ───────────────────────────────────────── */
body:has(.portal-page-themed) .alertify .ajs-body .form-control {
    background-color: var(--portal-alert-input-bg);
    border-color: var(--portal-c-border);
    color: var(--portal-c-text);
    border-radius: var(--bs-border-radius);
    font-size: var(--portal-text-md);
}

body:has(.portal-page-themed) .alertify .ajs-body .form-control:focus {
    background-color: var(--portal-alert-input-bg);
    border-color: var(--portal-c-accent-border);
    color: var(--portal-c-text);
    box-shadow: var(--portal-c-focus-ring);
}

/* ── Toast / notifier messages ────────────────────────────────────── */
/* Toasts are overlay glass, same recipe as the dialog shell above and the
   in-page menus: translucent surface + blur + specular top edge.
   They used to be the one overlay held back to an opaque surface, on the
   grounds that a moving element shouldn't carry a backdrop-filter. That
   made them the only chrome in the portal that didn't look like the rest
   of it, so they now match. The nesting rule still holds and is satisfied
   here: .alertify-notifier is appended to <body> with no filtered ancestor,
   so this is a top-level backdrop root, not blur inside blur. Degrades to
   the opaque surface automatically — the three gates at the end of
   portal-components.css repoint --portal-c-overlay and --portal-blur-*. */
body:has(.portal-page-themed) .alertify-notifier .ajs-message {
    background-color: var(--portal-c-overlay);
    color: var(--portal-c-text);
    border: 1px solid var(--portal-c-border);
    border-radius: var(--bs-border-radius-lg);
    backdrop-filter: var(--portal-blur-overlay);
    -webkit-backdrop-filter: var(--portal-blur-overlay);
    box-shadow: var(--portal-c-edge-card), var(--portal-c-elev-overlay, var(--portal-c-shadow));
    /* Clips the blur to the rounded box — without it Safari haloes the
       corners, same reason the dialog shell isolates. */
    isolation: isolate;
    text-shadow: none;
    font-weight: var(--portal-weight-medium);
    font-size: var(--portal-text-md);
    /* The vendor bootstrap theme centres toast text. That read fine on a solid
       colour pill, but against a hanging state icon a centred second line
       drifts away from the glyph. Everything else in the portal sets copy
       flush left; toasts now match. */
    text-align: left;
}

/* Padding lives on the VISIBLE state only: the dismiss animation
   (alertify-motion.css) collapses max-height/padding back to the vendor's
   zeroed base state — border-box padding here would floor the collapsed
   box at ~26px and the leftover stub would snap out of the stack when
   alertify's 1s removal timer fires. */
body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-visible {
    padding: 0.75rem 1rem;
}

/* State is the TINT OF THE GLASS ITSELF — no accent stripe, no coloured
   border. The state colour is mixed into the same translucent overlay the
   base rule uses, so a success toast is the portal's glass surface with a
   green cast rather than a green slab, and the blur/specular/elevation all
   carry through unchanged.
   Mixing into --portal-c-overlay (rather than compositing a tint layer on
   top) is what makes this degrade for free: when a gate repoints that token
   to --portal-c-overlay-opaque, the mix resolves against an opaque colour
   and the toast lands on a solid tint with no extra rules. */
body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-success,
body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-error,
body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-warning {
    background-color: color-mix(in srgb, var(--portal-toast-accent) 18%, var(--portal-c-overlay));
}

body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-success {
    --portal-toast-accent: var(--portal-toast-success);
}

body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-error {
    --portal-toast-accent: var(--portal-toast-danger);
}

body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-warning {
    --portal-toast-accent: var(--portal-toast-warning);
}

/* The icon is absolutely positioned OUT of flow (the vendor already sets
   position:relative on .ajs-message). Deliberately not a flex row: alertify
   messages carry inline markup — '<strong>Bot</strong> — alerted 3 fights out'
   — and flex would promote each inline element to its own flex item and space
   them apart, shredding the sentence. */
body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-success::before,
body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-error::before,
body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-warning::before {
    position: absolute;
    left: 1rem;
    /* Matches the visible-state padding-top + text line-height so the glyph
       sits on the first line, not centred against a multi-line message. */
    top: 0.75rem;
    line-height: 1.4;
    font-family: "Font Awesome 7 Free";
    font-weight: var(--portal-weight-strong);
    font-size: var(--portal-text-md);
    color: var(--portal-toast-accent);
}

/* Raw codepoints are unreadable — the FA name for each is named here. */
body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-success::before {
    content: "\f00c"; /* fa-check */
}

body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-error::before {
    content: "\f06a"; /* fa-circle-exclamation */
}

body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-warning::before {
    content: "\f071"; /* fa-triangle-exclamation */
}

/* Room for the icon. Like the base padding above this MUST stay on the
   visible state — padding on the resting rule floors the collapsed box at
   padding+border height and the dismiss animation leaves a stub behind. */
body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-visible.ajs-success,
body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-visible.ajs-error,
body:has(.portal-page-themed) .alertify-notifier .ajs-message.ajs-visible.ajs-warning {
    padding-left: 2.5rem;
}
