  @keyframes kadessaFloat{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-6px); } }
  @keyframes kadessaGlowPulse{
    0%,100%{ box-shadow:0 0 16px rgba(0,194,255,0.35), 0 0 0 rgba(0,194,255,0); }
    50%{ box-shadow:0 0 32px rgba(0,194,255,0.7), 0 0 50px rgba(0,115,230,0.3); }
  }
  @keyframes kadessaBreatheCore{
    0%,100%{ transform:scale(0.72); opacity:0.75; }
    50%{ transform:scale(1); opacity:1; }
  }

  #kadessa-launcher{
    position:fixed; right:22px; bottom:22px; z-index:99998;
    width:56px; height:56px; border-radius:50%;
    background:radial-gradient(circle at 35% 30%, #ffffff, #F2F8FC 70%);
    border:1px solid rgba(0,194,255,0.35); cursor:pointer;
    display:flex; align-items:center; justify-content:center;
    animation: kadessaFloat 4s ease-in-out infinite, kadessaGlowPulse 4s ease-in-out infinite;
    padding:0; overflow:hidden;
  }
  #kadessa-launcher:hover{ filter:brightness(1.04); }
  /* Small red dot shown when Kadessa has an unread proactive "eyes on it"
     message waiting -- e.g. flagged while the panel was closed -- so it's
     never silently lost, just deferred until the person opens the panel. */
  #kadessa-launcher.kadessa-has-proactive::after{
    content:''; position:absolute; top:2px; right:2px; width:12px; height:12px;
    border-radius:50%; background:#ff5a5a; border:2px solid var(--bg, #0A0F1E);
  }
  #kadessa-launcher-core{
    width:36px; height:36px; object-fit:contain; display:block;
    animation: kadessaBreatheCore 4s ease-in-out infinite;
    pointer-events:none;
  }

  #kadessa-panel{
    position:fixed; right:22px; bottom:90px; z-index:99999;
    width:340px; max-width:calc(100vw - 40px);
    height:460px; max-height:calc(100vh - 140px);
    background:var(--bg2, #0D1528);
    border-radius:var(--radius, 14px); overflow:hidden;
    box-shadow:0 12px 44px rgba(0,0,0,0.5), 0 0 0 1px rgba(0,194,255,0.15);
    display:none; flex-direction:column;
    font-family:'Inter', sans-serif;
    border:1px solid var(--border2, rgba(0,194,255,0.30));
  }
  #kadessa-panel.open{ display:flex; }
  #kadessa-head{
    background:linear-gradient(135deg, var(--cyan, #00C2FF), var(--purple, #0073E6));
    color:#fff; padding:12px 14px;
    display:flex; align-items:center; justify-content:space-between;
  }
  #kadessa-head strong{ font-size:14px; font-weight:700; }
  #kadessa-head span{ font-size:11px; opacity:0.9; display:block; }
  #kadessa-close{ background:none; border:none; color:#fff; font-size:18px; cursor:pointer; line-height:1; }
  #kadessa-thread{ flex:1; overflow-y:auto; padding:14px; display:flex; flex-direction:column; gap:10px; background:var(--bg, #0A0F1E); }
  .kadessa-msg{ max-width:82%; padding:9px 12px; border-radius:12px; font-size:13.5px; line-height:1.5; white-space:pre-wrap; }
  .kadessa-msg.user{ align-self:flex-end; background:var(--surface2, rgba(255,255,255,0.07)); color:var(--text, #E8F4FF); border-bottom-right-radius:3px; border:1px solid var(--border, rgba(0,194,255,0.10)); }
  .kadessa-msg.kadessa{ align-self:flex-start; background:rgba(0,194,255,0.10); color:var(--text, #E8F4FF); border-bottom-left-radius:3px; border:1px solid var(--border2, rgba(0,194,255,0.30)); }
  #kadessa-form{ display:flex; flex-direction:column; gap:6px; padding:10px; border-top:1px solid var(--border, rgba(0,194,255,0.10)); background:var(--bg2, #0D1528); }
  #kadessa-form-row{ display:flex; gap:6px; align-items:flex-end; }
  #kadessa-input{ flex:1; resize:none; background:var(--surface, rgba(255,255,255,0.04)); color:var(--text, #E8F4FF); border:1px solid var(--border, rgba(0,194,255,0.10)); border-radius:9px; padding:8px 10px; font-size:13.5px; font-family:inherit; max-height:70px; outline:none; }
  #kadessa-input:focus{ border-color:var(--cyan, #00C2FF); }
  #kadessa-input::placeholder{ color:var(--text3, #3A5A70); }
  #kadessa-send{ border:none; background:linear-gradient(135deg, var(--cyan, #00C2FF), var(--purple, #0073E6)); color:#fff; padding:0 14px; border-radius:9px; font-size:13px; font-weight:700; cursor:pointer; }
  #kadessa-send:disabled{ opacity:0.5; }
  #kadessa-attach-btn{ flex:0 0 auto; width:34px; height:34px; border-radius:9px; border:1px solid var(--border, rgba(0,194,255,0.10)); background:var(--surface, rgba(255,255,255,0.04)); color:var(--text3, #3A5A70); display:flex; align-items:center; justify-content:center; cursor:pointer; }
  #kadessa-attach-btn:hover{ color:var(--cyan, #00C2FF); border-color:var(--cyan, #00C2FF); }
  /* Container holds one chip per staged file -- a logo, a spreadsheet, and a
     Word doc attached in the same turn all sit here side by side, instead of
     the newest one silently bumping the others out of view (and out of
     Kadessa's context -- see kadessaPendingAttachments in the script below). */
  #kadessa-attach-chips{ display:none; flex-wrap:wrap; gap:6px; }
  #kadessa-attach-chips.show{ display:flex; }
  .kadessa-attach-chip{ display:flex; align-items:center; gap:6px; background:rgba(0,194,255,0.08); border:1px solid rgba(0,194,255,0.25); border-radius:8px; padding:5px 8px; font-size:12px; color:var(--text, #E8F4FF); max-width:100%; }
  .kadessa-attach-chip img.kadessa-attach-thumb-img{ width:18px; height:18px; border-radius:4px; object-fit:cover; flex:0 0 auto; }
  .kadessa-attach-chip-name{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:150px; }
  .kadessa-attach-chip-remove{ cursor:pointer; color:var(--text3, #3A5A70); border:none; background:none; font-size:15px; line-height:1; padding:0 2px; flex:0 0 auto; }
  .kadessa-attach-chip-remove:hover{ color:#ff6b6b; }
  #kadessa-mode-tag{ font-size:10px; color:var(--text2, #7BA8C4); text-align:center; padding:4px 0 0; background:var(--bg, #0A0F1E); margin:0; }

  /* ── ATTACHMENT THUMBNAILS: shared by the pre-send chip AND the sent
     message bubble, so a file reads as a small file-type icon (or an
     actual image thumbnail for a logo) everywhere it appears -- never
     just a bare filename floating in empty space. */
  .kadessa-attach-thumb{ width:18px; height:18px; border-radius:4px; flex:0 0 auto; display:flex; align-items:center; justify-content:center; }
  .kadessa-attach-thumb svg{ width:100%; height:100%; display:block; }
  .kadessa-attach-thumb.type-pdf{ background:rgba(255,90,90,0.16); }
  .kadessa-attach-thumb.type-doc{ background:rgba(60,130,255,0.16); }
  .kadessa-attach-thumb.type-xls{ background:rgba(46,196,140,0.16); }
  .kadessa-attach-thumb.type-csv{ background:rgba(46,196,140,0.16); }
  .kadessa-attach-thumb.type-file{ background:rgba(122,168,196,0.16); }

  /* ── SENT MESSAGE ATTACHMENT ROW: once a message is sent, the staged
     chips clear -- but what actually traveled with that turn should stay
     visible as thumbnails inside the bubble itself, so the thread never
     shows a plain caption with no visual record of what Kadessa received. */
  .kadessa-msg-attachments{ display:flex; flex-wrap:wrap; gap:5px; margin-bottom:7px; }
  .kadessa-msg-attach-item{ display:flex; align-items:center; gap:5px; background:rgba(0,0,0,0.18); border:1px solid rgba(255,255,255,0.10); border-radius:7px; padding:3px 7px 3px 3px; font-size:11px; max-width:100%; }
  .kadessa-msg-attach-item span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:130px; opacity:0.9; }
  .kadessa-msg-text{ white-space:pre-wrap; }

  /* ── KADESSA THINKING INDICATOR: particles collapsing into a core ── */
  .kadessa-msg.kadessa-thinking{ display:flex; align-items:center; gap:10px; padding:8px 12px; }
  .kadessa-vortex{ position:relative; width:24px; height:24px; flex-shrink:0; }
  .kadessa-particle{
    position:absolute; top:50%; left:50%; width:3px; height:3px; margin:-1.5px 0 0 -1.5px;
    border-radius:50%; background:var(--cyan, #00C2FF);
    animation-name: kadessaParticleCollapse; animation-duration:1.4s; animation-timing-function:cubic-bezier(.4,0,.7,1); animation-iteration-count:infinite;
  }
  .kadessa-vortex-core{
    position:absolute; inset:0; margin:auto; width:5px; height:5px; border-radius:50%;
    background: var(--cyan, #00C2FF);
    box-shadow: 0 0 6px 2px rgba(0,194,255,0.85), 0 0 14px 4px rgba(0,115,230,0.35);
    animation: kadessaVortexCore 1.4s ease-in-out infinite;
  }
  @keyframes kadessaParticleCollapse{
    0%{ transform: translate(var(--px), var(--py)) scale(1); opacity:0.95; }
    75%{ opacity:0.55; }
    100%{ transform: translate(0, 0) scale(0.15); opacity:0; }
  }
  @keyframes kadessaVortexCore{ 0%,100%{ transform: scale(0.65); opacity:0.55; } 50%{ transform: scale(1.25); opacity:1; } }
  .kadessa-thinking-label{ font-size:12.5px; color:var(--text2, #7BA8C4); letter-spacing:0.15px; transition:opacity 0.18s ease; }

  /* ── KADESSA ACTING INDICATOR ──────────────────────────────────────────
     Idle floats and breathes -- she's waiting. Thinking swirls -- she's
     considering. Acting needs to read as neither: it's the moment she
     TAKES OVER, running a real change from KADESSA_ACTIONS instead of just
     replying in the thread. So the icon stops drifting and holds firm,
     a solid ring closes around it like a lock engaging, and a calm
     radar-style pulse radiates outward the whole time she's in control --
     steady and continuous, never frantic. Each individual action inside
     a multi-action turn still gets its own decisive "claim" beat (a firm
     scale-snap + a brief bright flash on the ring) so a three-action turn
     reads as three deliberate moves, not one blur -- confident, not busy. */
  @keyframes kadessaActionHold{ 0%,100%{ transform:scale(1); } 50%{ transform:scale(1.018); } }
  @keyframes kadessaActionPing{
    0%{ transform:scale(1); opacity:0.5; }
    70%{ opacity:0; }
    100%{ transform:scale(1.6); opacity:0; }
  }
  @keyframes kadessaActionClaim{
    0%{ transform:scale(1); }
    32%{ transform:scale(0.91); }
    60%{ transform:scale(1.05); }
    100%{ transform:scale(1); }
  }
  @keyframes kadessaActionRingFlash{
    0%{ box-shadow:0 0 16px 2px rgba(0,229,255,0.75); border-color:#B6F6FF; }
    100%{ box-shadow:0 0 10px 1px rgba(0,229,255,0.42); border-color:#00E5FF; }
  }
  @keyframes kadessaActionBadgeBreathe{ 0%,100%{ opacity:1; } 50%{ opacity:0.35; } }
  /* Icon holds still and breathes with weight -- overrides the idle
     float/glow-pulse entirely (higher specificity), so "acting" visibly
     stops the waiting motion rather than layering on top of it. */
  #kadessa-launcher.kadessa-acting{ animation: kadessaActionHold 1.15s ease-in-out infinite; }
  /* The lock ring -- solid and steady, present for the full duration
     she's in control, not just a flash. */
  #kadessa-launcher.kadessa-acting::before{
    content:''; position:absolute; inset:-6px; border-radius:50%;
    border:2px solid #00E5FF; box-shadow:0 0 10px 1px rgba(0,229,255,0.42);
    pointer-events:none;
  }
  /* The radar ping -- one ring, continuously expanding and fading,
     the visual shorthand for "actively engaged right now." */
  #kadessa-launcher.kadessa-acting::after{
    content:''; position:absolute; inset:-6px; border-radius:50%;
    border:2px solid rgba(0,229,255,0.65);
    animation: kadessaActionPing 1.5s cubic-bezier(.22,.6,.35,1) infinite;
    pointer-events:none;
  }
  /* Per-action claim beat -- toggled on and off by kadessaPulseActing() for
     each entry in KADESSA_ACTIONS. Wins the cascade over the steady states
     above for exactly as long as it's applied, then hands back to them. */
  #kadessa-launcher.kadessa-action-claim{ animation: kadessaActionClaim 0.34s cubic-bezier(.3,1.4,.5,1); }
  #kadessa-launcher.kadessa-action-claim::before{ animation: kadessaActionRingFlash 0.42s ease-out; }
  /* Same calm-authority language, scaled down, for when the panel is
     already open -- sits next to the title so an in-progress action
     reads as distinct from a normal reply even while someone is looking
     right at it. */
  #kadessa-acting-badge{
    display:none; align-items:center; gap:6px; font-size:10.5px; font-weight:700;
    letter-spacing:0.4px; text-transform:uppercase; color:#fff; opacity:0.95;
  }
  #kadessa-acting-badge.show{ display:inline-flex; }
  #kadessa-acting-badge::before{
    content:''; width:7px; height:7px; border-radius:50%; background:#fff;
    box-shadow:0 0 6px 1px rgba(255,255,255,0.75);
    animation: kadessaActionBadgeBreathe 1.15s ease-in-out infinite;
  }
