/**
 * Mirror Ai — Shared Premium Components
 * =====================================
 * The premium primitives, shared by chat, document writer and Knowledge Hub.
 *
 * WHY
 * ---
 * The chat overhaul built a set of premium components (live orchestration card,
 * shimmer skeletons, code-copy chrome, attribution line). They lived inside
 * chat.css, so documents and the Hub could not use them and re-implemented
 * weaker versions — the same drift that gave us three colour palettes.
 *
 * WHAT MOVED
 * ----------
 * Only the rules that were already GENERIC (unscoped, not tied to a chat
 * message) were moved here, byte-for-byte. Chat's message-specific styling stays
 * in chat.css: chat is the live, approved surface, and relocating it would risk
 * regressing the revenue path for no user benefit.
 *
 * Loaded BEFORE the feature stylesheets, so a feature can still layer on top.
 * Colours come exclusively from workspace-tokens.css (--ws-*).
 *
 * CONTAINS
 *   .orch* / .orow*      progress card (real, honest state — never fake progress)
 *   .message-attrib      "answered by N specialists in X.Xs" attribution line
 *   .session-skeleton    shimmer loading rows
 *   .code-copy-btn       copy affordance on code blocks
 *   .pm-*                the reading surface primitives documents + the Hub adopt
 */

/* ========================================
   ========================================
   CHAT SESSIONS STYLES
   ========================================
   Canonical source: chat-sessions.css
   Duplicates removed — only unique skeleton loading rules remain here.
   ======================================== */

/* ============================================
   SKELETON LOADING STATE - Premium shimmer
   (Unique to chat.css — not in chat-sessions.css)
   ============================================ */
.session-skeleton {
    padding: 12px;
    margin: 8px 0;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.02);
}
.skeleton-line {
    height: 12px;
    background: linear-gradient(90deg,
        rgba(255, 255, 255, 0.04) 0%,
        rgba(255, 255, 255, 0.08) 50%,
        rgba(255, 255, 255, 0.04) 100%);
    background-size: 200% 100%;
    animation: chatSkeletonShimmer 1.5s ease-in-out infinite;
    border-radius: 6px;
}
.skeleton-title {
    width: 70%;
    margin-bottom: 10px;
}
.skeleton-preview {
    width: 90%;
    height: 10px;
}
/* ============================================================================
   COPY BUTTON — CODE BLOCKS
   ============================================================================ */
.code-copy-btn {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 30px;
    height: 30px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 6px;
    background: rgba(15, 21, 41, 0.8);
    color: rgba(255, 255, 255, 0.5);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    opacity: 0;
    transition: all 0.2s ease;
    z-index: 5;
    padding: 0;
}
pre:hover .code-copy-btn,
.code-copy-btn:focus-visible {
    opacity: 1;
}
.code-copy-btn:hover {
    background: rgba(0, 242, 254, 0.15);
    border-color: rgba(0, 242, 254, 0.3);
    color: var(--ws-accent);
}
/* (A stray `.code-copy-btn { opacity: 0.7 }` re-declaration used to sit here — a
   move artifact that overrode the reveal-on-hover `opacity: 0` above and left a
   standalone copy button faintly visible at rest. Removed; inside .code-block the
   button is explicitly opacity:1, which is the surface that actually matters.) */
/* ============================================================================
   PHASE 2 — LIVE AGENT ORCHESTRATION (HERO)
   Replaces the decorative thinking animation with an honest, premium view of
   the real multi-agent pipeline the chat backend streams. Container class is
   `orch-indicator` (set in showTypingIndicator*); rows are data-driven.
   ============================================================================ */
.orch-indicator {
    width: 100%;
    animation: streamFadeIn 0.25s ease-out;
}
.orch {
    max-width: 78ch;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 14px;
    background: rgba(255, 255, 255, 0.022);
    overflow: hidden;
}
.orch-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.orch-pulse {
    width: 9px;
    height: 9px;
    flex: none;
    border-radius: 50%;
    background: var(--chat-accent-primary, var(--ws-accent));
    box-shadow: 0 0 10px var(--chat-accent-primary, var(--ws-accent));
    animation: orchPulse 1.4s ease-in-out infinite;
}
.orch-title {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--chat-text-primary, var(--ws-text));
    transition: opacity 0.15s ease;
}
.orch-meta {
    margin-left: auto;
    font-size: 11.5px;
    color: var(--chat-text-muted, rgba(255, 255, 255, 0.6));
    font-variant-numeric: tabular-nums;
}
.orch-list { padding: 6px; }
.orow {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 9px 10px;
    border-radius: 10px;
}
.orow + .orow { margin-top: 1px; }
.orow-ic {
    width: 30px;
    height: 30px;
    flex: none;
    border-radius: 9px;
    display: grid;
    place-items: center;
    font-size: 13px;
    background: rgba(255, 255, 255, 0.04);
    color: var(--chat-text-muted, rgba(255, 255, 255, 0.6));
    transition: all 0.25s ease;
}
.orow-body { flex: 1; min-width: 0; }
.orow-name {
    font-size: 13.5px;
    font-weight: 500;
    color: var(--chat-text-primary, var(--ws-text));
}
.orow-sub {
    font-size: 11.5px;
    color: var(--chat-text-muted, rgba(255, 255, 255, 0.5));
    margin-top: 1px;
}
.orow-state {
    width: 22px;
    height: 22px;
    flex: none;
    display: grid;
    place-items: center;
    font-size: 12px;
}
.orow-spin {
    width: 14px;
    height: 14px;
    border: 2px solid rgba(255, 255, 255, 0.15);
    border-top-color: var(--chat-accent-primary, var(--ws-accent));
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}
.orow-found { color: var(--ws-success-text); font-weight: 500; }
.orch-foot {
    display: none;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
    font-size: 13px;
    color: var(--chat-text-secondary, rgba(255, 255, 255, 0.85));
}
/* Attribution footer on completed assistant messages ("show your working") */
.message-attrib {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
    padding: 6px 11px;
    border-radius: 9px;
    font-size: 11.5px;
    color: var(--chat-text-muted, rgba(255, 255, 255, 0.55));
    background: rgba(255, 255, 255, 0.025);
    border: 1px solid rgba(255, 255, 255, 0.07);
}
.message-attrib i { color: var(--chat-accent-primary, var(--ws-accent)); }
.message-attrib b { color: var(--chat-text-secondary, rgba(255, 255, 255, 0.85)); font-weight: 600; }
@keyframes orchPulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.4; transform: scale(0.8); }
}
/* Kill the pulse + spinner ONLY for users who ask for reduced motion. This rule was
   inside @media (prefers-reduced-motion: reduce) in chat.css; when the orchestration
   styles moved into this file the media wrapper was dropped, which froze the Live
   Orchestration pulse and every agent-row spinner for EVERYONE (a non-spinning
   spinner reads as a hang). Re-wrapped. */
@media (prefers-reduced-motion: reduce) {
    .orch-pulse, .orow-spin { animation: none; }
}


/* ============================================================================
   READING SURFACE (.pm-prose) — THE ONLY PLACE PROSE IS STYLED
   ----------------------------------------------------------------------------
   Chat, the document writer and the Knowledge Hub all render authored content.
   They used to style it in SIX places, and every one of them disagreed:

     chat.css              .message-text            1rem / 1.72 / 78ch measure
     chat.css (immersive)  .message-text            ...but line-height 1.6 — and
                                                    chat is ALWAYS immersive, so
                                                    this was chat's real value
     chat-mobile.css       html body .message-text  15px / 1.7 + its own table
     document-writer.css   .preview-content         UNSCOPED — 900px / 1.8, and
                                                    because it loads after this
                                                    file it silently overrode
                                                    .pm-prose on BOTH previews
     document-mobile.css   html body .preview-content   15px + clamp() headings
     blog-mobile.css       #blog-writer-view ...        16px + DIFFERENT clamp()

   So the same markdown rendered at three measures, three line-heights, three
   heading scales and FOUR table designs, and which one you got on mobile
   depended on which service you were standing in. Top-level lists in chat had
   no rule at all, so they fell back to the browser default (40px) while the
   editors indented 21.6px — the "indentation is different" the founder saw.

   All six are deleted. This is the one surface. Any element that can appear in
   rendered content is styled HERE, once, and nowhere else.

   Carried by: .message-text (chat) · #preview-content (documents) ·
               #blog-preview-content (the Hub) — all get class="pm-prose".

   THE MEASURE: --ws-measure (68ch). Chat was 78ch — wider than the 66–75
   character band that a century of typesetting says is readable, and wider than
   the editors. One measure, and it is the better one.
   ============================================================================ */

