    /* ══════════════════════════════════════════════════════════════════
       Unified layout — Classic + Bubble collapsed into a single
       index.html with body.mode-bubble (default) / body.mode-card.
       Rules below merged from the deleted styles-bubble.css.
       ══════════════════════════════════════════════════════════════════ */

    /* Panel arrangement: top incoming + bottom 4-tab. */
    .panels { flex-direction: column; gap: 12px; }
    .panels > .panel:first-child { flex: 3 1 0; min-height: 0; }
    .panels > .panel:last-child {
      flex: 2 1 0; min-height: 120px;
      display: flex; flex-direction: column;
    }
    .panels > .panel:last-child .panel-body {
      flex: 1; min-height: 0; overflow-y: auto;
    }

    /* Bottom panel auto-collapse (30s idle → tab headers only) */
    .panels > .panel.bp-collapsed { flex: 0 0 auto; min-height: 0; }
    .panels > .panel.bp-collapsed .panel-body { display: none; }

    /* Render-mode visibility */
    body.mode-bubble #card-stream { display: none; }
    body.mode-card   #bubble-field { display: none; }

    /* Bubble field (bubble mode) */
    .bubble-field {
      position: relative;
      flex: 1 1 0;
      min-height: 200px;
      overflow: hidden;
      border-radius: var(--radius-lg);
      background: var(--surface-lo);
      border: 1px solid var(--border);
    }
    .bubble-field #kp-feed { position: relative; height: 100%; }
    .bubble-field #splash { position: absolute; inset: 0; }
    .bubble-field #splash-logo-dark,
    .bubble-field #splash-logo-light { width: 200px; height: 200px; }
    .bubble-field:has(#splash) .bubble-field-empty { display: none !important; }
    .bubble-field-empty {
      position: absolute; inset: 0;
      display: flex; align-items: center; justify-content: center;
      color: var(--text-3); font-size: var(--fs-sm);
      pointer-events: none;
    }

    /* Floating bubble animation */
    @keyframes bubble-rise {
      from  { transform: translateY(0); opacity: 0; }
      8%    { opacity: 1; }
      88%   { opacity: 1; }
      to    { transform: translateY(calc(-1 * var(--rise-distance, 500px))); opacity: 0; }
    }
    .floating-bubble {
      position: absolute;
      bottom: -40px;
      animation: bubble-rise var(--card-ttl, 15s) linear forwards;
      border-radius: var(--radius-lg);
      padding: 8px 14px;
      border: 1px solid rgba(255, 255, 255, 0.18);
      cursor: pointer;
      background: rgba(255, 255, 255, 0.08);
      display: flex; flex-direction: column; gap: 2px;
      max-width: 340px;
      backdrop-filter: blur(20px) saturate(1.4);
      -webkit-backdrop-filter: blur(20px) saturate(1.4);
      box-shadow:
        0 1px 3px rgba(0, 0, 0, 0.12),
        inset 0 1px 0 rgba(255, 255, 255, 0.15);
      will-change: transform, opacity;
      white-space: normal; word-wrap: break-word; overflow: hidden;
      font-weight: 600; line-height: var(--lh-snug);
      transition: box-shadow 0.2s var(--ease-out), transform 0.2s var(--ease-out), border-color 0.2s;
      z-index: 1;
    }
    .floating-bubble:hover {
      box-shadow:
        0 4px 16px rgba(0, 0, 0, 0.15),
        0 0 20px var(--_glow, rgba(167, 139, 250, 0.25)),
        inset 0 1px 0 rgba(255, 255, 255, 0.2);
      transform: translateY(var(--hover-y, 0)) scale(1.06);
      border-color: rgba(255, 255, 255, 0.3);
    }
    /* Floating bubble term — override classic .bubble-term ellipsis. */
    .floating-bubble .bubble-term {
      font-weight: 600; font-size: var(--fs-base, 15px);
      line-height: var(--lh-snug, 1.3);
      white-space: normal; word-break: break-word;
      overflow: visible; text-overflow: clip;
    }
    .floating-bubble .bubble-ctx {
      font-size: var(--fs-xs, 12px); font-weight: 400;
      opacity: 0.8; line-height: 1.35;
      display: -webkit-box; -webkit-line-clamp: 2;
      -webkit-box-orient: vertical; overflow: hidden;
    }
    html.light .floating-bubble {
      background: rgba(255, 255, 255, 0.45);
      border-color: rgba(255, 255, 255, 0.5);
      box-shadow:
        0 1px 4px rgba(0, 0, 0, 0.06),
        inset 0 1px 0 rgba(255, 255, 255, 0.6);
    }
    html.light .floating-bubble:hover {
      background: rgba(255, 255, 255, 0.6);
      box-shadow:
        0 4px 16px rgba(0, 0, 0, 0.08),
        0 0 20px var(--_glow, rgba(167, 139, 250, 0.15)),
        inset 0 1px 0 rgba(255, 255, 255, 0.7);
    }
    .floating-bubble.cat-technologies       { color: #7cb3ff;  --_glow: rgba(59,130,246, 0.25); }
    .floating-bubble.cat-companies_products { color: #ffc444;  --_glow: rgba(245,158,11, 0.25); }
    .floating-bubble.cat-business_metrics   { color: #4eeab2;  --_glow: rgba(16,185,129, 0.25); }
    .floating-bubble.cat-compliance_risk    { color: #ff7b7b;  --_glow: rgba(239,68,68, 0.25); }
    .floating-bubble.cat-strategic_concepts { color: #b18cff;  --_glow: rgba(139,92,246, 0.25); }
    .floating-bubble.cat-key_numbers        { color: #4dd8e8;  --_glow: rgba(6,182,212, 0.25); }

    /* Card stream (card mode) — vertical scrollable list of .bubble cards */
    .card-stream {
      flex: 1 1 0; min-height: 200px;
      padding: 12px; overflow-y: auto;
      border-radius: var(--radius-lg);
      background: var(--surface-lo); border: 1px solid var(--border);
    }
    .card-stream::-webkit-scrollbar { width: 6px; }
    .card-stream::-webkit-scrollbar-track { background: transparent; }
    .card-stream::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
    .card-stream > .bubble ~ .empty-hint,
    .card-stream > .thread-header ~ .empty-hint { display: none; }

    /* Bottom panel tabs */
    .bp-tabs { display: flex; gap: 4px; padding: 0 12px; }
    .bp-tab {
      flex: 1; text-align: center; padding: 8px 0;
      font-size: var(--fs-sm); font-weight: 600;
      color: var(--text-3);
      background: none; border: none;
      border-bottom: 2px solid transparent;
      cursor: pointer;
      transition: color 0.15s, border-color 0.15s;
    }
    .bp-tab.active { color: var(--purple); border-bottom-color: var(--purple); }
    .bp-tab .tab-count { margin-left: 4px; }

    /* Default (portrait): icons hidden, text labels shown */
    .bp-tab .bp-tab-icon { display: none; }

    /* Landscape (≤1024px): bubble field + tab panel side-by-side */
    @media (orientation: landscape) and (max-width: 1024px) {
      .panels { flex-direction: row; gap: 8px; }
      .panels > .panel:first-child { flex: 1 1 0; min-width: 0; }
      .panels > .panel:last-child { flex: 1 1 0; min-height: 0; }

      #bp-panel { flex-direction: row; }
      #bp-panel .bp-tabs {
        flex-direction: column; gap: 6px; padding: 8px 4px;
        width: 48px; flex: 0 0 48px;
        border-right: 1px solid var(--border);
        border-bottom: none;
      }
      #bp-panel .bp-tab {
        flex-direction: column; gap: 2px; padding: 8px 4px; min-height: 0;
      }
      #bp-panel .bp-tab .bp-tab-icon { display: block; }
      #bp-panel .bp-tab .bp-tab-label { display: none; }
      #bp-panel .bp-tab.active {
        border-bottom: none;
        border-left: 2px solid var(--purple);
      }
      #bp-panel .panel-body { flex: 1; min-width: 0; }

      .panels > .panel:last-child.bp-collapsed {
        flex: 0 0 48px; min-width: 0;
      }
    }

    @media (max-width: 540px) { .bubble-field { min-height: 150px; } }

    /* ── Card description (card-mode visible-by-default summary) ──
       The classic card hid the short context inside .bubble-body and
       only revealed it on expand. With cards now the primary surface
       in card mode, the context is hoisted out so the term's meaning
       is readable at a glance. The body still expands on click to
       reveal lookup + dismiss actions.  */
    .bubble-description {
      padding: 0 12px 6px 28px;   /* left-align with bubble-term (past the dot) */
      font-size: var(--fs-sm);
      color: var(--text-2);
      line-height: 1.35;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }
