/* ==========================================================================
   NOVA — dark presentation canvas (no icons, no emoji)
   ========================================================================== */

:root {
    --fai-bg:            #0a0f1c;   /* main canvas — near-black navy, not pure black */
    --fai-bg-elevated:   #131b2e;   /* cards, panels, the glass surfaces sitting on the canvas */
    --fai-heading:       #f3f6ff;   /* bright near-white, for heading text on dark surfaces */
    --fai-navy:          #0b2545;   /* kept as a DEEP accent color (gradients, solid badges) — not text */
    --fai-blue:          #3b82f6;
    --fai-blue-mid:      #60a5fa;   /* lighter than the old light-theme mid-blue, for contrast on dark */
    --fai-blue-light:    rgba(96, 165, 250, 0.14);  /* translucent blue-glass tint, was a solid pale blue */
    --fai-blue-border:   rgba(255, 255, 255, 0.12); /* subtle light hairline, was a solid pale blue */
    --fai-text:          #dbe4f3;   /* light gray-blue body text — for DARK surfaces (stage, panels, cards) only */
    --fai-text-muted:    #8592ac;   /* muted version of the above — DARK surfaces only */
    --fai-white:         #ffffff;   /* still literal white — used for text/fill ON colored badges, never as a page background */
    --fai-yellow:        #f0b429;   /* accent color for the slide content itself — blue/white/black/yellow palette */

    /* The slide itself stays a white card (readable, unchanged from the
       original light theme) even though everything around it went dark —
       so anything rendered ON that white card (headings, body text, lists,
       diagrams, tables, the cover screen) needs its OWN text tokens,
       separate from --fai-text/--fai-text-muted above which are tuned for
       the DARK stage/panels/cards instead. Mixing these up is exactly what
       caused body text to render as barely-visible light grey on white. */
    --fai-slide-text:       #1e2a3f;
    --fai-slide-text-muted: #5b6b8c;
    /* Slide heading color, on the same "white card" tokens above. Its own
       variable (rather than reusing --fai-navy directly on the h1 rule)
       is what lets a slide background theme (see the fai-theme-* rules
       further down) re-theme headings just by overriding this one custom
       property, with no extra selectors needed. */
    --fai-slide-heading:    var(--fai-navy);

    /* "Chip" tokens — the translucent-blue badge look used by diagram
       steps, chart labels/tracks, table header cells, tree nodes, timeline
       labels, and auto-generated cards. Tuned for the ORIGINAL white card;
       a dark slide background theme overrides these three (see the
       fai-theme-* rules further down) so those components stay visibly a
       "chip" — not just plain unreadable dark-on-dark text — on any
       background, the same way --fai-slide-heading/-text/-text-muted
       already do for headings/paragraphs/lists. */
    --fai-chip-bg:     var(--fai-blue-light);
    --fai-chip-border: var(--fai-blue-border);
    --fai-chip-text:   var(--fai-navy);
}

#fortress-ai-wrap {
    max-width: 100%;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    color: var(--fai-text);
}

/* Explicit fullscreen sizing — without this, the element becoming the
   fullscreen element doesn't guarantee it visually fills the screen the
   way you'd expect; this makes sure it actually does. Targets the STAGE
   specifically (the slide + captions panel), not the whole plugin wrap —
   fullscreen should show the presentation, not the topic-generator and
   control-panel controls underneath it. */
#fortress-ai-stage:fullscreen,
#fortress-ai-stage:-webkit-full-screen {
    width: 100%;
    height: 100%;
    max-height: none;
    padding: 20px;
    box-sizing: border-box;
    border-radius: 0;
}

/* ---------------------------------------------------------
 * Stage / slide area — supports an optional full-bleed background image
 * (blue gradient overlay + frosted glass card on top) for a modern,
 * dynamic presentation look, or a plain white stage when none is set.
 * --------------------------------------------------------- */
#fortress-ai-stage {
    position: relative;
    width: 100%;
    height: 100vh;
    min-height: 560px;
    max-height: 920px;
    background: linear-gradient(135deg, #0b2545 0%, #143a7a 45%, #1d4ed8 70%, #0b2545 100%);
    background-size: 260% 260%;
    animation: fai-stage-gradient-drift 22s ease-in-out infinite;
    border-radius: 14px;
    overflow: hidden;
    box-sizing: border-box;
    color: var(--fai-text);
    display: flex;
    align-items: stretch;
    justify-content: flex-start;
    box-shadow: 0 1px 3px rgba(11, 37, 69, 0.06);
}

/* Below ~860px there isn't room for slide + panel side by side, so the
   caption panel drops underneath the slide instead — same "never on top
   of the slide" rule, just stacked instead of side-by-side. */
@media (max-width: 860px) {
    #fortress-ai-stage {
        flex-direction: column;
        height: auto;
        min-height: 0;
        max-height: none;
    }
}

/* ---------------------------------------------------------
 * Slide area — the slide now fills the entire width/height of its
 * side of the screen edge-to-edge, instead of floating as a smaller
 * white card inside a decorative background.
 * --------------------------------------------------------- */
.fortress-ai-slide-area {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
    height: 100%;
    display: flex;
}

@media (max-width: 860px) {
    .fortress-ai-slide-area {
        height: 62vh;
        min-height: 380px;
    }
}

@keyframes fai-stage-gradient-drift {
    0%   { background-position: 0% 30%; }
    50%  { background-position: 100% 70%; }
    100% { background-position: 0% 30%; }
}

/* Soft vignette for depth, sitting under the ambient blobs and the slide card. */
#fortress-ai-stage::before {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(120% 140% at 15% 10%, rgba(255, 255, 255, 0.08), transparent 60%);
    z-index: 0;
}

/* ---------------------------------------------------------
 * Ambient background motion — a few soft, slow-drifting blurred blobs
 * behind the slide content. Deliberately subtle: nothing that competes
 * for attention with the actual slide, just enough movement that the
 * stage doesn't feel like a static screenshot.
 * --------------------------------------------------------- */
.fortress-ai-ambient {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 0;
    border-radius: inherit;
}

.fortress-ai-ambient span {
    position: absolute;
    border-radius: 50%;
    filter: blur(46px);
    background: radial-gradient(circle, rgba(37, 99, 235, 0.30), rgba(37, 99, 235, 0) 70%);
}

.fortress-ai-ambient span:nth-child(1) {
    width: 240px;
    height: 240px;
    top: -70px;
    left: -50px;
    animation: fai-ambient-drift-1 24s ease-in-out infinite alternate;
}

.fortress-ai-ambient span:nth-child(2) {
    width: 280px;
    height: 280px;
    bottom: -90px;
    right: -70px;
    opacity: 0.7;
    animation: fai-ambient-drift-2 28s ease-in-out infinite alternate;
}

.fortress-ai-ambient span:nth-child(3) {
    width: 170px;
    height: 170px;
    top: 42%;
    left: 58%;
    opacity: 0.55;
    animation: fai-ambient-drift-3 32s ease-in-out infinite alternate;
}

@keyframes fai-ambient-drift-1 {
    0%   { transform: translate(0, 0); }
    100% { transform: translate(45px, 35px); }
}

@keyframes fai-ambient-drift-2 {
    0%   { transform: translate(0, 0); }
    100% { transform: translate(-35px, -45px); }
}

@keyframes fai-ambient-drift-3 {
    0%   { transform: translate(0, 0) scale(1); }
    100% { transform: translate(-28px, 22px) scale(1.18); }
}

/* ---------------------------------------------------------
 * Stage-wide network layer — unlike the slide-scoped AI-network
 * decoration (only on regular content slides, confined to slide
 * corners), this spans the WHOLE stage and is always present, so
 * something reads as continuously "running" even on a title slide or
 * during the cover screen, not just during specific answers. Kept
 * genuinely subtle — ambient texture behind everything else, never
 * competing with the slide or captions for attention.
 * --------------------------------------------------------- */
.fortress-ai-stage-network {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
    border-radius: inherit;
    opacity: 0.55;
}

/* A brief, subtle nudge in the direction the slide itself is moving —
   ties the ambient layer to the deck's own transition instead of it
   being an unrelated effect. */
.fortress-ai-stage-network.is-drifting-forward {
    animation: fai-stage-network-drift-forward 0.5s ease-out both;
}
.fortress-ai-stage-network.is-drifting-backward {
    animation: fai-stage-network-drift-backward 0.5s ease-out both;
}

@keyframes fai-stage-network-drift-forward {
    0%   { transform: translateX(0); }
    30%  { transform: translateX(-14px); }
    100% { transform: translateX(0); }
}

@keyframes fai-stage-network-drift-backward {
    0%   { transform: translateX(0); }
    30%  { transform: translateX(14px); }
    100% { transform: translateX(0); }
}

.fai-stage-node {
    position: absolute;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--fai-blue-mid);
    box-shadow: 0 0 10px 2px rgba(96, 165, 250, 0.6);
    animation: fai-const-node-pulse 3.4s ease-in-out infinite;
}

.fai-stage-node-1 { top: 18%; left: 12%; animation-delay: 0s; }
.fai-stage-node-2 { top: 62%; left: 30%; animation-delay: 0.9s; background: var(--fai-yellow); box-shadow: 0 0 10px 2px rgba(240, 180, 41, 0.55); }
.fai-stage-node-3 { top: 30%; left: 68%; animation-delay: 1.8s; }
.fai-stage-node-4 { top: 78%; left: 82%; animation-delay: 2.6s; background: var(--fai-yellow); box-shadow: 0 0 10px 2px rgba(240, 180, 41, 0.55); }

.fai-stage-line {
    position: absolute;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(96, 165, 250, 0.4), transparent);
    transform-origin: left center;
    animation: fai-const-line-pulse 6s ease-in-out infinite;
}

.fai-stage-line-1 { top: 24%; left: 8%; width: 30%; animation-delay: 0.3s; }
.fai-stage-line-2 { top: 68%; left: 55%; width: 24%; animation-delay: 2.4s; }

/* .fortress-ai-slide-card is the same rule set, addressable by class
   instead of id — reused by the Presentation Editor's own slide stage
   (#fortress-ai-editor-slide-card) so "how it looks while editing" is
   pixel-identical to the real audience-facing card, not a lookalike. */
#fortress-ai-slide-card,
.fortress-ai-slide-card {
    position: relative;
    z-index: 1;
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    overflow-x: hidden;
    background: var(--fai-white);
    padding: 56px 64px;
    box-sizing: border-box;
}

@media (max-width: 640px) {
    #fortress-ai-slide-card,
    .fortress-ai-slide-card {
        padding: 32px 24px;
    }
}

/* ---------------------------------------------------------
 * Slide background themes — picked from the Presentation Editor's
 * "Slide background" swatches (js/editor.js), stored as a hidden
 * ::theme:name:: marker line in the slide's raw text (stripped before
 * rendering — see markdownToHtml() in slide-render.js) and applied here
 * as a class on the card itself, set by JS alongside the existing
 * fai-layout-* class. Only the background + the three --fai-slide-*
 * text-color variables change per theme — every heading/body/list/table/
 * tree/etc. rule elsewhere in this file already reads those variables,
 * so one class swap re-themes the whole slide with nothing duplicated.
 * "Classic White" (the original, unthemed look) is the default — no
 * class needed for it.
 * --------------------------------------------------------- */
/* Dark themes also override the three --fai-chip-* tokens (see :root) to a
   translucent WHITE-based tint instead of the default translucent-BLUE-on-
   navy-text one — otherwise diagram steps/chart labels/table headers/tree
   nodes/timeline labels would stay dark navy text on a dark background and
   effectively disappear. --fai-chip-text intentionally reuses whatever
   --fai-slide-heading resolves to in the same rule, so there's only ever
   one near-white value to pick per theme, not two. */
#fortress-ai-slide-card.fai-theme-midnight {
    background: linear-gradient(135deg, #0b1224, #1c2c4d);
    --fai-slide-heading: #f5f8ff;
    --fai-slide-text: #dbe4f3;
    --fai-slide-text-muted: #9fb0cc;
    --fai-chip-bg: rgba(255, 255, 255, 0.10);
    --fai-chip-border: rgba(255, 255, 255, 0.24);
    --fai-chip-text: var(--fai-slide-heading);
}
#fortress-ai-slide-card.fai-theme-ocean {
    background: linear-gradient(135deg, #063a4a, #0f7590);
    --fai-slide-heading: #f2fbff;
    --fai-slide-text: #dff3fa;
    --fai-slide-text-muted: #a9d6e6;
    --fai-chip-bg: rgba(255, 255, 255, 0.10);
    --fai-chip-border: rgba(255, 255, 255, 0.24);
    --fai-chip-text: var(--fai-slide-heading);
}
#fortress-ai-slide-card.fai-theme-forest {
    background: linear-gradient(135deg, #0e2e1f, #1f5c3d);
    --fai-slide-heading: #f3fff6;
    --fai-slide-text: #dcf0e2;
    --fai-slide-text-muted: #a7cdb3;
    --fai-chip-bg: rgba(255, 255, 255, 0.10);
    --fai-chip-border: rgba(255, 255, 255, 0.24);
    --fai-chip-text: var(--fai-slide-heading);
}
#fortress-ai-slide-card.fai-theme-sunset {
    background: linear-gradient(135deg, #5a1f3d, #d9642c);
    --fai-slide-heading: #fff7ee;
    --fai-slide-text: #ffe9d9;
    --fai-slide-text-muted: #f0bd97;
    --fai-chip-bg: rgba(255, 255, 255, 0.14);
    --fai-chip-border: rgba(255, 255, 255, 0.28);
    --fai-chip-text: var(--fai-slide-heading);
}
#fortress-ai-slide-card.fai-theme-plum {
    background: linear-gradient(135deg, #2a103f, #6f2f90);
    --fai-slide-heading: #faf3ff;
    --fai-slide-text: #eaddf5;
    --fai-slide-text-muted: #c8aad9;
    --fai-chip-bg: rgba(255, 255, 255, 0.12);
    --fai-chip-border: rgba(255, 255, 255, 0.26);
    --fai-chip-text: var(--fai-slide-heading);
}
#fortress-ai-slide-card.fai-theme-slate {
    background: linear-gradient(135deg, #2b313d, #4a5568);
    --fai-slide-heading: #f7f9fb;
    --fai-slide-text: #dfe4ea;
    --fai-slide-text-muted: #a7afbc;
    --fai-chip-bg: rgba(255, 255, 255, 0.10);
    --fai-chip-border: rgba(255, 255, 255, 0.24);
    --fai-chip-text: var(--fai-slide-heading);
}
#fortress-ai-slide-card.fai-theme-cream {
    background: linear-gradient(135deg, #fdf8ef, #f3e9d2);
    --fai-slide-heading: #0b2545;
    --fai-slide-text: #3a3226;
    --fai-slide-text-muted: #6b6350;
    /* Light theme like the default white — the original translucent-blue
       chip tokens already read fine here, no override needed. */
}
#fortress-ai-slide-card.fai-theme-rose {
    background: linear-gradient(135deg, #4a1030, #b23a5e);
    --fai-slide-heading: #fff5f8;
    --fai-slide-text: #ffe3ec;
    --fai-slide-text-muted: #e9a8bf;
    --fai-chip-bg: rgba(255, 255, 255, 0.13);
    --fai-chip-border: rgba(255, 255, 255, 0.27);
    --fai-chip-text: var(--fai-slide-heading);
}
#fortress-ai-slide-card.fai-theme-amber {
    background: linear-gradient(135deg, #3d2b06, #a6720f);
    --fai-slide-heading: #fff8e6;
    --fai-slide-text: #ffe9bd;
    --fai-slide-text-muted: #d9b475;
    --fai-chip-bg: rgba(255, 255, 255, 0.14);
    --fai-chip-border: rgba(255, 255, 255, 0.28);
    --fai-chip-text: var(--fai-slide-heading);
}
#fortress-ai-slide-card.fai-theme-teal {
    background: linear-gradient(135deg, #063330, #0f8f7f);
    --fai-slide-heading: #eefffb;
    --fai-slide-text: #d7f5ef;
    --fai-slide-text-muted: #9fd6cc;
    --fai-chip-bg: rgba(255, 255, 255, 0.10);
    --fai-chip-border: rgba(255, 255, 255, 0.24);
    --fai-chip-text: var(--fai-slide-heading);
}
#fortress-ai-slide-card.fai-theme-indigo {
    background: linear-gradient(135deg, #1c1440, #4338ca);
    --fai-slide-heading: #f5f4ff;
    --fai-slide-text: #e3e0fa;
    --fai-slide-text-muted: #b3aee0;
    --fai-chip-bg: rgba(255, 255, 255, 0.12);
    --fai-chip-border: rgba(255, 255, 255, 0.26);
    --fai-chip-text: var(--fai-slide-heading);
}
#fortress-ai-slide-card.fai-theme-charcoal {
    background: linear-gradient(135deg, #14161a, #33383f);
    --fai-slide-heading: #f7f8f9;
    --fai-slide-text: #dfe2e6;
    --fai-slide-text-muted: #9ba1a9;
    --fai-chip-bg: rgba(255, 255, 255, 0.10);
    --fai-chip-border: rgba(255, 255, 255, 0.22);
    --fai-chip-text: var(--fai-slide-heading);
}
#fortress-ai-slide-card.fai-theme-mint {
    background: linear-gradient(135deg, #eafcf3, #cdf0dd);
    --fai-slide-heading: #0b2545;
    --fai-slide-text: #234a38;
    --fai-slide-text-muted: #5f8a76;
    /* Light theme — default chip tokens already read fine here. */
}

/* A slide background photo (set via the editor's "Background Photo/GIF/
   Video" button, stored as a ::bg:url:: marker — same idea as the theme
   markers above) takes priority over any color theme when present: JS sets
   the actual background-image inline (the URL is dynamic), this class just
   supplies a permanent dark scrim underneath it (via the inline
   background-image's own leading gradient layer) plus light text, so text
   stays readable over any photo without the admin having to think about
   contrast themselves. When the background is a looping VIDEO instead of a
   still photo, JS applies fai-theme-bgvideo below instead — see that rule
   for why it needs a real element rather than just a CSS property.
   */
#fortress-ai-slide-card.fai-theme-bgimage {
    background-size: cover;
    background-position: center;
    --fai-slide-heading: #ffffff;
    --fai-slide-text: #f1f4f9;
    --fai-slide-text-muted: #cbd5e1;
    --fai-chip-bg: rgba(255, 255, 255, 0.14);
    --fai-chip-border: rgba(255, 255, 255, 0.28);
    --fai-chip-text: var(--fai-slide-heading);
}

/* A slide background VIDEO, set the same way as a background photo but
   detected by file extension (see applySlideBackground() in
   js/presentation.js and js/editor.js) — CSS background-image can't play
   video, so #fortress-ai-slide-bg-video is a real <video> element (see the
   markup in company-ai.php) that JS points at the uploaded file and shows
   here instead. It sits behind #fortress-ai-slide-content (z-index below
   it) with a dark scrim between the two (this rule's own ::before) for the
   same reason the photo version needs one — so text stays readable over
   any footage without anyone having to think about contrast. */