.pm-prose {
    max-width: var(--ws-measure);
    color: var(--ws-text-secondary);
    /* Stated, not inherited. shared-ui.css named the font on `.message-text`, so
       CHAT had Inter with ligatures, kerning and antialiasing switched on while
       the two editor previews just inherited whatever <body> happened to be —
       no font-feature-settings, no smoothing. Same text, different rendering. */
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-feature-settings: 'liga' 1, 'kern' 1, 'calt' 1;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-size: 1rem;
    line-height: 1.72;
    letter-spacing: 0.001em;
}

/* Vertical rhythm: one rule, instead of per-element margin-bottom guesswork. */
.pm-prose > * + * { margin-top: 1.1em; }
.pm-prose p { margin: 0; }

/* ---- Headings ------------------------------------------------------------ */

.pm-prose h1,
.pm-prose h2,
.pm-prose h3,
.pm-prose h4,
.pm-prose h5,
.pm-prose h6 {
    color: var(--ws-text);
    font-weight: 650;
    line-height: 1.3;
    letter-spacing: -0.011em;
    margin-top: 1.9em;
    margin-bottom: 0.6em;
}

.pm-prose h1 { font-size: 1.6rem; }
.pm-prose h2 { font-size: 1.32rem; }
.pm-prose h3 { font-size: 1.12rem; }
.pm-prose h4 { font-size: 1rem; }
.pm-prose h5 { font-size: 0.95rem; font-weight: 600; }
.pm-prose h6 {
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ws-text-muted);
}

/* A quiet rule under h2 gives a long answer or document visible sections.
   Chat had this; the editors did not. */
.pm-prose h2 {
    padding-bottom: 0.3em;
    border-bottom: 1px solid var(--ws-glass-border);
}

.pm-prose h1:first-child,
.pm-prose h2:first-child,
.pm-prose h3:first-child { margin-top: 0; }

/* ---- Inline -------------------------------------------------------------- */

.pm-prose strong,
.pm-prose b { color: var(--ws-text); font-weight: 650; }

.pm-prose a {
    color: var(--ws-accent);
    text-decoration: none;
    border-bottom: 1px solid rgba(0, 242, 254, 0.3);
    /* A raw citation URL must not push the column sideways. */
    overflow-wrap: anywhere;
    transition: border-color var(--ws-t-fast);
}

.pm-prose a:hover { border-bottom-color: var(--ws-accent); }

.pm-prose img {
    max-width: 100%;
    height: auto;
    display: block;
    border-radius: var(--ws-radius-sm);
}

.pm-prose hr {
    border: 0;
    border-top: 1px solid var(--ws-glass-border);
    margin: 2.2em 0;
}

/* ---- Lists --------------------------------------------------------------- */
/* Chat had NO top-level list rule, so it inherited the browser's 40px — 1.85x
   the editors' indent, side by side, on the same markdown. */

.pm-prose ul,
.pm-prose ol { padding-left: 1.35em; }

.pm-prose li + li { margin-top: 0.4em; }
.pm-prose li::marker { color: var(--ws-text-subtle); }

/* Nesting tightens, so a deep list does not march off the measure. */
.pm-prose li > ul,
.pm-prose li > ol { margin-top: 0.4em; padding-left: 1.25em; }
.pm-prose li li > ul,
.pm-prose li li > ol { padding-left: 1em; }

/* ---- Blockquote ---------------------------------------------------------- */

.pm-prose blockquote {
    margin-left: 0;
    padding: 0.5em 0 0.5em 1.1em;
    border-left: 3px solid rgba(0, 242, 254, 0.4);
    border-radius: 0 var(--ws-radius-sm) var(--ws-radius-sm) 0;
    background: rgba(0, 242, 254, 0.04);
    color: var(--ws-text-muted);
}

.pm-prose blockquote > * + * { margin-top: 0.6em; }

/* ---- Tables: ONE design ---------------------------------------------------
   There were four. Three cell paddings, three header treatments, three border
   models. Chat's was also double-bordered: its JS wrapped every table in a
   `.table-responsive` div and BOTH the wrapper and the table drew a 1px,
   12px-radius border. That wrapper is gone (see js/shared/content-renderer.js).

   The table is its OWN scroll box: display:block + overflow-x:auto. Rendered
   markdown hands us a bare <table> with nothing to hook a wrapper onto, so the
   table has to contain its own overflow — the technique GitHub uses. A wide
   table scrolls inside the column instead of widening the page.
   -------------------------------------------------------------------------- */

