@mochabug/adapt-web
Version:
Browser client library for Adapt automation platform
1,006 lines (886 loc) • 29 kB
CSS
/* ==========================================================================
Mochabug Adapt Web — Combined Styles
Panel Manager CSS + Cap Widget CSS
========================================================================== */
:root { --mb-adapt-styles-loaded: 1; }
/* ── Root ────────────────────────────────────────────── */
.mb-adapt {
position: relative;
width: 100%;
height: 100%;
min-height: inherit;
display: flex;
flex-direction: column;
/* Two-layer CSS variables: --_X reads user-set --mb-adapt-X first, falls back to light default */
--_bg: var(--mb-adapt-bg, transparent);
--_font: var(--mb-adapt-font, system-ui, -apple-system, sans-serif);
--_button-hover-bg: var(--mb-adapt-button-hover-bg, rgba(128, 128, 128, 0.2));
--_separator-active: var(--mb-adapt-separator-active, rgba(59, 130, 246, 0.5));
--_floating-shadow: var(--mb-adapt-floating-shadow, 0 25px 50px -12px rgba(0, 0, 0, 0.25), 0 12px 24px -8px rgba(0, 0, 0, 0.15));
--_floating-border: var(--mb-adapt-floating-border, none);
--_floating-backdrop: var(--mb-adapt-floating-backdrop, none);
--_floating-radius: var(--mb-adapt-floating-radius, 8px);
--_status-card-bg: var(--mb-adapt-status-card-bg, #ffffff);
--_status-card-border: var(--mb-adapt-status-card-border, #e5e7eb);
--_status-card-shadow: var(--mb-adapt-status-card-shadow, 0 4px 24px rgba(0, 0, 0, 0.08), 0 2px 8px rgba(0, 0, 0, 0.04));
--_status-icon-bg: var(--mb-adapt-status-icon-bg, #fef2f2);
--_status-icon-stopped-bg: var(--mb-adapt-status-icon-stopped-bg, var(--mb-adapt-status-icon-bg, #f3f4f6));
--_status-text: var(--mb-adapt-status-text, #374151);
--_drag-ghost-shadow: var(--mb-adapt-drag-ghost-shadow, 0 4px 12px rgba(0, 0, 0, 0.15));
--_border-radius: var(--mb-adapt-border-radius, 8px);
--_z-base: var(--mb-adapt-z-base, 0);
--mb-adapt-responsive-breakpoint: 768;
--mb-adapt-responsive-hysteresis: 40;
/* Cap.js widget variables */
--_cap-background: var(--mb-adapt-cap-background, #ffffff);
--_cap-border-color: var(--mb-adapt-cap-border-color, #e2e8f0);
--_cap-border-radius: var(--mb-adapt-cap-border-radius, 16px);
--_cap-height: var(--mb-adapt-cap-height, 72px);
--_cap-width: var(--mb-adapt-cap-width, 380px);
--_cap-padding: var(--mb-adapt-cap-padding, 20px 28px);
--_cap-gap: var(--mb-adapt-cap-gap, 20px);
--_cap-color: var(--mb-adapt-cap-color, #1e293b);
--_cap-checkbox-size: var(--mb-adapt-cap-checkbox-size, 36px);
--_cap-checkbox-border: var(--mb-adapt-cap-checkbox-border, 2px solid #cbd5e1);
--_cap-checkbox-radius: var(--mb-adapt-cap-checkbox-radius, 10px);
--_cap-checkbox-background: var(--mb-adapt-cap-checkbox-background, #f8fafc);
--_cap-spinner-color: var(--mb-adapt-cap-spinner-color, #6366f1);
--_cap-spinner-bg: var(--mb-adapt-cap-spinner-bg, #e2e8f0);
--_cap-font: var(--mb-adapt-cap-font, inherit);
--_cap-spinner-thickness: var(--mb-adapt-cap-spinner-thickness, 3px);
--_cap-invalid-border-color: var(--mb-adapt-cap-invalid-border-color, #f55b50);
--_cap-invalid-ring-color: var(--mb-adapt-cap-invalid-ring-color, rgba(245, 91, 80, 0.2));
--_cap-shadow: var(--mb-adapt-cap-shadow, 0 4px 20px rgba(0, 0, 0, 0.08), 0 2px 8px rgba(0, 0, 0, 0.04));
--_cap-shadow-hover: var(--mb-adapt-cap-shadow-hover, 0 8px 30px rgba(0, 0, 0, 0.12), 0 4px 12px rgba(0, 0, 0, 0.06));
/* Fork panel theming */
--_main-bg: var(--mb-adapt-main-bg, transparent);
--_fork-bg: var(--mb-adapt-fork-bg, #ffffff);
--_fork-tab-bg: var(--mb-adapt-fork-tab-bg, #f3f3f3);
--_fork-tab-active-bg: var(--mb-adapt-fork-tab-active-bg, #ffffff);
--_fork-tab-color: var(--mb-adapt-fork-tab-color, rgb(51, 51, 51));
--_fork-tab-inactive-color: var(--mb-adapt-fork-tab-inactive-color, rgba(51, 51, 51, 0.7));
--_fork-separator: var(--mb-adapt-fork-separator, rgb(218, 218, 218));
/* Tab shape */
--_tab-radius: var(--mb-adapt-tab-radius, 0);
--_tab-shadow: var(--mb-adapt-tab-shadow, none);
--_tab-active-shadow: var(--mb-adapt-tab-active-shadow, none);
--_tab-gap: var(--mb-adapt-tab-gap, 0px);
--_tab-padding: var(--mb-adapt-tab-padding, 0 14px);
--_tab-font-size: var(--mb-adapt-tab-font-size, 13px);
--_tab-min-width: var(--mb-adapt-tab-min-width, 100px);
--_tab-spacing: var(--mb-adapt-tab-spacing, 6px);
--_toolbar-height: var(--mb-adapt-toolbar-height, 40px);
--_toolbar-padding: var(--mb-adapt-toolbar-padding, 0);
/* Drop targets — light defaults */
--_drop-header-bg: var(--mb-adapt-drop-header-bg, rgba(99, 102, 241, 0.18));
--_drop-center-bg: var(--mb-adapt-drop-center-bg, rgba(99, 102, 241, 0.12));
--_drop-split-bg: var(--mb-adapt-drop-split-bg, rgba(99, 102, 241, 0.14));
--_drop-border: var(--mb-adapt-drop-border, rgba(99, 102, 241, 0.55));
background: var(--_bg);
}
.mb-adapt--dark {
/* Cap.js widget dark mode */
--_cap-background: var(--mb-adapt-cap-background, #1e293b);
--_cap-border-color: var(--mb-adapt-cap-border-color, #334155);
--_cap-color: var(--mb-adapt-cap-color, #f1f5f9);
--_cap-checkbox-border: var(--mb-adapt-cap-checkbox-border, 2px solid #475569);
--_cap-checkbox-background: var(--mb-adapt-cap-checkbox-background, #0f172a);
--_cap-spinner-color: var(--mb-adapt-cap-spinner-color, #818cf8);
--_cap-spinner-bg: var(--mb-adapt-cap-spinner-bg, #334155);
--_cap-shadow: var(--mb-adapt-cap-shadow, 0 4px 20px rgba(0, 0, 0, 0.25), 0 2px 8px rgba(0, 0, 0, 0.15));
--_cap-shadow-hover: var(--mb-adapt-cap-shadow-hover, 0 8px 30px rgba(0, 0, 0, 0.35), 0 4px 12px rgba(0, 0, 0, 0.2));
/* Status card dark mode */
--_status-card-bg: var(--mb-adapt-status-card-bg, #1e293b);
--_status-card-border: var(--mb-adapt-status-card-border, #334155);
--_status-icon-bg: var(--mb-adapt-status-icon-bg, #351c1c);
--_status-icon-stopped-bg: var(--mb-adapt-status-icon-stopped-bg, var(--mb-adapt-status-icon-bg, #1e293b));
--_status-text: var(--mb-adapt-status-text, #e2e8f0);
/* Panel dark mode overrides */
--_button-hover-bg: var(--mb-adapt-button-hover-bg, rgba(128, 128, 128, 0.3));
--_separator-active: var(--mb-adapt-separator-active, rgba(99, 130, 246, 0.6));
--_floating-shadow: var(--mb-adapt-floating-shadow, 0 25px 50px -12px rgba(0, 0, 0, 0.5), 0 12px 24px -8px rgba(0, 0, 0, 0.3));
--_floating-border: var(--mb-adapt-floating-border, 1px solid rgba(255, 255, 255, 0.06));
--_status-card-shadow: var(--mb-adapt-status-card-shadow, 0 4px 24px rgba(0, 0, 0, 0.25), 0 2px 8px rgba(0, 0, 0, 0.15));
--_drag-ghost-shadow: var(--mb-adapt-drag-ghost-shadow, 0 4px 12px rgba(0, 0, 0, 0.35));
/* Fork panel dark mode */
--_main-bg: var(--mb-adapt-main-bg, transparent);
--_fork-bg: var(--mb-adapt-fork-bg, #1e1e1e);
--_fork-tab-bg: var(--mb-adapt-fork-tab-bg, #252526);
--_fork-tab-active-bg: var(--mb-adapt-fork-tab-active-bg, #1e1e1e);
--_fork-tab-color: var(--mb-adapt-fork-tab-color, #ffffff);
--_fork-tab-inactive-color: var(--mb-adapt-fork-tab-inactive-color, #969696);
--_fork-separator: var(--mb-adapt-fork-separator, rgb(68, 68, 68));
/* Drop target dark mode */
--_drop-header-bg: var(--mb-adapt-drop-header-bg, rgba(129, 140, 248, 0.22));
--_drop-center-bg: var(--mb-adapt-drop-center-bg, rgba(129, 140, 248, 0.15));
--_drop-split-bg: var(--mb-adapt-drop-split-bg, rgba(129, 140, 248, 0.18));
--_drop-border: var(--mb-adapt-drop-border, rgba(129, 140, 248, 0.6));
}
/* ── Layout (recursive split tree) ───────────────────── */
.mb-layout {
flex: 1;
min-height: 0;
position: relative;
display: flex;
}
.mb-split-container {
display: flex;
min-width: 0;
min-height: 0;
}
.mb-split-horizontal { flex-direction: row; }
.mb-split-vertical { flex-direction: column; }
.mb-split-leaf {
min-width: 0;
min-height: 0;
overflow: hidden;
}
/* Animated flex transition — applied temporarily during dock/undock/maximize */
.mb-split-leaf--animating {
transition: flex 0.25s ease;
}
.mb-split-container--animating {
transition: flex 0.25s ease;
}
.mb-layout-separator--animating {
transition: opacity 0.25s ease;
}
/* Draggable separator between split panels */
.mb-layout-separator {
flex: 0 0 5px;
background: var(--_fork-separator);
transition: background 0.15s;
position: relative;
z-index: calc(1 + var(--_z-base));
touch-action: none;
}
.mb-layout-separator-v { cursor: col-resize; }
.mb-layout-separator-h { cursor: row-resize; }
.mb-layout-separator:hover,
.mb-layout-separator--active {
background: var(--_separator-active);
}
/* ── Group ───────────────────────────────────────────── */
.mb-group {
display: flex;
flex-direction: column;
height: 100%;
background: var(--_bg);
}
.mb-group-header {
display: flex;
align-items: stretch;
height: var(--_toolbar-height);
min-height: var(--_toolbar-height);
padding: var(--_toolbar-padding);
background: var(--_fork-tab-bg);
border-bottom: 1px solid var(--_fork-separator);
user-select: none;
}
.mb-group-header-prefix {
display: flex;
align-items: stretch;
}
.mb-group-tabs {
display: flex;
align-items: stretch;
overflow-x: auto;
overflow-y: hidden;
flex: 0 1 auto;
min-width: 0;
}
.mb-group-tabs::-webkit-scrollbar {
height: 2px;
}
/* Drag handle — fills remaining header space so the user can grab it */
.mb-group-header-void {
flex: 1;
min-width: 40px;
touch-action: none;
}
.mb-group-header-actions {
display: flex;
align-items: center;
}
.mb-group-content {
flex: 1;
position: relative;
overflow: hidden;
background: var(--_fork-bg);
}
/* Main group overrides */
.mb-group[data-main-group="true"] {
background: var(--_bg);
}
.mb-group[data-main-group="true"] .mb-group-content {
background: var(--_main-bg);
}
/* ── Tab ─────────────────────────────────────────────── */
.mb-tab {
display: flex;
align-items: center;
gap: var(--_tab-spacing);
padding: var(--_tab-padding);
min-width: var(--_tab-min-width);
font-size: var(--_tab-font-size);
font-family: var(--_font);
white-space: nowrap;
cursor: pointer;
touch-action: none;
color: var(--_fork-tab-inactive-color);
background: var(--_fork-tab-bg);
border-right: 1px solid var(--_fork-separator);
border-radius: var(--_tab-radius);
box-shadow: var(--_tab-shadow);
margin: var(--_tab-gap);
transition: background 0.15s, box-shadow 0.15s;
}
.mb-tab[data-active="true"] {
color: var(--_fork-tab-color);
background: var(--_fork-tab-active-bg);
box-shadow: var(--_tab-active-shadow);
}
.mb-tab:hover {
background: var(--_fork-tab-active-bg);
}
.mb-tab-label {
display: flex;
align-items: center;
}
.mb-tab-label svg {
width: 14px;
height: 14px;
opacity: 0.7;
flex-shrink: 0;
}
.mb-tab[data-active="true"] .mb-tab-label svg {
opacity: 1;
}
.mb-tab-actions {
display: flex;
align-items: center;
gap: 2px;
width: 40px;
flex-shrink: 0;
justify-content: flex-end;
margin-left: auto;
}
.mb-tab-close {
width: 18px;
height: 18px;
padding: 0;
border: none;
background: transparent;
color: inherit;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
border-radius: 3px;
opacity: 0;
transition: opacity 0.15s, background 0.15s;
}
.mb-tab:hover .mb-tab-close {
opacity: 0.7;
}
.mb-tab-close:hover {
opacity: 1 ;
background: var(--_button-hover-bg);
}
.mb-tab-close svg {
width: 12px;
height: 12px;
}
/* ── Panel visibility ────────────────────────────────── */
.mb-panel {
width: 100%;
height: 100%;
position: absolute;
inset: 0;
}
.mb-panel[data-active="false"] {
display: none;
}
.mb-panel[data-active="true"] {
display: block;
}
/* ── Floating overlay ────────────────────────────────── */
.mb-floating-overlay {
position: fixed;
z-index: calc(100000 + var(--_z-base));
box-shadow: var(--_floating-shadow);
border: var(--_floating-border);
backdrop-filter: var(--_floating-backdrop);
-webkit-backdrop-filter: var(--_floating-backdrop);
border-radius: var(--_floating-radius);
display: flex;
flex-direction: column;
/* No overflow:hidden here — resize handles use negative offsets (top:-3px etc.)
and would be clipped. The inner .mb-group already has overflow:hidden for
its own border-radius clipping. */
}
.mb-floating-overlay > .mb-group {
flex: 1;
border-radius: var(--_floating-radius);
overflow: hidden;
}
/* Internal split layout inside a floating overlay */
.mb-floating-overlay > .mb-layout {
position: relative;
inset: auto;
height: auto;
flex: 1;
min-width: 0;
min-height: 0;
border-radius: var(--_floating-radius);
overflow: hidden;
}
.mb-floating-maximized {
border-radius: 0;
box-shadow: none;
}
.mb-floating-maximized .mb-group {
border-radius: 0;
}
.mb-floating-maximized .mb-resize-handle {
display: none ;
}
.mb-floating-maximized .mb-group-header-void {
pointer-events: none;
}
/* ── Resize handles ──────────────────────────────────── */
.mb-resize-handle {
position: absolute;
z-index: calc(10 + var(--_z-base));
touch-action: none;
}
.mb-resize-n { top: -3px; left: 8px; right: 8px; height: 6px; cursor: n-resize; }
.mb-resize-s { bottom: -3px; left: 8px; right: 8px; height: 6px; cursor: s-resize; }
.mb-resize-e { right: -3px; top: 8px; bottom: 8px; width: 6px; cursor: e-resize; }
.mb-resize-w { left: -3px; top: 8px; bottom: 8px; width: 6px; cursor: w-resize; }
.mb-resize-ne { top: -3px; right: -3px; width: 12px; height: 12px; cursor: ne-resize; }
.mb-resize-nw { top: -3px; left: -3px; width: 12px; height: 12px; cursor: nw-resize; }
.mb-resize-se { bottom: -3px; right: -3px; width: 12px; height: 12px; cursor: se-resize; }
.mb-resize-sw { bottom: -3px; left: -3px; width: 12px; height: 12px; cursor: sw-resize; }
/* ── Iframe styling ──────────────────────────────────── */
.mb-adapt__iframe {
width: 100%;
height: 100%;
min-height: 0;
border: 0;
display: block;
background: transparent;
border-radius: var(--_border-radius);
pointer-events: auto;
opacity: 0;
transition: opacity 0.1s ease-out;
}
.mb-adapt__iframe--visible {
opacity: 1;
}
.mb-adapt__iframe--hidden {
display: none;
}
/* ── Status message overlay ──────────────────────────── */
.mb-adapt__status-message {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
z-index: calc(200000 + var(--_z-base));
background: transparent;
pointer-events: none;
}
.mb-adapt__status-card {
pointer-events: auto;
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
padding: 32px 40px;
max-width: 380px;
border-radius: 16px;
background: var(--_status-card-bg);
border: 1px solid var(--_status-card-border);
box-shadow: var(--_status-card-shadow);
font-family: var(--_font);
text-align: center;
}
.mb-adapt__status-icon {
width: 48px;
height: 48px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
background: var(--_status-icon-bg);
}
.mb-adapt__status-icon svg {
width: 24px;
height: 24px;
}
.mb-adapt__status-icon--stopped {
background: var(--_status-icon-stopped-bg);
}
.mb-adapt__status-text {
color: var(--_status-text);
font-size: 15px;
line-height: 1.5;
margin: 0;
}
.mb-adapt__status-restart {
padding: 8px 20px;
border: 1px solid var(--_status-card-border);
border-radius: 8px;
background: transparent;
color: var(--_status-text);
font-size: 14px;
font-weight: 500;
font-family: var(--_font);
cursor: pointer;
transition: background 0.15s, border-color 0.15s;
}
.mb-adapt__status-restart:hover {
background: var(--_status-card-border);
}
/* ── Confirm-on-close dialog ────────────────────────── */
.mb-adapt__confirm-overlay {
position: fixed;
inset: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
z-index: calc(300000 + var(--_z-base));
background: rgba(0, 0, 0, 0.4);
height: auto;
min-height: 0;
}
.mb-adapt--dark.mb-adapt__confirm-overlay {
background: rgba(0, 0, 0, 0.55);
}
.mb-adapt__confirm-card {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 16px;
padding: 24px 28px;
max-width: 360px;
width: 100%;
border-radius: var(--_floating-radius);
background: var(--_fork-tab-active-bg);
border: 1px solid var(--_fork-separator);
box-shadow: var(--_floating-shadow);
font-family: var(--_font);
text-align: center;
}
.mb-adapt__confirm-text {
font-size: 14px;
line-height: 1.5;
color: var(--_fork-tab-color);
margin: 0;
}
.mb-adapt__confirm-buttons {
display: flex;
gap: 8px;
justify-content: flex-end;
}
.mb-adapt__confirm-btn {
padding: 8px 16px;
border-radius: 6px;
font-size: 13px;
font-family: var(--_font);
cursor: pointer;
font-weight: 500;
transition: background 0.15s, border-color 0.15s;
}
.mb-adapt__confirm-btn--cancel {
background: transparent;
border: 1px solid var(--_fork-separator);
color: var(--_fork-tab-color);
}
.mb-adapt__confirm-btn--cancel:hover {
background: var(--_button-hover-bg);
}
.mb-adapt__confirm-btn--confirm {
background: var(--_fork-tab-color);
color: var(--_fork-tab-active-bg);
border: 1px solid transparent;
}
.mb-adapt__confirm-btn--confirm:hover {
opacity: 0.85;
}
/* ── Cap.js widget positioning ───────────────────────── */
.mb-adapt-cap {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
z-index: calc(200000 + var(--_z-base));
}
.mb-adapt-cap > * {
pointer-events: auto;
}
/* Cap.js widget styling */
.mb-adapt cap-widget {
--cap-background: var(--_cap-background);
--cap-border-color: var(--_cap-border-color);
--cap-border-radius: var(--_cap-border-radius);
--cap-widget-height: var(--_cap-height);
--cap-widget-width: var(--_cap-width);
--cap-widget-padding: var(--_cap-padding);
--cap-gap: var(--_cap-gap);
--cap-color: var(--_cap-color);
--cap-checkbox-size: var(--_cap-checkbox-size);
--cap-checkbox-border: var(--_cap-checkbox-border);
--cap-checkbox-border-radius: var(--_cap-checkbox-radius);
--cap-checkbox-background: var(--_cap-checkbox-background);
--cap-checkbox-margin: 0;
--cap-font: var(--_cap-font);
--cap-spinner-color: var(--_cap-spinner-color);
--cap-spinner-background-color: var(--_cap-spinner-bg);
--cap-spinner-thickness: var(--_cap-spinner-thickness);
--cap-invalid-border-color: var(--_cap-invalid-border-color);
--cap-invalid-ring-color: var(--_cap-invalid-ring-color);
}
/* Hide Cap.js credits */
cap-widget::part(attribution) {
display: none ;
visibility: hidden ;
pointer-events: none ;
}
/* ── Fork group action buttons ───────────────────────── */
.mb-adapt-fork-actions {
display: flex;
align-items: center;
gap: 2px;
padding-right: 4px;
}
.mb-adapt-fork-actions button {
width: 20px;
height: 20px;
padding: 0;
border: none;
background: transparent;
color: var(--_fork-tab-color);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
border-radius: 3px;
opacity: 0.7;
transition: opacity 0.15s, background 0.15s;
}
.mb-adapt-fork-actions button:hover {
opacity: 1;
background: var(--_button-hover-bg);
}
.mb-adapt-fork-actions button svg {
width: 14px;
height: 14px;
}
/* ── Minimized-group tabs bar (at the top, NOT an overlay) ─── */
/* Sits at the top of .mb-adapt as a normal flow element so the layout
underneath shrinks to accommodate it. This prevents scrollbars when
docked panels are minimized — the iframe gets the remaining height. */
.mb-adapt-minimized-tabs {
display: none;
height: var(--_toolbar-height);
flex-shrink: 0;
z-index: calc(100 + var(--_z-base));
align-items: stretch;
background: var(--_fork-tab-bg);
border-bottom: 1px solid var(--_fork-separator);
user-select: none;
}
.mb-adapt-minimized-tab {
display: flex;
align-items: center;
gap: 8px;
padding: 0 12px;
flex: 1;
background: var(--_fork-tab-bg);
color: var(--_fork-tab-color);
font-size: var(--_tab-font-size);
font-family: var(--_font);
white-space: nowrap;
border-right: 1px solid var(--_fork-separator);
cursor: default;
}
.mb-adapt-minimized-tab-label {
flex: 1;
display: flex;
align-items: center;
gap: 4px;
}
.mb-adapt-minimized-tab-label svg {
width: 14px;
height: 14px;
opacity: 0.8;
flex-shrink: 0;
}
.mb-adapt-minimized-tab-action {
width: 22px;
height: 22px;
padding: 0;
border: none;
background: transparent;
color: inherit;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
opacity: 0.6;
transition: opacity 0.15s, background 0.15s;
}
.mb-adapt-minimized-tab-action:hover {
opacity: 1;
background: var(--_button-hover-bg);
}
.mb-adapt-minimized-tab-action svg {
width: 14px;
height: 14px;
}
/* Minimized tab drag handle cursor */
.mb-adapt-minimized-tab {
cursor: grab;
touch-action: none;
}
/* Drop target highlight for minimized tab merge */
.mb-adapt-minimized-tab--drop-target {
background: var(--_drop-header-bg) ;
box-shadow: inset 0 0 0 2px var(--_drop-border);
}
/* ── Pointer-drag ghost element ───────────────────────── */
.mb-drag-ghost {
position: fixed;
pointer-events: none;
z-index: calc(999999 + var(--_z-base));
padding: 4px 10px;
background: var(--_fork-tab-bg);
color: var(--_fork-tab-color);
border: 1px solid var(--_fork-separator);
border-radius: var(--_tab-radius, 4px);
font-size: var(--_tab-font-size);
font-family: var(--_font);
white-space: nowrap;
box-shadow: var(--_drag-ghost-shadow);
opacity: 0.92;
display: flex;
align-items: center;
}
.mb-drag-ghost svg {
width: 16px;
height: 16px;
}
/* ── Drop target highlight on group header ───────────── */
.mb-group-header--drop-target {
background: var(--_drop-header-bg) ;
box-shadow: inset 0 0 0 2px var(--_drop-border);
}
/* ── Drop overlay (content-area and dock-strip indicators) */
.mb-drop-overlay {
position: fixed;
pointer-events: none;
z-index: calc(999998 + var(--_z-base));
display: none;
box-sizing: border-box;
border-radius: 6px;
transition: opacity 0.1s ease-out;
}
.mb-drop-overlay[data-zone="center"] {
background: var(--_drop-center-bg);
border: 2px solid var(--_drop-border);
}
.mb-drop-overlay[data-zone="top"],
.mb-drop-overlay[data-zone="bottom"],
.mb-drop-overlay[data-zone="left"],
.mb-drop-overlay[data-zone="right"] {
background: var(--_drop-split-bg);
border: 2px solid var(--_drop-border);
}
/* ── Iframe pointer-event guard during drag ──────────── */
html.mb-dragging iframe,
html.mb-dragging webview {
pointer-events: none ;
}
/* ── Tab pop-out button ─────────────────────────────── */
.mb-tab-popout {
width: 18px;
height: 18px;
padding: 0;
border: none;
background: transparent;
color: inherit;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
border-radius: 3px;
opacity: 0;
transition: opacity 0.15s, background 0.15s;
}
.mb-tab:hover .mb-tab-popout {
opacity: 0.7;
}
.mb-tab-popout:hover {
opacity: 1 ;
background: var(--_button-hover-bg);
}
.mb-tab-popout svg {
width: 12px;
height: 12px;
}
/* Hide pop-out button on main group (never floats), when overlay
has 0 or 1 total tabs (nothing to pop out), and when floating is disallowed. */
.mb-group[data-main-group="true"] .mb-tab-popout,
.mb-floating-overlay[data-total-tab-count="0"] .mb-tab-popout,
.mb-floating-overlay[data-total-tab-count="1"] .mb-tab-popout,
.mb-group[data-allow-floating="false"] .mb-tab-popout {
display: none ;
}
/* ── Iframe portal layer ─────────────────────────────── */
/* MUST NOT create a stacking context — portal entries' z-indexes
must compete with floating overlays in the parent stacking context.
position: absolute + no z-index achieves this. */
.mb-iframe-portal-layer {
position: absolute;
width: 0;
height: 0;
overflow: visible;
pointer-events: none;
}
.mb-iframe-portal {
position: fixed;
pointer-events: auto;
overflow: hidden;
}
/* ── Touch device adjustments ────────────────────────── */
@media (hover: none) {
.mb-tab-close {
opacity: 0.5;
}
.mb-tab-popout {
opacity: 0.5;
}
.mb-tab:hover .mb-tab-close,
.mb-tab:hover .mb-tab-popout {
opacity: 0.7;
}
}
@media (pointer: coarse) {
.mb-tab-close,
.mb-tab-popout {
width: 24px;
height: 24px;
}
.mb-adapt-fork-actions button {
width: 26px;
height: 26px;
}
.mb-adapt-minimized-tab-action {
width: 28px;
height: 28px;
}
}
/* === CAP WIDGET === */
/* ============================================
Mochabug Adapt Cap Widget - Premium Design
============================================ */
.mb-adapt-cap {
/* Sizing */
--mb-cap-border-radius: 16px;
--mb-cap-height: 72px;
--mb-cap-width: 320px;
--mb-cap-padding: 18px 22px;
--mb-cap-gap: 16px;
/* Light Mode Colors */
--mb-cap-bg: #ffffff;
--mb-cap-border-color: #e5e7eb;
--mb-cap-text-color: #111827;
/* Checkbox */
--mb-cap-checkbox-size: 30px;
--mb-cap-checkbox-radius: 8px;
--mb-cap-checkbox-border-color: #d1d5db;
--mb-cap-checkbox-bg: #f9fafb;
/* Spinner */
--mb-cap-spinner-color: #6366f1;
--mb-cap-spinner-bg: #e5e7eb;
--mb-cap-invalid-border-color: #f55b50;
--mb-cap-invalid-ring-color: rgba(245, 91, 80, 0.2);
/* Typography */
--mb-cap-font: inherit;
/* Shadows */
--mb-cap-shadow:
0 1px 3px rgba(0, 0, 0, 0.08),
0 4px 12px rgba(0, 0, 0, 0.05);
--mb-cap-shadow-hover:
0 4px 12px rgba(0, 0, 0, 0.1),
0 8px 24px rgba(0, 0, 0, 0.08);
}
/* Dark Mode */
.mb-adapt-cap--dark {
--mb-cap-bg: #1f2937;
--mb-cap-border-color: #374151;
--mb-cap-text-color: #f9fafb;
--mb-cap-checkbox-border-color: #4b5563;
--mb-cap-checkbox-bg: #374151;
--mb-cap-spinner-color: #818cf8;
--mb-cap-spinner-bg: #4b5563;
--mb-cap-shadow:
0 1px 3px rgba(0, 0, 0, 0.3),
0 4px 12px rgba(0, 0, 0, 0.2);
--mb-cap-shadow-hover:
0 4px 12px rgba(0, 0, 0, 0.4),
0 8px 24px rgba(0, 0, 0, 0.3);
}
/* Container */
.mb-adapt-cap__container {
display: flex;
align-items: center;
justify-content: center;
}
/* Cap Widget — only CSS custom properties (cap.js recommended approach) */
.mb-adapt-cap cap-widget {
--cap-background: var(--mb-cap-bg);
--cap-border-color: var(--mb-cap-border-color);
--cap-border-radius: var(--mb-cap-border-radius);
--cap-widget-height: var(--mb-cap-height);
--cap-widget-width: var(--mb-cap-width);
--cap-widget-padding: var(--mb-cap-padding);
--cap-gap: var(--mb-cap-gap);
--cap-color: var(--mb-cap-text-color);
--cap-checkbox-size: var(--mb-cap-checkbox-size);
--cap-checkbox-border: 2px solid var(--mb-cap-checkbox-border-color);
--cap-checkbox-border-radius: var(--mb-cap-checkbox-radius);
--cap-checkbox-background: var(--mb-cap-checkbox-bg);
--cap-checkbox-margin: 0;
--cap-font: var(--mb-cap-font);
--cap-spinner-color: var(--mb-cap-spinner-color);
--cap-spinner-background-color: var(--mb-cap-spinner-bg);
--cap-spinner-thickness: 3px;
--cap-invalid-border-color: var(--mb-cap-invalid-border-color);
--cap-invalid-ring-color: var(--mb-cap-invalid-ring-color);
display: block;
}
/* Hide Cap.js credits. Cap's shadow CSS marks credits as display:block!important,
so keep this in the standalone CAP stylesheet and reinforce it at runtime. */
.mb-adapt-cap cap-widget::part(attribution),
cap-widget::part(attribution) {
display: none ;
visibility: hidden ;
pointer-events: none ;
}
/* Responsive */
@media (max-width: 380px) {
.mb-adapt-cap {
--mb-cap-width: 280px;
--mb-cap-height: 64px;
--mb-cap-padding: 14px 18px;
--mb-cap-checkbox-size: 26px;
}
}