/* Up to 3 presentation-wide brand logos (see the "Presentation logos" row
   in the Presentation Editor, js/editor.js) — shown side by side in the
   same corner of the Title Slide and every content slide, both here (the
   real audience-facing page) and in the editor's own live preview, which
   reuses this exact rule via the shared #fortress-ai-slide-card markup.
   The container is populated with one <img> per configured logo by
   presentation.js/editor.js — 0 to 3 of them, never templated server-side
   since the count varies. Positioned absolute against the card itself
   (ignoring its padding, same as the background video below) so it sits
   flush in the true corner rather than lining up with body text. Sits
   above everything else (highest z-index on the card) so it stays visible
   over any background theme, photo, or video. display:none by default —
   js/presentation.js and js/editor.js only reveal it once at least one
   logo URL is set. Top-LEFT corner specifically (not top-right) — the
   fullscreen button (.fortress-ai-nav-fullscreen below) already lives at
   top-right, and a couple of the AI-network decoration accents
   (.fai-tech-ring etc.) sit there too, so the logo(s) would otherwise
   overlap them. Sized up from the original single-logo version after
   feedback that it read as too small. */
#fortress-ai-slide-logos {
    display: none;
    position: absolute;
    top: 18px;
    left: 22px;
    z-index: 3;
    pointer-events: none;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    max-width: calc(100% - 44px);
}

#fortress-ai-slide-logos img {
    display: block;
    max-height: 60px;
    max-width: 220px;
    object-fit: contain;
}

@media (max-width: 640px) {
    #fortress-ai-slide-logos {
        top: 10px;
        left: 14px;
        gap: 10px;
    }
    #fortress-ai-slide-logos img {
        max-height: 42px;
        max-width: 140px;
    }
}

#fortress-ai-slide-bg-video {
    display: none;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
    pointer-events: none;
}
#fortress-ai-slide-card.fai-theme-bgvideo #fortress-ai-slide-bg-video {
    display: block;
}
#fortress-ai-slide-card.fai-theme-bgvideo::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    background: rgba(10, 15, 28, 0.55);
    pointer-events: none;
}
#fortress-ai-slide-card.fai-theme-bgvideo {
    --fai-slide-heading: #ffffff;
    --fai-slide-text: #f1f4f9;
    --fai-slide-text-muted: #cbd5e1;
    --fai-chip-bg: rgba(255, 255, 255, 0.14);
    --fai-chip-border: rgba(255, 255, 255, 0.28);
    --fai-chip-text: var(--fai-slide-heading);
}

/* Slide-change animation: JS re-triggers fortress-ai-animate-in on every
   render, and briefly applies fortress-ai-fade-out just before swapping
   content, for a proper crossfade rather than an instant cut. Direction-
   aware: forward (next) pushes left, backward (previous) pushes right —
   gives the audience a spatial sense of where they are in the deck, not
   just polish. The fortress-ai-dir-backward modifier swaps which keyframes
   run without needing to duplicate the extensive child-stagger selectors
   below, which stay keyed to the unchanged base class names. */
@keyframes fortress-ai-slide-in-forward {
    0%   { opacity: 0; transform: translateX(26px) translateY(6px) scale(0.99); }
    100% { opacity: 1; transform: translateX(0) translateY(0) scale(1); }
}
@keyframes fortress-ai-slide-out-forward {
    0%   { opacity: 1; transform: translateX(0); }
    100% { opacity: 0; transform: translateX(-26px); }
}
@keyframes fortress-ai-slide-in-backward {
    0%   { opacity: 0; transform: translateX(-26px) translateY(6px) scale(0.99); }
    100% { opacity: 1; transform: translateX(0) translateY(0) scale(1); }
}
@keyframes fortress-ai-slide-out-backward {
    0%   { opacity: 1; transform: translateX(0); }
    100% { opacity: 0; transform: translateX(26px); }
}

#fortress-ai-slide-content.fortress-ai-animate-in {
    animation: fortress-ai-slide-in-forward 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
#fortress-ai-slide-content.fortress-ai-animate-in.fortress-ai-dir-backward {
    animation-name: fortress-ai-slide-in-backward;
}

#fortress-ai-slide-content.fortress-ai-fade-out {
    animation: fortress-ai-slide-out-forward 0.18s ease both;
}
#fortress-ai-slide-content.fortress-ai-fade-out.fortress-ai-dir-backward {
    animation-name: fortress-ai-slide-out-backward;
}

#fortress-ai-slide-content {
    position: relative;
    flex: 1;
    min-height: 0;
    /* Explicit so it always paints above a background video + its dark
       scrim (see #fortress-ai-slide-bg-video / .fai-theme-bgvideo::before
       above, at z-index 0/1) regardless of DOM order. */
    z-index: 2;
}

/* ---------------------------------------------------------
 * Previous / Next / Fullscreen controls — plain text pill buttons, no
 * icons. Auto-hiding: fade out after a few seconds of no mouse
 * movement/touch over the stage (JS toggles .is-visible), reappear
 * immediately on the next movement — keeps the slide as the visual
 * focus instead of permanently-visible chrome.
 * --------------------------------------------------------- */
.fortress-ai-nav-btn {
    position: absolute;
    z-index: 2;
    padding: 9px 18px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.35);
    background: rgba(11, 37, 69, 0.45);
    color: var(--fai-white);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.01em;
    cursor: pointer;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    box-shadow: 0 2px 8px rgba(11, 37, 69, 0.12);
    opacity: 0;
    pointer-events: none;
    transition: background 0.15s ease, color 0.15s ease, transform 0.15s ease, opacity 0.4s ease;
}

.fortress-ai-nav-btn.is-visible {
    opacity: 1;
    pointer-events: auto;
}

.fortress-ai-nav-btn:hover {
    background: var(--fai-blue-mid);
    color: var(--fai-white);
}

.fortress-ai-nav-prev,
.fortress-ai-nav-next {
    top: 50%;
    transform: translateY(-50%);
}
.fortress-ai-nav-prev:hover,
.fortress-ai-nav-next:hover {
    transform: translateY(-50%) scale(1.04);
}

.fortress-ai-nav-prev { left: 16px; }
.fortress-ai-nav-next { right: 16px; }

.fortress-ai-nav-fullscreen {
    top: 16px;
    right: 16px;
}
.fortress-ai-nav-fullscreen:hover {
    transform: scale(1.04);
}

#fortress-ai-slide-content h1 {
    font-size: 32px;
    font-weight: 700;
    margin: 0 0 20px;
    color: var(--fai-slide-heading);
    letter-spacing: -0.01em;
}

/* A short animated accent bar under every heading — the one consistent
   "branded template" touch across every slide type, drawn in on entrance
   (matches the heading's own stagger) then a continuous shimmer, plus a
   traveling bright pulse (same technique as the diagram connectors) for
   a "live circuit trace" read rather than a plain static gradient bar. */
#fortress-ai-slide-content h1::after {
    content: '';
    display: block;
    width: 72px;
    height: 6px;
    margin-top: 14px;
    border-radius: 3px;
    position: relative;
    overflow: hidden;
    background: linear-gradient(90deg, var(--fai-blue), var(--fai-yellow), var(--fai-blue));
    background-size: 200% 100%;
    box-shadow: 0 2px 10px rgba(240, 180, 41, 0.35);
    animation: fai-accent-shimmer 2.2s ease-in-out infinite;
}

@keyframes fai-accent-shimmer {
    0%, 100% { background-position: 0% 50%; }
    50%      { background-position: 100% 50%; }
}

/* ---------------------------------------------------------
 * Regular content slides: an AI-network backdrop in the corner — a
 * glowing grid, several independently-pulsing nodes, and (via the real
 * elements below, not just pseudo-elements — more animate independently
 * that way) multiple simultaneous radar pings and traveling data pulses.
 * Confined to a corner and masked to a soft fade so it never competes
 * with bullets/diagrams/charts for attention. Title/hero slides (the
 * "ending"/section-divider slides) keep the calmer round floating shapes
 * instead — untouched by this section.
 * --------------------------------------------------------- */
#fortress-ai-slide-content:not(.fai-layout-title)::before {
    content: '';
    position: absolute;
    top: -10px;
    right: -10px;
    width: 250px;
    height: 195px;
    background-image:
        linear-gradient(rgba(37, 99, 235, 0.38) 1px, transparent 1px),
        linear-gradient(90deg, rgba(37, 99, 235, 0.38) 1px, transparent 1px),
        radial-gradient(circle 3.5px at 26px 26px, var(--fai-yellow), transparent 100%),
        radial-gradient(circle 3.5px at 130px 78px, var(--fai-blue), transparent 100%),
        radial-gradient(circle 3.5px at 208px 130px, var(--fai-yellow), transparent 100%),
        radial-gradient(circle 3.5px at 78px 156px, var(--fai-blue), transparent 100%);
    background-size: 26px 26px, 26px 26px, 100% 100%, 100% 100%, 100% 100%, 100% 100%;
    -webkit-mask-image: radial-gradient(ellipse 235px 195px at top right, black 40%, transparent 80%);
    mask-image: radial-gradient(ellipse 235px 195px at top right, black 40%, transparent 80%);
    animation: fai-circuit-pulse 1.8s ease-in-out infinite;
    pointer-events: none;
    z-index: -1;
}

@keyframes fai-circuit-pulse {
    0%, 100% { opacity: 0.55; }
    50%      { opacity: 1; }
}

/* Title/hero/section-divider slides ("ending" slides) keep the original
   soft round floating blobs — a deliberately calmer, more premium moment
   rather than the busier circuit texture. */