.pm-prose table {
    display: block;
    width: max-content;
    max-width: 100%;
    overflow-x: auto;
    /* `separate` (not collapse) so the radius clips cleanly on a block box. */
    border-collapse: separate;
    border-spacing: 0;
    border: 1px solid var(--ws-glass-border);
    border-radius: var(--ws-radius-md);
    background: var(--ws-bg-secondary);
    font-size: 0.9rem;
    margin: 0;
}

.pm-prose thead th {
    text-align: left;
    font-weight: 650;
    color: var(--ws-text);
    padding: 11px 16px;
    background: rgba(0, 242, 254, 0.08);
    border-bottom: 1px solid var(--ws-glass-border);
    white-space: nowrap;
}

.pm-prose tbody td {
    padding: 11px 16px;
    border-bottom: 1px solid var(--ws-glass-border);
    color: var(--ws-text-secondary);
    vertical-align: top;
}

.pm-prose tbody tr:last-child td { border-bottom: 0; }
.pm-prose tbody tr:nth-child(even) td { background: rgba(255, 255, 255, 0.022); }
.pm-prose tbody tr:hover td { background: rgba(0, 242, 254, 0.05); }

/* Column dividers — a dense data table is unreadable without them. */
.pm-prose th + th,
.pm-prose td + td { border-left: 1px solid rgba(255, 255, 255, 0.06); }

/* Numeric columns line up — tabular figures, right-aligned. */
.pm-prose td.num,
.pm-prose th.num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* ---- Code ----------------------------------------------------------------
   The chrome (window dots, language label, copy button) lived in chat.css and
   was built only by chat's JS, even though this file has always claimed the
   shared surface gives you "code chrome + copy, same as chat". It does now:
   MirrorContent.enhance() builds .code-block for all three services.
   -------------------------------------------------------------------------- */

.pm-prose code {
    font-family: 'JetBrains Mono', ui-monospace, Consolas, monospace;
    font-size: 0.86em;
    padding: 2px 5px;
    border-radius: 4px;
    background: rgba(0, 242, 254, 0.1);
    border: 1px solid var(--ws-glass-border);
    color: var(--ws-accent);
    overflow-wrap: anywhere;
}

.pm-prose pre {
    overflow-x: auto;
    padding: 14px 16px;
    border-radius: var(--ws-radius-md);
    background: var(--ws-bg-deep);
    border: 1px solid var(--ws-glass-border);
}

.pm-prose pre code {
    padding: 0;
    border: 0;
    background: none;
    color: var(--ws-text-secondary);
    font-size: 0.84rem;
    line-height: 1.6;
    overflow-wrap: normal;
}

/* The chrome owns the frame, so the <pre> inside it drops its own. */
.pm-prose .code-block {
    margin: 0;
    border: 1px solid var(--ws-glass-border);
    border-radius: var(--ws-radius-md);
    overflow: hidden;
    background: var(--ws-bg-deep);
}

.pm-prose .code-block pre {
    margin: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
}

.pm-prose .code-block-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    background: rgba(255, 255, 255, 0.025);
    border-bottom: 1px solid var(--ws-glass-border);
}

.pm-prose .code-block-dots { display: inline-flex; gap: 6px; }

.pm-prose .code-block-dots span {
    width: 10px;
    height: 10px;
    border-radius: 50%;
}

.pm-prose .code-block-dots span:nth-child(1) { background: var(--ws-danger); }
.pm-prose .code-block-dots span:nth-child(2) { background: var(--ws-warning); }
.pm-prose .code-block-dots span:nth-child(3) { background: var(--ws-success); }

.pm-prose .code-block-lang {
    font-family: 'JetBrains Mono', ui-monospace, Consolas, monospace;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: var(--ws-text-muted);
}

/* The copy button sits in the header (its base style is further up this file). */
.pm-prose .code-block .code-copy-btn {
    position: static;
    margin-left: auto;
    width: auto;
    height: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    border-radius: var(--ws-radius-sm);
    font-family: inherit;
    font-size: 11.5px;
    font-weight: 500;
    opacity: 1;
    background: var(--ws-glass-bg);
    border: 1px solid var(--ws-border-control);
    color: var(--ws-text-muted);
    cursor: pointer;
    transition: all var(--ws-t-fast);
}

.pm-prose .code-block .code-copy-btn:hover {
    color: var(--ws-accent);
    border-color: var(--ws-border-control-hover);
    background: rgba(0, 242, 254, 0.08);
}

.pm-prose .code-block .code-copy-btn.copied {
    color: var(--ws-success);
    border-color: rgba(16, 185, 129, 0.3);
    background: rgba(16, 185, 129, 0.12);
}

/* ---- Mobile: ONE scale ----------------------------------------------------
   There were three (chat-mobile, document-mobile, blog-mobile), and they set
   different body sizes (15px / 15px / 16px) and different clamp() heading
   ramps. This block replaces all three.

   It lives HERE rather than in a *-mobile.css file because after this refactor
   nothing downstream styles prose at all — so a later rule in this same file is
   the last word, and no `html body` specificity war is needed.
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {
    .pm-prose {
        max-width: 100%;
        font-size: 15px;
        line-height: 1.7;
        word-break: break-word;
    }

    .pm-prose h1 { font-size: clamp(22px, 5.5vw, 28px); }
    .pm-prose h2 { font-size: clamp(18px, 4.5vw, 22px); }
    .pm-prose h3 { font-size: clamp(16px, 4vw, 20px); }
    .pm-prose h4 { font-size: 15px; }

    .pm-prose ul,
    .pm-prose ol { padding-left: 1.25em; }

    .pm-prose code { font-size: 13px; }

    .pm-prose pre {
        padding: 12px;
        font-size: 13px;
        -webkit-overflow-scrolling: touch;
    }

    .pm-prose pre code {
        font-size: 13px;
        /* Wrap rather than scroll: a horizontal scroll inside a vertical scroll
           inside a message list is three nested scrolls on a 375px screen. */
        white-space: pre-wrap;
        overflow-wrap: anywhere;
    }

    .pm-prose table {
        font-size: 13.5px;
        -webkit-overflow-scrolling: touch;
    }

    .pm-prose thead th,
    .pm-prose tbody td { padding: 10px 14px; }
}

/* ============================================================================
   EMPTY STATE (.pm-empty)
   ============================================================================ */

.pm-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 40px 20px;
    text-align: center;
}

.pm-empty__icon {
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--ws-glass-bg);
    border: 1px solid var(--ws-glass-border);
    color: var(--ws-text-subtle);
    font-size: 1rem;
}

.pm-empty__title {
    color: var(--ws-text);
    font-size: 0.94rem;
    font-weight: 600;
    margin: 0;
}

.pm-empty__sub {
    color: var(--ws-text-subtle);
    font-size: 0.82rem;
    margin: 0;
    max-width: 34ch;
    line-height: 1.5;
}


/* ============================================================================
   THE AMBIENT — one atmosphere, identical in every view.
   ----------------------------------------------------------------------------
   Each view used to paint its own. They disagreed on hue AND on intensity:

     chat       purple + cyan
     documents  purple + cyan + pink rgba(247,37,133, .04)
     Hub        PINK rgba(247,37,133, .15) + MAGENTA rgba(181,23,158, .15) + cyan
                (~4x documents' intensity; the magenta existed nowhere else in
                 the entire codebase)

   So switching service changed the colour of the room. Now there is one wash,
   built from the brand accents only, applied to all three.

   Motion: none. Documents used to run EIGHT always-on ambient animations
   (ambientBreath, orbDrift x2, scanLight x2, holoShift x2, borderFlow x2,
   gradientFlow, backgroundShift) plus a film-grain overlay; chat ran a
   particleFloat starfield; the Hub ran nothing. They are all deleted. The
   atmosphere is now identical, still, and cheap — which is also what the calm
   reading surface wants, and what the battery wants.
   ============================================================================ */

:root {
    --ws-ambient:
        radial-gradient(ellipse 80% 60% at 15% 10%, rgba(118, 75, 162, 0.10) 0%, transparent 60%),
        radial-gradient(ellipse 70% 60% at 85% 85%, rgba(0, 242, 254, 0.07) 0%, transparent 60%);
}

.ws-canvas {
    background-color: var(--ws-bg-primary);
    background-image: var(--ws-ambient);
    background-attachment: fixed;
}
