
/* === Nyx Widget v5 — Sessions + Draggable Tabs === */

/* ══ Agent DEV Interface tokens ════════════════════════════════════════════
 *
 * The DEV pane was built with ~19 literal hex colours spread over ~165 inline
 * styles, all of them assuming a dark background. On a Nextcloud instance set
 * to the light theme the pane stayed near-black inside an otherwise white page
 * — not a deliberate dark mode, just a pane that had never been told a theme
 * existed.
 *
 * Every one of those literals now reads a token from here, and every token
 * defers to Nextcloud's own variable with the previous hex as its fallback.
 * So the pane follows the instance theme where NC defines one, and looks
 * exactly as it did before anywhere NC does not (older themes, the login
 * page, a bare iframe).
 *
 * Two rules about what is NOT tokenised to a Nextcloud variable:
 *
 *  - The violet is Nyx's brand, not `--color-primary-element`. An admin who
 *    themes their instance green should get a green Nextcloud with a violet
 *    Nyx in it, the same way the bubble stays violet.
 *  - The "filled" state backgrounds (an on-pill, an error banner) are rgba
 *    tints rather than solid colours, because a solid dark-green pill that
 *    reads as subtle on #0c0d10 reads as a mistake on white. A tint composites
 *    against whatever surface it lands on and stays subtle on both.
 */
.nyx-devpane,
#nyx-emoji-pop {
    --nyx-bg:            var(--color-main-background, #0c0d10);
    --nyx-surface:       var(--color-background-hover, #15171c);
    --nyx-raised:        var(--color-background-dark, #1f2229);
    --nyx-border:        var(--color-border, #2a2d33);
    --nyx-text:          var(--color-main-text, #e6e6ea);
    --nyx-dim:           var(--color-text-maxcontrast, #9aa0aa);
    /* Secondary buttons (Test, Reset, ↑, Refresh models). The old code used the
     * border colour as their background, which works on dark — #2a2d33 is a
     * step *lighter* than the #1f2229 row it sits on — but inverts on light,
     * where the border token is paler than the row and the button disappears.
     * NC's own secondary-button surface holds that contrast in both themes. */
    --nyx-btn:           var(--color-background-darker, #2a2d33);

    /* Nyx violet. Deliberately not --color-primary-element; see above. */
    --nyx-accent:        #6b21a8;
    --nyx-accent-hover:  #7c3aed;
    --nyx-on-accent:     #ffffff;
    --nyx-accent-soft:   rgba(124, 58, 237, 0.16);
    /* Section headings. #d8b4fe is unreadable on white, so the light theme
     * gets a deeper violet through NC's own primary-text token. */
    --nyx-accent-text:   var(--color-primary-element-light-text, #d8b4fe);

    --nyx-ok:            var(--color-text-success, #6ee7b7);
    --nyx-ok-soft:       rgba(52, 211, 153, 0.12);
    --nyx-danger:        var(--color-text-error, #ff7474);
    --nyx-danger-soft:   rgba(239, 68, 68, 0.11);
    --nyx-danger-solid:  var(--color-error, #5a1c1c);
    --nyx-warn:          var(--color-text-warning, #e0b341);
    --nyx-warn-soft:     rgba(245, 158, 11, 0.12);

    --nyx-radius:        var(--border-radius-element, 6px);
    --nyx-radius-lg:     var(--border-radius-container, 10px);
}

/* The agent avatar tile in the Agents tab. A button so it is reachable by
 * keyboard: picking a picture is the point of the control, and a bare <div>
 * with a click handler is not something you can tab to. */
.nyx-agent-avatar-tile {
    position: relative;
    width: 64px;
    height: 64px;
    flex-shrink: 0;
    border-radius: 50%;
    border: 1px solid var(--nyx-border);
    background: var(--nyx-raised);
    color: var(--nyx-text);
    padding: 0;
    overflow: hidden;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}
.nyx-agent-avatar-tile img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
/* The initial shown until a picture is set. Same glyph the agent's bubble
 * falls back to, so the tile is a true preview of what people will see. */
.nyx-agent-avatar-tile .nyx-avatar-initial {
    font-size: 26px;
    font-weight: 700;
    line-height: 1;
    opacity: 0.75;
}
.nyx-agent-avatar-tile .nyx-avatar-hint {
    position: absolute;
    inset: auto 0 0 0;
    padding: 3px 0 4px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    background: rgba(0, 0, 0, 0.62);
    color: #fff;
    opacity: 0;
    transition: opacity 120ms ease;
}
.nyx-agent-avatar-tile:hover .nyx-avatar-hint,
.nyx-agent-avatar-tile:focus-visible .nyx-avatar-hint { opacity: 1; }
.nyx-agent-avatar-tile:focus-visible {
    outline: 2px solid var(--nyx-accent-hover);
    outline-offset: 2px;
}
.nyx-agent-avatar-tile[aria-busy="true"] { opacity: 0.55; cursor: progress; }

/* Small status badges on an agent card and its area rows. */
.nyx-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: var(--border-radius-pill, 999px);
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}
.nyx-badge--neutral { background: var(--nyx-raised);      color: var(--nyx-dim); }
.nyx-badge--accent  { background: var(--nyx-accent-soft); color: var(--nyx-accent-text); }
.nyx-badge--ok      { background: var(--nyx-ok-soft);     color: var(--nyx-ok); }
.nyx-badge--warn    { background: var(--nyx-warn-soft);   color: var(--nyx-warn); }
.nyx-badge--danger  { background: var(--nyx-danger-soft); color: var(--nyx-danger); }

.nyx-fab {
    position: fixed;
    right: 24px;
    bottom: 24px;
    width: 64px;
    height: 64px;
    cursor: grab;
    touch-action: none;
    -webkit-user-select: none;
    user-select: none;
    border-radius: 50%;
    border: 3px solid rgba(255, 255, 255, 0.85);
    background: #1e1b4b;
    background-size: cover;
    background-position: center;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
    z-index: 10000;
    transition: transform .15s ease, box-shadow .15s ease;
    user-select: none;
    touch-action: none;
    overflow: hidden;
}
.nyx-fab img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
    pointer-events: none;
}
.nyx-fab:hover { transform: scale(1.06); box-shadow: 0 8px 32px rgba(0,0,0,0.55); }
.nyx-fab.nyx-dragging { cursor: grabbing; transform: scale(1.08); }
.nyx-fab:active { cursor: grabbing; }

.nyx-panel {
    position: fixed;
    right: 24px;
    bottom: 100px;
    width: min(440px, calc(100vw - 32px));
    height: min(640px, calc(100vh - 130px));
    background: var(--color-main-background, #fff);
    color: var(--color-main-text, #222);
    border: 1px solid var(--color-border-dark, #ddd);
    border-radius: 14px;
    box-shadow: 0 12px 48px rgba(0,0,0,0.35);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    z-index: 10001;
    font-family: var(--default-font, system-ui, sans-serif);
    touch-action: none;
}

/* Header */
/* The header stacks: controls row on top, credits strip underneath. Keeping the
   credits bar out of the control row is what lets .nyx-btn-close sit flush right
   (it used to be a sibling flex item after the buttons). */
.nyx-header {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding: 10px 8px 10px 14px;
    background: linear-gradient(135deg, #1e1b4b 0%, #6b21a8 100%);
    color: #fff;
    flex-shrink: 0;
    cursor: grab;
}
.nyx-header-row {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}
.nyx-header:active { cursor: grabbing; }
.nyx-header-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid rgba(255,255,255,0.3);
    flex-shrink: 0;
    pointer-events: none;
}
.nyx-header-title {
    font-weight: 700; font-size: 1.05em; flex: 1;
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* margin-left:auto pins the group right even if the title collapses to nothing.
   No trailing margin on the buttons — a per-button margin-left used to leave the
   last control (×) inset from the panel edge. Spacing is `gap` only now. */
.nyx-header-actions {
    display: flex; align-items: center; gap: 4px;
    margin-left: auto; flex-shrink: 0;
}
.nyx-header-actions button {
    background: transparent;
    color: #fff;
    border: none;
    font-size: 18px;
    margin: 0;
    padding: 0;
    cursor: pointer;
    width: 30px;
    height: 30px;
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    flex-shrink: 0;
}
/* `display:flex` above beats the UA stylesheet's `[hidden]{display:none}` on
   specificity, which would un-hide every button the launcher hides by attribute
   — including the admin-only ⚙ Dev button. Restore the attribute's meaning
   explicitly. Do not remove without re-running phase1-regression.spec.js. */
.nyx-header-actions button[hidden] { display: none !important; }

/* The close control is the last thing before the panel edge. */
.nyx-header-actions .nyx-btn-close { margin-right: 0; }
.nyx-header-actions .nyx-btn-close:hover { background: rgba(239,68,68,0.45); }
.nyx-header-actions button:hover { background: rgba(255,255,255,0.18); }

/* Minimize / Close buttons */
.nyx-btn-min, .nyx-btn-x {
    background: transparent;
    color: #fff;
    border: none;
    font-size: 20px;
    line-height: 1;
    width: 30px;
    height: 30px;
    border-radius: 6px;
    cursor: pointer;
    margin-left: 4px;
}
.nyx-btn-min:hover { background: rgba(255, 255, 255, 0.2); }
.nyx-btn-x:hover { background: rgba(220, 38, 38, 0.8); }

/* Modi bar */
.nyx-modi {
    display: flex;
    gap: 4px;
    padding: 8px;
    border-bottom: 1px solid var(--color-border, #eee);
    flex-shrink: 0;
    background: var(--color-background-hover, #f7f7f7);
}
.nyx-modus-btn {
    flex: 1;
    padding: 6px 4px;
    border: 1px solid transparent;
    border-radius: 8px;
    background: transparent;
    color: var(--color-main-text, #444);
    font-size: 12px;
    cursor: pointer;
    text-align: center;
    transition: background .12s, border-color .12s;
}
.nyx-modus-btn:hover { background: rgba(107, 33, 168, 0.08); }
.nyx-modus-btn.active {
    background: #6b21a8;
    color: #fff;
    border-color: #6b21a8;
}
.nyx-modus-btn .icon { font-size: 18px; display: block; margin-bottom: 2px; }

.nyx-modi-desc {
    font-size: 11px;
    color: var(--color-text-maxcontrast, #555);
    padding: 4px 8px 2px;
    font-style: italic;
}
.nyx-modi-bar {
    display: flex;
    gap: 4px;
    padding: 4px 8px 8px;
    border-bottom: 1px solid var(--color-border, #eee);
    background: var(--color-background-hover, #f7f7f7);
}

/* Toolbar */
.nyx-toolbar {
    display: flex;
    gap: 6px;
    padding: 6px 8px;
    border-bottom: 1px solid var(--color-border, #eee);
    align-items: center;
    background: var(--color-background-hover, #f7f7f7);
}
.nyx-toolbar label { font-size: 11px; opacity: 0.7; white-space: nowrap; }
.nyx-toolbar select {
    flex: 1;
    padding: 4px 6px;
    border-radius: 6px;
    border: 1px solid var(--color-border-dark, #ccc);
    background: var(--color-main-background, #fff);
    color: var(--color-main-text, #222);
    font-size: 12px;
    cursor: pointer;
}

/* Log / messages */
.nyx-log {
    flex: 1;
    overflow-y: auto;
    padding: 10px 12px;
    font-size: 13px;
    line-height: 1.4;
    background: var(--color-main-background, #fff);
}
.nyx-msg { margin-bottom: 10px; padding: 8px 10px; border-radius: 8px; max-width: 90%; word-wrap: break-word; }
.nyx-msg.user { background: var(--color-primary-element, #0082c9); color: #fff; margin-left: auto; }
.nyx-msg.assistant { background: var(--color-background-hover, #f0e9f8); color: var(--color-main-text, #222); display: flex; gap: 8px; align-items: flex-start; }
.nyx-msg-avatar { width: 24px; height: 24px; border-radius: 50%; object-fit: cover; flex-shrink: 0; margin-top: 2px; }
/*
 * min-width:0 is the load-bearing declaration here.
 *
 * A flex child defaults to min-width:auto, which means it refuses to shrink
 * below its max-content width. So one unbreakable child — a <select> whose
 * longest option is "Suno V5.5 — newest, custom personas, duration control" —
 * pushed the whole message bubble past the panel and gave the conversation a
 * horizontal scrollbar. max-width keeps the bubble inside the log even when the
 * content genuinely is wider; the child scrolls or wraps instead.
 */
.nyx-msg-content { flex: 1; min-width: 0; max-width: 100%; }
.nyx-msg-content select,
.nyx-msg-content input,
.nyx-msg-content textarea { max-width: 100%; box-sizing: border-box; }
.nyx-msg.system { background: rgba(255, 200, 0, 0.12); color: #6b21a8; font-style: italic; font-size: 12px; }
.nyx-msg.error { background: rgba(255, 0, 0, 0.08); color: #b00; }

/* Input area */
.nyx-input-area {
    display: flex;
    gap: 6px;
    padding: 8px;
    border-top: 1px solid var(--color-border, #eee);
    background: var(--color-background-hover, #f7f7f7);
    flex-shrink: 0;
}
.nyx-input-area textarea {
    flex: 1;
    resize: none;
    min-height: 38px;
    max-height: 100px;
    padding: 6px 8px;
    border-radius: 6px;
    border: 1px solid var(--color-border-dark, #ccc);
    background: var(--color-main-background, #fff);
    color: var(--color-main-text, #222);
    font-family: inherit;
    font-size: 13px;
}
.nyx-input-area button {
    padding: 6px 14px;
    border: none;
    border-radius: 6px;
    background: #6b21a8;
    color: #fff;
    font-weight: 600;
    cursor: pointer;
}
.nyx-input-area button:hover { background: #5b1898; }
.nyx-input-area button:disabled { background: #aaa; cursor: not-allowed; }

/* Status dot */
.nyx-status-dot {
    display: inline-block;
    width: 18px;
    text-align: center;
    font-size: 13px;
    margin-right: 4px;
    cursor: help;
}
.nyx-status-idle { color: #999; }
.nyx-status-pending { color: #f59e0b; animation: nyx-spin 1s linear infinite; }
.nyx-status-ok { color: #16a34a; }
.nyx-status-fail { color: #dc2626; }
@keyframes nyx-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

/* Confirm button */
.nyx-confirm-btn:hover { background: #5b1898 !important; transform: translateY(-1px); }
.nyx-confirm-btn:disabled { background: #444 !important; cursor: wait; }

.nyx-hidden { display: none !important; }
.nyx-dragging { transition: none !important; cursor: grabbing !important; user-select: none; }
.nyx-dragging * { pointer-events: none !important; }
/* The drag handle must keep receiving pointer events: it is the element that
   holds the pointer capture, and blanking it mid-drag is what made the panel
   drop the gesture. */
.nyx-dragging .nyx-header,
.nyx-dragging.nyx-fab { pointer-events: auto !important; }
/* Big blurred shadows repaint on every composited frame. Flatten them while the
   pointer is down, restore on release. */
.nyx-dragging { box-shadow: 0 4px 16px rgba(0,0,0,0.35) !important; }
.nyx-dragging, .nyx-dragging * { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; }

/* === v5: Draggable Minimized Session Tabs === */
.nyx-tab {
    position: fixed;
    min-width: 120px;
    max-width: 180px;
    height: 40px;
    background: linear-gradient(135deg, #1e1b4b 0%, #6b21a8 100%);
    color: #fff;
    border-radius: 20px;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 8px 0 14px;
    cursor: grab;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
    z-index: 10001;
    font-size: 13px;
    font-weight: 600;
    user-select: none;
    touch-action: none;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.nyx-tab:hover { transform: scale(1.04); box-shadow: 0 8px 28px rgba(0,0,0,0.45); }
.nyx-tab:active { cursor: grabbing; }
.nyx-tab.nyx-dragging { cursor: grabbing !important; transform: scale(1.06); }
.nyx-tab-icon { font-size: 16px; flex-shrink: 0; }
.nyx-tab-text { 
    flex: 1; 
    overflow: hidden; 
    text-overflow: ellipsis; 
    white-space: nowrap; 
}
.nyx-tab-close {
    background: rgba(255, 255, 255, 0.15);
    color: #fff;
    border: none;
    font-size: 16px;
    line-height: 1;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    cursor: pointer;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.12s;
}
.nyx-tab-close:hover { background: rgba(220, 38, 38, 0.8); }

/* Scrollbar styling */
.nyx-log::-webkit-scrollbar { width: 6px; }
.nyx-log::-webkit-scrollbar-track { background: transparent; }
.nyx-log::-webkit-scrollbar-thumb { background: rgba(107, 33, 168, 0.3); border-radius: 3px; }
.nyx-log::-webkit-scrollbar-thumb:hover { background: rgba(107, 33, 168, 0.5); }

/* v6: model label for non-admin users */
.nyx-model-label { font-size: 11px; opacity: 0.85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px; }

/* === v7: Welcome / greet message === */
.nyx-greet {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    padding: 18px 16px;
    margin: 8px 0 16px;
    background: linear-gradient(135deg, rgba(107, 33, 168, 0.06) 0%, rgba(30, 27, 75, 0.04) 100%);
    border: 1px solid rgba(107, 33, 168, 0.15);
    border-radius: 14px;
    animation: nyx-fade-in 0.3s ease;
}
.nyx-greet-avatar {
    width: 44px; height: 44px; border-radius: 50%;
    object-fit: cover; flex-shrink: 0;
    border: 2px solid rgba(107, 33, 168, 0.25);
    box-shadow: 0 2px 8px rgba(107, 33, 168, 0.2);
}
.nyx-greet-body { flex: 1; min-width: 0; }
.nyx-greet-hi {
    font-size: 15px; font-weight: 600;
    color: var(--color-main-text, #222);
    margin-bottom: 4px; line-height: 1.3;
}
.nyx-greet-sub {
    font-size: 12px; line-height: 1.4;
    color: var(--color-text-maxcontrast, #666);
}

/* === v7: Session picker overlay === */
.nyx-picker-overlay {
    position: fixed; inset: 0;
    background: rgba(10, 6, 20, 0.55);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    display: flex; align-items: center; justify-content: center;
    z-index: 10010;
    animation: nyx-fade-in 0.18s ease;
}
@keyframes nyx-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes nyx-slide-up { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }

.nyx-picker-card {
    width: min(420px, calc(100vw - 48px));
    max-height: min(560px, calc(100vh - 96px));
    background: var(--color-main-background, #fff);
    color: var(--color-main-text, #222);
    border-radius: 16px;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5);
    overflow: hidden;
    display: flex; flex-direction: column;
    animation: nyx-slide-up 0.22s ease;
    border: 1px solid rgba(107, 33, 168, 0.18);
}

.nyx-picker-head {
    display: flex; gap: 12px; align-items: center;
    padding: 18px 18px 14px;
    background: linear-gradient(135deg, #1e1b4b 0%, #6b21a8 100%);
    color: #fff;
}
.nyx-picker-avatar {
    width: 40px; height: 40px; border-radius: 50%;
    object-fit: cover; flex-shrink: 0;
    border: 2px solid rgba(255, 255, 255, 0.3);
}
.nyx-picker-headtxt { flex: 1; min-width: 0; }
.nyx-picker-title { font-size: 15px; font-weight: 700; line-height: 1.2; }
.nyx-picker-sub { font-size: 12px; opacity: 0.85; margin-top: 3px; line-height: 1.3; }

.nyx-picker-list {
    flex: 1; overflow-y: auto;
    padding: 10px;
    display: flex; flex-direction: column; gap: 6px;
}

.nyx-picker-item {
    display: flex; align-items: center; gap: 12px;
    padding: 12px;
    border-radius: 10px;
    background: var(--color-background-hover, #f7f7f7);
    border: 1px solid transparent;
    transition: border-color 0.12s, background 0.12s;
}
.nyx-picker-item:hover {
    background: rgba(107, 33, 168, 0.06);
    border-color: rgba(107, 33, 168, 0.25);
}
.nyx-picker-icon { font-size: 22px; flex-shrink: 0; }
.nyx-picker-meta { flex: 1; min-width: 0; }
.nyx-picker-tag {
    font-weight: 600; font-size: 13px;
    color: var(--color-main-text, #222);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nyx-picker-stats {
    font-size: 11px; margin-top: 2px;
    color: var(--color-text-maxcontrast, #777);
}
.nyx-picker-actions { display: flex; gap: 6px; flex-shrink: 0; }

.nyx-picker-btn {
    padding: 6px 12px;
    border-radius: 6px; border: none;
    font-size: 12px; font-weight: 600;
    cursor: pointer;
    transition: transform 0.1s, box-shadow 0.1s, background 0.12s;
}
.nyx-picker-btn:active { transform: scale(0.96); }
.nyx-picker-btn-primary {
    background: #6b21a8; color: #fff;
}
.nyx-picker-btn-primary:hover { background: #5b1898; box-shadow: 0 2px 8px rgba(107, 33, 168, 0.4); }
.nyx-picker-btn-danger {
    background: transparent;
    color: #dc2626;
    border: 1px solid rgba(220, 38, 38, 0.4);
}
.nyx-picker-btn-danger:hover { background: rgba(220, 38, 38, 0.08); border-color: #dc2626; }
.nyx-picker-btn-ghost {
    background: transparent;
    color: var(--color-text-maxcontrast, #777);
}
.nyx-picker-btn-ghost:hover { background: var(--color-background-hover, #eee); color: var(--color-main-text, #222); }

.nyx-picker-foot {
    padding: 10px 14px;
    border-top: 1px solid var(--color-border, #eee);
    display: flex; justify-content: flex-end;
    background: var(--color-background-hover, #fafafa);
}

/* === v7: recording / brainstorming tools === */
.nyx-pin-btn {
    position: absolute; top: 4px; right: 4px;
    background: none; border: none; cursor: pointer;
    font-size: 12px; opacity: 0; transition: opacity 0.15s;
    padding: 2px;
}
.nyx-msg { position: relative; }
.nyx-msg:hover .nyx-pin-btn { opacity: 0.6; }
.nyx-pin-btn:hover { opacity: 1 !important; }
.nyx-pin-btn.pinned { opacity: 1; }

.nyx-tools-btn {
    background: none; border: 1px solid rgba(107,33,168,0.3); border-radius: 6px;
    color: inherit; cursor: pointer; font-size: 14px; line-height: 1;
    padding: 4px 8px; margin-left: auto;
}
.nyx-tools-btn:hover { background: rgba(107,33,168,0.12); }

.nyx-tools {
    border-top: 1px solid rgba(107,33,168,0.15);
    padding: 10px 12px;
    display: flex; flex-direction: column; gap: 6px;
    max-height: 260px; overflow-y: auto;
    background: rgba(107,33,168,0.03);
}
.nyx-tools-label { font-size: 11px; font-weight: 600; opacity: 0.7; text-transform: uppercase; letter-spacing: 0.4px; }
.nyx-tools-note, .nyx-tools-tags {
    width: 100%; box-sizing: border-box;
    border: 1px solid rgba(107,33,168,0.25); border-radius: 8px;
    padding: 8px 10px; font-size: 13px; font-family: inherit;
    background: var(--color-main-background, #fff); color: inherit;
    resize: vertical;
}
.nyx-tools-row { display: flex; gap: 8px; margin-top: 4px; }
.nyx-tools-empty { padding: 14px; text-align: center; opacity: 0.6; font-size: 13px; }

/* ── Locked modes (voice / musik) ──────────────────────────────────────────
   The backends work; these two are simply not handed out yet. They are
   greyed rather than removed so the widget still answers "can Nyx do music?"
   — with "yes, ask Jo" instead of silence. The note is baked into the button
   so the answer is readable on a touch screen, where there is no hover. */
.nyx-modus-btn--locked {
	opacity: 0.42;
	cursor: not-allowed;
	filter: grayscale(1);
}

.nyx-modus-btn--locked:hover,
.nyx-modus-btn--locked:focus-visible {
	opacity: 0.62;
	filter: grayscale(0.7);
}

/* === v1.8.6 polish ===
 * Goal: same visual foundation as before; improve alignment, focus
 * indicators, and drag responsiveness. No palette/dimension changes. */
.nyx-modus-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-height: 52px;
    transition:
        background 200ms cubic-bezier(0.22, 0.61, 0.36, 1),
        border-color 200ms cubic-bezier(0.22, 0.61, 0.36, 1),
        color 200ms cubic-bezier(0.22, 0.61, 0.36, 1),
        transform 200ms cubic-bezier(0.22, 0.61, 0.36, 1),
        box-shadow 200ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
/* The v1.8.6 rule above turned this button into a centred column flex with its
 * own `gap: 2px`, but the original `.icon` declaration further up still carries
 * `margin-bottom: 2px` from the pre-flex layout. Both apply, so the glyph is
 * pushed 4px off the label instead of 2px — and because the margin is part of
 * the centred content box, the emoji itself ends up sitting high in the button.
 * The gap owns the spacing now; the margin is left over and has to go.
 * `display: flex` (rather than the inherited `block`) centres the glyph
 * horizontally too, which matters because emoji advance widths vary. */
.nyx-modus-btn .icon {
    line-height: 1;
    font-size: 18px;
    margin-bottom: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
.nyx-modus-btn:hover:not(.nyx-modus-btn--locked) {
    background: rgba(107, 33, 168, 0.10);
    border-color: rgba(107, 33, 168, 0.25);
    transform: translateY(-1px);
}
.nyx-modus-btn:focus-visible {
    outline: 2px solid #d8b4fe;
    outline-offset: 2px;
}
.nyx-modus-btn.active {
    box-shadow: 0 4px 12px rgba(107, 33, 168, 0.40);
}

/* Developer button (admin-only) — visible focus, smooth hover, no `display`
 * gymnastics; visibility is gated by the `hidden` attribute from the JS. */
.nyx-btn-dev {
    background: transparent;
    color: #fff;
    border: none;
    font-size: 18px;
    margin-left: 6px;
    cursor: pointer;
    width: 30px;
    height: 30px;
    border-radius: 6px;
    transition:
        background 200ms cubic-bezier(0.22, 0.61, 0.36, 1),
        transform 200ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.nyx-btn-dev:hover  { background: rgba(255, 255, 255, 0.18); transform: scale(1.06); }
.nyx-btn-dev:active { transform: scale(0.96); }
.nyx-btn-dev:focus-visible { outline: 2px solid #d8b4fe; outline-offset: 2px; }
.nyx-btn-dev[hidden] { display: none; }

/* Drag-only GPU hint. Applied via JS `target.style.willChange = 'transform'`
 * on pointerdown and cleared on pointerup so we are not paying for a hint
 * when nothing is moving. */
.nyx-dragging { will-change: transform; cursor: grabbing !important; }

/* prefers-reduced-motion: kill the polish transitions so animation-sensitive
 * users get instant state changes. The drag path is already rAF-driven and
 * does not animate, but the hover/focus transitions are disabled here too. */
@media (prefers-reduced-motion: reduce) {
    .nyx-modus-btn,
    .nyx-btn-dev,
    .nyx-header,
    .nyx-fab {
        transition: none !important;
    }
}

/* --- Phase: header controls, session id chip, accessible confirm dialog --- */
.nyx-session-id{
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 11px; letter-spacing: .04em;
    padding: 2px 6px; border-radius: 6px;
    background: rgba(255,255,255,.12); color: #e9d5ff;
    margin-right: 6px; user-select: text;
}
.nyx-btn-new{
    background: transparent; border: 0; color: #e9d5ff; cursor: pointer;
    font-size: 16px; line-height: 1; padding: 4px 7px; border-radius: 6px;
}
.nyx-btn-new:hover{ background: rgba(255,255,255,.14); }
.nyx-btn-new:focus-visible{ outline: 2px solid #c4b5fd; outline-offset: 2px; }
.nyx-confirm-back{
    position: absolute; inset: 0; z-index: 40; display: flex;
    align-items: center; justify-content: center;
    background: rgba(0,0,0,.55); border-radius: inherit;
}
.nyx-confirm{
    background: #1e1b2e; color: #ede9fe; border: 1px solid rgba(255,255,255,.14);
    border-radius: 12px; padding: 18px; max-width: 320px; margin: 16px;
    box-shadow: 0 12px 40px rgba(0,0,0,.5);
}
.nyx-confirm p{ margin: 0 0 14px; font-size: 13px; line-height: 1.5; }
.nyx-confirm-row{ display: flex; gap: 8px; justify-content: flex-end; }
.nyx-confirm-row button:focus-visible{ outline: 2px solid #c4b5fd; outline-offset: 2px; }
@media (prefers-reduced-motion: reduce){ .nyx-confirm, .nyx-confirm-back{ transition: none !important; } }