#fortress-ai-slide-content.fai-layout-title::before {
    content: '';
    position: absolute;
    top: -80px;
    right: -80px;
    width: 320px;
    height: 320px;
    border-radius: 50%;
    background: radial-gradient(circle at 32% 32%, rgba(37, 99, 235, 0.26), rgba(240, 180, 41, 0.10) 55%, transparent 75%);
    animation: fai-slide-accent-float 7s ease-in-out infinite;
    pointer-events: none;
    z-index: -1;
}

#fortress-ai-slide-content.fai-layout-title::after {
    content: '';
    position: absolute;
    bottom: -60px;
    left: -60px;
    width: 240px;
    height: 240px;
    border-radius: 50%;
    background: radial-gradient(circle at 32% 32%, rgba(240, 180, 41, 0.16), rgba(11, 37, 69, 0.14) 55%, transparent 75%);
    animation: fai-slide-accent-float 9s ease-in-out infinite reverse;
    pointer-events: none;
    z-index: -1;
}

@keyframes fai-slide-accent-float {
    0%, 100%   { transform: translate(0, 0) scale(1); }
    50%        { transform: translate(-24px, 22px) scale(1.15); }
}

#fortress-ai-slide-content.fai-layout-title h1::after {
    margin-left: auto;
    margin-right: auto;
}

/* ---------------------------------------------------------
 * AI-network decoration — real elements (not pseudo-elements), so several
 * radar pings and traveling data nodes can animate independently and
 * simultaneously, the way an actual "AI thinking/processing" visual reads
 * (think a voice-assistant listening indicator or a live network diagram),
 * rather than one lone dot on a static grid. Positioned over the same
 * corner as the circuit-grid backdrop above. Automatically hidden on
 * title/hero slides, which keep the calmer round shapes instead.
 * --------------------------------------------------------- */
.fai-tech-decoration {
    position: absolute;
    width: 250px;
    height: 195px;
    pointer-events: none;
    z-index: -1;
    overflow: hidden;
}

.fai-tech-decoration-tr {
    top: -10px;
    right: -10px;
    -webkit-mask-image: radial-gradient(ellipse 235px 195px at top right, black 40%, transparent 80%);
    mask-image: radial-gradient(ellipse 235px 195px at top right, black 40%, transparent 80%);
}

.fai-tech-decoration-bl {
    bottom: -10px;
    left: -10px;
    width: 190px;
    height: 150px;
    -webkit-mask-image: radial-gradient(ellipse 180px 140px at bottom left, black 40%, transparent 80%);
    mask-image: radial-gradient(ellipse 180px 140px at bottom left, black 40%, transparent 80%);
}

#fortress-ai-slide-content.fai-layout-title ~ .fai-tech-decoration {
    display: none;
}

/* Radar pings — several rings expanding outward and fading, each on its
   own timer so they're never in sync, like an active signal broadcasting
   rather than one mechanical pulse. */
.fai-tech-ring {
    position: absolute;
    top: 20px;
    right: 20px;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    border: 1.5px solid var(--fai-blue);
    animation: fai-radar-ping 2.6s cubic-bezier(0.2, 0.6, 0.4, 1) infinite;
}
.fai-tech-ring-2 {
    top: 74px;
    right: 92px;
    border-color: var(--fai-yellow);
    animation-delay: 0.7s;
    animation-duration: 3.1s;
}
.fai-tech-ring-3 {
    top: 118px;
    right: 30px;
    width: 36px;
    height: 36px;
    animation-delay: 1.5s;
    animation-duration: 2.3s;
}

@keyframes fai-radar-ping {
    0%   { transform: scale(0.35); opacity: 0.85; }
    100% { transform: scale(1.7);  opacity: 0; }
}

/* Network nodes — small glowing points, each pulsing at its own pace, like
   independent points in an active neural net rather than a static grid. */
.fai-tech-node {
    position: absolute;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--fai-yellow);
    box-shadow: 0 0 8px 2px rgba(240, 180, 41, 0.8);
    animation: fai-node-pulse 1.6s ease-in-out infinite;
}
.fai-tech-node-1 { top: 30px;  right: 130px; animation-delay: 0s; }
.fai-tech-node-2 {
    top: 95px; right: 50px;
    background: var(--fai-blue-mid);
    box-shadow: 0 0 8px 2px rgba(96, 165, 250, 0.8);
    animation-delay: 0.4s;
}
.fai-tech-node-3 { top: 150px; right: 165px; animation-delay: 0.9s; }

@keyframes fai-node-pulse {
    0%, 100% { transform: scale(0.8); opacity: 0.6; }
    50%      { transform: scale(1.5); opacity: 1; }
}

/* Traveling data pulses — small bright dots moving along two different
   paths (one mostly horizontal, one mostly vertical) so motion reads from
   more than one direction at once, like data actually moving through a
   live network rather than a single repeating loop. */
.fai-tech-pulse {
    position: absolute;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--fai-white);
    box-shadow: 0 0 10px 3px rgba(255, 255, 255, 0.9);
}
.fai-tech-pulse-h {
    top: 26px;
    right: 20px;
    animation: fai-pulse-travel-h 3.2s linear infinite;
}
.fai-tech-pulse-v {
    top: 20px;
    right: 96px;
    background: var(--fai-yellow);
    box-shadow: 0 0 10px 3px rgba(240, 180, 41, 0.9);
    animation: fai-pulse-travel-v 3.8s linear infinite 0.6s;
}

@keyframes fai-pulse-travel-h {
    0%   { transform: translate(0, 0);       opacity: 0; }
    8%   { opacity: 1; }
    42%  { opacity: 1; }
    50%  { transform: translate(-210px, 0);  opacity: 0; }
    100% { transform: translate(-210px, 0);  opacity: 0; }
}

@keyframes fai-pulse-travel-v {
    0%   { transform: translate(0, 0);       opacity: 0; }
    8%   { opacity: 1; }
    42%  { opacity: 1; }
    50%  { transform: translate(0, 150px);   opacity: 0; }
    100% { transform: translate(0, 150px);   opacity: 0; }
}

#fortress-ai-slide-content h2 {
    font-size: 22px;
    font-weight: 600;
    margin: 0 0 16px;
    color: var(--fai-blue-mid);
}

#fortress-ai-slide-content p {
    font-size: 17px;
    line-height: 1.65;
    margin: 0 0 14px;
    color: var(--fai-slide-text);
    opacity: 0;
    animation: fai-diagram-step-in 0.45s ease both;
}

#fortress-ai-slide-content ul {
    font-size: 17px;
    line-height: 1.8;
    margin: 0 0 14px;
    padding-left: 24px;
    color: var(--fai-slide-text);
}

#fortress-ai-slide-content ul li {
    opacity: 0;
    animation: fai-diagram-step-in 0.45s ease both;
}

#fortress-ai-slide-content ul li::marker {
    color: var(--fai-blue-mid);
}

/* Staggered "PowerPoint-style" entrance: each element within the slide
   fades/slides in slightly after the one before it, instead of the whole
   slide appearing as one flat block. */
#fortress-ai-slide-content.fortress-ai-animate-in > * {
    animation: fortress-ai-element-in 0.45s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
#fortress-ai-slide-content.fortress-ai-animate-in > *:nth-child(1) { animation-delay: 0.02s; }
#fortress-ai-slide-content.fortress-ai-animate-in > *:nth-child(2) { animation-delay: 0.10s; }
#fortress-ai-slide-content.fortress-ai-animate-in > *:nth-child(3) { animation-delay: 0.18s; }
#fortress-ai-slide-content.fortress-ai-animate-in > *:nth-child(4) { animation-delay: 0.26s; }
#fortress-ai-slide-content.fortress-ai-animate-in > *:nth-child(5) { animation-delay: 0.34s; }
#fortress-ai-slide-content.fortress-ai-animate-in > *:nth-child(n+6) { animation-delay: 0.40s; }
#fortress-ai-slide-content.fortress-ai-animate-in ul.fortress-ai-animate-in-list li,
#fortress-ai-slide-content.fortress-ai-animate-in > ul > li {
    animation: fortress-ai-element-in 0.4s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
#fortress-ai-slide-content.fortress-ai-animate-in > ul > li:nth-child(1) { animation-delay: 0.16s; }
#fortress-ai-slide-content.fortress-ai-animate-in > ul > li:nth-child(2) { animation-delay: 0.22s; }
#fortress-ai-slide-content.fortress-ai-animate-in > ul > li:nth-child(3) { animation-delay: 0.28s; }
#fortress-ai-slide-content.fortress-ai-animate-in > ul > li:nth-child(4) { animation-delay: 0.34s; }
#fortress-ai-slide-content.fortress-ai-animate-in > ul > li:nth-child(5) { animation-delay: 0.40s; }
#fortress-ai-slide-content.fortress-ai-animate-in > ul > li:nth-child(n+6) { animation-delay: 0.46s; }

@keyframes fortress-ai-element-in {
    0%   { opacity: 0; transform: translateY(10px); }
    100% { opacity: 1; transform: translateY(0); }
}

/* ---------------------------------------------------------
 * Layout variants — PowerPoint-style visual variety, chosen per slide with
 * a ::title:: or ::split:: directive on the slide's first line (plain
 * stacked layout, the previous-only behavior, is the default).
 * --------------------------------------------------------- */

/* Title layout: a centered, large focal slide — section dividers, openers. */
#fortress-ai-slide-content.fai-layout-title {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    height: 100%;
}
#fortress-ai-slide-content.fai-layout-title h1 {
    font-size: 44px;
    margin-bottom: 14px;
    background: linear-gradient(100deg, var(--fai-navy) 15%, var(--fai-blue) 40%, var(--fai-yellow) 55%, var(--fai-blue) 70%, var(--fai-navy) 85%);
    background-size: 250% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: var(--fai-navy); /* fallback if background-clip: text isn't supported */
    animation: fai-title-gradient-shift 4s ease-in-out infinite;
}

@keyframes fai-title-gradient-shift {
    0%, 100% { background-position: 0% 50%; }
    50%      { background-position: 100% 50%; }
}
#fortress-ai-slide-content.fai-layout-title p {
    font-size: 19px;
    max-width: 560px;
    color: var(--fai-slide-text-muted);
}

/* Split layout: bullet list flows into two columns for a denser, more
   "deck-like" look on slides with several short points. */
#fortress-ai-slide-content.fai-layout-split ul {
    columns: 2;
    column-gap: 32px;
}
#fortress-ai-slide-content.fai-layout-split ul li {
    break-inside: avoid;
    margin-bottom: 10px;
}

/* ---------------------------------------------------------
 * Diagrams — a connected flow of steps. Drawn automatically from a plain
 * bullet list that reads like a sequence ("Step 1", "First,", "Then,"...),
 * or written explicitly with ::diagram:: ... ::enddiagram::. Each box and
 * connector animates in with a stagger (delay set inline per element by
 * the renderer), then settles into a slow idle drift so the deck doesn't
 * go completely static once the entrance finishes.
 * --------------------------------------------------------- */
.fai-diagram {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 18px 0;
}

.fai-diagram-step {
    position: relative;
    background: var(--fai-chip-bg);
    border: 1px solid var(--fai-chip-border);
    border-radius: 10px;
    padding: 12px 18px 12px 40px;
    font-size: 15px;
    font-weight: 600;
    color: var(--fai-chip-text);
    white-space: normal;
    overflow-wrap: break-word;
    word-break: break-word;
    max-width: 260px;
    opacity: 0;
    transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease, opacity 0.3s ease, filter 0.3s ease;
    animation:
        fai-diagram-step-in 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) both,
        fai-diagram-drift 4s ease-in-out 0.6s infinite,
        fai-diagram-glow 3s ease-in-out 0.6s infinite;
}

/* Synchronized narration — highlights the element currently being spoken
   about, so the audience can visually follow along in real time as NOVA
   talks through a diagram/tree/timeline. */
.fai-diagram-step.is-narrating {
    border-color: var(--fai-yellow);
    box-shadow: 0 0 0 3px rgba(240, 180, 41, 0.3), 0 4px 16px rgba(240, 180, 41, 0.25);
    transform: scale(1.045);
}

.fai-diagram-step::before {
    content: attr(data-num);
    position: absolute;
    left: 8px;
    top: 50%;
    transform: translateY(-50%);
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--fai-blue-mid), var(--fai-navy));
    color: var(--fai-white);
    font-size: 11px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ---------------------------------------------------------
 * Auto/manual bar chart — animated, dependency-free. Bars grow in on
 * entrance (width set by JS via requestAnimationFrame, transitioned by
 * CSS) and keep a slow shimmer afterward so it reads as live, not static.
 * --------------------------------------------------------- */
.fai-chart {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin: 16px 0;
}

.fai-chart-row {
    display: grid;
    grid-template-columns: minmax(90px, 30%) 1fr auto;
    align-items: center;
    gap: 12px;
    opacity: 0;
    animation: fai-diagram-step-in 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

.fai-chart-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--fai-chip-text);
    overflow-wrap: break-word;
    word-break: break-word;
}

.fai-chart-track {
    position: relative;
    height: 12px;
    border-radius: 999px;
    background: var(--fai-chip-bg);
    border: 1px solid var(--fai-chip-border);
    overflow: hidden;
}

.fai-chart-bar {
    position: absolute;
    inset: 0 auto 0 0;
    width: 0%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--fai-blue-mid), var(--fai-blue));
    transition: width 0.9s cubic-bezier(0.22, 0.61, 0.36, 1);
    overflow: hidden;
}

/* A soft light sweep travels across each filled bar — the chart's
   equivalent of the diagram connector's traveling pulse. */
.fai-chart-bar::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    width: 40%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.45), transparent);
    animation: fai-chart-sweep 2.6s ease-in-out 1s infinite;
}

@keyframes fai-chart-sweep {
    0%   { transform: translateX(-120%); }
    100% { transform: translateX(280%); }
}

.fai-chart-value {
    font-size: 13px;
    font-weight: 700;
    color: var(--fai-blue-mid);
    min-width: 40px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------
 * Comparison table — for "compare X and Y" style answers (documents,
 * options, policies). Rows stagger in like the diagram/chart do, for a
 * consistent feel across all three visual types.
 * --------------------------------------------------------- */
.fai-compare-table {
    width: 100%;
    margin: 16px 0;
    border-collapse: collapse;
    font-size: 13px;
}

.fai-compare-table th {
    text-align: left;
    padding: 9px 12px;
    background: var(--fai-chip-bg);
    color: var(--fai-chip-text);
    font-weight: 700;
    border-bottom: 2px solid var(--fai-chip-border);
}

.fai-compare-table th:first-child {
    border-top-left-radius: 8px;
}
.fai-compare-table th:last-child {
    border-top-right-radius: 8px;
}

.fai-compare-table td {
    padding: 9px 12px;
    border-bottom: 1px solid var(--fai-chip-border);
    color: var(--fai-slide-text);
}

.fai-compare-table tbody tr {
    opacity: 0;
    animation: fai-diagram-step-in 0.4s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

.fai-compare-table tbody tr:nth-child(odd) {
    background: rgba(37, 99, 235, 0.04);
}

.fai-diagram-arrow {
    width: 22px;
    height: 2px;
    background: var(--fai-chip-border);
    position: relative;
    flex-shrink: 0;
    opacity: 0;
    transform-origin: left center;
    animation: fai-diagram-arrow-in 0.35s ease both;
}
.fai-diagram-arrow::after {
    content: '';
    position: absolute;
    right: -1px;
    top: 50%;
    width: 8px;
    height: 8px;
    border-right: 2px solid var(--fai-blue-mid);
    border-bottom: 2px solid var(--fai-blue-mid);
    transform: translateY(-50%) rotate(-45deg);
}

/* A small glowing dot that keeps traveling left-to-right along the
   connector once it's drawn in — a live "packet moving through the
   pipeline" cue instead of a connector that goes static after entrance. */
.fai-diagram-arrow::before {
    content: '';
    position: absolute;
    left: -3px;
    top: 50%;
    width: 6px;
    height: 6px;
    margin-top: -3px;
    border-radius: 50%;
    background: var(--fai-blue-mid);
    box-shadow: 0 0 8px 2px rgba(37, 99, 235, 0.75);
    animation: fai-diagram-flow 1.4s linear var(--fai-pulse-delay, 0s) infinite;
    animation-delay: calc(0.35s + var(--fai-pulse-delay, 0s));
}

@keyframes fai-diagram-step-in {
    0%   { opacity: 0; transform: translateY(10px) scale(0.94); }
    100% { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes fai-diagram-arrow-in {
    0%   { opacity: 1; transform: scaleX(0); }
    100% { opacity: 1; transform: scaleX(1); }
}

@keyframes fai-diagram-flow {
    0%   { left: -3px; opacity: 0; }
    12%  { opacity: 1; }
    88%  { opacity: 1; }
    100% { left: 19px; opacity: 0; }
}

@keyframes fai-diagram-drift {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-3px); }
}

@keyframes fai-diagram-glow {
    0%, 100% { box-shadow: 0 0 0 0 rgba(37, 99, 235, 0); }
    50%      { box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.10); }
}

/* Numbered card grid — auto-drawn from a short flat bullet list (a handful
   of parallel points, not a sequence). Number badge is CSS-generated
   content, not real text, so it stays out of plain-text extraction. */
.fai-auto-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 14px;
    margin: 18px 0;
}

.fai-auto-card {
    position: relative;
    background: var(--fai-chip-bg);
    border: 1px solid var(--fai-chip-border);
    border-radius: 12px;
    padding: 16px 16px 16px 50px;
    opacity: 0;
    animation:
        fai-diagram-step-in 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) both,
        fai-diagram-drift 4.5s ease-in-out 0.6s infinite,
        fai-diagram-glow 3.4s ease-in-out 0.6s infinite;
}

.fai-auto-card::before {
    content: attr(data-num);
    position: absolute;
    left: 13px;
    top: 15px;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--fai-blue-mid), var(--fai-navy));
    color: var(--fai-white);
    font-size: 12px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}

#fortress-ai-slide-content .fai-auto-card p {
    margin: 0;
    font-size: 15px;
    line-height: 1.5;
    color: var(--fai-slide-text);
}

/* Fallback for longer/mixed lists — still animated, just a plain list
   rather than a diagram or card grid. */
#fortress-ai-slide-content .fai-auto-list {
    list-style: none;
    margin: 0 0 14px;
    padding: 0;
}

#fortress-ai-slide-content .fai-auto-list li {
    position: relative;
    padding-left: 24px;
    margin-bottom: 10px;
    font-size: 16px;
    line-height: 1.55;
    color: var(--fai-slide-text);
    opacity: 0;
    animation:
        fai-diagram-step-in 0.45s ease both,
        fai-diagram-drift 4.2s ease-in-out 0.6s infinite;
}

#fortress-ai-slide-content .fai-auto-list li::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 8px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--fai-blue-mid);
}

/* ---------------------------------------------------------
 * Tree — org chart / decision tree, drawn from indentation-based text.
 * Classic CSS-only connector-line technique on nested <ul>/<li>: each
 * child gets a vertical line up to its parent's row and a horizontal
 * line into its own box, so the whole thing reads as a real hierarchy
 * diagram rather than an indented list.
 * --------------------------------------------------------- */
/* Vertical indented tree — connector lines still show the hierarchy
   clearly (a line down from each parent, a stub into each child), but
   text wraps naturally within the slide's width instead of spreading
   siblings out horizontally. That horizontal org-chart layout looked
   right for short labels ("CTO", "CFO") but forced horizontal scrolling
   the moment a label was an actual sentence ("RAG over uploaded PDFs and
   docs") — this fixes that for any content, not just short ones. */
.fai-tree {
    padding: 6px 4px;
    overflow: visible;
}

.fai-tree > ul {
    padding-left: 0;
    border-left: none;
}

.fai-tree ul {
    list-style: none;
    margin: 4px 0 0 6px;
    padding-left: 16px;
    border-left: 2px solid var(--fai-blue-border);
}

.fai-tree li {
    position: relative;
    padding: 5px 0;
    opacity: 0;
    animation: fai-diagram-step-in 0.4s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

/* Horizontal stub connecting the parent's vertical line into each child —
   not shown on the root, which has no incoming connector. */
.fai-tree li:not(.fai-tree-root)::before {
    content: '';
    position: absolute;
    top: 18px;
    left: -16px;
    width: 14px;
    height: 0;
    border-top: 2px solid var(--fai-blue-border);
}

.fai-tree-node {
    display: inline-block;
    padding: 7px 13px;
    border-radius: 8px;
    background: var(--fai-chip-bg);
    border: 1px solid var(--fai-chip-border);
    color: var(--fai-slide-text);
    font-size: 13px;
    font-weight: 600;
    line-height: 1.4;
    max-width: 100%;
    white-space: normal;
    transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease, opacity 0.3s ease, filter 0.3s ease;
}

.fai-tree-node.is-narrating {
    border-color: var(--fai-yellow);
    box-shadow: 0 0 0 3px rgba(240, 180, 41, 0.3), 0 4px 16px rgba(240, 180, 41, 0.25);
    transform: scale(1.06);
}

.fai-tree-root > .fai-tree-node {
    background: linear-gradient(135deg, var(--fai-blue-mid), var(--fai-navy));
    color: var(--fai-white);
    border-color: transparent;
}

.fai-tree-edge-label {
    display: block;
    font-size: 10px;
    font-weight: 700;
    color: var(--fai-chip-text);
    margin-bottom: 2px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

/* ---------------------------------------------------------
 * Timeline — a horizontal sequence of dated/staged points.
 * --------------------------------------------------------- */
.fai-timeline {
    display: flex;
    overflow-x: auto;
    padding: 16px 4px 4px;
    gap: 0;
}

.fai-timeline-item {
    flex: 1 0 140px;
    min-width: 140px;
    position: relative;
    padding-top: 22px;
    padding-right: 16px;
    opacity: 0;
    transition: opacity 0.3s ease, filter 0.3s ease;
    animation: fai-diagram-step-in 0.45s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

.fai-timeline-item::before {
    /* the connecting line running through the row of dots */
    content: '';
    position: absolute;
    top: 6px;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--fai-blue-border);
}

.fai-timeline-item:last-child::before {
    right: 50%;
}

.fai-timeline-item:first-child::before {
    left: 50%;
}

.fai-timeline-dot {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--fai-blue-mid), var(--fai-navy));
    border: 2px solid var(--fai-white);
    box-shadow: 0 0 0 1px var(--fai-blue-border);
    transition: transform 0.3s ease, box-shadow 0.3s ease, background 0.3s ease;
}

.fai-timeline-item.is-narrating .fai-timeline-dot {
    background: var(--fai-yellow);
    transform: translateX(-50%) scale(1.4);
    box-shadow: 0 0 0 4px rgba(240, 180, 41, 0.3), 0 0 12px 2px rgba(240, 180, 41, 0.5);
}

.fai-timeline-item.is-narrating .fai-timeline-label {
    color: var(--fai-blue);
}

/* Spotlight — while one element is being narrated, its siblings dim
   slightly rather than staying at full brightness, so the highlight reads
   as a deliberate spotlight moving through the visual, not just a color
   change on one box among visual equals. */
.fai-diagram-step.is-dimmed,
.fai-tree-node.is-dimmed,
.fai-timeline-item.is-dimmed {
    opacity: 0.4;
    filter: saturate(0.7);
}

.fai-timeline-label {
    text-align: center;
    font-size: 12px;
    font-weight: 700;
    color: var(--fai-chip-text);
    margin-bottom: 4px;
}

.fai-timeline-text {
    text-align: center;
    font-size: 12px;
    line-height: 1.4;
    color: var(--fai-slide-text-muted);
}

/* ---------------------------------------------------------
 * Cover screen
 * --------------------------------------------------------- */
.fortress-ai-cover {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
}

.fortress-ai-cover h1 {
    font-size: 38px;
    font-weight: 700;
    margin: 0 0 16px;
    color: var(--fai-slide-heading);
    letter-spacing: -0.01em;
}

.fortress-ai-cover p {
    font-size: 16px;
    color: var(--fai-slide-text-muted);
    max-width: 440px;
    line-height: 1.6;
}

#fortress-ai-counter {
    position: absolute;
    bottom: 14px;
    right: 20px;
    font-size: 13px;
    color: rgba(255, 255, 255, 0.85);
    z-index: 2;
}

/* ---------------------------------------------------------
 * Caption panel — where the assistant's words appear: a dedicated
 * column beside the slide (never on top of it). Karaoke-highlighted
 * word-by-word as it's spoken, same as before, just relocated.
 * Sits full-height on wide screens; drops to a bar under the slide
 * on narrow ones (see the media query on .fortress-ai-slide-area).
 * --------------------------------------------------------- */
.fortress-ai-caption-panel {
    position: relative;
    z-index: 1;
    flex: 0 0 380px;
    width: 380px;
    max-width: 38%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 48px 40px;
    box-sizing: border-box;
    color: var(--fai-white);
    overflow-y: auto;
    overflow-x: hidden;
}

/* A soft gradient seam instead of a hard border-left — fades in/out
   vertically rather than a flat solid line running the full height, so
   the slide and caption panel read as one continuous surface with a
   gentle seam, not two regions bolted together. */
.fortress-ai-caption-panel::before {
    content: '';
    position: absolute;
    top: 6%;
    bottom: 6%;
    left: 0;
    width: 1px;
    background: linear-gradient(180deg,
        transparent,
        rgba(255, 255, 255, 0.16) 25%,
        rgba(255, 255, 255, 0.16) 75%,
        transparent
    );
    pointer-events: none;
}

@media (max-width: 860px) {
    .fortress-ai-caption-panel {
        flex: 1 1 auto;
        width: 100%;
        max-width: none;
        height: auto;
        min-height: 200px;
        padding: 28px 24px;
    }
    .fortress-ai-caption-panel::before {
        top: 0;
        bottom: auto;
        left: 6%;
        right: 6%;
        width: auto;
        height: 1px;
        background: linear-gradient(90deg,
            transparent,
            rgba(255, 255, 255, 0.16) 25%,
            rgba(255, 255, 255, 0.16) 75%,
            transparent
        );
    }
}

.fortress-ai-caption-panel-label {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-align: center;
    color: rgba(255, 255, 255, 0.55);
    margin: 0 0 14px;
}

/* Compact state indicator (see js/presentation.js's refreshStageLabel())
   — deliberately understated for "Ready", the common resting state, so
   it doesn't read as an alarm or an active-processing indicator; the
   text itself already carries the meaning, this is just quiet supporting
   chrome right under the assistant's name. */
#fortress-ai-state-label {
    font-size: 13px;
    font-weight: 500;
    text-align: center;
    color: rgba(255, 255, 255, 0.65);
    margin: -6px 0 14px;
    letter-spacing: 0.02em;
    transition: color 0.25s ease;
}

.fortress-ai-caption-panel-idle p {
    margin: 0;
    text-align: center;
    font-size: 13px;
    line-height: 1.5;
    color: rgba(255, 255, 255, 0.45);
}

#fortress-ai-captions-text {
    display: none;
    margin: 0;
    text-align: center;
    font-size: 15px;
    font-weight: 500;
    line-height: 1.5;
    color: rgba(255, 255, 255, 0.85);
    max-width: 100%;
    overflow-wrap: break-word;
    word-break: break-word;
    hyphens: auto;
}

/* ---------------------------------------------------------
 * Live visual (diagram or chart) attached to a spoken answer or
 * narration — rendered ON THE SLIDE itself, not in the side captions
 * panel, since it's visual content about what's being discussed and the
 * audience is already looking at the slide. Sits at the bottom of the
 * slide card, in normal flow (gently pushes slide content up rather than
 * covering it), uses the same light theme as the rest of the slide. */
#fortress-ai-live-visual {
    display: none;
    flex: 0 0 auto;
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px dashed var(--fai-blue-border);
    max-height: 42%;
    overflow-y: auto;
}
#fortress-ai-live-visual.is-visible {
    display: block;
    animation: fai-live-visual-in 0.4s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

/* A live Q&A/vision-answer/diagram-refinement response — NOT a slide's own
   authored diagram narrated as part of regular presenting, which stays
   the plain inline panel above (js/presentation.js only adds this
   modifier for the transient-answer call sites, see applyLiveVisual()'s
   isAnswerOverlay param) — used to render inline alongside the current
   slide's own heading/text, sharing the same limited vertical space; on a
   slide that already had real content, the two visually collided. This
   modifier turns the SAME element into a full "blank page" takeover of
   the whole slide card instead — nothing else is visible underneath while
   she explains, so there's nothing left to clash with. Automatically
   cleared once she finishes speaking the answer (the onDone passed to
   speak()/speakWithSync() at each Q&A/vision/refine/repeat call site),
   handing the view back to the plain slide exactly as it was. Bleeds past
   the card's own padding (negative inset matching it, see
   #fortress-ai-slide-card above) for a genuine edge-to-edge takeover, with
   that same padding reapplied inside; background is inherited from the
   slide card so it still respects whatever color theme is active instead
   of assuming a plain white page. */
#fortress-ai-live-visual.is-visible.is-answer-overlay {
    display: flex;
    flex-direction: column;
    position: absolute;
    top: -56px;
    right: -64px;
    bottom: -56px;
    left: -64px;
    z-index: 10;
    margin-top: 0;
    padding: 56px 64px;
    border-top: none;
    max-height: none;
    background: inherit;
    animation: fai-live-visual-in 0.3s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

@media (max-width: 640px) {
    #fortress-ai-live-visual.is-visible.is-answer-overlay {
        top: -32px;
        right: -24px;
        bottom: -32px;
        left: -24px;
        padding: 32px 24px;
    }
}
#fortress-ai-live-visual-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fai-blue);
    margin: 0 0 10px;
}
@keyframes fai-live-visual-in {
    0%   { opacity: 0; transform: translateY(10px); }
    100% { opacity: 1; transform: translateY(0); }
}

/* JS toggles is-visible on the panel itself (#fortress-ai-captions) —
   swap the idle hint for the live captions rather than covering anything. */
#fortress-ai-captions.is-visible .fortress-ai-caption-panel-idle {
    display: none;
}

#fortress-ai-captions.is-visible #fortress-ai-captions-text {
    display: block;
}

.fortress-ai-caption-spoken {
    color: var(--fai-white);
    font-weight: 600;
}

.fortress-ai-caption-unspoken {
    color: rgba(255, 255, 255, 0.45);
}

#fortress-ai-progress-track {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 3px;
    background: rgba(37, 99, 235, 0.12);
    z-index: 2;
}

#fortress-ai-progress-bar {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, var(--fai-blue-mid), var(--fai-navy));
    transition: width 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ---------------------------------------------------------
 * Control panel
 * --------------------------------------------------------- */
#fortress-ai-panel {
    margin-top: 14px;
    display: flex;
    align-items: flex-start;
    gap: 16px;
    padding: 16px 18px;
    background: var(--fai-bg-elevated);
    border-radius: 10px;
    border: 1px solid var(--fai-blue-border);
}

/* ---------------------------------------------------------
 * AI Orb — a scattered constellation of small connected nodes, not one
 * solid shape, in the top-right corner of the slide. No face, no
 * icons/emoji/photos: a bespoke SVG mark, closer to how Siri/Gemini
 * Live/etc. represent an assistant than a literal avatar.
 * Three distinct states, driven by JS via class toggles:
 *   - idle/listening: each node pulses independently on its own offset
 *     timer, so it reads as organic rather than mechanical
 *   - thinking: the whole network of nodes pulls inward and releases,
 *     repeatedly — reads as active processing, converging on an answer
 *   - speaking: nodes and connecting lines pulse quickly in rhythm
 * --------------------------------------------------------- */
#fortress-ai-avatar {
    position: relative;
    width: 148px;
    height: 148px;
    flex-shrink: 0;
    margin: 0 auto 22px;
    filter: drop-shadow(0 4px 18px rgba(11, 37, 69, 0.35));
    animation: fai-orb-breathe 4s ease-in-out infinite;
}

/* Reacts to real microphone amplitude while listening (JS sets
   --mic-level, 0 to 1, from live Web Audio analysis) — not decorative,
   this is genuinely driven by actual room sound, so it's true whenever
   she's not currently speaking or thinking, not just a synthetic loop. */
#fortress-ai-avatar-listening-ring {
    position: absolute;
    inset: -18px;
    border-radius: 50%;
    border: 2px solid var(--fai-blue-mid);
    opacity: 0;
    transform: scale(1);
    transition: opacity 0.4s ease;
    pointer-events: none;
}

#fortress-ai-avatar.is-listening-live #fortress-ai-avatar-listening-ring {
    opacity: calc(var(--mic-level, 0) * 0.8);
    transform: scale(calc(1 + var(--mic-level, 0) * 0.22));
    transition: opacity 0.08s linear, transform 0.08s linear;
}

/* The ~6-second "Yes? I'm listening..." window right after the wake word
   is heard on its own (see setAwaitingCommand() in js/presentation.js) —
   a distinct green pulsing ring, deliberately different from every other
   orb state (blue breathing = idle/thinking/speaking, mic-reactive ring =
   ambient room volume) so it reads specifically as "your turn, say the
   command now." Needed because the plain status text for this same window
   lives in the control panel below the stage, which the Fullscreen API
   hides entirely once the stage goes fullscreen — this cue lives on the
   avatar inside the stage itself, so it's the one that still shows up
   there. */
#fortress-ai-avatar.is-awaiting-command #fortress-ai-avatar-listening-ring {
    border-color: #34d399;
    animation: fai-ring-awaiting-pulse 0.9s ease-in-out infinite;
}
#fortress-ai-avatar.is-awaiting-command {
    animation: fai-orb-breathe 0.9s ease-in-out infinite;
}

@keyframes fai-ring-awaiting-pulse {
    0%, 100% { opacity: 0.55; transform: scale(1); }
    50%      { opacity: 1;    transform: scale(1.2); }
}

/* Paused (Pause button, the "pause" voice command, or the Space keyboard
   shortcut in js/presentation.js) — the visual opposite of every "active"
   state above: everything just stops and dims, rather than another
   flavor of pulsing, so it reads unambiguously as "nothing is happening
   right now" instead of thinking/listening/speaking. Needed on the avatar
   itself for the same reason as is-awaiting-command above — the Pause
   button's own label lives in the control panel outside the fullscreened
   stage, invisible once you're actually presenting fullscreen. */
#fortress-ai-avatar.is-paused {
    animation: none;
    opacity: 0.45;
    filter: grayscale(0.7) drop-shadow(0 4px 18px rgba(11, 37, 69, 0.35));
}
#fortress-ai-avatar.is-paused .fai-const-node,
#fortress-ai-avatar.is-paused .fai-const-line,
#fortress-ai-avatar.is-paused .fai-constellation-nodes {
    animation: none;
}

.fai-constellation-nodes,
.fai-constellation-lines {
    transform-box: fill-box;
    transform-origin: center;
}

.fai-const-line {
    stroke: var(--fai-blue-mid);
    stroke-width: 0.6;
    opacity: 0.2;
    animation: fai-const-line-pulse 4s ease-in-out infinite;
}

.fai-const-line:nth-child(1) { animation-delay: 0s; }
.fai-const-line:nth-child(2) { animation-delay: 0.3s; }
.fai-const-line:nth-child(3) { animation-delay: 0.6s; }
.fai-const-line:nth-child(4) { animation-delay: 0.9s; }
.fai-const-line:nth-child(5) { animation-delay: 1.2s; }
.fai-const-line:nth-child(6) { animation-delay: 1.5s; }
.fai-const-line:nth-child(7) { animation-delay: 1.8s; }
.fai-const-line:nth-child(8) { animation-delay: 2.1s; }
.fai-const-line:nth-child(9) { animation-delay: 2.4s; }

@keyframes fai-const-line-pulse {
    0%, 100% { opacity: 0.15; }
    50%      { opacity: 0.5; }
}

.fai-const-node {
    fill: var(--fai-blue-mid);
    opacity: 0.55;
    transform-box: fill-box;
    transform-origin: center;
    animation: fai-const-node-pulse 3.2s ease-in-out infinite;
}

.fai-const-node-1 { animation-delay: 0s; }
.fai-const-node-2 { animation-delay: 0.5s; }
.fai-const-node-3 { animation-delay: 1s; }
.fai-const-node-4 { animation-delay: 1.5s; }
.fai-const-node-5 { animation-delay: 2s; }
.fai-const-node-6 { animation-delay: 2.5s; }
.fai-const-node-7 { animation-delay: 0.25s; }

@keyframes fai-const-node-pulse {
    0%, 100% { transform: scale(0.85); opacity: 0.5; }
    50%      { transform: scale(1.3);  opacity: 1; }
}

/* The core stays the one stable anchor point everything else pulses
   around — no independent pulse animation of its own. */
.fai-const-core {
    fill: url(#fai-orb-grad);
    opacity: 1;
    animation: none;
}

@keyframes fai-orb-breathe {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.035); }
}

/* Thinking: the whole node network pulls inward and releases, repeatedly
   (a single group-level scale, rather than calculating each node's own
   path to center) — plus every node/line speeds up. Reads as active
   processing, converging toward an answer. */
#fortress-ai-avatar.is-thinking {
    animation: fai-orb-breathe 1.3s ease-in-out infinite;
}
#fortress-ai-avatar.is-thinking .fai-constellation-nodes {
    animation: fai-const-converge 1.1s ease-in-out infinite;
}
#fortress-ai-avatar.is-thinking .fai-const-node {
    animation-duration: 0.8s;
}
#fortress-ai-avatar.is-thinking .fai-const-line {
    animation-duration: 0.7s;
}

@keyframes fai-const-converge {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(0.8); }
}

/* Preparing to speak: text generation is done and voice audio is being
   fetched/synthesized — a distinct honest state between "Thinking" and
   "Speaking" so that TTS latency isn't misread as still-thinking latency.
   Visually a calmer, more settled version of is-thinking (no converging
   pull), easing toward the speaking pulse rather than repeating it. */
#fortress-ai-avatar.is-preparing-speech {
    animation: fai-orb-breathe 0.9s ease-in-out infinite;
}
#fortress-ai-avatar.is-preparing-speech .fai-const-node {
    animation-duration: 0.65s;
    opacity: 0.85;
}
#fortress-ai-avatar.is-preparing-speech .fai-const-line {
    animation-duration: 0.6s;
}

/* Speaking: nodes and connecting lines pulse quickly in rhythm — a
   clearer "actively talking" cue than a static glow. */
#fortress-ai-avatar.is-speaking {
    animation: fai-orb-breathe 1.1s ease-in-out infinite;
}
#fortress-ai-avatar.is-speaking .fai-const-node {
    animation-duration: 0.55s;
    opacity: 0.75;
}
#fortress-ai-avatar.is-speaking .fai-const-line {
    animation-duration: 0.5s;
    opacity: 0.4;
}

/* Uncertain/honest-uncertainty answers — deliberately irregular,
   slightly desynchronized flicker instead of the smooth speaking rhythm.
   Not alarming (no red, no fast strobing), just visibly "off" enough
   that honesty about not knowing something reads as part of her
   character, not just a sentence she happens to say. */
#fortress-ai-avatar.is-uncertain .fai-const-node {
    animation-name: fai-const-flicker;
    animation-duration: 0.9s;
    animation-timing-function: ease-in-out;
}
#fortress-ai-avatar.is-uncertain .fai-const-node-1 { animation-duration: 0.7s; }
#fortress-ai-avatar.is-uncertain .fai-const-node-3 { animation-duration: 1.1s; }
#fortress-ai-avatar.is-uncertain .fai-const-node-5 { animation-duration: 0.8s; }
#fortress-ai-avatar.is-uncertain .fai-const-node-7 { animation-duration: 1s; }
#fortress-ai-avatar.is-uncertain .fai-const-line {
    animation-duration: 1.4s;
    opacity: 0.25;
}

@keyframes fai-const-flicker {
    0%   { opacity: 0.4; transform: scale(0.9); }
    35%  { opacity: 0.85; transform: scale(1.1); }
    55%  { opacity: 0.5; transform: scale(0.95); }
    100% { opacity: 0.4; transform: scale(0.9); }
}

/* One-shot pulse when a diagram/chart/table/tree/timeline genuinely
   appears — a quick outward burst from the core, distinct from the
   looping idle/thinking/speaking animations, since this fires once per
   creation rather than continuously. */
#fortress-ai-avatar.is-creating .fai-const-core {
    animation: fai-const-burst 0.7s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
#fortress-ai-avatar.is-creating .fai-const-node {
    animation: fai-const-burst-outward 0.7s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
#fortress-ai-avatar.is-creating .fai-const-line {
    animation: fai-const-line-pulse 0.35s ease-out 2;
    opacity: 0.7;
}

@keyframes fai-const-burst {
    0%   { transform: scale(1); }
    40%  { transform: scale(1.35); }
    100% { transform: scale(1); }
}

@keyframes fai-const-burst-outward {
    0%   { transform: scale(1);   opacity: 0.6; }
    40%  { transform: scale(1.7); opacity: 1; }
    100% { transform: scale(1);   opacity: 0.6; }
}


#fortress-ai-mic {
    flex-shrink: 0;
    padding: 10px 18px;
    border-radius: 6px;
    border: 1px solid var(--fai-blue);
    background: var(--fai-white);
    color: var(--fai-blue);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.01em;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
    white-space: nowrap;
}

#fortress-ai-mic:hover {
    background: var(--fai-blue);
    color: var(--fai-white);
}

#fortress-ai-mic.is-active {
    background: var(--fai-blue);
    color: var(--fai-white);
    box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.15);
}

#fortress-ai-mic:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

#fortress-ai-panel-main {
    flex: 1;
    min-width: 0;
}

.fortress-ai-btn {
    display: inline-block;
    margin-bottom: 8px;
    margin-right: 8px;
    padding: 8px 16px;
    border-radius: 6px;
    border: 1px solid var(--fai-blue);
    background: var(--fai-white);
    color: var(--fai-blue);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}

.fortress-ai-btn:hover {
    background: var(--fai-blue);
    color: var(--fai-white);
}

.fortress-ai-btn.is-active {
    background: var(--fai-navy);
    border-color: var(--fai-navy);
    color: var(--fai-white);
}

.fortress-ai-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
    background: var(--fai-white);
    color: var(--fai-blue);
}

/* ---------------------------------------------------------
 * .fortress-ai-btn-secondary — the plain (non-primary) button variant,
 * used throughout this file. Generating/editing decks itself moved to the
 * dedicated Presentation Editor (css/editor.css, [fortress_ai_editor]) —
 * this stays here since .fortress-ai-btn/-secondary are shared, generic
 * button styles still used elsewhere on this (audience-facing) page.
 * --------------------------------------------------------- */
.fortress-ai-btn-secondary {
    margin: 0;
    white-space: nowrap;
}

/* A photo/GIF inserted into a slide via the Presentation Editor's
   "Insert Image" button — rendered inline by markdownToHtml() from the
   `![](url)` line it writes into the raw slide text. Capped rather than
   stretched full-bleed since this sits alongside normal text content on
   an otherwise NOVA-generated slide. */
.fortress-ai-slide-inline-image {
    display: block;
    max-width: 100%;
    max-height: 320px;
    margin: 14px auto;
    border-radius: 10px;
    object-fit: contain;
}

/* Left/Right placement — set via the small Left/Center/Right buttons next
   to each image thumbnail in the Presentation Editor (js/editor.js), never
   typed by hand. Floated so the slide's own text/bullets wrap around it
   instead of always stacking full-width above/below. */
.fortress-ai-slide-inline-image.fai-img-left,
.fortress-ai-slide-inline-image.fai-img-right {
    max-width: 42%;
    max-height: 260px;
    margin-top: 4px;
    margin-bottom: 14px;
}
.fortress-ai-slide-inline-image.fai-img-left {
    float: left;
    margin-left: 0;
    margin-right: 20px;
}
.fortress-ai-slide-inline-image.fai-img-right {
    float: right;
    margin-left: 20px;
    margin-right: 0;
}

/* ---------------------------------------------------------
 * Meeting Mode — structured summary after "End Meeting".
 * --------------------------------------------------------- */
#fortress-ai-meeting-results {
    max-height: 0;
    overflow: hidden;
    opacity: 0;
    margin-top: 0;
    transition: max-height 0.35s ease, opacity 0.3s ease, margin-top 0.35s ease;
}

#fortress-ai-meeting-results.is-visible {
    max-height: 1200px;
    opacity: 1;
    margin-top: 14px;
}

.fortress-ai-meeting-loading {
    padding: 16px 18px;
    border-radius: 10px;
    background: var(--fai-bg-elevated);
    border: 1px solid var(--fai-blue-border);
    color: var(--fai-text-muted);
    font-size: 13px;
}

.fortress-ai-meeting-card {
    padding: 20px 22px;
    border-radius: 12px;
    background: var(--fai-bg-elevated);
    border: 1px solid var(--fai-blue-border);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
}

.fortress-ai-meeting-header {
    font-size: 15px;
    font-weight: 700;
    color: var(--fai-heading);
    margin-bottom: 12px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--fai-blue-border);
}

.fortress-ai-meeting-summary {
    margin: 0 0 14px;
    font-size: 13px;
    line-height: 1.55;
    color: var(--fai-text);
}

.fortress-ai-meeting-block {
    margin-bottom: 14px;
    font-size: 13px;
}

.fortress-ai-meeting-block:last-child {
    margin-bottom: 0;
}

.fortress-ai-meeting-block strong {
    display: block;
    color: var(--fai-heading);
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-bottom: 6px;
}

.fortress-ai-meeting-block ul {
    margin: 0;
    padding-left: 18px;
}

.fortress-ai-meeting-block li {
    margin-bottom: 4px;
    color: var(--fai-text);
    line-height: 1.5;
}

#fortress-ai-status {
    font-size: 13px;
    color: var(--fai-blue-mid);
}


#fortress-ai-status-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 4px;
}

/* ---------------------------------------------------------
 * Suggested-question chips — quick, unobtrusive starting points.
 * --------------------------------------------------------- */
#fortress-ai-suggestions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 10px;
}

.fortress-ai-suggestion {
    padding: 6px 12px;
    border-radius: 999px;
    border: 1px solid var(--fai-blue-border);
    background: transparent;
    color: var(--fai-text-muted);
    font-size: 12px;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.fortress-ai-suggestion:hover {
    background: var(--fai-blue-light);
    color: var(--fai-blue-mid);
    border-color: var(--fai-blue-mid);
}

/* Talking indicator — plain bars, no icon glyphs */
.fortress-ai-waveform {
    display: none;
    align-items: center;
    gap: 3px;
    height: 16px;
}

.fortress-ai-waveform.is-talking {
    display: flex;
}

/* Driven by JS on each real word-boundary event during speech (see
   onboundary in speak()), not a generic infinite loop — genuinely
   reactive to actual speech timing rather than decorative motion that
   happens to be nearby. Browsers don't expose TTS audio to the Web Audio
   API for true amplitude analysis, so word timing is the closest honest
   signal available. */
.fortress-ai-waveform span {
    display: block;
    width: 3px;
    height: 100%;
    background: var(--fai-blue-mid);
    border-radius: 2px;
    transform: scaleY(0.25);
    transform-origin: center;
    transition: transform 0.15s ease-out;
}

/* ---------------------------------------------------------
 * Admin — Knowledge Documents panel
 * --------------------------------------------------------- */
.fortress-ai-admin-docs {
    margin-top: 20px;
    max-width: 900px;
}

.fortress-ai-admin-docs table.widefat {
    border: 1px solid var(--fai-blue-border);
}

.fortress-ai-admin-docs th {
    color: var(--fai-navy);
}

.fortress-ai-doc-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 4px;
    background: var(--fai-blue-light);
    color: var(--fai-blue);
    border: 1px solid var(--fai-blue-border);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.fortress-ai-doc-delete {
    color: #b42318;
}

