/* MIROJAM — Global Styles */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;500;600;700&family=Noto+Sans:wght@100;200;300;400;500;600;700;800&family=Roboto:wght@300;400;500;700&family=Montserrat:wght@200;300;400;500;600;700&family=Oswald:wght@300;400;500;700&family=Merriweather:wght@300;400;700&family=PT+Serif:wght@400;700&family=Caveat:wght@400;700&family=Pangolin&family=Neucha&family=Bad+Script&family=Lobster&family=Roboto+Mono:wght@300;400;500;700&family=Yanone+Kaffeesatz:wght@300;400;500;600;700&family=Ruslan+Display&family=Rubik+Bubbles&family=Amatic+SC:wght@400;700&family=Play:wght@400;700&display=swap');

:root {
    --bg: #0c0c0d;
    --panel: #151517;
    --panel-2: #1c1c1f;
    --panel-3: #26262a;
    --line: #33333a;
    --text: #efece6;
    --muted: #9a958c;
    --muted-2: #79756d;
    /* Gold accent (mapped onto legacy --blue vars so all usages turn gold) */
    --blue: #ffffff;
    --blue-2: #d8d8d8;
    --blue-hover: #ffffff;
    --gold: #ffffff;
    --gold-2: #d8d8d8;
    --gold-hover: #ffffff;
    --on-gold: #1a1712;
    --green: #22c55e;
    --green-bg: rgba(34,197,94,.12);
    --orange: #f59e0b;
    --orange-bg: rgba(245,158,11,.12);
    --danger: #8b5cf6;
    --danger-2: #7c3aed;
    --danger-bg: rgba(139,92,246,.14);
    --on-danger: #ffffff;
    --on-secondary: #ffffff;
    /* Borders & overlays (white-on-dark). NOTE: these were self-referential (`--border: var(--border)`) which is
       invalid CSS → bordered elements silently lost their border in dark mode while light mode had them. Concrete
       subtle white-alpha values restore the intended look (mirrors the light theme's rgba(0,0,0,.13) tokens). */
    --border: rgba(255,255,255,.09);
    --border-faint: rgba(255,255,255,.05);
    --border-strong: rgba(255,255,255,.17);
    --border-ring: rgba(255,255,255,.12);
    --hover-row: rgba(255,255,255,.05);
    --fill-soft: rgba(255,255,255,.05);
    --avatar-ring: rgba(255,255,255,.2);
    --panel-hover: #2f2f36;
    /* Accent (gold) tints */
    --gold-bg: rgba(255,255,255,.12);
    --gold-bg-soft: rgba(255,255,255,.05);
    /* Status accents (translucent) */
    --orange-border: rgba(245,158,11,.3);
    --orange-faint: rgba(245,158,11,.5);
    /* Misc effects */
    --flash: rgba(255,255,255,.96);
    /* Ambient glow (body background) */
    --glow-strong: rgba(255,255,255,.08);
    --glow-soft: rgba(255,255,255,.04);
    --glow-white: var(--hover-row);
    /* Elevation */
    --backdrop: rgba(0,0,0,.6);
    --popover-bg: rgba(20,20,23,.97);
    --shadow-md: 0 8px 24px rgba(0,0,0,.3);
    --shadow-lg: 0 16px 48px rgba(0,0,0,.3);
    --radius-xl: 24px;
    --radius-lg: 18px;
    --radius-md: 14px;
    --radius-sm: 10px;
    --radius-xs: 8px;
    /* Control sizing (original givemeacomment density — tune here to re-scale UI) */
    --btn-h: 44px;
    --btn-sm-h: 34px;
    --input-h: 46px;
    --topbar-h: 60px;
    --shadow-card: 0 2px 16px rgba(0,0,0,.45);
    --transition: .18s ease;
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
    margin: 0;
    min-height: 100vh;
    background: var(--bg);
    color: var(--text);
    font-family: 'Noto Sans', 'Segoe UI', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    font-size: 14px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

body {
    background:
        radial-gradient(ellipse 80% 60% at 5% 0%, var(--glow-strong) 0%, transparent 50%),
        radial-gradient(ellipse 70% 55% at 95% 100%, var(--glow-soft) 0%, transparent 50%),
        radial-gradient(ellipse 50% 40% at 50% 50%, var(--glow-white) 0%, transparent 60%),
        var(--bg);
    background-attachment: fixed;
}

a { color: var(--blue); text-decoration: none; }
/* Links inside board blocks follow the block's text colour (so the colour control works on them). */
.be-el-inner a { color: inherit; text-decoration: underline; }
a:hover { color: var(--blue-hover); }

button, input, textarea, select { font: inherit; }
button { cursor: pointer; outline: none; }
img { max-width: 100%; }

/* ---------- Utility ---------- */
.text-muted { color: var(--muted); }
.text-danger { color: var(--danger); }
.text-center { text-align: center; }
.mt-md { margin-top: 16px; }
.mt-lg { margin-top: 24px; }
.mb-sm { margin-bottom: 8px; }
.mb-md { margin-bottom: 16px; }
.hidden { display: none !important; }
.flex { display: flex; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-sm { gap: 8px; }

/* ---------- Auth Pages ---------- */
.auth-page {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 24px;
}

.auth-card {
    width: 100%;
    max-width: 420px;
    background: var(--panel-2);
    border: 1px solid var(--line);
    border-radius: var(--radius-xl);
    padding: 40px 36px;
    box-shadow: var(--shadow-card);
}

.auth-logo {
    font-size: 13px;
    font-weight: 800;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--blue);
    margin-bottom: 4px;
}

.auth-title {
    font-size: 24px;
    font-weight: 700;
    margin: 0 0 6px;
}

.auth-subtitle {
    color: var(--muted);
    font-size: 13px;
    margin-bottom: 28px;
}

/* ---------- Forms ---------- */
.form-group {
    margin-bottom: 18px;
}

.form-label {
    display: block;
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    margin-bottom: 6px;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.form-input {
    display: block;
    width: 100%;
    height: var(--input-h);
    padding: 0 16px;
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    transition: border-color var(--transition);
}
/* API-key fields: masked like a password but a plain text input, so the browser's
   password manager never offers to "save a password" for them. */
.be-keyfield { -webkit-text-security: disc; text-security: disc; }

.form-input:focus {
    outline: none;
    border-color: var(--blue);
}

.form-input::placeholder {
    color: var(--muted-2);
}

/* Number inputs — hide the OS spinner triangles everywhere (they don't match the dark portal theme). */
input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }
.form-input[type="number"] { text-align: center; }

textarea.form-input {
    height: auto;
    min-height: 100px;
    padding: 12px 16px;
    resize: vertical;
}

select.form-input {
    appearance: none;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%239ca9bc' stroke-width='2' fill='none'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    padding-right: 36px;
}

.form-error {
    color: var(--danger);
    font-size: 12px;
    margin-top: 4px;
}

.form-hint {
    color: var(--muted-2);
    font-size: 12px;
    margin-top: 4px;
}

/* ---------- Buttons ---------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: var(--btn-h);
    padding: 0 22px;
    border: none;
    border-radius: var(--radius-md);
    font-weight: 600;
    font-size: 14px;
    transition: all var(--transition);
    white-space: nowrap;
    text-decoration: none;
}

.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

.btn-primary {
    background: var(--blue-2);
    color: var(--on-gold);
}
.btn-primary:hover { background: var(--blue); color: var(--on-gold); }

.btn-secondary {
    background: var(--panel-3);
    color: var(--text);
    border: 1px solid var(--line);
}
.btn-secondary:hover { background: var(--panel-hover); color: var(--text); }

.btn-danger {
    background: var(--danger);
    color: var(--on-danger);
}
.btn-danger:hover { background: var(--danger-2); color: var(--on-danger); }

.btn-ghost {
    background: transparent;
    color: var(--muted);
    border: 1px solid var(--line);
}
.btn-ghost:hover { color: var(--text); border-color: var(--muted); }

.btn-sm {
    height: var(--btn-sm-h);
    padding: 0 14px;
    font-size: 12px;
    border-radius: var(--radius-sm);
}

.btn-full { width: 100%; }

.btn svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* ---------- App Layout ---------- */
.app-shell {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.app-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    padding: 0 28px;
    height: var(--topbar-h);
    background: var(--panel-2);
    border-bottom: 1px solid var(--border);
    flex-shrink: 0;
}

.app-topbar-brand {
    font-size: 18px;
    font-weight: 800;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.app-topbar-brand span { color: var(--blue); }
.portal-logo { height: 26px; width: auto; max-width: 180px; object-fit: contain; display: block; }
/* recolour the logo to a solid silhouette that matches the tone: white on dark, black on a light tone */
.portal-logo { filter: brightness(0) invert(1); }
:root.portal-light .portal-logo { filter: brightness(0); }
.portal-name { white-space: nowrap; }
/* Admin → Portal settings card */
#portalCard .portal-grid { display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); gap: 30px; align-items: start; }
/* Uniform vertical rhythm: the column drives spacing via gap, children carry no own margins */
#portalCard .portal-col { display: flex; flex-direction: column; gap: 16px; }
#portalCard .portal-col > .form-group { margin: 0; }
#portalCard .portal-sec { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); padding-bottom: 8px; margin: 0; border-bottom: 1px solid var(--border); }
#portalCard .portal-col > .portal-sec ~ .portal-sec { margin-top: 6px; }   /* a little extra before a second section */
#portalCard .portal-preview { display: flex; align-items: center; gap: 10px; min-height: 60px; padding: 14px 16px; border: 1px solid var(--border); border-radius: 12px; margin: 0;
    background-color: #8a8a92;
    background-image: linear-gradient(45deg, rgba(0,0,0,.18) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.18) 75%), linear-gradient(45deg, rgba(0,0,0,.18) 25%, transparent 25%, transparent 75%, rgba(0,0,0,.18) 75%);
    background-size: 16px 16px; background-position: 0 0, 8px 8px; }
#portalCard .portal-preview img { height: 28px; width: auto; max-width: 150px; object-fit: contain; }
#portalCard .portal-preview span { font-size: 18px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; text-shadow: 0 1px 2px rgba(0,0,0,.35); }
#portalCard .portal-row { display: flex; gap: 14px; align-items: flex-start; }
#portalCard .portal-hint { font-size: 11px; color: var(--muted-2); margin-top: 6px; line-height: 1.45; }
#portalCard .portal-col > .portal-hint { margin-top: -4px; }   /* hug the colors grid above it */
#portalCard .portal-asset { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
#portalCard .portal-asset img { height: 38px; border-radius: 8px; border: 1px solid var(--border); }
#portalCard .be-cpick { width: 32px; height: 32px; }   /* admin theme swatches a bit larger; the wrapped input auto-fills (see .be-cpick > input) */
#portalCard .portal-range { width: 100%; accent-color: var(--gold); }
#portalCard .portal-colors { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
#portalCard .portal-swatch { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--panel-2); cursor: pointer; font-size: 13px; }
#portalCard .portal-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border); }
/* Live theme preview — a mini mock UI that reflects the current theme fields */
#portalCard .theme-preview { position: relative; margin-top: 14px; border-radius: 14px; overflow: hidden; border: 1px solid var(--tp-border, var(--border)); background: var(--tp-bg, var(--bg)); }
#portalCard .theme-preview .tp-bg { position: absolute; inset: 0; background-size: cover; background-position: center; pointer-events: none; }
#portalCard .theme-preview .tp-frame { position: relative; z-index: 1; }
#portalCard .tp-topbar { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--tp-border, var(--border)); background: color-mix(in srgb, var(--tp-panel, var(--panel)) 80%, transparent); }
#portalCard .tp-logo { height: 24px; width: auto; max-width: 120px; object-fit: contain; }
/* Gray separators between rows of the admin users table */
#usersTableBody td { border-bottom: 1px solid var(--border); }
#usersTableBody tr:last-child td { border-bottom: none; }
#portalCard .tp-nav { display: flex; gap: 14px; font-size: 13px; }
#portalCard .tp-navlink { color: var(--tp-muted, var(--muted)); }
#portalCard .tp-navlink.tp-active { color: var(--tp-accent, var(--gold)); font-weight: 600; }
#portalCard .tp-body { padding: 18px 16px; }
#portalCard .tp-card { max-width: 360px; padding: 16px; border-radius: 12px; background: var(--tp-panel, var(--panel)); border: 1px solid var(--tp-border, var(--border)); }
#portalCard .tp-ctitle { font-size: 15px; font-weight: 700; color: var(--tp-text, var(--text)); margin-bottom: 6px; }
#portalCard .tp-text { font-size: 13px; color: var(--tp-text, var(--text)); margin-bottom: 4px; }
#portalCard .tp-muted { font-size: 12px; color: var(--tp-muted, var(--muted)); margin-bottom: 12px; }
#portalCard .tp-actions { display: flex; align-items: center; gap: 10px; }
#portalCard .tp-btn { border: none; border-radius: 9px; padding: 8px 16px; font-size: 13px; font-weight: 600; cursor: default; background: var(--tp-accent, var(--gold)); color: var(--tp-on-accent, #1a1712); }
#portalCard .tp-badge { font-size: 11px; font-weight: 600; padding: 3px 10px; border-radius: 999px; color: var(--tp-accent, var(--gold)); background: color-mix(in srgb, var(--tp-accent, var(--gold)) 16%, transparent); }
@media (max-width: 640px) { #portalCard .portal-grid { grid-template-columns: 1fr; gap: 18px; } }

/* Live preview: block colours (left) + notifications & comments panels (right) */
#portalCard .portal-preview-row { display: flex; gap: 14px; flex-wrap: wrap; align-items: stretch; }
#portalCard .portal-preview-row > .theme-preview { flex: 1 1 340px; min-width: 280px; margin-top: 0; }
#portalCard .tp-panels { flex: 1 1 300px; min-width: 260px; display: flex; flex-direction: column; gap: 12px; }
#portalCard .tp-pane { border-radius: 14px; border: 1px solid var(--tp-border, var(--border)); background: var(--tp-panel, var(--panel)); padding: 10px; }
#portalCard .tp-pane-head { display: flex; align-items: center; justify-content: space-between; font-size: 13px; font-weight: 700; color: var(--tp-text, var(--text)); padding: 2px 4px 9px; border-bottom: 1px solid var(--tp-border, var(--border)); margin-bottom: 8px; }
#portalCard .tp-pane-link { font-size: 11px; font-weight: 600; color: var(--tp-accent, var(--gold)); }
/* notifications */
#portalCard .tp-notif { position: relative; display: flex; align-items: flex-start; gap: 9px; padding: 8px; border-radius: 10px; }
#portalCard .tp-notif.tp-unread { background: color-mix(in srgb, var(--tp-accent, var(--gold)) 9%, transparent); }
#portalCard .tp-notif-ic { width: 26px; height: 26px; border-radius: 8px; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--tp-text, var(--text)) 14%, transparent); color: var(--tp-text, var(--text)); }
#portalCard .tp-notif-tx { font-size: 12px; line-height: 1.4; color: var(--tp-muted, var(--muted)); }
#portalCard .tp-notif-tx b { color: var(--tp-text, var(--text)); }
#portalCard .tp-notif-snip { display: block; color: var(--tp-muted, var(--muted)); font-style: italic; }
#portalCard .tp-notif-dot { position: absolute; top: 10px; right: 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--tp-danger, #ef4444); }
/* comments */
#portalCard .tp-citem { padding: 8px; border-radius: 10px; margin-bottom: 2px; }
#portalCard .tp-citem.tp-citem-new { background: color-mix(in srgb, var(--tp-danger, #ef4444) 14%, transparent); border-left: 3px solid var(--tp-danger, #ef4444); }
#portalCard .tp-citem-head { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
#portalCard .tp-citem-ic { width: 24px; height: 24px; border-radius: 7px; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--tp-text, var(--text)) 14%, transparent); color: var(--tp-text, var(--text)); }
#portalCard .tp-citem-title { font-size: 12px; font-weight: 600; color: var(--tp-text, var(--text)); }
#portalCard .tp-cnew { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; padding: 1px 6px; border-radius: 6px; background: var(--tp-danger, #ef4444); color: var(--tp-on-danger, #fff); }
#portalCard .tp-citem-tx { font-size: 12px; color: var(--tp-muted, var(--muted)); line-height: 1.4; }

/* Floating «What's new» panel (admin-authored news, draggable, always visible) */
.whatsnew { position: fixed; right: 24px; bottom: 24px; z-index: 900; width: 300px; max-width: calc(100vw - 24px); max-height: 60vh; display: flex; flex-direction: column; background: var(--panel); border: 1px solid var(--border); border-radius: 14px; box-shadow: 0 14px 44px rgba(0,0,0,.5); overflow: hidden; }
.whatsnew-head { display: flex; align-items: center; gap: 8px; padding: 11px 14px; font-size: 13px; font-weight: 700; color: var(--text); background: color-mix(in srgb, var(--gold) 14%, var(--panel-2)); border-bottom: 1px solid var(--border); user-select: none; }
.whatsnew-head svg { color: var(--gold); flex: 0 0 auto; }
.whatsnew-body { padding: 12px 14px; font-size: 13px; line-height: 1.5; color: var(--muted); flex: 1 1 auto; min-height: 0; max-height: 52vh; overflow-y: auto; word-break: break-word; }
.whatsnew-body .wn-line { margin: 2px 0; }
.whatsnew-body .wn-sp { height: 7px; }
.whatsnew-body .wn-list { margin: 5px 0; padding-left: 18px; }
.whatsnew-body .wn-list li { margin: 3px 0; }
.whatsnew-body b { color: var(--text); }

/* Topbar settings dropdown */
.topbar-dropdown { position: relative; }
.topbar-menu {
    position: fixed; right: 8px; top: calc(var(--topbar-h) + 4px); left: auto;
    width: 280px; max-width: calc(100vw - 16px); background: var(--popover-bg); border: 1px solid var(--border-ring);
    border-radius: var(--radius-md); box-shadow: var(--shadow-lg); backdrop-filter: blur(8px);
    padding: 6px; display: none; z-index: 60;
}
.topbar-menu.open { display: block; }
/* Tone/scale popup reset buttons: the generic `.app-topbar-nav svg` rules (which only hit the portal,
   not the board) were blanking these inline icons — force them to render explicitly. */
/* The popup is counter-scaled (transform: scale(1/zoom)) to offset the UI-scale `zoom`; that shrinks thin
   strokes below 1px and the browser drops them → blank squares. non-scaling-stroke keeps the stroke at a
   constant device width regardless of the transform, so the arrows always render. Colour is theme-explicit too. */
#portalTonePop button svg { display: block !important; width: 15px !important; height: 15px !important; fill: none !important; stroke: #d8d5ce !important; stroke-width: 2 !important; opacity: 1 !important; }
#portalTonePop button svg path { vector-effect: non-scaling-stroke; }
:root.portal-light #portalTonePop button svg { stroke: #3a3a42 !important; }
#portalTonePop button { color: inherit; }
.topbar-menu-item {
    display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box;
    height: 40px; padding: 0 12px; margin: 0; border: none; background: transparent;
    color: var(--text); font-size: 13px; border-radius: var(--radius-sm); cursor: pointer; text-align: left;
}
.topbar-menu-item:hover { background: var(--fill-soft); }
.topbar-menu-item > svg { width: 17px; height: 17px; flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; color: var(--muted); }
.topbar-menu-item .tm-label { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-menu-item .tm-value { flex-shrink: 0; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.topbar-menu-sep { height: 1px; background: var(--border); margin: 5px 8px; }
.tm-storage { padding: 10px 12px 12px; }
.tm-storage-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 8px; font-size: 12px; }
.tm-storage-row > span:first-child { color: var(--muted); }
.tm-storage-val { color: var(--text); font-variant-numeric: tabular-nums; }
.tm-storage-track { height: 6px; border-radius: 999px; background: var(--bg); overflow: hidden; }
.tm-storage-fill { height: 100%; background: var(--gold); border-radius: 999px; }
.tm-storage-fill.warning { background: var(--orange); }
.tm-storage-fill.danger { background: var(--danger); }

/* ---- Notification bell ---- */
.notif-wrap { display: inline-flex; }
.notif-bell { position: relative; }
.notif-badge {
    position: absolute; top: 1px; right: 1px; min-width: 16px; height: 16px; padding: 0 4px; box-sizing: border-box;
    background: var(--danger); color: #fff; border-radius: 999px; font-size: 9px; font-weight: 700;
    display: flex; align-items: center; justify-content: center; line-height: 1; pointer-events: none;
}
.notif-bell.has-unread > svg { color: var(--gold); }
.notif-menu { width: 340px; max-width: calc(100vw - 16px); padding: 0; z-index: 1000; }
#beVoicePanel.notif-menu { width: 480px; max-width: calc(100vw - 16px); }   /* comms panel wider → the per-participant action buttons fit ~6 per row */
/* Настройки в панели разрослись (устройства+динамик+режим+4 галочки+прослушка) — на ноутбучном экране низ
   уезжал за край без прокрутки. Скроллится ТОЛЬКО тело настроек, шапка с «Назад» остаётся на месте. */
#beVoicePanel .be-rtc-settings { max-height: min(74vh, calc(100vh - 150px)); overflow-y: auto; }
/* «Мои заметки» — card system */
.nc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; max-height: 62vh; overflow-y: auto; padding: 2px; }
.nc-card { display: flex; flex-direction: column; gap: 6px; background: var(--panel-2, #1c1c22); border: 1px solid var(--border); border-radius: 12px; padding: 10px; }
.nc-card-head { display: flex; align-items: center; gap: 6px; }
.nc-card-title { flex: 1; min-width: 0; background: transparent; border: none; border-bottom: 1px solid transparent; color: var(--text); font-size: 14px; font-weight: 600; padding: 2px 0; outline: none; }
.nc-card-title:focus { border-bottom-color: var(--border-strong, var(--border)); }
.nc-card-del { flex: none; width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center; border: none; border-radius: 7px; background: transparent; color: var(--muted); cursor: pointer; }
.nc-card-del:hover { background: var(--panel-3, rgba(255,255,255,.06)); color: var(--danger, #e5484d); }
.nc-card-body { min-height: 70px; max-height: 40vh; overflow-y: auto; font-size: 13px; line-height: 1.45; color: var(--text); outline: none; white-space: pre-wrap; word-break: break-word; }
.nc-card-body:empty::before { content: 'Текст заметки…'; color: var(--muted); pointer-events: none; }
.nc-card-body a { color: var(--gold); text-decoration: underline; cursor: pointer; }
.nc-files { display: flex; flex-direction: column; gap: 4px; }
.nc-file { display: flex; align-items: center; gap: 6px; font-size: 12px; background: var(--fill-soft, rgba(255,255,255,.03)); border: 1px solid var(--border); border-radius: 8px; padding: 3px 6px; }
.nc-file-nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); text-decoration: none; }
.nc-file-nm:hover { color: var(--gold); text-decoration: underline; }
.nc-file-sz { flex: none; font-size: 10px; color: var(--muted); }
.nc-file-x { flex: none; width: 18px; height: 18px; border: none; border-radius: 5px; background: transparent; color: var(--muted); cursor: pointer; font-size: 11px; }
.nc-file-x:hover { background: var(--panel-3, rgba(255,255,255,.06)); color: var(--danger, #e5484d); }
.nc-attach { align-self: flex-start; margin-top: auto; display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; color: var(--muted); background: transparent; border: 1px dashed var(--border); border-radius: 8px; padding: 4px 9px; cursor: pointer; }
.nc-attach:hover { color: var(--gold); border-color: var(--gold); }
.notif-head {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 12px 14px; border-bottom: 1px solid var(--border);
}
.notif-head > span { font-weight: 700; font-size: 13px; }
.notif-readall {
    border: none; background: transparent; color: var(--gold); font-size: 12px; cursor: pointer;
    padding: 4px 6px; border-radius: var(--radius-sm);
}
.notif-readall:hover { background: var(--fill-soft); }
.notif-actions { display: inline-flex; align-items: center; gap: 2px; }
.notif-delall { color: var(--muted); }
.notif-delall:hover { color: #e0736b; background: var(--fill-soft); }
.notif-empty { padding: 26px 14px; text-align: center; color: var(--muted); font-size: 13px; }
.notif-list { max-height: min(420px, 70vh); overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 8px; }
.notif-item { display: flex; align-items: flex-start; gap: 8px; border-radius: var(--radius-sm); background: var(--panel-3, rgba(255,255,255,.03)); }
.notif-item.unread { background: color-mix(in srgb, var(--gold) 11%, transparent); }
.notif-dot {
    flex: none; width: 9px; height: 9px; margin: 16px 0 0 8px; padding: 0; border-radius: 50%;
    border: 1.5px solid var(--muted); background: transparent; cursor: pointer;
}
.notif-item.unread .notif-dot { background: var(--gold); border-color: var(--gold); }
.notif-main { display: block; flex: 1; min-width: 0; padding: 11px 6px 11px 4px; text-decoration: none; color: inherit; cursor: pointer; }
.notif-del { flex: none; align-self: center; margin-right: 8px; width: 24px; height: 24px; padding: 0; border: none; background: none; color: var(--muted-2); cursor: pointer; border-radius: 6px; line-height: 0; font-size: 15px; }
.notif-del:hover { color: var(--danger); background: var(--fill-soft); }
.notif-line { font-size: 13px; color: var(--text); }
.notif-line b { font-weight: 700; }
.notif-snip { font-size: 12px; color: var(--muted); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.notif-time { font-size: 11px; color: var(--muted-2); margin-top: 3px; }

/* ---- @mention autocomplete ---- */
.mention-pop {
    position: fixed; z-index: 9999; background: var(--popover-bg); border: 1px solid var(--border-ring);
    border-radius: var(--radius-md); box-shadow: var(--shadow-lg); backdrop-filter: blur(8px);
    padding: 4px; max-height: 240px; overflow-y: auto;
}
.mention-opt { padding: 7px 10px; border-radius: var(--radius-sm); font-size: 13px; color: var(--text); cursor: pointer; white-space: nowrap; }
.mention-opt.active, .mention-opt:hover { background: var(--fill-soft); }
.mention-opt.mention-tag { display: flex; align-items: baseline; gap: 8px; font-weight: 600; }
.mention-opt .mention-desc { font-weight: 400; font-size: 11.5px; color: var(--muted); }
/* Photo-mask picker flyout */
.be-mask-menu { position: fixed; z-index: 10000; display: flex; flex-direction: column; gap: 2px; padding: 5px; min-width: 150px;
    background: var(--popover-bg); border: 1px solid var(--border-ring); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); }
.be-mask-opt { text-align: left; padding: 7px 10px; border: none; background: none; color: var(--text); font-size: 13px; border-radius: var(--radius-sm); cursor: pointer; }
.be-mask-opt:hover { background: var(--fill-soft); }
.be-mask-opt.on { background: var(--fill-soft); font-weight: 700; color: var(--gold); }
.be-mask-soft { flex-direction: column; gap: 4px; padding: 8px 10px 4px; margin-top: 4px; border-top: 1px solid var(--border); }
.be-mask-soft span { font-size: 12px; color: var(--text-dim, var(--text)); }
.be-mask-soft input[type=range] { width: 100%; accent-color: var(--gold); }
/* Photo-adjust popover (brightness/contrast/saturation/temperature/tint) */
.be-photo-menu { min-width: 220px; }
.be-photo-row { position: relative; }
.be-photo-val { position: absolute; right: 10px; top: 7px; font-size: 12px; color: var(--gold); font-variant-numeric: tabular-nums; }

.app-topbar-nav {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;                 /* allow shrinking so it scrolls instead of overflowing the page */
    overflow-x: auto;            /* horizontal scroll at ANY width when items don't fit (incl. iPad) */
    flex-wrap: nowrap;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.app-topbar-nav::-webkit-scrollbar { display: none; }
.app-topbar-nav > * { flex-shrink: 0; }   /* keep each item full-width; never squeeze «Общие доски» into 2 lines */

.app-topbar-nav a,
.app-topbar-nav button {
    height: 36px;
    padding: 0 14px;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--muted);
    font-size: 13px;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;          /* never wrap a nav label to a 2nd line */
    transition: all var(--transition);
    text-decoration: none;
}

.app-topbar-nav a:hover,
.app-topbar-nav button:hover,
.app-topbar-nav a.active {
    color: var(--text);
    background: var(--border);
}
/* icon-only topbar actions → compact SQUARE hitboxes (text nav links keep their padding) */
.app-topbar-nav .notif-bell,
.app-topbar-nav a[href="/manual"] { width: 36px; padding: 0; justify-content: center; }
.app-topbar-nav a[href^="?lang"] { padding: 0 9px; gap: 5px; }

.app-topbar-nav svg {
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.app-content {
    flex: 1;
    padding: 28px;
    max-width: 1400px;
    width: 100%;
    margin: 0 auto;
}

/* ---------- Cards ---------- */
.card {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
}

.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 20px 24px;
    border-bottom: 1px solid var(--border-faint);
}

.card-title {
    font-size: 18px;
    font-weight: 700;
    margin: 0;
}

.card-body {
    padding: 24px;
}

/* ---------- Page Header ---------- */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    margin-bottom: 24px;
    flex-wrap: wrap;
}

.page-title {
    font-size: 26px;
    font-weight: 700;
    margin: 0;
}

.page-subtitle {
    color: var(--muted);
    font-size: 13px;
    margin-top: 2px;
}

/* ---------- Status Badges ---------- */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 26px;
    padding: 0 10px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}

.badge-ready { background: var(--green-bg); color: var(--green); }
.badge-converting { background: var(--orange-bg); color: var(--orange); }
.badge-error { background: var(--danger-bg); color: var(--danger); }
.badge-queued { background: var(--gold-bg); color: var(--gold); }
.badge-uploading { background: var(--gold-bg); color: var(--gold); }
.badge-active { background: var(--green-bg); color: var(--green); }
.badge-blocked { background: var(--danger-bg); color: var(--danger); }
.badge-pending { background: var(--gold-bg); color: var(--gold); }
.badge-completed { background: var(--green-bg); color: var(--green); }
.badge-in_progress { background: var(--orange-bg); color: var(--orange); }
.badge-admin { background: var(--gold-bg); color: var(--gold); }
.badge-user { background: var(--fill-soft); color: var(--muted); }

.badge-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}

.badge-spinner {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    border: 2px solid var(--avatar-ring);
    border-top-color: currentColor;
    animation: badge-spin .8s linear infinite;
    flex-shrink: 0;
}

@keyframes badge-spin {
    to { transform: rotate(360deg); }
}

.badge-animated {
    animation: badge-pulse 2s ease-in-out infinite;
}

@keyframes badge-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .7; }
}

/* ---------- Projects Grid ---------- */
.projects-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 18px;
}

.project-card {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 22px;
    display: flex;
    flex-direction: column;
    gap: 14px;
    transition: all var(--transition);
    text-decoration: none;
    color: inherit;
}

.project-card:hover {
    border-color: var(--border-strong);
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
    color: inherit;
}

.project-card-title {
    font-size: 17px;
    font-weight: 700;
    margin: 0;
    word-break: break-word;
    overflow-wrap: anywhere;
    line-height: 1.3;
}

.project-card-meta {
    display: flex;
    align-items: center;
    gap: 14px;
    color: var(--muted);
    font-size: 12px;
}

.project-card-meta span {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.project-card-footer {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    margin-top: auto;
    padding-top: 12px;
    border-top: 1px solid var(--border-faint);
}
.project-card-footer > span:first-child:empty { display: none; }   /* folders have no date row */
.board-card-actions { display: flex; flex-wrap: wrap; gap: 5px; }   /* icons wrap neatly, never overflow */

/* ===== List view: compact rows, the big preview becomes a small square thumbnail (toggle in the header) ===== */
body.list-view .projects-grid { grid-template-columns: 1fr; gap: 8px; }
body.list-view .project-card {
    display: grid;
    grid-template-columns: 56px minmax(0, 1fr) auto;
    align-items: center;
    column-gap: 16px; row-gap: 3px;
    padding: 9px 16px;
}
/* dashboard project cards wrap thumb/title/meta in an <a>; display:contents promotes those to grid items of the
   card so the placement below works for BOTH boards (direct children) and projects (nested under the link). */
body.list-view .project-card > a { display: contents !important; } /* beat the inline style="display:block" on the project <a> wrapper, else thumb/title/meta collapse into one grid cell */
/* big preview / project cover / folder icon → small square on the left, spanning both rows */
body.list-view .project-card .board-thumb,
body.list-view .project-card .proj-thumb,
body.list-view .project-card .folder-card-icon {
    grid-column: 1; grid-row: 1 / span 2;
    width: 56px; height: 56px; min-height: 0; aspect-ratio: 1 / 1; margin: 0; border-radius: 8px;
}
body.list-view .project-card .folder-card-icon svg { width: 26px; height: 26px; }
body.list-view .project-card .board-prev,
body.list-view .project-card .proj-prev { width: 100%; height: 100%; object-fit: cover; }
/* title (row 1) + meta (row 2) in the middle column */
body.list-view .project-card .project-card-title {
    grid-column: 2; grid-row: 1; margin: 0; font-size: 15px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body.list-view .project-card .project-card-meta { grid-column: 2; grid-row: 2; margin: 0; flex-wrap: nowrap; overflow: hidden; }
body.list-view .project-card > a > div:not([class]) { display: none; }   /* project description (no class) — hide in the compact row */
/* status badge → top-right, actions → bottom-right */
body.list-view .project-card > .be-status-badge { position: static; grid-column: 3; grid-row: 1; justify-self: end; }
body.list-view .project-card > .project-card-footer {
    grid-column: 3; grid-row: 2; flex-direction: row; align-items: center; justify-content: flex-end;
    gap: 10px; margin: 0; padding: 0; border: none;
}
body.list-view .project-card > .project-card-footer .board-card-actions { flex-wrap: nowrap; }
#prevToggle.on, #listToggle.on { color: var(--gold); border-color: var(--gold); }
.sort-select { height: 32px; padding: 0 8px; border: 1px solid var(--border); background: var(--panel-2); color: var(--text); border-radius: var(--radius-sm); font-size: 13px; cursor: pointer; font-family: inherit; }
.sort-select:hover { border-color: var(--border-strong); }
.sort-select:focus { outline: none; border-color: var(--gold); }

/* ---------- Version List ---------- */
.version-item {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border-faint);
    transition: background var(--transition);
}

.version-item:hover { background: var(--hover-row); }
.version-item:last-child { border-bottom: none; }

.version-number {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: var(--panel-3);
    border: 1px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 15px;
    flex-shrink: 0;
}

.version-info { flex: 1; min-width: 0; }

.version-name {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.version-meta {
    color: var(--muted);
    font-size: 12px;
    margin-top: 2px;
}

.version-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

/* Dark scrollbars everywhere (matches the admin log) */
* { scrollbar-width: thin; scrollbar-color: #34343c transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: rgba(0,0,0,.25); }
*::-webkit-scrollbar-thumb { background: #2c2c33; border-radius: 8px; border: 2px solid transparent; background-clip: padding-box; }
*::-webkit-scrollbar-thumb:hover { background: #3a3a44; background-clip: padding-box; }
*::-webkit-scrollbar-corner { background: transparent; }

/* Dark scrollbar (AI/VPN log) */
.scroll-dark { scrollbar-width: thin; scrollbar-color: #34343c rgba(0,0,0,.25); }
.scroll-dark::-webkit-scrollbar { width: 10px; height: 10px; }
.scroll-dark::-webkit-scrollbar-track { background: rgba(0,0,0,.28); border-radius: 8px; }
.scroll-dark::-webkit-scrollbar-thumb { background: #2c2c33; border-radius: 8px; border: 2px solid transparent; background-clip: padding-box; }
.scroll-dark::-webkit-scrollbar-thumb:hover { background: #3a3a44; background-clip: padding-box; }

/* Portal-style thin scrollbar (logs, tariffs, etc.) */
.scroll-portal { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
.scroll-portal::-webkit-scrollbar { width: 8px; height: 8px; }
.scroll-portal::-webkit-scrollbar-track { background: transparent; }
.scroll-portal::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 8px; border: 2px solid transparent; background-clip: padding-box; }
.scroll-portal::-webkit-scrollbar-thumb:hover { background: var(--gold); background-clip: padding-box; }

/* Compact square icon button (admin user-row actions) */
.icon-btn { width: 30px; height: 30px; padding: 0; justify-content: center; flex: 0 0 auto; }
/* Admin users "Действия" row — keep the role <select> and icon buttons the same height/aligned */
.user-actions .form-input, .user-actions .icon-btn, .user-actions .btn { height: 32px; box-sizing: border-box; }

/* Mobile: stack the version row (info above, action buttons wrap below) so the
   long meta line doesn't collide with the buttons; let header buttons wrap too. */
@media (max-width: 640px) {
    .version-item { flex-wrap: wrap; align-items: flex-start; gap: 10px; }
    .version-info { flex: 1 1 60%; }
    .version-meta { white-space: normal; line-height: 1.5; }
    .version-actions { flex: 1 1 100%; flex-wrap: wrap; }
    /* Header action buttons (e.g. Upload / Delete project) — equal width, fill the row */
    .page-header .flex { flex-wrap: wrap; width: 100%; }
    .page-header .flex > .btn { flex: 1 1 0; justify-content: center; }
}

/* ---------- Empty State ---------- */
.empty-state {
    padding: 60px 24px;
    text-align: center;
    color: var(--muted);
}

.empty-state-icon {
    width: 64px;
    height: 64px;
    margin: 0 auto 18px;
    border-radius: 50%;
    background: var(--panel-3);
    display: flex;
    align-items: center;
    justify-content: center;
}

.empty-state-icon svg {
    width: 28px;
    height: 28px;
    stroke: var(--muted);
    fill: none;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.empty-state-title {
    font-size: 17px;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 6px;
}

.empty-state-text {
    font-size: 13px;
    max-width: 360px;
    margin: 0 auto 18px;
    line-height: 1.5;
}

/* ---------- Table ---------- */
.data-table {
    width: 100%;
    border-collapse: collapse;
}

.data-table th {
    text-align: left;
    padding: 12px 16px;
    font-size: 11px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .04em;
    border-bottom: 1px solid var(--line);
}

.data-table td {
    padding: 14px 16px;
    border-bottom: 1px solid var(--border-faint);
    vertical-align: middle;
}

.data-table tr:hover td { background: var(--hover-row); }

/* ---------- Modal ---------- */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: var(--backdrop);
    backdrop-filter: blur(8px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    z-index: 100;
    opacity: 0;
    visibility: hidden;
    transition: all .2s ease;
}

.modal-overlay.open {
    opacity: 1;
    visibility: visible;
}

.modal-dialog {
    width: 100%;
    max-width: 520px;
    max-height: 90vh;
    overflow: auto;
    background: var(--panel-2);
    color: var(--text);   /* so titles/text follow the modal's (possibly tone-overridden) --text instead of inheriting body's */
    border: 1px solid var(--border-ring);
    border-radius: var(--radius-xl);
    padding: 32px;
    box-shadow: var(--shadow-lg);
}

.modal-title {
    font-size: 20px;
    font-weight: 700;
    margin: 0 0 8px;
}

.modal-subtitle {
    color: var(--muted);
    font-size: 13px;
    margin-bottom: 24px;
}

.modal-actions {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    margin-top: 24px;
}

/* ---------- Toast ---------- */
.toast-container {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 200;
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: center;
}

.toast {
    background: var(--popover-bg);
    color: var(--text);
    border: 1px solid var(--border-ring);
    border-radius: var(--radius-md);
    padding: 12px 20px;
    font-size: 13px;
    font-weight: 500;
    box-shadow: var(--shadow-md);
    opacity: 0;
    transform: translateY(12px);
    transition: all .25s ease;
    pointer-events: none;
}

.toast.show {
    opacity: 1;
    transform: translateY(0);
}

/* ---------- Upload Zone ---------- */
.upload-zone {
    border: 2px dashed var(--line);
    border-radius: var(--radius-lg);
    padding: 40px 24px;
    text-align: center;
    transition: all var(--transition);
    cursor: pointer;
}

.upload-zone:hover,
.upload-zone.dragover {
    border-color: var(--blue);
    background: var(--gold-bg-soft);
}

.upload-zone-icon {
    width: 52px;
    height: 52px;
    margin: 0 auto 14px;
    border-radius: 50%;
    background: var(--panel-3);
    display: flex;
    align-items: center;
    justify-content: center;
}

.upload-zone-icon svg {
    width: 24px;
    height: 24px;
    stroke: var(--blue);
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.upload-zone-text { font-weight: 600; margin-bottom: 4px; }
.upload-zone-hint { color: var(--muted); font-size: 12px; }

/* Progress bar */
.progress-bar {
    width: 100%;
    height: 6px;
    background: var(--panel-3);
    border-radius: 999px;
    overflow: hidden;
    margin-top: 12px;
}

.progress-bar-fill {
    height: 100%;
    background: var(--blue);
    border-radius: 999px;
    transition: width .3s ease;
    width: 0%;
}

/* ---------- Link copy ---------- */
.link-display {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    padding: 8px 12px;
}

.link-display input {
    flex: 1;
    background: none;
    border: none;
    color: var(--text);
    font-size: 13px;
    outline: none;
}

.link-display button {
    flex-shrink: 0;
}
.link-display .link-del-btn {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0; width: 34px; height: 32px; color: var(--muted);
}
.link-display .link-del-btn:hover { color: var(--danger); background: var(--fill-soft); }

/* Admin: tariffs (2fr) + settings (3fr) side by side, stacked on mobile */
.admin-2col { display: grid; grid-template-columns: 2fr 3fr; }
@media (max-width: 640px) { .admin-2col { grid-template-columns: 1fr; } }
/* Mobile: stack admin blocks one under another + make stat tiles compact */
@media (max-width: 640px) {
    #statsGrid { grid-template-columns: 1fr 1fr !important; gap: 8px !important; }
    #statsGrid .card { padding: 12px 8px !important; }
    #statsGrid .card > div:first-child { font-size: 21px !important; }
    #statsGrid .card > div:last-child { font-size: 11px !important; line-height: 1.25; }
    .be-admin-grid { grid-template-columns: 1fr !important; }
    /* Log window: cap height so it doesn't stretch to fit all content */
    #aiVpnLogBody { flex: none !important; max-height: 300px !important; }
    /* Shrink the whole admin UI a bit on phones */
    .admin-scale { zoom: 0.85; }
}

/* ---------- Responsive ---------- */
@media (max-width: 640px) {
    .app-topbar { padding: 0 12px; gap: 8px; }
    .app-topbar-brand { flex-shrink: 0; }
    /* Top nav scrolls horizontally (liked); the dropdown is fixed so the scroll-clip doesn't hide it */
    .app-topbar-nav { min-width: 0; overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
    .app-topbar-nav::-webkit-scrollbar { display: none; }
    .app-topbar-nav > * { flex-shrink: 0; }
    .topbar-menu { position: fixed; top: calc(var(--topbar-h) + 4px); right: 8px; left: auto; max-width: calc(100vw - 16px); }

    .app-content { padding: 16px; overflow-x: hidden; }        /* no sideways page scroll */
    .card { max-width: 100%; overflow-x: auto; box-sizing: border-box; }  /* wide tables scroll inside the card */
    .app-content [style*="grid-template-columns"] { grid-template-columns: 1fr !important; }  /* one column on phones */
    .app-content .card > div[style*="display:flex"] { flex-wrap: wrap; }
    .app-content .form-input { max-width: 100%; }

    .auth-card { padding: 28px 22px; }
    .projects-grid { grid-template-columns: 1fr; }
    .page-header { flex-direction: column; align-items: flex-start; }
    /* List view on mobile: a clean 3-ROW row (title+status / meta / actions). The many action icons used to sit in a
       single nowrap column that overflowed the screen and squished the text — now they wrap on their own full-width row. */
    body.list-view .project-card {
        grid-template-columns: 44px minmax(0, 1fr) auto;
        column-gap: 10px; row-gap: 4px; padding: 10px 12px;
    }
    body.list-view .project-card .board-thumb,
    body.list-view .project-card .proj-thumb,
    body.list-view .project-card .folder-card-icon { grid-column: 1; grid-row: 1 / span 2; width: 44px; height: 44px; }
    body.list-view .project-card .folder-card-icon svg { width: 22px; height: 22px; }
    body.list-view .project-card .project-card-title { grid-column: 2; grid-row: 1; font-size: 14px; line-height: 1.3; }
    body.list-view .project-card > .be-status-badge { grid-column: 3; grid-row: 1; justify-self: end; align-self: start; }
    body.list-view .project-card .project-card-meta { grid-column: 2; grid-row: 2; font-size: 11px; gap: 6px 12px; flex-wrap: wrap; overflow: visible; }
    body.list-view .project-card .project-card-meta span { gap: 3px; white-space: nowrap; }
    /* split the footer: creation DATE → right of the size (row 2); action BUTTONS → their own full-width row (row 3) */
    body.list-view .project-card > .project-card-footer { display: contents; }
    body.list-view .project-card > .project-card-footer > span { grid-column: 3; grid-row: 2; justify-self: end; align-self: center; margin: 0; font-size: 11px; color: var(--muted); white-space: nowrap; }
    body.list-view .project-card > .project-card-footer > .board-card-actions { grid-column: 1 / -1; grid-row: 3; display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
}
/* Long-press-armed element (mobile) — clear it can now be dragged */
.be-el.lp-drag .be-el-inner { outline: 2px solid var(--gold-hover); outline-offset: 1px; }

/* ====================================================================
   Board editor (infinite canvas)
   ==================================================================== */
.be-root { position: fixed; inset: 0; background: var(--bg); overflow: hidden; user-select: none; }

/* Canvas viewport (pans/zooms an infinite dotted grid via JS) */
.be-canvas {
    position: absolute; inset: 0; overflow: hidden;
    background-color: var(--be-canvas-bg, var(--bg));   /* board tone — user-adjustable via slider */
    background-image: radial-gradient(circle, var(--grid-dot, rgba(150,150,160,.16)) 1.8px, transparent 1.8px);
    background-size: 24px 24px;
    background-position: 0 0;
    cursor: default;
}
.be-canvas.be-grid-off { background-image: none; }   /* G hotkey toggles the navigation dots */
/* Faint centre crosshair at world origin — constant screen size, tinted like the dots, toggles with them */
#beCenterMark { position: absolute; left: 0; top: 0; width: 0; height: 0; transform: translate(-50%, -50%) scale(var(--be-invz, 1)); transform-origin: center; pointer-events: none; z-index: -100001; }   /* behind every block (incl. frames) — sits with the background dots */
#beCenterMark svg { display: block; width: 54px; height: 54px; margin: -27px 0 0 -27px; overflow: visible; }
#beCenterMark svg line { stroke: var(--grid-dot, rgba(150,150,160,.16)); stroke-width: 1.8; stroke-linecap: round; }   /* same tone/opacity as the dots, tracks the dots slider */
.be-canvas.be-grid-off #beCenterMark { display: none; }
/* Alignment guides — accent-coloured (--gold), thicker, dashed, fade out when removed. The .v/.h dash
   pattern is painted with a repeating gradient so a single thin div renders as a dashed line. */
.be-snap-guide { pointer-events: none; z-index: 7; opacity: .55; transition: opacity .18s ease; }
.be-snap-guide.v { background: repeating-linear-gradient(180deg, var(--gold) 0 6px, transparent 6px 11px); -webkit-mask: linear-gradient(180deg, transparent 0, #000 18%, #000 82%, transparent 100%); mask: linear-gradient(180deg, transparent 0, #000 18%, #000 82%, transparent 100%); }
.be-snap-guide.h { background: repeating-linear-gradient(90deg, var(--gold) 0 6px, transparent 6px 11px); -webkit-mask: linear-gradient(90deg, transparent 0, #000 18%, #000 82%, transparent 100%); mask: linear-gradient(90deg, transparent 0, #000 18%, #000 82%, transparent 100%); }
.be-snap-guide.be-snap-out, .be-snap-eq.be-snap-out { opacity: 0; }
/* Multi-edge snap (butt-adjacent both sides / exact overlap of a same-size block) → solid, brighter «locked» guide. */
.be-snap-guide.be-snap-strong { opacity: .95; }
.be-snap-guide.be-snap-strong.v { background: var(--gold); }
.be-snap-guide.be-snap-strong.h { background: var(--gold); }
/* Equal-spacing (distribution) indicators — a gap bar with small end ticks */
.be-snap-eq { pointer-events: none; z-index: 7; opacity: .6; transition: opacity .18s ease; }
/* Fixed-period gradient dashes (NOT a CSS `dashed` border — that auto-fits dash length to the line,
   so dashes visibly stretch/shrink as the gap bar changes length during a drag). */
.be-snap-eq.eqh { background: repeating-linear-gradient(90deg, var(--gold) 0 6px, transparent 6px 11px); }
.be-snap-eq.eqv { background: repeating-linear-gradient(180deg, var(--gold) 0 6px, transparent 6px 11px); }
.be-snap-eq.eqh::before, .be-snap-eq.eqh::after { content: ''; position: absolute; top: -3px; height: 8px; border-left: 2px solid var(--gold); }
.be-snap-eq.eqh::before { left: 0; } .be-snap-eq.eqh::after { right: 0; }
.be-snap-eq.eqv::before, .be-snap-eq.eqv::after { content: ''; position: absolute; left: -3px; width: 8px; border-top: 2px solid var(--gold); }
.be-snap-eq.eqv::before { top: 0; } .be-snap-eq.eqv::after { bottom: 0; }
/* Block highlighted as the connection target while dragging a connector onto it */
.be-el.be-conn-target { outline: 2px dashed var(--gold-hover, #cba74e) !important; outline-offset: 3px; }
.be-canchor-ghost { pointer-events: none; opacity: .9; }
/* Light board tone → light chrome on the TOP BAR + TOOLBAR + flyout AND the block-editing panels. */
.be-root.be-canvas-light .be-topbar .be-panel,
.be-root.be-canvas-light .be-toolbar,
.be-root.be-canvas-light .be-tool-flyout { background: rgba(248,248,250,.96); border-color: rgba(0,0,0,.14); }
.be-root.be-canvas-light .be-topbar .be-panel,
.be-root.be-canvas-light .be-topbar .be-btn,
.be-root.be-canvas-light .be-title-text,
.be-root.be-canvas-light .be-topbar-left,
.be-root.be-canvas-light .be-toolbar .be-tool,
.be-root.be-canvas-light .be-tool-flyout .be-tool { color: #1a1a1e !important; }
.be-root.be-canvas-light .be-topbar .be-btn svg,
.be-root.be-canvas-light .be-toolbar .be-tool svg,
.be-root.be-canvas-light .be-tool-flyout .be-tool svg { color: #1a1a1e; stroke: currentColor; }
/* Light tone: brand + board title in the top-left were light-on-light (their inline color:var(--gold)/var(--text) beat
   the inherited dark ink) → force them dark. Covers BOTH the guest page (body.be-public) and the owner page (.be-root). */
body.be-public.be-canvas-light .be-topbar-left .be-panel > span,
body.be-public.be-canvas-light .be-topbar-left .app-topbar-brand,
body.be-public.be-canvas-light .be-topbar-left .app-topbar-brand .portal-name,
.be-root.be-canvas-light .be-topbar-left .app-topbar-brand,
.be-root.be-canvas-light .be-topbar-left .app-topbar-brand .portal-name { color: #1a1a1e !important; }
/* selected tool highlight on a light toolbar */
.be-root.be-canvas-light .be-toolbar .be-tool.active,
.be-root.be-canvas-light .be-tool-flyout .be-tool.active { background: rgba(0,0,0,.10); color: #161616 !important; }
.be-root.be-canvas-light .be-toolbar .be-tool:hover,
.be-root.be-canvas-light .be-tool-flyout .be-tool:hover { background: rgba(0,0,0,.06); }
/* hover/active fills on light chrome use --fill-soft/--fill (= dark-theme grey) → retint to dark-on-light */
.be-root.be-canvas-light .be-topbar .be-panel,
.be-root.be-canvas-light .be-toolbar,
.be-root.be-canvas-light .be-tool-flyout,
.be-root.be-canvas-light .be-props,
.be-root.be-canvas-light .be-align-bar { --fill-soft: rgba(0,0,0,.07); --fill: rgba(0,0,0,.11); }
/* Light tone: props-panel sliders (fill-opacity etc.) — light track + thumb ring, matching the popover sliders (which already get these via the light-palette list). */
.be-root.be-canvas-light .be-props .be-fill-range,
.be-root.be-canvas-light .be-props .be-draw-range { --line: rgba(0,0,0,.16); --panel-2: #f1f1f4; }
/* ⚠ Панели мало перекрасить ФОН: подписи внутри задаются инлайном через `var(--muted)` (например цифры и
   названия у степперов «Строки»/«Столбцы»), и на белом они оставались светло-серыми — почти невидимыми.
   Переопределяем чернильные токены целиком, как это сделано у `.be-bar` и боковой панели ревью. */
.be-root.be-canvas-light .be-props,
.be-root.be-canvas-light .be-props .be-dd-menu,
.be-root.be-canvas-light .be-align-bar,
.be-root.be-canvas-light .be-conn-pop,
body.be-canvas-light .be-conn-pop { --text: #1a1a1e; --muted: #55555e; --muted-2: #6f6f78; --border: rgba(0,0,0,.14); --border-strong: rgba(0,0,0,.3); }
/* Light tone: the alignment bar (it can sit under <body>, not only .be-root) — make it light too. */
body.be-canvas-light .be-align-bar { background: rgba(248,248,250,.97) !important; border-color: rgba(0,0,0,.14) !important; --fill-soft: rgba(0,0,0,.07); --fill: rgba(0,0,0,.11); }
body.be-canvas-light .be-align-bar .be-fmt-btn { color: #1a1a1e !important; }
body.be-canvas-light .be-align-bar .be-fmt-btn svg { color: #1a1a1e; stroke: currentColor; }
body.be-canvas-light .be-align-bar .be-fmt-btn.active { background: rgba(0,0,0,.12) !important; color: #161616 !important; }
body.be-canvas-light .be-align-bar .be-fmt-btn:hover { background: rgba(0,0,0,.06) !important; }
/* ⚠ Пилюля масштаба выделения («100%») красится НЕ кнопочными правилами: у неё свой фон `--panel-3` (тёмный).
   Чернильные токены панели на светлом тоне уже переопределены, поэтому выходил чёрный прямоугольник с тёмной
   надписью — «100%» было не прочесть. Красим фон, рамку и значок явно; панель бывает и под <body>, и под .be-root. */
.be-root.be-canvas-light .be-align-scale,
body.be-canvas-light .be-align-scale { background: #fff !important; border-color: rgba(0,0,0,.16) !important; color: #1a1a1e !important; }
.be-root.be-canvas-light .be-align-scale svg,
body.be-canvas-light .be-align-scale svg { color: #1a1a1e; }
.be-root.be-canvas-light .be-align-scale.dragging, .be-root.be-canvas-light .be-align-scale:hover,
body.be-canvas-light .be-align-scale.dragging, body.be-canvas-light .be-align-scale:hover { border-color: var(--gold) !important; }
/* Per-block comment bar follows a light canvas tone (vars cascade to its head/body/inputs) */
.be-root.be-canvas-light .be-bar { --panel-2: #f3f3f6; --border: rgba(0,0,0,.14); --text: #1a1a1e; --muted: #5a5a63; --muted-2: #8a8a93; --border-strong: rgba(0,0,0,.3); }
.be-root.be-canvas-light .be-bar-ic { background: rgba(0,0,0,.08); }
.be-root.be-canvas-light .be-bar-ic svg { stroke: #444; }
/* Sticker picker panel + file/audio blocks follow a light canvas tone */
.be-root.be-canvas-light .be-sticker-panel { --popover-bg: rgba(248,248,250,.98); --border-ring: rgba(0,0,0,.14); --text: #1a1a1e; --muted: #5a5a63; --muted-2: #6a6a73; --border: rgba(0,0,0,.12); --border-strong: rgba(0,0,0,.25); --panel-2: #ececf0; --panel-3: #e2e2e8; --fill-soft: rgba(0,0,0,.05); --on-gold: #1a1712; }
.be-root.be-canvas-light .be-el[data-type="file"] .be-el-inner,
.be-root.be-canvas-light .be-el[data-type="audio"] .be-el-inner { --panel-2: #f3f3f6; --panel-3: #e8e8ec; --text: #1a1a1e; --muted-2: #777; --border: rgba(0,0,0,.14); --line: rgba(0,0,0,.12); }
.be-root.be-canvas-light .be-file-icon, .be-root.be-canvas-light .be-audio-icon, .be-root.be-canvas-light .be-audio-cover:not(.has-img) { color: #3a3a42; }   /* file/music glyph dark on a light block */
/* AI blocks (картинка/текст) placeholder follows a light canvas */
.be-root.be-canvas-light .be-el[data-type="ai_image"] .be-el-inner,
.be-root.be-canvas-light .be-el[data-type="ai_text"] .be-el-inner { --panel-2: #ececf0; --text: #1a1a1e; --muted-2: #9a9aa3; }
/* Light canvas → ALL board modals/dialogs/popovers use the light palette (they live on <body>, which also carries .be-canvas-light) */
body.be-canvas-light .modal-dialog,
body.be-canvas-light .be-ins-box,
body.be-canvas-light .be-embed-box,
body.be-canvas-light .be-ctx,
body.be-canvas-light .be-dd-menu,
body.be-canvas-light .be-conn-pop,
body.be-canvas-light .be-export-card,
body.be-canvas-light .be-io-pop,
body.be-canvas-light .be-io-mcard,
body.be-canvas-light .be-lkdiag-card,
body.be-canvas-light #beViewPop,
body.be-canvas-light .be-cpop,
body.be-canvas-light .be-up-bar,
body.be-canvas-light .be-busy {
    --bg: #fbfbfd; --panel: #fbfbfd; --panel-2: #f1f1f4; --panel-3: #e7e7ec; --panel-hover: #e2e2e8;
    --text: #1a1a1e; --muted: #57575f; --muted-2: #84848e;
    --border: rgba(0,0,0,.13); --border-faint: rgba(0,0,0,.07); --border-strong: rgba(0,0,0,.22); --border-ring: rgba(0,0,0,.14);
    --line: rgba(0,0,0,.16); --fill-soft: rgba(0,0,0,.05); --fill: rgba(0,0,0,.08); --popover-bg: #fbfbfd; --gold-bg: rgba(203,167,78,.16);
    /* --gold inherits from body.be-canvas-light (the dark-gold default OR the admin «светлый акцент») so
       gold accents + slider thumbs in popovers follow the admin light-accent colour. */
}
/* light modal: native select dropdown arrow goes dark for contrast */
body.be-canvas-light .modal-dialog select.form-input { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%231a1a1e' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") !important; }
/* hotkeys help-grid key caps + AI block tag darken on a light canvas */
.be-canvas-light .be-help-grid kbd { color: #33333b; background: rgba(0,0,0,.05); border-color: rgba(0,0,0,.14); }
.be-root.be-canvas-light .be-ai-tag { color: #33333b; }
/* Calculator block follows a light canvas */
.be-root.be-canvas-light .be-el[data-type="calc"] .be-el-inner { --panel-2: #f3f3f6; --text: #1a1a1e; --muted: #6a6a73; --border-strong: rgba(0,0,0,.22); }
/* Connection-anchor triangles darken on a light canvas (gold was low-contrast) */
.be-root.be-canvas-light .be-canchor::before { background: #44444d; }
/* Light board tone: gold accents default to a readable dark gold (the dark-theme default --gold is white →
   invisible on light). The admin «золотой акцент (светлый)» setting overrides these vars via portalHeadStyle. */
body.be-canvas-light, .be-root.be-canvas-light { --gold: #8a6d1e; --gold-2: #9a7a22; --gold-hover: #9a7a22; --on-gold: #ffffff; }
/* light tone: gold accent text-links / result-calc value follow --gold (so the admin accent applies) */
.be-canvas-light .notif-readall,
.be-canvas-light .be-reply-toggle { color: var(--gold); }
.be-root.be-canvas-light .be-el[data-type="calc"][data-calc-result="1"] .be-calc-val { color: var(--gold); }
/* board loading overlay follows a light tone */
body.be-canvas-light #beLoad { background: rgba(248,248,250,.92); }
body.be-canvas-light .be-load-box { background: #f0f4f2; --text: #1a1a1e; --border-strong: rgba(0,0,0,.16); }
body.be-canvas-light .be-load-track { background: rgba(0,0,0,.1); }
body.be-canvas-light .be-load-bar { background: #5a5a5f; }   /* dark grey on the white splash */
/* slider value numbers in the editing panel darken on a light canvas (--text wasn't overridden there) */
.be-canvas-light .be-draw-wval, .be-root.be-canvas-light .be-props .be-draw-wval { color: #1a1a1e; }
/* line-edit hint panel follows a light canvas (its bg is hardcoded dark) */
.be-root.be-canvas-light .be-line-hint { background: rgba(250,250,252,.98); border-color: rgba(0,0,0,.18); color: #1a1a1e; }
.be-root.be-canvas-light .be-line-hint-row { color: #4a4a52; }
.be-root.be-canvas-light .be-line-hint-title { color: var(--gold); }
/* text-block default dashed outline darkens on a light canvas (was faint white) */
.be-root.be-canvas-light .be-el[data-type="text"] .be-el-inner { border-color: rgba(0,0,0,.34); }
.be-root.be-canvas-light .be-el[data-type="text"][data-nested="1"] .be-el-inner { border-color: transparent; }
/* selection outline of ANY block darkens on a light canvas (gold-hover was low-contrast) */
.be-root.be-canvas-light .be-el.selected { outline-color: rgba(0,0,0,.5); }
.be-root.be-canvas-light .be-el.lp-drag .be-el-inner { outline-color: rgba(0,0,0,.5); }
.be-root.be-canvas-light .be-topbar .be-btn.active,
.be-root.be-canvas-light .be-topbar .be-btn.primary { background: rgba(0,0,0,.12) !important; color: #161616 !important; }
/* Block-editing panels (props bar + align bar + their popups) go light too, with dark icons. */
.be-root.be-canvas-light .be-props,
.be-root.be-canvas-light .be-align-bar,
.be-root.be-canvas-light .be-props .be-dd-menu,
.be-root.be-canvas-light .be-conn-pop,
.be-root.be-canvas-light .be-conn-style-menu { background: rgba(248,248,250,.97) !important; border-color: rgba(0,0,0,.14) !important; }
.be-root.be-canvas-light .be-props,
.be-root.be-canvas-light .be-align-bar,
.be-root.be-canvas-light .be-props .be-ctl-lbl,
.be-root.be-canvas-light .be-conn-pop .be-ctl-lbl,
body.be-canvas-light .be-conn-pop .be-ctl-lbl,
.be-root.be-canvas-light .be-props .be-btn:not(.danger),
.be-root.be-canvas-light .be-props .be-fmt-btn,
.be-root.be-canvas-light .be-props .be-dd-trig,
.be-root.be-canvas-light .be-align-bar .be-fmt-btn,
.be-root.be-canvas-light .be-conn-pop,
.be-root.be-canvas-light .be-conn-style-menu .be-btn { color: #1a1a1e !important; }
.be-root.be-canvas-light .be-props .be-btn:not(.danger) svg,
.be-root.be-canvas-light .be-props .be-fmt-btn svg,
.be-root.be-canvas-light .be-props .be-dd-trig svg,
.be-root.be-canvas-light .be-align-bar .be-fmt-btn svg,
.be-root.be-canvas-light .be-conn-style-menu .be-btn svg { color: #1a1a1e; }
.be-root.be-canvas-light .be-props .be-fmt-btn.active,
.be-root.be-canvas-light .be-props .be-btn.primary,
.be-root.be-canvas-light .be-conn-style-menu .be-btn.primary,
.be-root.be-canvas-light .be-align-bar .be-fmt-btn.active { background: rgba(0,0,0,.12) !important; color: #161616 !important; }
.be-root.be-canvas-light .be-props .be-fmt-btn:hover,
.be-root.be-canvas-light .be-props .be-btn:not(.danger):hover { background: rgba(0,0,0,.06); }
.be-root.be-canvas-light .be-props input[type=text],
.be-root.be-canvas-light .be-props input[type=number] { background: #fff; color: #1a1a1e; border-color: rgba(0,0,0,.18); }
.be-root.be-canvas-light .be-props select,
.be-root.be-canvas-light .be-props .be-fmt-select { background-color: #fff; color: #1a1a1e; border-color: rgba(0,0,0,.18); }
/* ALL dropdown indicators dark on a light panel — filled chevrons (.be-dd-chev, fill hardcoded to var(--text)
   for iOS), native-select arrows (background-image hardcodes a light colour) and CSS-triangle tool carets. */
.be-root.be-canvas-light .be-dd-chev,
.be-root.be-canvas-light .be-tool-caret { color: #1a1a1e !important; }
.be-root.be-canvas-light .be-dd-chev path { fill: #1a1a1e !important; }
.be-root.be-canvas-light .be-fmt-select,
.be-root.be-canvas-light select.form-input { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%231a1a1e' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") !important; }
/* Popup panels (notifications · comments · chat · voice) are lifted to <body> → flagged via body.be-canvas-light.
   They're built on CSS vars, so redefining the vars on the panel turns the whole thing light automatically. */
body.be-canvas-light .topbar-menu {
    --popover-bg: #f6f6f8; --panel: #f6f6f8; --panel-2: #eeeef2; --panel-3: #e7e7ec;
    --text: #1a1a1e; --muted: #55555f; --muted-2: #7e7e88;
    --border: rgba(0,0,0,.14); --border-ring: rgba(0,0,0,.14); --fill-soft: rgba(0,0,0,.05);
    color: #1a1a1e;
}
body.be-canvas-light .topbar-menu .be-chat-input,
body.be-canvas-light .topbar-menu input[type=text],
body.be-canvas-light .topbar-menu textarea { background: #fff; color: #1a1a1e; border-color: rgba(0,0,0,.18); }

/* Personal portal tone → light page theme (per-user, applied as a class on <html>; --bg set inline from the slider). */
:root.portal-light {
    --panel: #fbfbfd; --panel-2: #f1f1f4; --panel-3: #e7e7ec; --panel-hover: #e2e2e8;
    --text: #1a1a1e; --muted: #57575f; --muted-2: #84848e;
    --border: rgba(0,0,0,.13); --border-faint: rgba(0,0,0,.07); --border-strong: rgba(0,0,0,.22); --border-ring: rgba(0,0,0,.14);
    --line: rgba(0,0,0,.16); --fill-soft: rgba(0,0,0,.05); --fill: rgba(0,0,0,.08); --popover-bg: #fbfbfd;
    --gold: #8a6d1e; --gold-2: #9a7a22; --gold-hover: #9a7a22;   /* all gold accents/labels readable on the light portal */
}
/* keep gold-FILLED buttons recognisable (the var override would darken their background too much) */
:root.portal-light .btn-primary,
:root.portal-light .btn.btn-primary { --gold: #cba74e; --gold-2: #cba74e; --gold-hover: #b8963f; }
/* default folder glyph follows the container colour (gold); custom-coloured folders keep their hex */
.folder-card-icon { color: var(--gold); }
/* light portal tone → brand text + default folder glyph go dark for contrast */
:root.portal-light .app-topbar-brand,
:root.portal-light .app-topbar-brand span,
:root.portal-light .review-brand,
:root.portal-light .review-brand span,
:root.portal-light .reg-hero-brand,
:root.portal-light .reg-hero-brand span,
:root.portal-light .reg-hero-brand .portal-name { color: #1a1a1e !important; }
:root.portal-light .folder-card-icon { color: #1a1a1e; }
:root.portal-light .impersonate-banner { color: #1a1a1e; }
:root.portal-light .whatsnew-head svg { color: #1a1a1e; }
/* light portal → board-card action icons + empty-preview glyph darken for contrast */
:root.portal-light .icon-action { color: #33333b; }
:root.portal-light .icon-action:hover { color: #111; border-color: var(--muted); }
:root.portal-light .board-ph { stroke: #b9b9c2; }   /* empty-preview grid glyph: softer grey on the light thumb (gold was low-contrast) */
/* «What's new» panel collapse */
.whatsnew-toggle { margin-left: auto; background: none; border: none; color: inherit; cursor: pointer; display: inline-flex; align-items: center; padding: 2px; flex: none; }
.whatsnew-toggle svg { transition: transform .2s; }
/* Collapsed → a small gold FAB-style circle showing just the icon; click it to expand. */
.whatsnew.collapsed { width: 52px; height: 52px; min-height: 0; max-height: none; border-radius: 50%; overflow: hidden; cursor: pointer; background: var(--gold, #cba74e); box-shadow: 0 8px 24px rgba(0,0,0,.45); }
.whatsnew.collapsed:hover { filter: brightness(1.08); }
.whatsnew.collapsed .whatsnew-head { padding: 0; height: 100%; justify-content: center; background: transparent; border-bottom: none; }
.whatsnew.collapsed .whatsnew-head > span, .whatsnew.collapsed .whatsnew-toggle { display: none; }
.whatsnew.collapsed .whatsnew-head svg { width: 22px; height: 22px; color: var(--on-gold, #161616); }
.whatsnew.collapsed .whatsnew-body { display: none; }
/* portal / review tone slider — visible track + outlined thumb (works on light AND dark) */
/* Portal/review tone+scale sliders share the SAME look as the board «Вид» sliders (one consistent style). */
#portalToneSlider, #portalScaleSlider, #rvToneSlider { -webkit-appearance: none; appearance: none; height: 16px; background: transparent; cursor: pointer; }
#portalToneSlider::-webkit-slider-runnable-track, #portalScaleSlider::-webkit-slider-runnable-track, #rvToneSlider::-webkit-slider-runnable-track { height: 5px; border-radius: 3px; background: var(--fill, rgba(127,127,127,.3)); }
#portalToneSlider::-webkit-slider-thumb, #portalScaleSlider::-webkit-slider-thumb, #rvToneSlider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; box-sizing: border-box; width: 16px; height: 16px; border-radius: 50%; background: var(--gold, #cba74e); border: 2px solid #fff; cursor: pointer; margin-top: -5.5px; }
#portalToneSlider::-moz-range-thumb, #portalScaleSlider::-moz-range-thumb, #rvToneSlider::-moz-range-thumb { box-sizing: border-box; width: 16px; height: 16px; border-radius: 50%; background: var(--gold, #cba74e); border: 2px solid #fff; cursor: pointer; }
#portalToneSlider::-moz-range-track, #portalScaleSlider::-moz-range-track, #rvToneSlider::-moz-range-track { height: 5px; border-radius: 3px; background: var(--fill, rgba(127,127,127,.3)); }
/* distinct link blue — readable on light AND dark backgrounds; a plain click opens it. Specificity must beat
   `.be-el-inner a { color: inherit }` (line ~96) or the link would inherit the block's (often invisible) text colour. */
.be-el-inner a.be-tlink, a.be-tlink { color: #4a90e2 !important; text-decoration: underline; cursor: pointer; pointer-events: auto; display: inline !important; }   /* display:inline!important overrides any stale inline display:none baked into a saved link */
.be-el-inner a.be-tlink:hover, a.be-tlink:hover { color: #6aa9ef !important; filter: none; }
.be-el.editing .be-tlink { cursor: text; }   /* while editing the text, links behave as plain text (no hand cursor, no navigation) */
/* Flash a block when jumping to it from a @mention notification */
.be-el.be-flash { animation: beFlash 1.6s ease; }
@keyframes beFlash { 0%, 100% { box-shadow: none; } 20%, 60% { box-shadow: 0 0 0 4px rgba(203,167,78,.55); } }
/* ── Board content search (magnifier): floating find-bar under the topbar + match highlights on the board ── */
.be-search-bar { position: fixed; top: 66px; left: 50%; transform: translateX(-50%); z-index: 40; display: flex; align-items: center; gap: 4px; background: var(--popover-bg); border: 1px solid var(--border-ring); border-radius: 12px; padding: 5px 8px; box-shadow: var(--shadow-lg); backdrop-filter: blur(8px); }
.be-search-ico { color: var(--muted); flex: none; }
.be-search-input { background: transparent; border: none; outline: none; color: var(--text); font-size: 14px; width: 210px; padding: 4px 2px; }
.be-search-input::placeholder { color: var(--muted-2); }
.be-search-count { font-size: 12px; color: var(--muted); min-width: 46px; text-align: center; font-variant-numeric: tabular-nums; }
.be-search-nav { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: none; background: transparent; color: var(--muted); border-radius: 8px; cursor: pointer; transition: background .12s, color .12s; }
.be-search-nav:hover { background: var(--fill-soft, rgba(255,255,255,.08)); color: var(--text); }
.be-search-x:hover { color: var(--danger, #ef6a63); }
.be-el.be-search-hit { box-shadow: 0 0 0 2px rgba(203,167,78,.5), 0 0 10px rgba(203,167,78,.3); border-radius: 4px; }   /* ring only → no layout shift */
.be-el.be-search-current { box-shadow: 0 0 0 3px var(--gold, #cba74e), 0 0 16px rgba(203,167,78,.6); }
/* Keyboard block-hopping (arrow keys, nothing selected): a very thin, faint pulsing focus ring — kept subtle so it
   doesn't obscure the block's text while reading */
.be-el.be-nav-focus { box-shadow: 0 0 0 1px rgba(203,167,78,.35); border-radius: 4px; animation: beNavPulse 1.7s ease-in-out infinite; }
@keyframes beNavPulse { 0%, 100% { box-shadow: 0 0 0 1px rgba(203,167,78,.25); } 50% { box-shadow: 0 0 0 1px rgba(203,167,78,.5); } }
@media (max-width: 700px) { .be-search-bar { top: 52px; gap: 2px; padding: 4px 6px; } .be-search-input { width: 42vw; } }
.be-view-pop { position: fixed; display: none; width: 300px; max-width: calc(100vw - 16px); background: var(--popover-bg); border: 1px solid var(--border-ring); border-radius: 12px; padding: 8px; z-index: 60; box-shadow: var(--shadow-lg); color: var(--text); }   /* color so children using inherit (resync btn, rescale row) follow the theme — incl. the light-canvas --text override */
.be-view-pop.open { display: block; }
.be-view-row { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text); padding: 7px 6px; }
.be-view-row > span { white-space: nowrap; width: 84px; flex: none; }
/* Drag-to-change percent value (zoom sensitivity) — value chip, drag left/right. */
.be-view-drag > span:first-child { width: auto; flex: none; }   /* long label sizes to content, no overlap with the chip */
.be-view-row .be-drag-pct { flex: 0 0 78px; width: 78px; text-align: center; cursor: ew-resize; user-select: none; font-variant-numeric: tabular-nums; font-weight: 600; background: var(--fill-soft); border: 1px solid var(--border); border-radius: 8px; padding: 5px 0; margin-left: auto; }
.be-view-row .be-drag-pct:hover { border-color: var(--gold); }
.be-view-row input[type=range] { flex: 1; min-width: 0; -webkit-appearance: none; appearance: none; height: 16px; background: transparent; cursor: pointer; }
.be-view-row input[type=range]::-webkit-slider-runnable-track { height: 5px; border-radius: 3px; background: var(--fill, rgba(127,127,127,.28)); }
.be-view-row input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; box-sizing: border-box; width: 16px; height: 16px; border-radius: 50%; background: var(--gold, #cba74e); border: 2px solid #fff; cursor: pointer; margin-top: -5.5px; }
.be-view-row input[type=range]::-moz-range-thumb { box-sizing: border-box; width: 16px; height: 16px; border-radius: 50%; background: var(--gold, #cba74e); border: 2px solid #fff; cursor: pointer; }
.be-view-row input[type=range]::-moz-range-track { height: 5px; border-radius: 3px; background: var(--fill, rgba(127,127,127,.28)); }
.be-view-row input[type=checkbox] { margin-left: auto; }
.be-view-reset { flex: none; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--line); background: var(--panel-3); color: var(--muted); border-radius: 6px; cursor: pointer; }
.be-view-reset:hover { color: var(--text); border-color: var(--muted); }
/* Force the reset arrow to the high-contrast text colour (--muted was resolving too close to the panel in some
   tone scopes → invisible icon). var(--text) always contrasts the panel; opacity keeps the soft look. */
.be-view-reset svg { stroke: var(--text) !important; opacity: .72; }
.be-view-reset:hover svg { opacity: 1; }
.be-view-row input[type=checkbox] { width: 17px; height: 17px; accent-color: var(--gold, #cba74e); cursor: pointer; }
/* Video-upload modal options (gray boxes, full width) */
.be-vopt { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px; margin: 0 0 8px; cursor: pointer; font-size: 13px; color: var(--text); transition: border-color .15s; }
.be-vopt:hover { border-color: var(--muted); }
.be-vopt input { width: 16px; height: 16px; accent-color: var(--gold, #cba74e); cursor: pointer; flex: none; }
/* Радио рисуем сами: в теме --gold может быть БЕЛЫМ, и нативная отмеченная точка сливалась с неотмеченными —
   выглядело так, будто «выбраны все». Отмеченный вариант подсвечивает и кольцо, и всю карточку. */
/* Кружок-индикатор segmented-выбора «Куда добавить» (радио заменены кнопками — см. board.js) */
/* Буллеты выбора — как везде в портале (accent-color): пустой контур ⇄ ПОЛНЫЙ закрашенный кружок */
.be-vradio { width: 16px; height: 16px; flex: none; border: 2px solid var(--muted, #888); border-radius: 50%; box-sizing: border-box; background: transparent; }
.be-vopt.be-vopt-on .be-vradio { border-color: var(--gold, #cba74e); background: var(--gold, #cba74e); }
.be-vopt input[type=radio] { -webkit-appearance: none; appearance: none; border: 2px solid var(--muted, #888); border-radius: 50%; background: transparent; }
.be-vopt input[type=radio]:checked { border-color: var(--gold, #cba74e); background: var(--gold, #cba74e); }
.be-vopt:has(input[type=radio]:checked), .be-vopt.be-vopt-on { border-color: var(--gold, #cba74e) !important; background: var(--gold-bg, rgba(203,167,78,.10)); }
.be-vopt.be-vopt-on span, .be-vopt:has(input[type=radio]:checked) span { color: var(--text); }
.be-vopt-label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; margin: 6px 0 6px; }
.be-vopt-hint { color: var(--muted); }
/* Compact modals on phones (e.g. the «Вставить видео» dialog with many options didn't fit). */
@media (max-width: 700px) {
    #beExportBtn { display: none !important; }   /* «Сохранение, экспорт, импорт и шаблоны» — desktop only */
    .modal-overlay { padding: 8px; align-items: flex-start; }
    .modal-dialog { padding: 16px; max-height: 94vh; border-radius: 14px; }
    .modal-title { font-size: 17px; }
    .modal-subtitle { font-size: 12px; margin-bottom: 10px; }
    .be-vopt { padding: 8px 10px; margin-bottom: 6px; font-size: 12px; }
    .be-vopt-label { margin: 4px 0; }
    .modal-dialog .form-input { height: 34px; font-size: 13px; }
    #beVideoList { max-height: 32vh; }
}
/* Floating chat button (bottom-right) + chat panel anchored above it */
.be-chat-fab { position: fixed; right: 18px; bottom: 18px; width: 52px; height: 52px; border-radius: 50%; background: var(--gold, #cba74e); color: var(--on-gold, #161616); border: none; cursor: pointer; box-shadow: 0 6px 20px rgba(0,0,0,.45); display: flex; align-items: center; justify-content: center; z-index: 55; }
.be-chat-fab:hover { filter: brightness(1.08); }
.be-chat-fab.be-feat-disabled { background: var(--panel-3, #26262a); color: var(--muted); }
.be-chat-fab .be-new-badge { position: absolute; top: -11px; left: 50%; right: auto; transform: translateX(-50%); min-width: 20px; height: 20px; padding: 0 5px; border-radius: 999px; font-size: 11px; }   /* round badge, lifted above and horizontally centred over the FAB circle */
#beChatPanel { top: auto; bottom: 82px; right: 18px; left: auto; }
/* Mobile: keep the chat circle visible for EVERYONE (users + guests) — sits above the call-strip/load-info at the bottom-right;
   its z-index (55) is above the bottom props strip (z-30) so it stays visible even while editing a block. */
@media (max-width: 700px) { .be-chat-fab { width: 46px; height: 46px; right: 10px; bottom: 92px; } .be-chat-fab svg { width: 21px; height: 21px; } #beChatPanel { bottom: 8px; right: 8px; } }

/* Server-load info widget (left of the chat FAB; shown to users + guests; admin can hide it) */
.be-el.be-bar-open { z-index: 99999 !important; }   /* an open block-comment bar must sit above every other block */
/* Compact call-participants strip — sits just above the «частный сервер» widget. */
.be-callstrip { position: fixed; right: 84px; bottom: 62px; z-index: 13; min-width: 156px; max-width: 240px;
    font-size: 11px; line-height: 1; color: var(--muted, #9aa3b2);
    background: rgba(20,20,24,.62); border: 1px solid var(--border, #2c2c34); border-radius: 12px;
    padding: 5px 5px 4px; backdrop-filter: blur(7px); box-shadow: 0 4px 14px rgba(0,0,0,.3); user-select: none;
    display: flex; flex-direction: column; gap: 1px; }
.be-callstrip .be-cs-head { display: flex; align-items: center; gap: 5px; font-size: 10px; opacity: .82; padding: 1px 5px 4px; border-bottom: 1px solid var(--border, #2c2c34); margin-bottom: 2px; }
.be-callstrip .be-cs-head svg { opacity: .85; flex: none; }
.be-callstrip .be-cs-fit { margin-left: auto; flex: none; width: 22px; height: 20px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: none; border-radius: 5px; background: var(--fill-soft, rgba(255,255,255,.08)); color: inherit; cursor: pointer; opacity: .9; }
.be-callstrip .be-cs-fit:hover { background: var(--gold, #cba74e); color: var(--on-gold, #1a1305); opacity: 1; }
/* Off-screen participant arrows: edge pill pointing to an on-board camera that's out of view; click → pan to them. */
.be-call-arrow { position: fixed; transform: translate(-50%, -50%); display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 9px 0 7px; border: none; border-radius: 999px; background: var(--gold, #cba74e); color: var(--on-gold, #1a1305); font-size: 11px; font-weight: 700; cursor: pointer; box-shadow: 0 3px 10px rgba(0,0,0,.4); white-space: nowrap; pointer-events: auto; }
.be-call-arrow:hover { filter: brightness(1.1); }
.be-call-arrow .be-ca-ic { display: inline-flex; font-size: 12px; line-height: 1; }
.be-call-arrow .be-ca-nm { max-width: 120px; overflow: hidden; text-overflow: ellipsis; }
.be-cs-row { display: flex; align-items: center; gap: 7px; padding: 3px 6px; border-radius: 7px; }
.be-cs-row.clickable { cursor: pointer; }
.be-cs-row.clickable:hover { background: rgba(255,255,255,.10); }
.be-cs-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text, #d8d8e0); }
.be-cs-mic, .be-cs-cam { flex: 0 0 auto; display: inline-flex; align-items: center; }
.be-cs-mic svg, .be-cs-cam svg { width: 13px; height: 13px; }
.be-cs-mic.on { color: #6fcaa0; }
.be-cs-mic.off { color: #e0726f; }
.be-cs-cam.corner { color: #4ea3cb; }
.be-cs-cam.board { color: var(--gold, #cba74e); }   /* on board = accent (it's the clickable one) */
.be-tile-flash { outline: 3px solid var(--gold, #cba74e) !important; outline-offset: 2px; }
body.be-canvas-light .be-callstrip { background: rgba(255,255,255,.82); color: #5a5a63; border-color: #e4e4ea; }
body.be-canvas-light .be-cs-name { color: #3a3a42; }
@media (max-width: 700px) { .be-callstrip { right: 64px; bottom: 46px; max-width: min(188px, calc(100vw - 74px)); font-size: 10px; } }   /* left of the chat FAB column (FAB now visible on mobile) */
.be-loadinfo { position: fixed; right: 84px; bottom: 24px; z-index: 13; display: flex; align-items: center; gap: 8px;
    font-size: 11px; line-height: 1; color: var(--muted, #9aa3b2); white-space: nowrap;
    background: rgba(20,20,24,.62); border: 1px solid var(--border, #2c2c34); border-radius: 999px;
    padding: 5px 11px; backdrop-filter: blur(7px); box-shadow: 0 4px 14px rgba(0,0,0,.3); user-select: none; }
.be-loadinfo .be-li-priv { display: inline-flex; align-items: center; gap: 4px; opacity: .82; }
.be-loadinfo .be-li-stats { display: inline-flex; align-items: center; gap: 9px; padding-left: 8px; border-left: 1px solid var(--border, #2c2c34); }
.be-loadinfo .be-li-m { display: inline-flex; align-items: center; gap: 3px; }
.be-loadinfo .be-li-m svg { opacity: .7; }
.be-loadinfo .be-li-m b { font-weight: 700; color: var(--text, #d8d8e0); }
.be-loadinfo .be-li-m.coop { color: var(--gold, #cba74e); }
.be-loadinfo .be-li-m.coop svg { opacity: 1; }
.be-loadinfo .be-li-m.on { color: var(--gold, #cba74e); }
.be-loadinfo .be-li-m.on svg { opacity: 1; }
.be-loadinfo .be-li-m.call, .be-loadinfo .be-li-m.call b { color: #4ea3cb; }
.be-loadinfo .be-li-m.call svg { opacity: 1; }
.be-loadinfo .be-li-m.rec, .be-loadinfo .be-li-m.rec b { color: #e05656; }
.be-loadinfo .be-li-m.rec svg { opacity: 1; animation: be-rec-blink 1.4s ease-in-out infinite; }
@keyframes be-rec-blink { 50% { opacity: .35; } }
.be-loadinfo.busy { border-color: var(--amber, #b9831a); color: var(--amber, #b9831a); }
body.be-canvas-light .be-loadinfo { background: rgba(255,255,255,.82); color: #5a5a63; border-color: #e4e4ea; }
body.be-canvas-light .be-loadinfo .be-li-m:not(.call):not(.rec) b { color: #5a5a63; }   /* counts match the «частный сервер» text colour on a light board (was --text light grey → invisible) */
body.be-canvas-light .be-loadinfo .be-li-m:not(.on):not(.call):not(.rec) svg { color: #5a5a63; }
.be-loadinfo .be-li-log { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; margin-left: 4px; padding: 0; border: 0; border-radius: 6px; background: transparent; color: inherit; cursor: pointer; opacity: .72; }
.be-loadinfo .be-li-log:hover { opacity: 1; background: rgba(255,255,255,.12); color: var(--gold, #cba74e); }
.be-loadinfo .be-li-log svg { width: 14px; height: 14px; }
body.be-canvas-light .be-loadinfo .be-li-log:hover { background: rgba(0,0,0,.07); }

/* LiveKit connection diagnostics panel */
.be-lkdiag { position: fixed; inset: 0; z-index: 100001; background: rgba(0,0,0,.5); display: flex; align-items: center; justify-content: center; backdrop-filter: blur(2px); }
.be-rtc-dock-btn.be-rtc-log { color: #9aa3b2; }
.be-rtc-dock-btn.be-rtc-log:hover { color: #cfd4dd; }

/* GIF block — fully borderless so a white-bg GIF merges with white geometry behind it */
.be-el.be-gif .be-el-inner { background: transparent !important; border: none !important; box-shadow: none !important; }

/* Video → GIF dialog (fragment + crop) */
.be-gifc-stage { position: relative; margin: 8px auto 10px; background: #000; border-radius: 8px; overflow: hidden; width: 100%; max-width: 560px; height: 240px; }
.be-gifc-stage video { width: 100%; height: 100%; display: block; object-fit: contain; }
.be-gifc-crop { position: absolute; left: 15%; top: 15%; width: 70%; height: 70%; border: 2px solid var(--gold, #cba74e); box-shadow: 0 0 0 9999px rgba(0,0,0,.45); cursor: move; box-sizing: border-box; }
.be-gifc-crop i { position: absolute; width: 12px; height: 12px; background: var(--gold, #cba74e); border-radius: 2px; }
.be-gifc-crop i[data-h="nw"] { left: -6px; top: -6px; cursor: nwse-resize; }
.be-gifc-crop i[data-h="ne"] { right: -6px; top: -6px; cursor: nesw-resize; }
.be-gifc-crop i[data-h="sw"] { left: -6px; bottom: -6px; cursor: nesw-resize; }
.be-gifc-crop i[data-h="se"] { right: -6px; bottom: -6px; cursor: nwse-resize; }
.be-gifc-time { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); margin-bottom: 6px; font-variant-numeric: tabular-nums; }
.be-gifc-lbl { font-size: 12px; color: var(--muted); display: block; margin: 8px 0 3px; }
.be-gifc-rng { width: 100%; margin: 0 0 2px; }
.be-gifc-chk { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--text); margin: 12px 0 2px; cursor: pointer; }
.be-gifc-row { display: flex; gap: 12px; }
.be-gifc-row > div { flex: 1; }
.be-lkdiag-card { width: 92vw; max-width: 560px; max-height: 84vh; display: flex; flex-direction: column; background: var(--popover-bg, #1a1a1f); border: 1px solid var(--border-ring, #333); border-radius: 14px; box-shadow: var(--shadow-lg); overflow: hidden; }
.be-lkdiag-head { display: flex; align-items: center; justify-content: space-between; padding: 13px 16px; border-bottom: 1px solid var(--line, #333); color: var(--text); }
.be-lkdiag-head b { font-size: 15px; }
.be-lkdiag-x { border: 0; background: transparent; color: var(--muted); font-size: 15px; cursor: pointer; padding: 4px 8px; border-radius: 8px; }
.be-lkdiag-x:hover { color: var(--text); background: var(--fill-soft, rgba(255,255,255,.07)); }
.be-lkdiag-tabs { display: flex; gap: 2px; padding: 0 12px; border-bottom: 1px solid var(--line, #333); flex: none; }
.be-lkdiag-tab { padding: 9px 14px; border: 0; background: transparent; color: var(--muted); font-size: 13px; font-weight: 600; cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.be-lkdiag-tab:hover { color: var(--text); }
.be-lkdiag-tab.on { color: var(--text); border-bottom-color: var(--gold, #cba74e); }
.be-lkdiag-pane { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; }
.be-lkdiag-ctx { display: grid; grid-template-columns: 1fr 1fr; gap: 5px 16px; padding: 12px 16px; border-bottom: 1px solid var(--line, #333); }
.be-lkdiag-ctx div { display: flex; justify-content: space-between; gap: 8px; font-size: 12px; min-width: 0; }
.be-lkdiag-ctx span { color: var(--muted); flex: 0 0 auto; }
.be-lkdiag-ctx b { color: var(--text); font-weight: 600; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.be-lkdiag-ctx .be-lkdiag-full { grid-column: 1 / -1; }   /* long codec list → full width */
.be-lkdiag-ctx .be-lkdiag-full b { white-space: normal; word-break: break-word; overflow: visible; }
.be-lkdiag-sub { padding: 9px 16px 4px; font-size: 11px; color: var(--muted); line-height: 1.4; }
.be-lkdiag-body { padding: 4px 10px 10px; overflow-y: auto; flex: 1 1 auto; min-height: 0; font-variant-numeric: tabular-nums; }
.be-lkdiag-dl { flex: 1 1 auto; min-height: 140px; margin: 6px 12px 12px; padding: 9px 11px; overflow: auto; background: var(--panel-2, #161619); border: 1px solid var(--line, #2a2a30); border-radius: 8px; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 11px; line-height: 1.45; color: var(--text); white-space: pre-wrap; word-break: break-word; }
.be-lk-row { display: flex; gap: 8px; padding: 4px 6px; font-size: 12px; border-radius: 6px; align-items: baseline; color: var(--text); }
.be-lk-t { color: var(--muted-2, #888); flex: 0 0 58px; }
.be-lk-dt { color: var(--muted); flex: 0 0 52px; text-align: right; }
.be-lk-st { flex: 1; min-width: 0; word-break: break-word; }
.be-lk-st i { color: var(--muted); font-style: normal; }
.be-lk-error { background: rgba(224,86,86,.12); }
.be-lk-error .be-lk-st { color: #e98a8a; }
.be-lk-ok .be-lk-st { color: #5cc98a; }
.be-lk-warn .be-lk-st { color: #e0b15a; }
.be-lk-slow .be-lk-dt { color: #e0b15a; font-weight: 700; }
.be-lkdiag-empty { padding: 26px 12px; text-align: center; color: var(--muted); font-size: 13px; }
.be-lkdiag-foot { display: flex; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--line, #333); justify-content: flex-end; }
@media (max-width: 700px) { .be-loadinfo { right: 10px; bottom: 10px; font-size: 10px; padding: 4px 9px; } .be-loadinfo .be-li-priv span { display: none; } }

/* ---- AI board assistant ---------------------------------------------------- */
.be-ai-fab { position: fixed; right: 18px; bottom: 18px; width: 52px; height: 52px; border-radius: 50%; border: none; cursor: pointer; z-index: 56;
    background: linear-gradient(140deg, #a855f7 0%, #7c3aed 55%, #6d28d9 100%);
    box-shadow: 0 6px 22px rgba(124,58,237,.5), 0 0 0 1px rgba(168,85,247,.35) inset;
    display: flex; align-items: center; justify-content: center; transition: transform .15s, filter .15s; }
.be-ai-fab:hover { filter: brightness(1.08); transform: translateY(-1px); }
.be-ai-fab:active { transform: translateY(0); }
.be-ai-fab.is-busy { animation: beAiPulse 1.1s ease-in-out infinite; }
@keyframes beAiPulse { 0%,100% { box-shadow: 0 6px 22px rgba(124,58,237,.5), 0 0 0 1px rgba(168,85,247,.35) inset; } 50% { box-shadow: 0 6px 30px rgba(168,85,247,.85), 0 0 0 2px rgba(192,132,252,.6) inset; } }

.be-ai-panel { position: fixed; right: 18px; bottom: 144px; width: 400px; max-width: calc(100vw - 36px); max-height: 74vh;
    background: var(--panel-2, #1c1c22); border: 1px solid var(--border, #2c2c34); border-radius: 16px;
    box-shadow: 0 18px 50px rgba(0,0,0,.55); z-index: 57; display: none; flex-direction: column; overflow: hidden; }
.be-ai-panel.open { display: flex; }
.be-ai-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px; border-bottom: 1px solid var(--border, #2c2c34);
    background: linear-gradient(120deg, rgba(168,85,247,.16), rgba(124,58,237,.04)); }
.be-ai-title { display: inline-flex; align-items: center; gap: 7px; font-weight: 700; font-size: 14px; color: var(--text, #eee); }
.be-ai-title svg { color: #a855f7; }
.be-ai-x { background: none; border: none; color: var(--muted, #99a); cursor: pointer; padding: 4px; border-radius: 8px; display: flex; }
.be-ai-x:hover { background: var(--panel-3, #26262a); color: var(--text); }
.be-ai-body { flex: 1; overflow-y: auto; padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; }
.be-ai-hello { font-size: 12.5px; line-height: 1.5; color: var(--muted, #9aa); background: var(--panel-3, #24242a); border-radius: 12px; padding: 11px 13px; }
.be-ai-msg { font-size: 13px; line-height: 1.5; border-radius: 12px; padding: 9px 12px; max-width: 92%; white-space: pre-wrap; word-wrap: break-word; }
.be-ai-msg.user { align-self: flex-end; background: linear-gradient(135deg, #7c3aed, #6d28d9); color: #fff; border-bottom-right-radius: 4px; }
.be-ai-msg.bot { align-self: flex-start; background: var(--panel-3, #26262a); color: var(--text, #eee); border-bottom-left-radius: 4px; }
.be-ai-msg.err { align-self: flex-start; background: rgba(239,68,68,.14); color: #fca5a5; }
.be-ai-card { align-self: flex-start; width: 92%; background: var(--panel-3, #26262a); border: 1px solid var(--border, #34343c); border-radius: 12px; padding: 10px 12px; }
.be-ai-card-sum { font-size: 12px; color: var(--muted, #9aa); display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 9px; }
.be-ai-card-sum b { color: var(--text, #eee); font-weight: 700; }
.be-ai-card-acts { display: flex; gap: 8px; }
.be-ai-apply, .be-ai-cancel { flex: 1; border: none; border-radius: 9px; padding: 7px 0; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.be-ai-apply { background: linear-gradient(135deg, #a855f7, #7c3aed); color: #fff; }
.be-ai-apply:hover { filter: brightness(1.08); }
.be-ai-apply:disabled { opacity: .5; cursor: default; }
.be-ai-cancel { background: var(--panel-1, #161618); color: var(--muted, #9aa); }
.be-ai-cancel:hover { color: var(--text); }
.be-ai-typing { align-self: flex-start; color: var(--muted, #9aa); font-size: 12.5px; display: inline-flex; gap: 4px; align-items: center; }
.be-ai-typing i { width: 6px; height: 6px; border-radius: 50%; background: #a855f7; display: inline-block; animation: beAiDot 1s infinite; }
.be-ai-typing i:nth-child(2) { animation-delay: .15s; } .be-ai-typing i:nth-child(3) { animation-delay: .3s; }
@keyframes beAiDot { 0%,60%,100% { opacity: .25; } 30% { opacity: 1; } }
.be-ai-form { display: flex; gap: 8px; align-items: flex-end; padding: 10px 12px; border-top: 1px solid var(--border, #2c2c34); }
.be-ai-input { flex: 1; resize: none; min-height: 76px; max-height: 240px; background: var(--panel-1, #161618); border: 1px solid var(--border, #34343c); color: var(--text, #eee); border-radius: 10px; padding: 10px 12px; font: inherit; font-size: 13.5px; line-height: 1.45; }
.be-ai-input:focus { outline: none; border-color: #a855f7; }
.be-ai-send { flex: 0 0 auto; width: 38px; height: 38px; border: none; border-radius: 10px; cursor: pointer; display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, #a855f7, #7c3aed); color: #fff; }
.be-ai-send:hover { filter: brightness(1.08); }
.be-ai-send:disabled { opacity: .5; cursor: default; }
/* Attach-file button + chips for the AI assistant */
.be-ai-attach { flex: 0 0 auto; width: 38px; height: 38px; border-radius: 10px; cursor: pointer; display: flex; align-items: center; justify-content: center;
    background: var(--panel-1, #161618); border: 1px solid var(--border, #34343c); color: var(--muted, #9a9aa6); transition: color .15s, border-color .15s; }
.be-ai-attach:hover { color: #a855f7; border-color: #a855f7; }
.be-ai-files { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 12px; max-height: 88px; overflow-y: auto; }
.be-ai-files:not(:empty) { padding: 8px 12px 0; }
.be-ai-file { display: inline-flex; align-items: center; gap: 5px; max-width: 100%; font-size: 12px; color: var(--text, #eee);
    background: rgba(168,85,247,.14); border: 1px solid rgba(168,85,247,.4); border-radius: 8px; padding: 3px 6px 3px 7px; }
.be-ai-file svg { flex: 0 0 auto; color: #a855f7; }
.be-ai-file.be-ai-img img { flex: 0 0 auto; width: 28px; height: 20px; object-fit: cover; border-radius: 4px; }   /* screenshot attach → tiny thumbnail in the chip */
.be-ai-file-nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 160px; }
.be-ai-file b { font-weight: 600; opacity: .6; font-size: 11px; }
.be-ai-file-x { border: none; background: none; color: var(--muted, #9a9aa6); cursor: pointer; font-size: 15px; line-height: 1; padding: 0 1px; }
.be-ai-file-x:hover { color: #ef4444; }
body.be-canvas-light .be-ai-attach { background: #faf9fc; border-color: #e4e4ea; color: #6b6b78; }
body.be-canvas-light .be-ai-file { color: #2a2440; }
body.be-canvas-light .be-ai-panel { background: #fff; border-color: #e4e4ea; box-shadow: 0 18px 50px rgba(40,30,60,.22); }
body.be-canvas-light .be-ai-head { border-bottom-color: #ece9f4; background: linear-gradient(120deg, rgba(168,85,247,.14), rgba(124,58,237,.03)); }
body.be-canvas-light .be-ai-title { color: #1c1530; }
body.be-canvas-light .be-ai-x { color: #6b6b76; }
body.be-canvas-light .be-ai-x:hover { background: #f0eef6; color: #1c1530; }
body.be-canvas-light .be-ai-hello, body.be-canvas-light .be-ai-msg.bot, body.be-canvas-light .be-ai-card { background: #f3f3f6; color: #222; }
body.be-canvas-light .be-ai-hello { color: #44464d; }
body.be-canvas-light .be-ai-card-sum { color: #6b6b76; }
body.be-canvas-light .be-ai-card-sum b { color: #1c1530; }
body.be-canvas-light .be-ai-card { border-color: #e4e4ea; }
body.be-canvas-light .be-ai-cancel { background: #f0f0f4; color: #555; }
body.be-canvas-light .be-ai-cancel:hover { color: #1c1530; }
body.be-canvas-light .be-ai-typing { color: #6b6b76; }
body.be-canvas-light .be-ai-form { border-top-color: #ece9f4; }
body.be-canvas-light .be-ai-input { background: #f6f6f9; color: #222; border-color: #dcdce4; }
body.be-canvas-light .be-ai-input::placeholder { color: #9a9aa4; }
@media (max-width: 700px) { .be-ai-fab { display: none; } .be-ai-panel { right: 8px; left: 8px; width: auto; bottom: 8px; } }

/* ---- RTMP/OBS module modal ---- */
.be-rtmp-flabel { display: block; font-size: 12px; color: var(--muted, #9aa); margin: 12px 0 4px; }
.be-rtmp-hint { color: var(--muted-2, #778); font-size: 11px; }
.be-rtmp-row { display: flex; gap: 8px; }
.be-rtmp-row .form-input { flex: 1; font-family: ui-monospace, monospace; font-size: 12.5px; }
.be-rtmp-copy { flex: 0 0 auto; white-space: nowrap; }
.be-rtmp-chk { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; margin: 14px 0 2px; cursor: pointer; line-height: 1.35; }
.be-rtmp-chk input { width: 16px; height: 16px; flex: 0 0 16px; margin-top: 1px; accent-color: #a855f7; cursor: pointer; }
.be-rtmp-chktext { flex: 1; min-width: 0; }   /* label + hint flow/wrap as one block to the right of the control */
.be-obs-del { flex: none; padding: 6px 11px; }   /* compact ✕ for a saved OBS link row */
.be-rtmp-chktext .be-rtmp-hint { display: block; margin-top: 1px; line-height: 1.3; }   /* hint on its own line → wraps as a clean paragraph */
.be-rtmp-sep { height: 1px; background: var(--border, #2c2c34); margin: 16px 0 4px; }
/* In-page OBS capture view: full-screen camera grid in the board tab (for OBS «Window Capture» + chroma-key bg). */
#beObsCap { position: fixed; inset: 0; z-index: 9999; overflow: hidden; }
#beObsCap .obscap-grid { position: absolute; inset: 0; display: grid; gap: 6px; padding: 6px; box-sizing: border-box; }
#beObsCap .obscap-grid.split { display: flex; flex-direction: row; align-items: stretch; }
#beObsCap .obscap-screens { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
#beObsCap .obscap-cams { flex: 0 0 22%; min-width: 140px; display: flex; flex-direction: column; gap: 6px; overflow: hidden; }
#beObsCap .obscap-grid.split .obscap-screens .obscap-tile { flex: 1 1 0; min-height: 0; }
#beObsCap .obscap-grid.split .obscap-cams .obscap-tile { flex: 0 1 auto; width: 100%; aspect-ratio: 16 / 9; min-height: 0; }
#beObsCap .obscap-tile { position: relative; background: transparent; overflow: hidden; display: flex; align-items: center; justify-content: center; }
#beObsCap .obscap-tile video { width: 100%; height: 100%; object-fit: contain; display: block; }
#beObsCap .obscap-name { position: absolute; left: 8px; bottom: 7px; font-size: 14px; font-weight: 600; color: #fff; background: rgba(0,0,0,.5); padding: 2px 9px; border-radius: 7px; max-width: 80%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#beObsCap .obscap-exit { position: fixed; right: 12px; bottom: 12px; z-index: 2; display: none; align-items: center; gap: 8px; background: rgba(15,15,18,.92); border: 1px solid rgba(255,255,255,.18); border-radius: 10px; padding: 7px 10px; font-size: 12px; color: #fff; box-shadow: 0 8px 26px rgba(0,0,0,.45); backdrop-filter: blur(6px); }
#beObsCap .obscap-exit.show { display: flex; }
#beObsCap .obscap-exit-btn { font: inherit; padding: 5px 11px; border-radius: 7px; border: none; cursor: pointer; background: #e0726f; color: #fff; }
#beObsCap .obscap-exit-btn.ghost { background: rgba(255,255,255,.14); }
/* OBS-visibility toggles — a distinct blue so they don't look like the call-control icons; red when hidden. */
.be-rtcadm-obsbtn { color: #4ea3cb; }
.be-rtcadm-obsbtn:hover { background: rgba(78,163,203,.14); }
.be-rtcadm-obsbtn.obshid { color: #e0726f; background: rgba(224,114,111,.16); }
.be-rtcadm-obsgrp { display: inline-flex; align-items: center; }
.be-rtcadm-obsgrp::before { content: 'OBS'; font-size: 8px; font-weight: 700; letter-spacing: .04em; color: #4ea3cb; opacity: .85; margin-right: 2px; }
/* Click a participant name to rename them locally (same as the board comms panel). */
.be-rtcadm-rename { cursor: pointer; }
.be-rtcadm-rename:hover { text-decoration: underline; text-underline-offset: 2px; }
/* Selected participant → a small accent dot (portal accent) in the corner so you know who you're working with. */
.be-rtcadm-row { position: relative; }
.be-rtcadm-seldot { display: none; position: absolute; top: 3px; right: 3px; width: 7px; height: 7px; border-radius: 50%; background: var(--gold, #cba74e); box-shadow: 0 0 0 2px rgba(0,0,0,.3); pointer-events: none; }
.be-rtcadm-row.sel .be-rtcadm-seldot { display: block; }
/* Cursor hint while placing a sticker (click the board to drop it). */
.be-place-hint { position: fixed; z-index: 10000; pointer-events: none; background: rgba(20,20,24,.93); color: #fff; border: 1px solid var(--border-ring, rgba(255,255,255,.18)); border-radius: 8px; padding: 5px 10px; font-size: 12px; box-shadow: 0 6px 20px rgba(0,0,0,.45); white-space: nowrap; backdrop-filter: blur(6px); }
body.be-placing, body.be-placing .be-canvas { cursor: copy !important; }
/* «Неактивный» component — greyed, purely visual (fully editable, draggable, resizable, deletable). Filter on the NODE
   (not the inner) so decorative pseudo-shadows — e.g. the sticky's ::before/::after lifted corners — grey + fade WITH
   the block instead of a full-strength dark shadow showing through a translucent inner. */
.be-el.be-frozen { filter: grayscale(1) opacity(.55); }
/* Positioned with TOP (not bottom): makeDraggablePanel sets `top` inline, and a `bottom` here too would stretch the
   fixed panel between them (empty space + clipped). Height hugs content, capped at max-height with the list scrolling. */
.be-tray-panel { position: fixed; right: 16px; top: 92px; z-index: 60; width: 214px; max-height: 72vh; display: flex; flex-direction: column; background: var(--popover-bg, rgba(22,22,26,.97)); border: 1px solid var(--border-ring, rgba(255,255,255,.16)); border-radius: 12px; box-shadow: 0 14px 40px rgba(0,0,0,.5); backdrop-filter: blur(8px); overflow: hidden; }
.be-tray-head { display: flex; align-items: center; gap: 8px; padding: 9px 12px; border-bottom: 1px solid var(--line, #333); cursor: grab; color: var(--text); font-weight: 700; font-size: 13px; }
.be-tray-head:active { cursor: grabbing; }
.be-tray-count { margin-left: auto; font-size: 11px; color: var(--on-gold, #1a1a1a); background: var(--gold); border-radius: 10px; padding: 1px 7px; font-weight: 700; }
.be-tray-list { flex: 1 1 auto; min-height: 0; padding: 8px; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; }
.be-tray-card { position: relative; display: flex; flex-direction: column; gap: 6px; border: 1px solid var(--line, #333); border-radius: 10px; padding: 7px; background: var(--fill-soft, rgba(255,255,255,.03)); }
.be-tray-x { position: absolute; top: 4px; right: 4px; width: 20px; height: 20px; padding: 0; border: 0; border-radius: 6px; background: rgba(12,12,15,.66); color: #ddd; font-size: 12px; line-height: 1; cursor: pointer; display: none; align-items: center; justify-content: center; }
.be-tray-card:hover .be-tray-x { display: inline-flex; }
.be-tray-x:hover { background: rgba(12,12,15,.92); color: #fff; }
.be-tray-thumb { width: 100%; aspect-ratio: 16 / 10; border-radius: 7px; background: var(--panel-2, #101014) center / contain no-repeat; }
.be-tray-name { font-size: 12px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.be-tray-acts { display: flex; gap: 6px; }
.be-tray-acts button { flex: 1; min-width: 0; font-size: 12px; padding: 5px 6px; border-radius: 7px; border: 1px solid var(--line); background: var(--panel-3); color: var(--text); cursor: pointer; }
.be-tray-acts button:hover { border-color: var(--gold); }
.be-tray-ins { background: var(--gold) !important; color: var(--on-gold, #1a1a1a) !important; border-color: var(--gold) !important; font-weight: 700; }
.be-tray-fly { position: fixed; z-index: 100200; pointer-events: none; background: center / cover no-repeat rgba(20,20,24,.5); border-radius: 8px; box-shadow: 0 8px 26px rgba(0,0,0,.45); transition: all .42s cubic-bezier(.5, 0, .2, 1); }
/* Marquee «Выделение» panel: «Все» + the object types caught, click a type to narrow the selection. */
.be-seltypes { position: fixed; top: 70px; left: 50%; transform: translateX(-50%); z-index: 56; display: none; align-items: center; gap: 6px; background: var(--popover-bg, rgba(20,20,24,.96)); border: 1px solid var(--border-ring, rgba(255,255,255,.16)); border-radius: 10px; padding: 6px 8px; box-shadow: 0 14px 40px rgba(0,0,0,.45); backdrop-filter: blur(8px); max-width: calc(100vw - 24px); overflow-x: auto; scrollbar-width: none; }
.be-seltypes.show { display: flex; }
.be-seltypes::-webkit-scrollbar { display: none; }
.be-seltypes-h { font-size: 11px; color: var(--muted); font-weight: 700; padding: 0 4px; flex: none; }
.be-seltypes-b { flex: none; font-size: 12px; padding: 5px 10px; border-radius: 7px; border: 1px solid var(--line); background: var(--panel-3); color: var(--text); cursor: pointer; white-space: nowrap; }
.be-seltypes-b:hover { border-color: var(--gold); }
.be-seltypes-b.on { background: var(--gold); color: var(--on-gold, #1a1a1a); border-color: var(--gold); }
.be-seltypes-conn { border-style: dashed; }   /* connector-arrows chip — dashed hints it selects the links, not blocks */
.be-root.be-canvas-light .be-seltypes { background: rgba(248,248,250,.96); color: #1a1a1e; }
/* …and the same accent dot on the selected participant's CAMERA tile. Tile mode → next to the name (in the bar);
   OBS capture overlay → top-LEFT corner. */
.be-rtc-tile.be-rtc-sel .be-rtc-bar::before { content: ''; width: 9px; height: 9px; border-radius: 50%; background: var(--gold, #cba74e); flex: none; align-self: center; margin: 0 5px 0 2px; }
/* OBS capture overlay: accent dot in the TOP-LEFT corner of the selected participant's tile (so you can tell who's selected). */
#beObsCap .obscap-tile.obscap-sel::after { content: ''; position: absolute; top: 8px; left: 8px; width: 13px; height: 13px; border-radius: 50%; background: var(--gold, #cba74e); box-shadow: 0 0 0 2px rgba(0,0,0,.5); z-index: 6; pointer-events: none; }
.be-rtmp-hint code { background: var(--panel-3, #26262a); padding: 1px 5px; border-radius: 4px; font-size: 11px; }

.be-canvas.panning { cursor: grabbing; }
/* Drag-and-drop file overlay */
.be-drop-ov { position: fixed; inset: 10px; z-index: 9998; display: none; align-items: center; justify-content: center; pointer-events: none; background: rgba(12,12,13,.55); border: 3px dashed var(--gold); border-radius: 14px; }
.be-drop-ov.show { display: flex; }
.be-drop-msg { display: flex; align-items: center; gap: 10px; background: var(--panel-2); border: 1px solid var(--gold); color: var(--gold); padding: 14px 24px; border-radius: 12px; font-size: 15px; font-weight: 600; box-shadow: 0 8px 30px rgba(0,0,0,.5); }
/* Hovering the "snap to grid" tool reveals the faint alignment grid (same size/offset as the dotted bg, set inline by JS) */
.be-canvas.grid-hover {
    background-image:
        linear-gradient(to right, rgba(203,167,78,.22) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(203,167,78,.22) 1px, transparent 1px);
}
.be-canvas.placing { cursor: crosshair; }
.be-canvas { touch-action: none; }

/* Rotate handle + marquee */
.be-rotate {
    position: absolute; width: 16px; height: 16px; border-radius: 50%;
    background: var(--bg); border: 2px solid var(--gold-hover); cursor: grab; z-index: 7;
}
.be-rotate:active { cursor: grabbing; }
.be-rotate::before { content: ''; position: absolute; inset: -9px; border-radius: 50%; }   /* enlarge grab target */
.be-rotate::after { content: ''; position: absolute; left: 50%; top: 100%; width: 2px; height: 12px; background: var(--gold-hover); transform: translateX(-50%); }
/* Corner rotation handles (one just outside each corner). Plain circle — no tail, no glyph. */
.be-rotate.be-rotate-c { width: 14px; height: 14px; background: var(--bg); border: 2px solid var(--gold-hover); box-shadow: 0 1px 3px rgba(0,0,0,.3); }
.be-rotate.be-rotate-c::after { content: none; }
.be-marquee {
    position: absolute; border: 1px solid var(--gold); background: rgba(203,167,78,.12);
    pointer-events: none; z-index: 9;
}

/* Screen-recording status bar (top-center) */
.be-rec-bar {
    position: fixed; top: 14px; left: 50%; transform: translateX(-50%); z-index: 200;
    display: flex; align-items: center; gap: 10px; padding: 8px 12px;
    background: var(--popover-bg, #1a1a1f); border: 1px solid var(--border-ring, #333);
    border-radius: 12px; box-shadow: var(--shadow-lg, 0 8px 30px rgba(0,0,0,.5));
    backdrop-filter: blur(8px);
}
.be-rec-preview { width: 150px; height: 84px; object-fit: cover; border-radius: 8px; background: #000; transform: scaleX(-1); border: 1px solid var(--border-ring, #333); }
/* «Экран+камера» composite is a wide canvas → show it WHOLE (no crop/stretch) and don't mirror it (the screen text would flip). */
.be-rec-preview.be-rec-preview-wide { width: 230px; height: 96px; object-fit: contain; transform: none; }
.be-rec-dot { width: 12px; height: 12px; border-radius: 50%; background: #ef4444; animation: beRecPulse 1s ease-in-out infinite; }
@keyframes beRecPulse { 0%,100% { opacity: 1; } 50% { opacity: .25; } }
.be-rec-time { color: var(--text); font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; min-width: 42px; }
.be-rec-btn {
    border: none; border-radius: 9px; padding: 7px 12px; font-size: 12px; cursor: pointer;
    background: var(--fill-soft, rgba(255,255,255,.08)); color: var(--text);
}
.be-rec-btn:hover { background: var(--fill, rgba(255,255,255,.14)); }
.be-rec-btn.stop { background: var(--gold-2, #cba74e); color: var(--on-gold, #1a1712); font-weight: 600; }

/* Web image search modal grid */
.be-imgs-grid {
    display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px;
    max-height: 52vh; overflow-y: auto; padding: 2px;
}
.be-imgs-tile {
    position: relative; padding: 0; border: 2px solid transparent; border-radius: 8px;
    overflow: hidden; cursor: pointer; background: var(--panel-2); aspect-ratio: 1 / 1;
}
.be-imgs-tile img { width: 100%; height: 100%; object-fit: contain; display: block; }
.be-imgs-tile:hover { border-color: var(--border-strong); }
.be-imgs-tile.sel { border-color: var(--gold); }
.be-imgs-tile.sel::after {
    content: '✓'; position: absolute; top: 4px; right: 4px; width: 20px; height: 20px;
    display: flex; align-items: center; justify-content: center; border-radius: 50%;
    background: var(--gold); color: var(--on-gold); font-size: 13px; font-weight: 700;
}
@media (max-width: 640px) { .be-imgs-grid { grid-template-columns: repeat(3, 1fr); } }

/* Audio (voice-comment) block: gold mic placeholder + player */
.be-el[data-type="audio"] .be-el-inner { background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.be-audio { width: 100%; height: 100%; box-sizing: border-box; padding: 12px 14px; display: flex; align-items: center; gap: 12px; }
.be-audio-icon { color: var(--gold); flex-shrink: 0; }
.be-audio-icon svg { width: 34px; height: 34px; display: block; }
.be-audio audio { flex: 1; min-width: 0; height: 34px; }
/* Custom audio player (replaces the default browser controls bar) */
.be-aud-player { display: flex; align-items: center; gap: 9px; width: 100%; min-width: 0; }
.be-aud-player audio { display: none; }
.be-aud-play { flex: none; width: 32px; height: 32px; border: 0; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; background: var(--gold); color: #1a1712; padding: 0; transition: filter .12s, transform .08s; }
.be-aud-play svg { width: 16px; height: 16px; }
.be-aud-play:hover { filter: brightness(1.08); }
.be-aud-play:active { transform: scale(.94); }
.be-aud-vol { flex: none; width: 26px; height: 26px; border: 0; background: transparent; cursor: pointer; color: var(--muted); display: flex; align-items: center; justify-content: center; padding: 0; transition: color .12s; }
.be-aud-vol svg { width: 19px; height: 19px; }
.be-aud-vol:hover, .be-aud-vol.muted { color: var(--text); }
.be-aud-time, .be-aud-dur { flex: none; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; min-width: 32px; }
.be-aud-time { text-align: right; }
.be-aud-track { position: relative; flex: 1; min-width: 30px; height: 5px; border-radius: 3px; background: rgba(255,255,255,.16); cursor: pointer; }
.be-aud-track:hover { height: 6px; }
.be-aud-fill { position: absolute; left: 0; top: 0; height: 100%; width: 0; border-radius: 3px; background: var(--gold); }
.be-aud-knob { position: absolute; top: 50%; left: 0; width: 12px; height: 12px; border-radius: 50%; background: var(--gold); transform: translate(-50%, -50%); box-shadow: 0 1px 4px rgba(0,0,0,.45); opacity: 0; transition: opacity .12s; }
.be-aud-player:hover .be-aud-knob { opacity: 1; }
/* Volume slider next to the mute icon. */
.be-aud-voltrack { position: relative; flex: none; width: 50px; height: 5px; border-radius: 3px; background: rgba(255,255,255,.16); cursor: pointer; touch-action: none; }
.be-aud-voltrack:hover { height: 6px; }
.be-aud-volfill { position: absolute; left: 0; top: 0; height: 100%; width: 100%; border-radius: 3px; background: var(--muted); }
.be-aud-voltrack:hover .be-aud-volfill { background: var(--gold); }
.be-root.be-canvas-light .be-aud-track { background: rgba(0,0,0,.13); }
/* Rich audio card (plain audio FILE): cover + title/artist·album/filename + player */
.be-audio-rich { align-items: stretch; gap: 12px; }
.be-audio-cover { width: 64px; flex: none; align-self: center; aspect-ratio: 1; border-radius: 8px; display: flex; align-items: center; justify-content: center; background: var(--fill-soft, rgba(255,255,255,.06)); color: var(--gold); overflow: hidden; }
.be-audio-cover svg { width: 30px; height: 30px; }
.be-audio-cover.has-img { background: none; }
.be-audio-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.be-audio-body { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 3px; }
.be-audio-title { font-weight: 600; font-size: 13px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.be-audio-sub { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.be-audio-file { font-size: 10px; color: var(--muted-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Subtle pill chips behind the track texts so the card doesn't look bare. */
.be-audio-title, .be-audio-sub, .be-audio-file { align-self: flex-start; max-width: 100%; box-sizing: border-box; padding: 2px 9px; border-radius: 999px; background: var(--fill-soft, rgba(255,255,255,.05)); border: 1px solid var(--border, rgba(255,255,255,.07)); }
.be-audio-rich audio { flex: none; width: 100%; height: 30px; margin-top: 2px; }

/* File block: portal-styled card with icon, name, size and download */
.be-el[data-type="file"] .be-el-inner { background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.be-file {
    width: 100%; height: 100%; box-sizing: border-box; padding: 12px;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; text-align: center;
}
.be-file-icon { color: var(--gold); }
.be-file-icon svg { width: 44px; height: 44px; display: block; }
.be-file-name {
    font-size: 12.5px; color: var(--text); font-weight: 600; line-height: 1.4; padding-bottom: 2px;
    max-width: 100%; word-break: break-word; overflow-wrap: anywhere;   /* full name, wraps to as many lines as needed (block grows to fit) */
}
.be-file-size { font-size: 11px; color: var(--muted-2); }
.be-file-dl {
    margin-top: 4px; display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
    padding: 6px 12px; border-radius: 8px; font-size: 12px; font-weight: 600;
    background: var(--gold); color: var(--on-gold); text-decoration: none;
}
.be-file-dl:hover { background: var(--gold-hover); color: var(--on-gold); }
.be-file-dl, .be-file-dl:hover, .be-file-dl span, .be-file-dl svg { color: var(--on-gold); }
/* Beat the generic `.be-el-inner a { text-decoration: underline }` (line ~96): the download button is a button, not a text link — no underline, themed text colour. */
.be-el-inner a.be-file-dl, .be-el-inner a.be-file-dl:hover { text-decoration: none; color: var(--on-gold); }
.be-file-totext {
    margin-top: 6px; display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
    padding: 6px 12px; border-radius: 8px; font-size: 12px; font-weight: 600;
    background: var(--panel-3); color: var(--text); border: 1px solid var(--line);
}
.be-file-totext:hover { border-color: var(--gold); }

/* Multi-file upload progress bar (top-center) */
.be-up-bar {
    position: fixed; top: 14px; left: 50%; transform: translateX(-50%); z-index: 200;
    display: flex; flex-direction: column; gap: 6px; width: min(360px, 80vw); padding: 10px 14px;
    background: var(--popover-bg, #1a1a1f); border: 1px solid var(--border-ring, #333);
    border-radius: 12px; box-shadow: var(--shadow-lg, 0 8px 30px rgba(0,0,0,.5)); backdrop-filter: blur(8px);
}
/* Drop below the fixed admin notice (top:0, ~38px tall) so the upload bar isn't clipped behind it. */
.portal-notice-fixed ~ .be-up-bar { top: 52px; }
.be-up-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 12px; }
.be-up-name { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 230px; }
.be-up-count { color: var(--muted-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.be-up-status { color: var(--text); }   /* tone-aware: dark on light board, light on dark — no coloured accent */
.be-up-track { height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; }
.be-up-fill { height: 100%; width: 0; background: var(--gold); border-radius: 3px; transition: width .15s ease; }
/* Scenario-plan «Сгенерировать»: queue plaque (reuses .be-up-bar), per-cell spinner overlay, style-prompt dialog. */
.be-gen-bar .be-up-name { display: inline-flex; align-items: center; max-width: 260px; }
.be-cell-gen { position: absolute; inset: 0; z-index: 6; display: flex; align-items: center; justify-content: center; background: rgba(10,10,14,.45); border-radius: inherit; pointer-events: none; }
.be-cell-gen-spin { width: 22px; height: 22px; border: 2.5px solid rgba(255,255,255,.9); border-top-color: var(--gold, #cba74e); border-radius: 50%; box-shadow: 0 0 6px rgba(0,0,0,.35); animation: be-busy-rot .8s linear infinite; }   /* dark board → admin accent (--gold = theme_accent) */
/* Light board: use the admin accent (light-tone or the main one) rather than the muted built-in gold; ring stays white. */
body.be-canvas-light .be-cell-gen-spin, .be-root.be-canvas-light .be-cell-gen-spin { border-top-color: var(--accent-light, var(--gold, #cba74e)); }
.be-scen-gen-presets { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.be-scen-gen-preset { padding: 5px 11px; font-size: 12px; border: 1px solid var(--border); border-radius: 999px; background: var(--panel-2); color: var(--text); cursor: pointer; }
.be-scen-gen-preset:hover { border-color: var(--gold); }
.be-scen-gen-input { width: 100%; box-sizing: border-box; resize: vertical; padding: 8px 10px; font-size: 13px; border: 1px solid var(--border); border-radius: 8px; background: var(--panel-2); color: var(--text); outline: none; font-family: inherit; }
.be-scen-gen-input:focus { border-color: var(--gold); }
.be-up-cancel { flex: none; margin-left: 6px; border: none; background: transparent; color: var(--muted); cursor: pointer; font-size: 13px; line-height: 1; padding: 3px 5px; border-radius: 5px; }
.be-up-cancel:hover { color: var(--danger, #ef4444); background: rgba(255,255,255,.08); }
/* "A peer is uploading" banner — shown to everyone else on the board while someone uploads */
.be-upl-banner {
    position: fixed; top: 58px; left: 50%; transform: translateX(-50%); z-index: 199;
    display: flex; align-items: center; gap: 9px; padding: 8px 14px; max-width: 80vw;
    background: var(--popover-bg, #1a1a1f); border: 1px solid var(--border-ring, #333);
    border-radius: 999px; box-shadow: var(--shadow-md, 0 6px 20px rgba(0,0,0,.4)); backdrop-filter: blur(8px);
    font-size: 12px; color: var(--text); white-space: nowrap;
}
.be-upl-spin { flex: none; width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--line, #444); border-top-color: var(--gold, #cba74e); animation: be-upl-rot .8s linear infinite; }
@keyframes be-upl-rot { to { transform: rotate(360deg); } }

/* Session-expired badge (left of the collab avatars) */
.be-auth-badge { display: none; align-items: center; gap: 6px; height: 30px; padding: 0 12px; margin-right: 6px; background: rgba(239,68,68,.15); border: 1px solid rgba(239,68,68,.5); color: #ef4444; border-radius: 8px; font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.be-auth-badge:hover { background: rgba(239,68,68,.25); }
.be-auth-badge svg { width: 14px; height: 14px; flex: none; }

/* Server-overloaded lamp (top panel) */
.be-load-lamp { display: none; align-items: center; gap: 7px; height: 30px; padding: 0 10px; margin-right: 6px; background: rgba(245,158,11,.15); border: 1px solid rgba(245,158,11,.5); color: #f59e0b; border-radius: 8px; font-size: 12px; font-weight: 600; white-space: nowrap; }
.be-load-dot { width: 9px; height: 9px; border-radius: 50%; background: #f59e0b; box-shadow: 0 0 7px rgba(245,158,11,.85); animation: be-load-pulse 1.2s ease-in-out infinite; }
@keyframes be-load-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* Indeterminate "working…" indicator (board PNG render, crop save, etc.) */
.be-busy { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); z-index: 100000; display: none; align-items: center; gap: 10px; padding: 10px 16px; background: var(--panel, #16161a); border: 1px solid var(--border, #2a2a31); border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.45); font-size: 13px; color: var(--text, #edf3ff); }
.be-busy-cancel { margin-left: 4px; border: 1px solid var(--border-ring, #3a3a44) !important; }
.be-busy-spin { width: 16px; height: 16px; border: 2px solid rgba(255,255,255,.25); border-top-color: var(--gold, #cba74e); border-radius: 50%; animation: be-busy-rot .7s linear infinite; flex: none; }
@keyframes be-busy-rot { to { transform: rotate(360deg); } }

/* Bezier editing hint for selected line/arrow */
.be-line-hint {
    position: absolute; z-index: 13; transform: translateY(-100%);
    width: auto; max-width: none; padding: 10px 14px; border-radius: 10px; margin-bottom: 14px;
    background: rgba(6,6,8,.98); border: 1px solid var(--border-strong, #3a3a42);
    color: var(--text, #efece6); font-size: 11.5px; line-height: 1.3;
    box-shadow: 0 14px 40px rgba(0,0,0,.6); pointer-events: none;
    display: flex; flex-direction: column; gap: 5px; white-space: nowrap; backdrop-filter: blur(10px);
}
.be-line-hint-title {
    font-size: 10px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
    color: var(--gold, #cba74e); margin-bottom: 1px;
}
.be-line-hint-row { position: relative; padding-left: 14px; color: var(--muted, #9aa3b2); }
.be-line-hint-row::before {
    content: ''; position: absolute; left: 2px; top: 6px; width: 5px; height: 5px;
    border-radius: 50%; background: var(--gold, #cba74e);
}
.be-hint-x {
    position: absolute; top: 4px; right: 5px; width: 18px; height: 18px; padding: 0;
    border: none; background: none; color: var(--muted, #9aa3b2); font-size: 16px; line-height: 1;
    cursor: pointer; pointer-events: auto; border-radius: 5px;
}
.be-hint-x:hover { color: var(--text, #efece6); background: rgba(255,255,255,.1); }

/* Draggable connector attach-point handles (both ends) + popup reset button.
   NB: no opacity transition — the connector <g> is rebuilt every wobble frame, and a transition on a
   freshly-created element flickers. Pinned points only change colour; they still hide when not hovered. */
.be-conn-anchor { fill: var(--gold, #cba74e); stroke: #0b0b0e; stroke-width: 1.5; opacity: 0; cursor: grab; pointer-events: none; }
.be-conn-anchor.pinned { fill: #4ea1ff; }
.be-conn-g:hover .be-conn-anchor, .be-conn-g.sel .be-conn-anchor { opacity: 1; pointer-events: auto; }
/* Manual bend-point handles on a selected connector (drag to move, double-click to remove). */
.be-conn-pt { fill: #fff; stroke: var(--gold, #cba74e); stroke-width: 3; cursor: grab; pointer-events: auto; }   /* the conn SVG layer is pointer-events:none — opt IN so the handle is grabbable */
.be-conn-pt:hover { fill: var(--gold, #cba74e); stroke: #fff; }
.be-conn-anchor:active { cursor: grabbing; }
.be-conn-reset { opacity: 0; cursor: pointer; pointer-events: none; }
.be-conn-reset circle { fill: #2a2a30; stroke: #4ea1ff; stroke-width: 1.5; }
.be-conn-reset path { stroke: #fff; stroke-width: 1.8; stroke-linecap: round; }
.be-conn-g:hover .be-conn-reset, .be-conn-g.sel .be-conn-reset { opacity: 1; pointer-events: auto; }
.be-conn-reset:hover circle { fill: #b3261e; stroke: #b3261e; }

/* World layer — translated + scaled; elements live in world coordinates */
.be-world { position: absolute; top: 0; left: 0; transform-origin: 0 0; z-index: 2; }

/* ---- Elements ---- */
.be-el { position: absolute; box-sizing: border-box; }
/* Lines/arrows are thin — only the stroke should select, not the invisible square bounding box.
   The wide transparent hit-path inside the SVG (pointer-events:stroke) still catches clicks near
   the stroke and the event bubbles to the node's handler; empty bbox area clicks pass through. */
.be-el[data-type="line"], .be-el[data-type="arrow"] { pointer-events: none; }
.be-el[data-type="line"] > .be-bar, .be-el[data-type="arrow"] > .be-bar { pointer-events: auto; }
.be-el.dragging { cursor: grabbing; }
/* content-visibility: the browser skips rendering a block's heavy body (photos, table cells, text) while it's off-screen,
   then paints it on approach — complements the JS culling in the CULL_PAD band and does the whole job on boards under the
   cull threshold. Scoped to .be-el-inner (NOT .be-el) so sibling badges / the belowstack caption / the .be-anim overlay —
   all children of .be-el — always render and are never clipped. contain-intrinsic-size:auto remembers the real box so a
   skipped block reserves the right space (the block is already explicitly sized, so there's no reflow either way). */
.be-el .be-el-inner { width: 100%; height: 100%; content-visibility: auto; contain-intrinsic-size: auto 1px; }
/* Line/arrow paths spill past the element box while editing bezier nodes/handles (the box is only re-fitted on mouseup),
   and content-visibility:auto's implied PAINT containment would clip that overhang to the stale rect → the arrow looked
   cropped by an invisible rectangle mid-drag. Paths are cheap to paint, so opt them out of the containment entirely. */
.be-el[data-type="line"] .be-el-inner, .be-el[data-type="arrow"] .be-el-inner { content-visibility: visible; contain: none; }
/* Far-zoom canvas snapshot (body.be-snapshot): below SNAP_Z on big boards the whole 2000-node DOM is replaced by ONE
   rasterised <canvas> child of #beWorld (rides the pan/zoom transform for free). Hide every live layer — element nodes,
   connector SVGs, selection overlay, comment pins — so only the canvas paints. Miro-like: 2000 nodes → 1 draw. */
.be-snapshot #beWorld .be-el { display: none !important; }
.be-snapshot #beConnLayer, .be-snapshot #beConnLayerTop, .be-snapshot #beOverlay, .be-snapshot #beComments { display: none !important; }
.be-snapcanvas { position: absolute; pointer-events: none; z-index: 0; image-rendering: auto; }

.be-el[data-type="rect"] .be-el-inner { background: var(--gold-bg); border: 2px solid var(--gold); border-radius: var(--radius-sm); position: relative; }
/* ==== Баблы (реплики как в комиксах) ====
   Форму задаёт SVG-контур внутри блока, а не CSS-коробка: хвост обязан выходить ЗА её границы,
   поэтому у svg `overflow: visible`, а сама коробка прозрачна (фон и рамку рисует path). */
/* ⚠ У контейнера блока стоит `content-visibility: auto` (оптимизация отсечения) — он включает
   paint-containment и СРЕЗАЛ хвост по краю блока. У баблов containment снимаем: терять на них нечего,
   блоков-баблов на ковре немного, а хвост обязан выходить наружу. */
.be-el.be-bubble-el > .be-el-inner { content-visibility: visible; contain: none; overflow: visible; }
.be-el.be-bubble-el { overflow: visible; }
.be-el .be-el-inner > .be-bubble { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; z-index: 0; }
.be-el .be-el-inner > .be-bubble + .be-shape-text { position: relative; z-index: 1; }
/* Точка-ручка на кончике хвоста: видна только у выделенного бабла, размер держится постоянным на любом зуме. */
.be-bubble-tail { position: absolute; width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%;
    background: var(--gold, #cba74e); border: 2px solid var(--panel, #16161a); box-sizing: border-box;
    cursor: grab; opacity: 0; pointer-events: none; transition: opacity .12s; z-index: 3;
    transform: scale(var(--be-invz, 1)); transform-origin: center; }
.be-el.selected > .be-bubble-tail { opacity: 1; pointer-events: auto; }
.be-bubble-tail:active { cursor: grabbing; }
.be-el[data-type="ellipse"] .be-el-inner { background: var(--gold-bg); border: 2px solid var(--gold); border-radius: 50%; position: relative; }
/* Centered editable text inside shapes (double-click to edit). Wrapper centers vert+horiz;
   the inner box is the contentEditable, so the caret is centered even when empty. */
.be-shape-text {
    position: absolute; inset: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; padding: 6px 8px;
    box-sizing: border-box; overflow: hidden; pointer-events: none;
}
.be-shape-text-in { max-width: 100%; word-break: break-word; line-height: 1.3; outline: none; }
.be-el.editing .be-shape-text { pointer-events: auto; }
.be-el.editing .be-shape-text-in { cursor: text; min-width: 8px; }

/* Board loading overlay + progress bar (shown while a large board renders). */
#beLoad { position: fixed; inset: 0; z-index: 100000; display: none; align-items: center; justify-content: center; background: rgba(10,10,12,.92); backdrop-filter: blur(4px); }
.be-load-box { width: min(330px, 78vw); text-align: center; background: #000000; border: 1px solid var(--border-strong, #34343d); border-radius: 14px; padding: 28px 30px; box-shadow: 0 16px 100px rgba(0,0,0,.28); }
.be-load-carpet { display: block; width: 170px; max-width: 62vw; height: auto; aspect-ratio: 320 / 172; margin: 0 auto 18px; }   /* reserve height up-front (dark gif 320×172) so the box doesn't grow when the gif loads */
body.be-canvas-light .be-load-carpet { aspect-ratio: 320 / 180; }   /* light gif is 320×180 */
.be-load-title { color: var(--text, #edf3ff); font-size: 15px; font-weight: 600; margin-bottom: 14px; letter-spacing: .01em; }
.be-load-track { height: 8px; background: rgba(255,255,255,.14); border-radius: 5px; overflow: hidden; }
.be-load-bar { height: 100%; width: 0; background: #c9c9cf; border-radius: 5px; transition: width .15s linear; }   /* neutral grey, NOT the portal accent: light grey on the dark splash */

/* Video buffering bar (shown while a board video buffers after play). */
.be-el[data-type="video"] .be-el-inner { position: relative; }
.be-vid-buffer { position: absolute; left: 0; right: 0; top: 0; height: 3px; background: rgba(255,255,255,.18); opacity: 0; transition: opacity .2s; pointer-events: none; z-index: 6; }
.be-vid-buffer.show { opacity: 1; }
.be-vid-buffer-fill { height: 100%; width: 0; background: var(--gold, #cba74e); transition: width .2s linear; }
/* Bright loading overlay on a video block until the first frame/poster appears */
.be-vid-loading { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: #0b0b0d; border-radius: var(--radius-xs); pointer-events: none; z-index: 5; }
.be-vid-loading-spin { width: 34px; height: 34px; border: 3px solid rgba(203,167,78,.25); border-top-color: var(--gold, #cba74e); border-radius: 50%; box-shadow: 0 0 14px rgba(203,167,78,.4); animation: be-busy-rot .8s linear infinite; }
/* Centred "ВИДЕО" tag (portal accent) on plain video blocks. Non-interactive; fades out while playing or when the
   block is selected so it never covers the video content or the edit handles. */
.be-vid-tag { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 5; padding: 5px 15px; border-radius: 999px; font-size: 13px; font-weight: 700; letter-spacing: .09em; background: var(--gold, #cba74e); color: var(--on-gold, #1a1712); pointer-events: none; box-shadow: 0 2px 10px rgba(0,0,0,.4); transition: opacity .18s; }
.be-el.be-vid-play .be-vid-tag, .be-el.selected .be-vid-tag { opacity: 0; }
/* Hide the native player chrome until the video block is selected (Chromium/WebKit). The <video> keeps controls=true
   so selecting/playing still work — toggling the attribute in JS during the selecting click broke block dragging. */
.be-el[data-type="video"]:not(.selected) video::-webkit-media-controls,
.be-el[data-type="video"]:not(.selected) video::-webkit-media-controls-enclosure,
.be-el[data-type="video"]:not(.selected) video::-webkit-media-controls-panel { display: none !important; opacity: 0 !important; }

/* Calculator blocks */
.be-el[data-type="calc"] .be-el-inner { background: var(--panel-2, #16161a); border: 1.5px solid var(--border-strong, #34343d); border-radius: 10px; overflow: hidden; }
.be-el[data-type="calc"][data-calc-result="1"] .be-el-inner { border-color: var(--gold, #cba74e); box-shadow: inset 0 0 0 1px rgba(203,167,78,.2); }
.be-calc { width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; padding: 6px 8px; box-sizing: border-box; position: relative; }
.be-calc-val { font-size: 24px; font-weight: 700; color: var(--text, #edf3ff); font-variant-numeric: tabular-nums; text-align: center; outline: none; max-width: 100%; overflow: hidden; word-break: break-word; line-height: 1.1; }
.be-el[data-type="calc"][data-calc-result="1"] .be-calc-val { color: var(--gold, #cba74e); }
/* Countdown timer block */
.be-timer { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; user-select: none; color: #eef1f8; box-sizing: border-box; padding: 8px; }
.be-timer-time { font: 800 40px/1 "Segoe UI", system-ui, -apple-system, Roboto, "Helvetica Neue", sans-serif; letter-spacing: 1.5px; color: #eef1f8; font-variant-numeric: tabular-nums; cursor: text; }
.be-timer-ctrls { display: flex; gap: 5px; flex-wrap: wrap; justify-content: center; align-items: center; }
.be-timer-ctrls button { min-width: 38px; height: 34px; padding: 0 9px; border: 1px solid rgba(255,255,255,.16); border-radius: 9px; background: rgba(255,255,255,.06); color: #dfe5f2; font: 700 13px/1 system-ui, sans-serif; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.be-timer-ctrls button:hover { background: rgba(255,255,255,.18); }
.be-timer-ctrls button svg { width: 18px; height: 18px; display: block; }
.be-timer-play { background: rgba(138,160,255,.22) !important; border-color: rgba(138,160,255,.5) !important; }
.be-timer-mode { background: rgba(255,205,110,.16) !important; border-color: rgba(255,205,110,.42) !important; font-size: 13px !important; }
@keyframes beTimerWarn { 0%,100% { color: #ff5a5a; text-shadow: 0 0 14px rgba(255,90,90,.75); } 50% { color: #fff; text-shadow: none; } }
.be-timer-warn .be-timer-time { animation: beTimerWarn .55s steps(1, end) infinite; }
@keyframes beTimerOver { 0%,100% { background: #d32f2f; } 50% { background: transparent; } }
.be-timer-over { animation: beTimerOver .5s steps(1, end) infinite; }
.be-timer-over .be-timer-time { color: #fff; text-shadow: 0 0 14px rgba(255,255,255,.6); }
/* Reading-time block (readtime): narration time of the connected text */
.be-readtime { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; user-select: none; color: #eef1f8; box-sizing: border-box; padding: 8px; text-align: center; }
.be-rt-ico { color: rgba(238,241,248,.6); line-height: 0; margin-bottom: 2px; }
.be-rt-ico svg { width: 30px; height: 30px; display: block; }
.be-rt-time { font: 800 34px/1 "Segoe UI", system-ui, -apple-system, Roboto, "Helvetica Neue", sans-serif; letter-spacing: 1px; color: #eef1f8; font-variant-numeric: tabular-nums; }
.be-rt-sub { font: 600 12px/1.2 system-ui, sans-serif; color: rgba(238,241,248,.6); padding: 0 6px; }
.be-readtime.be-rt-empty { gap: 12px; }
.be-readtime.be-rt-empty .be-rt-time { display: none; }   /* no placeholder digits in the empty state */
/* Video-editor launcher block on the board. MUST live here (always loaded), NOT in the lazy veditor.css — the block
   renders on first board open before the editor module is loaded, else it appears unstyled until you open the editor. */
.be-el[data-type="veditor"] .be-el-inner { border-radius: var(--radius-sm, 10px); overflow: hidden; }
.be-ved-card { width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; color: #e8e8ea; text-align: center; padding: 8px; box-sizing: border-box; border-radius: inherit; }
.be-ved-ic { font-size: 34px; line-height: 1; }
.be-ved-title { font-weight: 700; font-size: 14px; }
.be-ved-meta { font-size: 11px; opacity: .7; }
.be-ved-open { margin-top: 6px; height: 30px; padding: 0 14px; border: 1px solid var(--gold, #cba74e); background: var(--gold, #cba74e); color: #1a1712; border-radius: 8px; cursor: pointer; font-weight: 600; font-size: 12px; }
.be-ved-open:hover { filter: brightness(1.08); }
.be-ved-card-m { gap: 3px; padding: 6px; }
.be-ved-card-m .be-ved-ic { font-size: 26px; }
.be-ved-card-m .be-ved-title { font-size: 13px; }
.be-ved-note { margin-top: 4px; font-size: 11px; padding: 2px 9px; border-radius: 999px; background: rgba(255, 255, 255, .1); color: #e8e8ea; opacity: .85; white-space: nowrap; }
/* Operation badge (top-left) + breakdown line ("5 + 3 + 2") for the clear calc model */
.be-calc-op { position: absolute; top: 4px; left: 6px; font-size: 13px; font-weight: 800; line-height: 1; color: var(--gold, #cba74e); opacity: .85; pointer-events: none; }
.be-calc-formula { font-size: 11px; color: var(--muted, #9a958c); font-variant-numeric: tabular-nums; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1.2; }

.be-el[data-type="sticky"] .be-el-inner {
    background: var(--gold); color: var(--on-gold); border-radius: 2px 2px 7px 7px;
    padding: 14px; overflow: hidden;   /* FALLBACK only — the real inset is set inline & DYNAMIC by stickyPad() (share of the note size, capped) so small notes don't look over-padded; autoFitSticky + shotText read the same */
    display: flex; align-items: center; justify-content: center; text-align: center;
    line-height: 1.2; white-space: pre-wrap; word-break: normal; overflow-wrap: break-word;
    box-shadow: 0 2px 4px rgba(0,0,0,.16);
    /* faint shading toward the bottom edge → the paper looks like it curls up */
    background-image: linear-gradient(to bottom, transparent 76%, rgba(0,0,0,.045) 92%, rgba(0,0,0,.11) 100%);
}
/* While editing, stack lines vertically: the contenteditable's per-line <div>s (inserted on Enter) are flex items — in
   the default row direction they'd sit SIDE BY SIDE (text drifts right, and the off-screen-measured auto-fit no longer
   matches the layout). Column makes Enter a real new line + keeps the size adaptation correct. (A rendered, non-editing
   sticky is a single text node, so the direction doesn't change its centered look.) */
.be-el[data-type="sticky"].editing .be-el-inner { flex-direction: column; }
/* The «peeled / lifted bottom corners» (two skewed ::before/::after with a 14px-blur box-shadow) were removed 2026-07-20:
   two big blurred shadows + transforms per sticky re-rasterised on every zoom and hurt FPS on sticky-heavy boards.
   The light inner shadow (`.be-el-inner` box-shadow: 0 2px 4px) stays for depth. */
.be-el[data-type="text"] .be-el-inner {
    color: var(--text); padding: 5px 7px; overflow: hidden;
    font-size: 14px; line-height: 1.35; white-space: pre-wrap; word-break: break-word;
    border: 1px dashed rgba(255,255,255,.16); border-radius: var(--radius-sm);
}
.be-el[data-type="text"] .be-el-inner ul,
.be-el[data-type="text"] .be-el-inner ol { margin: 4px 0; padding-left: 6px; list-style-position: inside; }   /* inside → markers flow WITH the text (never drift/clip past the left edge, incl. when the block is a flex column for v-align) */
/* Pasted paragraphs (ChatGPT/Docs) come as <p> with default browser margins → an un-deletable gap between paragraphs
   that Enter keeps re-creating. Zero the block margins so paragraphs behave as plain line breaks (add a blank line for space). */
.be-el[data-type="text"] .be-el-inner p,
.be-el[data-type="ai_text"] .be-el-inner p,
.be-el[data-type="text"] .be-el-inner h1, .be-el[data-type="text"] .be-el-inner h2, .be-el[data-type="text"] .be-el-inner h3,
.be-el[data-type="text"] .be-el-inner h4, .be-el[data-type="text"] .be-el-inner h5, .be-el[data-type="text"] .be-el-inner h6 { margin: 0; }
/* Inside a group (container shape) the dashed border is hidden */
.be-el[data-type="text"][data-nested="1"] .be-el-inner { border-color: transparent; }
.be-el[data-type="image"] .be-el-inner { overflow: hidden; border-radius: var(--radius-xs); background: transparent; border: none; box-shadow: none; }   /* clean by default like GIFs — no panel frame/border unless set in the props panel */
/* Stickers: the image itself is the object — no panel box around it */
.be-el[data-sticker="1"] .be-el-inner { background: transparent; border: none; border-radius: 0; box-shadow: none; overflow: visible; }
.be-el[data-sticker="1"] .be-el-inner img { filter: drop-shadow(0 2px 4px rgba(0,0,0,.35)); }
.be-el[data-type="video"] .be-el-inner { overflow: hidden; border-radius: var(--radius-xs); background: #000; position: relative; }
/* Custom video controls — shown ONLY on CSS-zoomed screens (.be-vctrl-on set by applyVideoCtrlMode), where the native
   <video> scrubber thumb drifts off the timeline. Percentage-based fill/knob → the playhead always sits on the line.
   Overlaid at the video's bottom, revealed with the block selection (mirrors the native "controls only when selected"). */
.be-vctrl { position: absolute; left: 6px; right: 6px; bottom: 6px; display: none; align-items: center; gap: 8px; padding: 6px 10px; border-radius: 10px; background: rgba(14,14,18,.78); z-index: 6; }
.be-el.selected.be-vctrl-on .be-vctrl { display: flex; }
.be-vctrl button { background: none; border: none; padding: 0; color: #fff; cursor: pointer; display: flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.be-vctrl-play svg, .be-vctrl-btn svg { width: 20px; height: 20px; }
.be-vctrl button.muted { opacity: .55; }
.be-vctrl-time { color: #e8e8ec; font-size: 11px; font-variant-numeric: tabular-nums; flex: 0 0 auto; min-width: 30px; text-align: center; }
.be-vctrl-track { position: relative; flex: 1 1 auto; height: 5px; border-radius: 3px; background: rgba(255,255,255,.25); cursor: pointer; }
.be-vctrl-fill { position: absolute; left: 0; top: 0; height: 100%; width: 0; border-radius: 3px; background: var(--gold, #cba74e); }
.be-vctrl-knob { position: absolute; top: 50%; left: 0; width: 13px; height: 13px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.4); transform: translate(-50%,-50%); }
.be-el[data-type="video"] .be-el-inner video { position: relative; z-index: 0; }
/* Subtle inner gray frame, drawn over the video edges */
.be-el[data-type="video"] .be-el-inner::before {
    content: ''; position: absolute; inset: 0; z-index: 5; pointer-events: none;
    border: 2px solid rgba(200, 200, 205, .45); border-radius: var(--radius-xs);
}
/* When a custom border is chosen, drop the default gray frame */
.be-el[data-type="video"][data-bordered="1"] .be-el-inner::before { display: none; }
.be-el[data-type="ai_image"] .be-el-inner,
.be-el[data-type="ai_text"] .be-el-inner {
    overflow: hidden; border-radius: var(--radius-sm);
    background: var(--panel-2); border: 2px dashed var(--muted-2);
}
/* Type badge so картинка/текст blocks are distinguishable on the board */
.be-ai-badge {
    position: absolute; top: 6px; right: 6px; z-index: 3; pointer-events: none;
    display: inline-flex; align-items: center; gap: 4px;
    background: rgba(0,0,0,.55); color: #fff; font-size: 10px; font-weight: 700;
    letter-spacing: .04em; text-transform: uppercase; padding: 2px 7px; border-radius: 10px;
}
.be-ai-ph { width: 100%; height: 100%; display: flex; flex-direction: column; padding: 10px; gap: 8px; box-sizing: border-box; }
.be-ai-tag { font-size: 11px; font-weight: 800; letter-spacing: .08em; color: var(--gold); }
.be-ai-prompt { flex: 1; overflow: auto; font-size: 13px; color: var(--text); line-height: 1.35; white-space: pre-wrap; word-break: break-word; min-height: 0; }
.be-ai-prompt:empty::before { content: ''; }
.be-ai-gen {
    align-self: stretch; height: 32px; border: none; border-radius: var(--radius-sm);
    background: var(--gold-2); color: var(--on-gold); font-weight: 600; font-size: 13px; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.be-ai-gen:hover { background: var(--gold); }
.be-ai-gen svg, .be-gen-act svg { display: block; }
.be-aigen { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; text-align: center; color: var(--muted); font-size: 13px; font-weight: 500; background: var(--panel-2); border-radius: var(--radius-xs); padding: 8px; box-sizing: border-box; }
.be-spinner { width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--border-strong); border-top-color: var(--gold); animation: beSpin .8s linear infinite; }
@keyframes beSpin { to { transform: rotate(360deg); } }
/* Video conversion overlay (centered, with a percent progress bar) */
.be-converting {
    width: 100%; height: 100%; display: flex; flex-direction: column; gap: 10px;
    align-items: center; justify-content: center; background: var(--panel-2);
    color: var(--muted); border-radius: var(--radius-xs); font-size: 12px; padding: 0 16px; box-sizing: border-box;
}
.be-conv-label { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.be-conv-track { width: min(70%, 220px); height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; }
.be-conv-fill { height: 100%; width: 0; background: var(--gold); border-radius: 3px; transition: width .4s ease; }
/* Generated text block */
.be-ai-text { width: 100%; height: 100%; overflow: auto; padding: 10px 12px; box-sizing: border-box; font-size: 13px; line-height: 1.45; color: var(--text); white-space: pre-wrap; word-break: break-word; }
/* Generation versions bar (bottom of AI block) */
.be-genbar {
    position: absolute; left: 50%; bottom: 5px; transform: translateX(-50%); z-index: 4;
    display: flex; align-items: center; gap: 3px; padding: 3px 5px;
    background: rgba(0,0,0,.6); border-radius: 16px;
}
.be-gen-nav, .be-gen-act {
    border: none; background: transparent; color: #fff; cursor: pointer;
    width: 30px; height: 30px; border-radius: 10px; font-size: 19px; line-height: 1;
    display: inline-flex; align-items: center; justify-content: center;
}
.be-gen-nav:hover, .be-gen-act:hover { background: rgba(255,255,255,.18); }
.be-gen-nav:disabled { opacity: .35; cursor: default; }
.be-gen-act svg { width: 19px; height: 19px; }
.be-gen-lbl { color: #fff; font-size: 12px; padding: 0 5px; font-variant-numeric: tabular-nums; }
/* Media border controls */
.be-media-ctrls { display: inline-flex; align-items: flex-start; gap: 6px; }
/* All colour pickers: a round swatch. The eyedropper icon is overlaid as a real <svg>
   (two-tone — dark glyph + white halo, visible on any colour) via a .be-cpick wrapper in JS,
   because ::-webkit-color-swatch won't reliably show a background-image. Small grey ring. */
input[type="color"], .be-media-color {
    -webkit-appearance: none; -moz-appearance: none; appearance: none;
    width: 28px; height: 28px; min-width: 28px; padding: 0; flex: none;
    border: 1px solid rgba(180,182,190,.5); border-radius: 50%;
    background: none; cursor: pointer; box-sizing: border-box; overflow: hidden;
    box-shadow: 0 0 0 1px rgba(0,0,0,.18) inset;
}
input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
input[type="color"]::-webkit-color-swatch,
input[type="color"]::-moz-color-swatch { border: none; border-radius: 50%; }
/* The wrapper clips the native swatch into a perfect circle (overflow+radius on a real element
   works where it doesn't on the ::-webkit-color-swatch pseudo) and carries the grey ring. */
.be-cpick { position: relative; display: inline-flex; flex: none; width: 28px; height: 28px; border-radius: 50%; overflow: hidden; border: 1px solid rgba(180,182,190,.55); box-shadow: 0 0 0 1px rgba(0,0,0,.18) inset; vertical-align: middle; }
/* Oversize the input so the colour swatch always covers the whole circle (no corners/edges left). */
.be-cpick > input[type="color"] { width: 160%; height: 160%; min-width: 0; margin: -30%; border: none; border-radius: 0; box-shadow: none; padding: 0; }
.be-cpick-ic { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; pointer-events: none; z-index: 2; }
.be-cpick-ic svg { width: 16px; height: 16px; }

/* Connector editor — compact panel: presets, control row, label below */
.be-conn-pop { width: max-content !important; max-width: min(98vw, 1160px); overflow: visible; }   /* fit the single settings row (label text tools + line tools) */
.be-conn-row .be-slider-ctl { margin-top: 5px; }   /* nudge the thickness slider down to the buttons' centre line */
.be-cpop-grip { position: absolute; top: -13px; left: 50%; transform: translateX(-50%); width: 36px; height: 14px; display: flex; align-items: center; justify-content: center; background: var(--popover-bg); border: 1px solid var(--border-ring); border-bottom: none; border-radius: 7px 7px 0 0; color: var(--muted); cursor: grab; touch-action: none; z-index: 1; }   /* без своей тени: ручка — продолжение панели, а не наклейка поверх неё */
.be-cpop-grip:hover { color: var(--text); }
.be-cpop-grip:active { cursor: grabbing; }
/* Ряд капсул стрелки живёт по тем же меркам, что ряд панели блока: те же зазоры и ТА ЖЕ высота
   (панель стала однострочной — подпись переехала в меню «Действия», второй ряд больше не нужен). */
.be-conn-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4px; margin-top: 0; }
.be-cpop.be-conn-pop { padding: 6px; }   /* специфичность выше .be-cpop (12px), иначе панель выше блочной */
/* ⚠ Ручку перетаскивания сдвигаем ВПРАВО: панель стрелки узкая, и по центру она налезала на ярлычок
   «Соединительная стрелка» (у блоков панель шире, там оба помещаются). */
.be-conn-pop .be-cpop-grip { left: auto; right: 14px; transform: none; }
/* Ярлычок типа над панелью стрелки — точная копия блочного #bePropsType (та же геометрия и тон). */
#beConnPropsType { position: absolute; top: -17px; left: 10px; font-size: 9px; line-height: 1;
    color: var(--muted-2); background: var(--popover-bg); border: 1px solid var(--border-ring);
    border-bottom: none; border-radius: 8px 8px 0 0; padding: 3px 9px 4px; letter-spacing: .03em; z-index: 1; }
.be-root.be-canvas-light #beConnPropsType { background: rgba(248,248,250,.97); border-color: rgba(0,0,0,.14); color: #6a6a73; }
/* Bend-style icon dropdown */
.be-conn-style-menu { position: absolute; top: calc(100% + 4px); left: 0; z-index: 6; display: flex; gap: 3px; padding: 4px; background: var(--popover-bg); border: 1px solid var(--border-ring); border-radius: 9px; box-shadow: var(--shadow-md); }
.be-conn-style-menu .be-btn { width: 34px; height: 30px; }
/* Compact icon dropdowns in the props bar (colours / B-I-U / alignment / layer order):
   bigger icon on top, a small triangle below. */
.be-dd { position: relative; display: inline-flex; flex: none; }
.be-dd-trig { flex-direction: column; gap: 0; width: 34px; min-width: 34px; padding: 0; }
.be-dd-ico { display: inline-flex; align-items: center; justify-content: center; height: 18px; line-height: 1; font-size: 15px; font-weight: 800; }
.be-dd-ico svg { width: 18px; height: 18px; }
.be-dd-ico .be-swatch { width: 17px; height: 17px; border-width: 1.5px; flex: none; margin: 0; }
.be-dd-ico .be-swatch:hover { transform: none; }
.be-dd-chev { width: 10px; height: 6px; opacity: .7; flex: none; margin-top: 1px; color: var(--text); }
.be-dd-chev path { fill: var(--text); }   /* iOS sometimes ignores fill="currentColor" → force the triangle to the text colour */
.be-dd-menu { position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%); z-index: 200; display: none; gap: 3px; padding: 5px; background: var(--popover-bg); border: 1px solid var(--border-ring); border-radius: 10px; box-shadow: var(--shadow-md); white-space: nowrap; }
.be-dd-menu.open { display: flex; }
/* Select-style dropdown (font/weight/spacing/border) — vertical list of labelled options, opens upward like .be-dd-menu. */
.be-dd-sel .be-dd-trig { width: auto !important; min-width: 40px; padding: 0 8px; gap: 3px; }
/* Цифровые пресеты (кегль): триггер как у всех (30px), меню узкое, числа по центру */
.be-dd-sel.be-dd-nums .be-dd-trig { width: 30px !important; min-width: 30px; padding: 0; }
/* Комбо «Кегль»: поле ввода + всегда видимый ▾ с пресетами одним контролом; нативный спиннер скрыт */
.be-sizecombo { display: inline-flex; align-items: center; height: 30px; }
.be-sizecombo .be-num-input { width: 40px; height: 30px; border-top-right-radius: 0; border-bottom-right-radius: 0; }
.be-fmt-size::-webkit-inner-spin-button, .be-fmt-size::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.be-fmt-size { -moz-appearance: textfield; appearance: textfield; }
.be-dd-sel.be-dd-nums.be-dd-sizecombo .be-dd-trig { width: 17px !important; min-width: 17px !important; padding: 0; height: 30px;
    border-top-left-radius: 0; border-bottom-left-radius: 0; }
.be-dd-sizecombo .be-dd-ico { display: none; }
/* Треугольник кегля — тот же уголок, что у селектов («Строки»/«Вес»), а не жирная стрелка */
.be-dd-sizecombo .be-dd-chev { display: none; }
.be-dd-sel.be-dd-nums.be-dd-sizecombo .be-dd-trig {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23c5c9d4' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: center; background-size: 9px 6px; }
.be-dd-menu.be-dds.be-ddn.open { min-width: 0; width: max-content; }
.be-dd-menu.be-dds.be-ddn .be-fmt-btn { justify-content: center; padding: 0 14px; }
.be-dd-sel .be-dd-menu.open, .be-dd-menu.be-dds.open { display: flex; flex-direction: column; gap: 2px; min-width: 96px; max-height: 52vh; overflow-y: auto; white-space: nowrap; }
.be-dd-sel .be-dd-menu .be-fmt-btn, .be-dd-menu.be-dds .be-fmt-btn { width: 100%; min-width: 0; height: 30px; justify-content: flex-start; padding: 0 10px; font-size: 13px; }
/* Gesture-hint cards (top-left) are useless on touch + take too much room on a phone → hide them. */
@media (max-width: 760px), (pointer: coarse) { .be-line-hint { display: none !important; } }
.be-dd-menu.be-ddc.open { display: grid; grid-template-columns: repeat(6, 30px); justify-content: center; align-items: center; gap: 8px; }   /* wider, shorter panel; equal horizontal & vertical spacing */
/* «Тень» dropdown — a compact settings panel (toggle + sliders + colour) instead of a button list */
.be-shadow-panel { width: 240px; display: flex; flex-direction: column; gap: 9px; padding: 3px 2px; white-space: normal; }
.be-shadow-tog { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--text); cursor: pointer; }
.be-shadow-tog input { width: 16px; height: 16px; accent-color: var(--gold); cursor: pointer; }
.be-shadow-row { display: flex; align-items: center; gap: 8px; }
.be-shadow-lbl { flex: 0 0 96px; font-size: 12px; color: var(--muted-2, #9a9aa3); }
.be-shadow-range { flex: 1; min-width: 0; accent-color: var(--gold); }
.be-shadow-val { flex: 0 0 40px; text-align: right; font-size: 11px; font-variant-numeric: tabular-nums; color: var(--text); }
.be-shadow-colorin { flex: 1; height: 28px; padding: 0; border: 1px solid var(--border-ring); border-radius: 7px; background: none; cursor: pointer; }
/* Indeterminate progress bar (ElevenLabs load voices / voice test) — duration is unknown (network + VPN warmup). */
.el-busybar { height: 6px; border-radius: 4px; background: var(--panel-3, rgba(255,255,255,.08)); overflow: hidden; }
.el-busybar > span { display: block; width: 40%; height: 100%; border-radius: 4px; background: var(--gold, #cba74e); animation: el-busy 1.1s ease-in-out infinite; }
@keyframes el-busy { 0% { margin-left: -40%; } 100% { margin-left: 100%; } }
/* Frame title label (Miro-style) — sits just above the frame's top-left; drag it to move the frame, dbl-click to rename. */
.be-frame-label { position: absolute; left: 0; bottom: 100%; margin-bottom: 4px; max-width: 100%; padding: 1px 6px; font-size: 13px; font-weight: 600; line-height: 1.5; color: var(--muted-2, #9a9aa3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: move; user-select: none; border-radius: 5px; }
.be-frame-label.editing { background: var(--popover-bg, #1c1c22); color: var(--text, #e8e8ea); outline: 1px solid var(--gold, #cba74e); cursor: text; overflow: visible; }
.be-el.be-landing > .be-frame-label:not(.editing) { background: var(--gold, #cba74e); color: var(--on-gold, #1a1305); padding: 1px 8px; }   /* landing label = gold pill, distinct from a plain frame */
.be-el.be-landing > .be-landing-grid { position: absolute; inset: 0; pointer-events: none; border-radius: inherit; overflow: hidden; z-index: 1;
    background-image:
        repeating-linear-gradient(to right, rgba(130,140,165,.09) 0 1px, transparent 1px calc(100% / 12)),
        repeating-linear-gradient(to bottom, rgba(130,140,165,.07) 0 1px, transparent 1px 64px); }
/* 3×3 «align within the cell» grid for a block anchored to a table cell. */
.be-cellalign { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); gap: 2px; width: 34px; height: 34px; padding: 2px; border: 1px solid var(--border); border-radius: 6px; background: var(--panel-2); }
.be-cellalign .be-ca-dot { border: none; padding: 0; margin: 0; border-radius: 2px; background: rgba(255,255,255,.14); cursor: pointer; }   /* tone-adaptive dots (light on dark tone; dark on light tone — see canvas-light override) */
.be-cellalign .be-ca-dot:hover { background: var(--gold-bg, rgba(203,167,78,.25)); }
.be-cellalign .be-ca-dot.active { background: var(--gold, #cba74e); }
body.be-canvas-light .be-cellalign, .be-root.be-canvas-light .be-cellalign { background: #eef0f3; border-color: rgba(0,0,0,.16); }
body.be-canvas-light .be-cellalign .be-ca-dot, .be-root.be-canvas-light .be-cellalign .be-ca-dot { background: rgba(0,0,0,.13); }
body.be-canvas-light .be-cellalign .be-ca-dot.active, .be-root.be-canvas-light .be-cellalign .be-ca-dot.active { background: var(--gold, #cba74e); }   /* keep the accent on the active cell (outrank the light-dot override) */
/* Image placeholder (rect + props.imgPlaceholder): dashed frame + icon; double-click uploads a real picture. */
.be-el.be-imgph-host > .be-el-inner { position: relative; }
.be-el.be-imgph-host > .be-el-inner > .be-imgph { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; border-radius: inherit; border: 2px dashed rgba(120,120,140,.5); color: rgba(90,90,110,.85); font-size: 12px; font-weight: 600; letter-spacing: .3px; pointer-events: none; }
.be-el.be-imgph-dark > .be-el-inner > .be-imgph { border-color: rgba(150,155,180,.5); color: rgba(200,205,222,.82); }
/* Selected → the portal accent (admin «Настройки портала» overrides --gold). Border + icon/label follow it. */
.be-el.be-imgph-host.selected > .be-el-inner > .be-imgph,
.be-el.be-imgph-dark.selected > .be-el-inner > .be-imgph { border-color: var(--gold); color: var(--gold); }
/* «Анимация» props-panel dropdown. */
.be-anim-panel { display: flex; flex-direction: column; gap: 8px; min-width: 214px; }
.be-anim-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; }
.be-anim-pick { padding: 6px 8px; font-size: 12px; border: 1px solid var(--border); border-radius: 7px; background: var(--panel-2); color: var(--text); cursor: pointer; text-align: left; }
.be-anim-pick:hover { border-color: var(--gold); }
.be-anim-pick.active { background: var(--gold); color: var(--on-gold, #1a1305); border-color: var(--gold); }
.be-anim-row { display: flex; align-items: center; gap: 8px; }
.be-anim-lbl { font-size: 12px; color: var(--muted); min-width: 62px; }
.be-anim-auto { padding: 4px 10px; font-size: 12px; border: 1px solid var(--border); border-radius: 6px; background: var(--panel-2); color: var(--text); cursor: pointer; }
.be-anim-auto.active { background: var(--gold); color: var(--on-gold, #1a1305); border-color: var(--gold); }
.be-anim-colorin { width: 30px; height: 26px; padding: 0; border: 1px solid var(--border); border-radius: 6px; background: none; cursor: pointer; }
.be-anim-range { flex: 1; min-width: 0; }
.be-anim-val { font-size: 11px; color: var(--muted); min-width: 34px; text-align: right; }
/* ===== Block animations (props.anim) — light CSS/SVG accents. Overlay never blocks clicks (pointer-events:none)
   and never reaches the canvas screenshot (DOM-only, like the shadow); default colour = the portal accent (--gold). ===== */
.be-anim { position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 4; }
.be-anim > svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; display: block; }
.be-anim rect { fill: none; stroke: var(--anim-color, var(--gold, #cba74e)); stroke-width: var(--anim-w, 2px); }
@media (prefers-reduced-motion: reduce) { .be-anim, .be-anim *, .be-anim::before, .be-anim::after { animation: none !important; } }
/* ===== Far-zoom performance mode (body.be-farzoom, toggled below zoom FARZOOM_Z in applyViewportTransform):
   when zoomed out the whole board is on screen, per-element detail is invisible, yet drop-shadow/box-shadow blur and
   the animation overlay cost the GPU the same as at 1:1. Shed them. Shape (clip-path/mask) is NOT touched, so cropped
   photos keep their outline; only the expensive blur/animation layers are dropped. Screenshots use a separate painter,
   so this live-view class never affects exports. ===== */
.be-farzoom .be-anim { display: none !important; }
.be-farzoom .be-el .be-el-inner, .be-farzoom .be-el .be-el-inner img { box-shadow: none !important; filter: none !important; animation: none !important; }
/* --- contour effects: <rect pathLength="100"> → dashes are size-independent, geometry set per render --- */
.be-anim[data-anim="chase"] rect { stroke-linecap: round; stroke-dasharray: 14 86; filter: drop-shadow(0 0 4px var(--anim-color, var(--gold))); animation: be-anim-run var(--anim-dur, 3s) linear infinite; }
.be-anim[data-anim="dot"] rect { stroke-linecap: round; stroke-dasharray: 1.5 98.5; stroke-width: calc(var(--anim-w, 2px) * 1.7); filter: drop-shadow(0 0 5px var(--anim-color, var(--gold))); animation: be-anim-run var(--anim-dur, 3s) linear infinite; }
.be-anim[data-anim="dual"] rect { stroke-linecap: round; stroke-dasharray: 12 88; filter: drop-shadow(0 0 3px var(--anim-color, var(--gold))); }
.be-anim[data-anim="dual"] rect.be-a { animation: be-anim-run var(--anim-dur, 3s) linear infinite; }
.be-anim[data-anim="dual"] rect.be-b { animation: be-anim-run-rev var(--anim-dur, 3s) linear infinite; }
.be-anim[data-anim="neon"] rect { stroke-linecap: round; stroke-dasharray: 42 58; opacity: .9; filter: blur(1px) drop-shadow(0 0 6px var(--anim-color, var(--gold))); animation: be-anim-run var(--anim-dur, 5s) linear infinite; }
.be-anim[data-anim="ants"] rect { stroke-dasharray: 5 5; animation: be-anim-ants var(--anim-dur, 6s) linear infinite; }
@keyframes be-anim-run { to { stroke-dashoffset: -100; } }
@keyframes be-anim-run-rev { to { stroke-dashoffset: 100; } }
@keyframes be-anim-ants { to { stroke-dashoffset: -10; } }
/* --- CSS-only overlays --- */
.be-anim[data-anim="scanner"] { overflow: hidden; }
.be-anim[data-anim="scanner"]::before { content: ''; position: absolute; top: -5%; bottom: -5%; width: 16%; left: 0; background: linear-gradient(90deg, transparent, var(--anim-color, var(--gold)), transparent); filter: blur(2px); opacity: .8; animation: be-anim-scan var(--anim-dur, 2.6s) ease-in-out infinite alternate; }
@keyframes be-anim-scan { from { transform: translateX(-100%); } to { transform: translateX(525%); } }
.be-anim[data-anim="shine"] { overflow: hidden; }
.be-anim[data-anim="shine"]::before { content: ''; position: absolute; top: -50%; bottom: -50%; width: 38%; left: -55%; background: linear-gradient(90deg, transparent, rgba(255,255,255,.85), transparent); transform: skewX(-18deg); opacity: .5; animation: be-anim-shine var(--anim-dur, 4.5s) ease-in-out infinite; }
@keyframes be-anim-shine { 0% { transform: translateX(0) skewX(-18deg); } 28%, 100% { transform: translateX(440%) skewX(-18deg); } }
.be-anim[data-anim="glow"]::after { content: ''; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 14px 1px var(--anim-color, var(--gold)), 0 0 12px var(--anim-color, var(--gold)); animation: be-anim-glow var(--anim-dur, 2.8s) ease-in-out infinite; }
@keyframes be-anim-glow { 0%, 100% { opacity: .28; } 50% { opacity: .9; } }
.be-anim[data-anim="gradient"] { padding: var(--anim-w, 2px); background: conic-gradient(from 0deg, var(--anim-color, var(--gold)), #ffffff, var(--anim-color, var(--gold))); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask-composite: exclude; animation: be-anim-hue var(--anim-dur, 6s) linear infinite; }
@keyframes be-anim-hue { to { filter: hue-rotate(360deg); } }
.be-anim[data-anim="corners"] i { position: absolute; width: 16px; height: 16px; border: 2px solid var(--anim-color, var(--gold)); opacity: .2; animation: be-anim-corner var(--anim-dur, 2.4s) ease-in-out infinite; }
.be-anim[data-anim="corners"] i:nth-child(1) { top: 4px; left: 4px; border-right: none; border-bottom: none; animation-delay: 0s; }
.be-anim[data-anim="corners"] i:nth-child(2) { top: 4px; right: 4px; border-left: none; border-bottom: none; animation-delay: .18s; }
.be-anim[data-anim="corners"] i:nth-child(3) { bottom: 4px; right: 4px; border-left: none; border-top: none; animation-delay: .36s; }
.be-anim[data-anim="corners"] i:nth-child(4) { bottom: 4px; left: 4px; border-right: none; border-top: none; animation-delay: .54s; }
@keyframes be-anim-corner { 0%, 100% { opacity: .18; } 40% { opacity: 1; } }
/* Symmetric side safe-zones: two draggable vertical guides (editor aid only; hidden on the public link via showGrid). */
.be-el.be-landing > .be-landing-safe { position: absolute; inset: 0; pointer-events: none; z-index: 2; border-radius: inherit; }
.be-el.be-landing > .be-landing-safe .be-lz { position: absolute; top: 0; bottom: 0; width: 14px; margin-left: -7px; pointer-events: none; cursor: ew-resize; }   /* real 14px-wide grab strip centred on the line */
.be-el.be-landing > .be-landing-safe .be-lz::before { content: ''; position: absolute; left: 7px; top: 0; bottom: 0; border-left: 1px dashed rgba(203,167,78,.6); }   /* the visible dashed line at the strip's centre */
.be-el.be-landing.selected > .be-landing-safe .be-lz { pointer-events: auto; }   /* grabbable only while the landing is selected */
.be-el.be-landing.selected > .be-landing-safe .be-lz::before { border-left-color: rgba(203,167,78,.95); border-left-width: 2px; }
.be-el.be-landing.selected > .be-landing-safe .be-lz:hover::before { border-left-color: rgba(230,195,110,1); }
.be-el.be-landing > .be-landing-link { position: absolute; right: 0; bottom: 100%; margin-bottom: 4px; width: 26px; height: 22px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: none; border-radius: 5px; background: var(--gold, #cba74e); color: var(--on-gold, #1a1305); cursor: pointer; opacity: 0; transition: opacity .12s; }
.be-el.be-landing:hover > .be-landing-link, .be-el.be-landing.selected > .be-landing-link { opacity: 1; }
.be-el.be-landing > .be-landing-link:hover { filter: brightness(1.12); }
/* Гостю кнопка ВИДНА (иначе непонятно, откуда берётся публичная ссылка), но приглушена — по клику приходит
   плашка «создание ссылки доступно только владельцу». Не `disabled`: с ним не было бы ни клика, ни объяснения. */
.be-el.be-landing > .be-landing-link.be-landing-link-ro { background: var(--fill, rgba(255,255,255,.14)); color: var(--muted, #9a9aa4); }
.be-el.be-landing > .be-landing-link.be-landing-link-ro:hover { filter: none; background: var(--fill-strong, rgba(255,255,255,.2)); }
/* Landing settings popover (pretty /l/{slug} address + copy). */
/* Inline landing link (pretty /l/{slug} + copy) on the props-panel top row. */
.be-lp-inline { display: inline-flex; align-items: center; gap: 2px; height: 34px; padding: 0 4px 0 8px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 8px; }
.be-lp-inline .be-lp-pre { color: var(--muted); font-size: 12px; }
.be-lp-inline .be-lp-input2 { width: 150px; height: 26px; border: none; background: transparent; color: var(--text); font-size: 12px; padding: 0 2px; outline: none; }
.be-lp-inline .be-lp-copy2 { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; border: none; border-radius: 6px; background: var(--panel-3, rgba(255,255,255,.06)); color: var(--text); cursor: pointer; }
.be-lp-inline .be-lp-copy2:hover { background: var(--gold-bg, rgba(203,167,78,.25)); }
.be-landing-panel { position: fixed; z-index: 80; width: 264px; background: var(--popover-bg, #1c1d22); color: var(--text, #eee); border: 1px solid rgba(255,255,255,.12); border-radius: 10px; padding: 12px; box-shadow: 0 10px 32px rgba(0,0,0,.5); font-size: 13px; }
.be-landing-panel .be-lp-title { font-weight: 700; margin-bottom: 8px; }
.be-landing-panel .be-lp-lbl { color: var(--muted, #9a9aa5); font-size: 11px; margin-bottom: 4px; }
.be-landing-panel .be-lp-slug { display: flex; align-items: center; gap: 2px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.12); border-radius: 6px; padding: 0 8px; }
.be-landing-panel .be-lp-slug > span { color: var(--muted, #9a9aa5); }
.be-landing-panel .be-lp-input { flex: 1; background: none; border: none; color: var(--text, #eee); height: 30px; outline: none; font-size: 13px; min-width: 0; }
.be-landing-panel .be-lp-url { width: 100%; margin-top: 8px; background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.10); border-radius: 6px; color: var(--muted, #cfcfd6); height: 28px; padding: 0 8px; font-size: 12px; box-sizing: border-box; }
.be-landing-panel .be-lp-actions { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.be-landing-panel .be-lp-copy { background: var(--gold, #cba74e); color: var(--on-gold, #1a1305); border: none; border-radius: 6px; height: 30px; padding: 0 14px; font-weight: 600; cursor: pointer; }
.be-landing-panel .be-lp-copy:hover { filter: brightness(1.08); }
.be-landing-panel .be-lp-hint { color: var(--muted, #9a9aa5); font-size: 11px; }
/* Public landing page: the link opens the board in a stripped, scroll-only read-only view of one landing. */
body.be-landing-view .be-topbar, body.be-landing-view .be-toolbar, body.be-landing-view .be-tool-wrap, body.be-landing-view #beProps,
body.be-landing-view .be-align-bar, body.be-landing-view #beViewPop, body.be-landing-view .be-seltypes, body.be-landing-view #beZoomBar,
body.be-landing-view .be-callstrip, body.be-landing-view #beVoicePanel, body.be-landing-view #beLoadInfo, body.be-landing-view #beLoad,
body.be-landing-view .be-loadinfo,
body.be-landing-view #beCursors, body.be-landing-view #beRemoteSel, body.be-landing-view #beOverlay { display: none !important; }
body.be-landing-view #beCanvas { background-color: #2a2a2e; cursor: default; }
body.be-landing-view .be-el.selected, body.be-landing-view .be-el.be-landing { outline: none !important; box-shadow: none !important; }   /* no selection/outline of the landing block on the public page */
/* Landing link: hide the board from the FIRST paint (server adds .be-landing-pending) so you never glimpse the full
   board while it boots — revealed only once enterLandingView() has scoped + fitted the landing. */
body.be-landing-pending { background: #2a2a2e; }
body.be-landing-pending #beRoot { visibility: hidden; }
body.be-landing-pending::after { content: ''; position: fixed; top: 50%; left: 50%; width: 32px; height: 32px; margin: -16px 0 0 -16px; border: 3px solid rgba(255,255,255,.16); border-top-color: rgba(255,255,255,.7); border-radius: 50%; animation: be-landing-spin .7s linear infinite; z-index: 5; }
@keyframes be-landing-spin { to { transform: rotate(360deg); } }
body.be-landing-view .be-el.be-landing > .be-frame-label, body.be-landing-view .be-el.be-landing > .be-landing-link { display: none !important; }   /* no label/share button on the public page */
body.be-landing-view .be-el.be-landing { border-color: transparent !important; box-shadow: none !important; outline: none !important; }   /* the landing IS the page → no border/edge line of its own */
/* Slim draggable scrollbar for the public landing page (real scroll is emulated → no native one to rely on). */
.be-landing-scroll { position: fixed; top: 0; right: 0; width: 14px; height: 100vh; z-index: 60; }
.be-landing-scroll .be-landing-thumb { position: absolute; right: 3px; width: 7px; min-height: 30px; border-radius: 5px; background: rgba(170,170,182,.5); cursor: grab; transition: background .15s, width .15s; }
.be-landing-scroll:hover .be-landing-thumb, .be-landing-scroll .be-landing-thumb:active { background: rgba(205,205,216,.85); width: 9px; right: 2px; }
.be-root.be-canvas-light .be-frame-label { color: #6a6a73; }
/* Tiny caption under a control (colour pickers, numeric menus) so its purpose is clear */
/* ── Группы инструментов панели блока (Текст / Рамка / Эффекты / Размер / Связи / Действия).
   Внутри группы лежат ОБЫЧНЫЕ .be-ctl — те же узлы, что раньше стояли в панели, просто на клик глубже.
   Меню группы разворачивается вверх само (positionBeDdMenu переворачивает его, когда снизу нет места —
   на мобильном панель прижата к нижнему краю). */
/* Меню группы подбирает ширину под содержимое (max-width — только потолок); кнопки по центру,
   в строке .be-grp-row, подпись (.be-shape-label-input) ложится ПОД неё; её стандарт — 560px. */
/* ⚠ Потолок был 560px — ряд «Текста» из десяти контролов упирался в него впритык
   (замер стендом: нужно ~551px), и последний контрол уезжал на вторую строку. Запас на будущие контролы;
   `calc(100vw - 40px)` по-прежнему держит меню в окне на узких экранах — там перенос остаётся и это правильно. */
.be-grp-body { display: block; padding: 4px 2px; max-width: min(700px, calc(100vw - 40px)); }
.be-grp-row { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: center; gap: 10px 6px; }
/* Мобильный: меню группы — ОДНА строка с горизонтальной прокруткой, не многоэтажка */
@media (max-width: 700px) {
    .be-grp-row { flex-wrap: nowrap; justify-content: flex-start; overflow-x: auto;
        -webkit-overflow-scrolling: touch; max-width: calc(100vw - 40px); padding-bottom: 2px; }
}   /* горизонтальный шаг 6px — как в основной панели */
/* Селекты в меню группы не шире соседей: «Вес» распирало самым длинным пунктом («Полужирный»). */
.be-grp-body .be-fmt-select { max-width: 88px; }
/* Поле «Подпись» в меню: стандартная ширина 560px (потолок — вьюпорт), не дает меню схлопнуться уже себя */
.be-grp-body > .be-shape-label-input { width: min(560px, calc(100vw - 60px)); margin-top: 9px; display: block; }   /* воздух: подписи кнопок не липнут к полю ввода */
.be-dd-menu.be-grp-menu.open { display: block; }   /* внутри — своя flex-раскладка, не строка кнопок */
/* Ручка перетаскивания меню группы */
.be-grp-grip { height: 10px; margin: -2px 0 2px; display: flex; align-items: center; justify-content: center; cursor: grab; }
.be-grp-grip::before { content: ''; width: 36px; height: 3px; border-radius: 2px; background: var(--border-ring); }
.be-grp-grip:hover::before { background: var(--gold, #cba74e); }
.be-grp-grip:active { cursor: grabbing; }
/* ==== video review block (плеер + лента справа, как в разделе «Видео») ==== */
.be-el.be-vreview { display: flex; }
.be-el.be-vreview > .be-el-inner { flex: 1; min-width: 0; }
.be-vr-side { width: 300px; flex: none; display: flex; flex-direction: column; min-height: 0;
    background: var(--panel-2, #1c1c21); border: 1px solid var(--border-ring); border-left: none;
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0; box-sizing: border-box; overflow: hidden; }
.be-vr-head { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-bottom: 1px solid var(--border); flex: none; }
.be-vr-title { font-size: 12px; font-weight: 600; color: var(--text); }
.be-vr-count { margin-left: auto; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.be-vr-act { width: 24px; height: 24px; flex: none; display: inline-flex; align-items: center; justify-content: center;
    border: none; border-radius: 7px; background: var(--panel-3, rgba(255,255,255,.05)); color: var(--muted); cursor: pointer;
    box-shadow: inset 0 0 0 1px rgba(255,255,255,.06); }
.be-vr-act:hover { color: var(--text); background: var(--panel-hover); }
.be-vr-list { flex: 1; min-height: 0; overflow-y: auto; padding: 8px; }
.be-vr-side .be-vc-composer { border-top: 1px solid var(--border); padding: 8px; margin: 0; flex: none; }
.be-vr-side .be-vc-card { background: var(--panel-3, rgba(255,255,255,.04)); }
/* Светлый тон ковра: панели мало перекрасить ФОН — иначе на белом остаются тёмные поля ввода, серая шапка
   и почти невидимые «Кадр»/«Отправить». Переопределяем ВЕСЬ набор токенов, как это сделано у `.be-bar`,
   и панель со всей начинкой (карточки, поля, кнопки) светлеет разом.
   ⚠ `--panel-2` уводим в БЕЛЫЙ, а фон самой панели оставляем серым явно: иначе поле ввода сливается с панелью. */
body.be-canvas-light .be-vr-side {
    background: #f4f4f7;
    --panel-2: #ffffff; --panel-3: #ececf0; --panel-hover: rgba(0,0,0,.06);
    --text: #1a1a1e; --muted: #55555e; --muted-2: #6f6f78;
    --border: rgba(0,0,0,.14); --border-strong: rgba(0,0,0,.3); --border-ring: rgba(0,0,0,.14);
    --fill-soft: rgba(0,0,0,.06); --fill: rgba(0,0,0,.10);
}
body.be-canvas-light .be-vr-side .be-vr-act { box-shadow: inset 0 0 0 1px rgba(0,0,0,.10); }   /* белая внутренняя обводка на белом не видна */
body.be-canvas-light .be-vr-side .be-reply-input::placeholder { color: #83838d; }
/* «Отправить» — главное действие: на светлом даём заливку, как у primary в остальных всплывающих панелях. */
body.be-canvas-light .be-vr-side .be-btn.primary { background: var(--gold-2); color: var(--on-gold, #1a1712); }
/* ==== video review comments in block bar ==== */
.be-vc-card { display: flex; gap: 8px; padding: 7px 8px; border-radius: 9px; background: var(--fill-soft, rgba(255,255,255,.04)); margin-bottom: 6px; }
.be-vc-card.resolved { opacity: .62; }
.be-vc-thumb { width: 74px; height: 42px; object-fit: cover; border-radius: 6px; cursor: pointer; flex: none; border: 1px solid var(--border); }
.be-vc-main { flex: 1; min-width: 0; }
.be-vc-head { display: flex; align-items: center; gap: 8px; font-size: 11px; margin-bottom: 2px; }
.be-vc-author { font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 40%; }
.be-vc-tc { border: none; background: var(--gold-bg, rgba(203,167,78,.18)); color: var(--gold, #cba74e); font-size: 10px; border-radius: 6px; padding: 1px 7px; cursor: pointer; font-variant-numeric: tabular-nums; }
.be-vc-date { margin-left: auto; color: var(--muted-2); font-size: 10px; white-space: nowrap; }
.be-vc-text { font-size: 12.5px; color: var(--text); white-space: pre-wrap; word-break: break-word; }
.be-vc-actions { display: flex; gap: 10px; margin-top: 4px; }
.be-vc-act { border: none; background: none; padding: 0; color: var(--muted); font-size: 10.5px; cursor: pointer; }
.be-vc-act:hover { color: var(--gold, #cba74e); }
.be-vc-kids { margin-top: 6px; border-left: 2px solid var(--border); padding-left: 8px; }
.be-vc-card.be-vc-reply { background: transparent; padding: 4px 0; margin-bottom: 2px; }
.be-vc-composer { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.be-vc-composer .be-vc-name { height: 28px; }
.be-vc-comprow { display: flex; align-items: center; gap: 8px; }
.be-vc-shotbtn { height: 28px; padding: 0 10px; font-size: 12px; display: inline-flex; align-items: center; gap: 5px; line-height: 1; }
.be-vc-shotprev { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; color: var(--muted); }
.be-vc-shotprev img { width: 46px; height: 26px; object-fit: cover; border-radius: 4px; border: 1px solid var(--border); }
.be-vc-shotprev b { color: var(--gold, #cba74e); font-variant-numeric: tabular-nums; }
.be-vc-send { height: 28px; padding: 0 14px; margin-left: auto; font-size: 12px; }
.be-vc-replyform { display: flex; gap: 6px; margin-top: 6px; align-items: flex-end; }
.be-vc-replyform textarea { flex: 1; }
body.be-canvas-light .be-vc-card { background: rgba(0,0,0,.05); }

/* Разделители, которые внутри группы теряют смысл (группа сама и есть разделение). */
.be-grp-body .be-props-sep { display: none; }
/* Один размер квадратных кнопок в панели и меню групп: «толстые» .be-btn (36px) ломали ровный ритм. */
.be-props .be-ctl .be-btn, .be-grp-body .be-btn { height: 30px; min-width: 30px; padding: 0 6px; }
.be-props .be-ctl .be-btn svg, .be-grp-body .be-btn svg { width: 17px; height: 17px; }
/* Иконки кнопок — единый цвет тона (белые на тёмном), без серых полутонов «до наведения»:
   .be-btn по умолчанию var(--muted) и белел на hover — в панели и меню это выглядело разнобоем. */
.be-props .be-ctl .be-btn:not(.danger):not(.primary), .be-dd-menu .be-btn:not(.danger):not(.primary) { color: var(--text); }
/* Светлый тон: меню поднято в <body> — правила .be-props его не достают, дублируем по body-классу */
body.be-canvas-light .be-dd-menu .be-btn:not(.danger):not(.primary),
body.be-canvas-light .be-dd-menu .be-fmt-btn:not(.active),
body.be-canvas-light .be-dd-menu .be-ctl-lbl { color: #1a1a1e; }
/* Подпись-тип панели («Текстовый блок») — ярлычок над верхней кромкой */
/* В режиме узкой ленты (be-force-mstrip / мобильный) панель скроллится и клипует absolute-детей — ярлык прячем */
.be-root.be-force-mstrip #bePropsType { display: none; }
#bePropsType { position: absolute; top: -17px; left: 10px; font-size: 9px; line-height: 1;
    color: var(--muted-2); background: var(--popover-bg); border: 1px solid var(--border-ring);
    border-bottom: none; border-radius: 8px 8px 0 0; padding: 3px 9px 4px; letter-spacing: .03em; z-index: 1; }
/* ⚠ Ярлычок сидит НАД панелью, и её собственная верхняя рамка проходила прямо под ним — получалась черта,
   отрезающая ярлычок от панели. Закрашиваем этот отрезок полоской фона панели: ярлычок сливается с ней,
   как вкладка. (Тот же приём нужен обоим ярлычкам — блока и стрелки.) */
#bePropsType::after, #beConnPropsType::after { content: ''; position: absolute; left: 0; right: 0; bottom: -1px;
    height: 1px; background: var(--popover-bg); }
.be-root.be-canvas-light #bePropsType::after,
.be-root.be-canvas-light #beConnPropsType::after { background: rgba(248,248,250,.97); }
/* ⚠ Ярлычок примыкает к панели без нижней границы, поэтому обязан повторять её фон и рамку. На светлом тоне
   ковра он оставался тёмным (свои var-ы, а панели цвет задан явно) и выглядел чужим наростом сверху.
   Ручка перетаскивания (.be-props-grip) устроена так же и болела тем же — правим обе одним правилом. */
.be-root.be-canvas-light #bePropsType,
.be-root.be-canvas-light .be-props.be-props-float .be-props-grip { background: rgba(248,248,250,.97); border-color: rgba(0,0,0,.14); color: #6a6a73; }
.be-root.be-canvas-light .be-props.be-props-float .be-props-grip:hover { color: #1a1a1e; }
/* Триггер группы: чуть заметнее обычной кнопки — это «вход», а не действие. */
.be-dd-grp > .be-dd-trig { border-color: var(--border-ring); }
.be-dd-grp > .be-dd-trig:hover { border-color: var(--gold, #cba74e); }
.be-ctl { display: inline-flex; flex-direction: column; align-items: center; gap: 2px; }
/* control sits in a fixed-height band (matches buttons) so sliders centre on the buttons' middle
   and every caption lines up on the same row underneath */
.be-ctl-top { display: inline-flex; align-items: center; justify-content: center; height: 30px; }
/* Ширину .be-ctl задаёт КОНТРОЛ, а не подпись: раньше длинная подпись («Прозрачность», «Коннектор»)
   распирала свою ячейку и расстояния между кнопками плясали. width:0 + min/max 100%+14px = подпись
   симметрично нависает до 7px с каждой стороны, длиннее — многоточие. Зазор между кнопками ровный. */
.be-ctl-lbl { font-size: 7px; line-height: 1; color: var(--muted-2); white-space: nowrap; letter-spacing: .01em;
    width: 0; min-width: calc(100% + 8px); max-width: calc(100% + 8px); margin: 0 -4px;
    text-align: center; overflow: hidden; text-overflow: ellipsis; }
/* Единая МИНИМАЛЬНАЯ ширина ячейки: длинные подписи («Коннектор», «Огибание») больше не наезжают на
   соседей — ячейка вмещает подпись, кнопка центрируется, шаг между ячейками остаётся ровным. */
.be-props .be-ctl, .be-dd-menu .be-ctl, .be-conn-pop .be-ctl { min-width: 34px; }
/* A colour control = preset dropdown + free picker side by side in one rounded pill, captioned as one */
.be-colorctl { display: inline-flex; align-items: center; gap: 3px; }   /* капсула убрана: цвет — такая же кнопка, как все (просьба пользователя) */
.be-slider-ctl { display: inline-flex; align-items: center; gap: 6px; }
.be-colorctl .be-dd-trig, .be-colorctl .be-media-color { flex: none; }
/* Light tone: dark обводка on the connector editor's colour controls (pill + swatch + picker) so they read on the light panel. */
body.be-canvas-light .be-conn-pop .be-colorctl,
.be-root.be-canvas-light .be-conn-pop .be-colorctl { border-color: rgba(0,0,0,.62); }
body.be-canvas-light .be-conn-pop .be-colorctl .be-swatch,
body.be-canvas-light .be-conn-pop .be-colorctl .be-media-color,
.be-root.be-canvas-light .be-conn-pop .be-colorctl .be-swatch,
.be-root.be-canvas-light .be-conn-pop .be-colorctl .be-media-color { border-color: rgba(0,0,0,.5); }
.be-video-row {
    display: flex; align-items: center; gap: 12px; padding: 10px 12px;
    background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-md);
    cursor: pointer; transition: all var(--transition);
}
.be-video-row:hover { border-color: var(--gold); background: var(--panel-3); }
.be-video-row .be-video-ic { color: var(--gold); flex-shrink: 0; }
.be-video-row .be-video-meta { min-width: 0; }
.be-video-row .be-video-title { font-weight: 600; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.be-video-row .be-video-sub { color: var(--muted); font-size: 11px; }
.be-el[data-type="line"] .be-el-inner,
.be-el[data-type="arrow"] .be-el-inner { overflow: visible; }

.be-el .be-editable:focus { outline: none; }
.be-el.editing { cursor: text; }
.be-el.editing .be-el-inner { cursor: text; }

/* Comments layer (pins + popups, screen space) */
#beComments { position: absolute; inset: 0; pointer-events: none; z-index: 12; }
#beComments > * { pointer-events: auto; }
.be-pin {
    position: absolute; width: 26px; height: 26px; transform: translate(-50%, -100%);
    border: none; border-radius: 50% 50% 50% 2px; background: var(--gold); color: var(--on-gold);
    display: flex; align-items: center; justify-content: center; cursor: pointer;
    box-shadow: var(--shadow-md); transition: transform .1s;
}
.be-pin:hover { transform: translate(-50%, -100%) scale(1.12); }
.be-pin.resolved { background: var(--green); color: #07210f; }
.be-cpop {
    position: absolute; transform: translate(-50%, 0); width: 240px; padding: 12px;
    background: var(--popover-bg); border: 1px solid var(--border-ring); border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg); backdrop-filter: blur(8px); z-index: 13;
}
.be-cpop-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.be-cpop-head b { font-size: 13px; color: var(--text); }
.be-cpop-date { font-size: 10px; color: var(--muted-2); }
.be-cpop-text { font-size: 13px; color: var(--text); line-height: 1.45; white-space: pre-wrap; word-break: break-word; }
.be-cpop-actions { display: flex; gap: 6px; justify-content: flex-end; margin-top: 10px; }
.be-cpop .be-btn.primary { background: var(--gold-2); color: var(--on-gold); }
/* View-popup action buttons: larger rounded icon buttons (resolve / delete) */
.be-cpop:not(.be-ccompose) .be-cpop-actions .be-btn {
    width: 40px; min-width: 40px; height: 40px; padding: 0; border-radius: 11px;
    background: var(--fill-soft); color: var(--text);
}
.be-cpop:not(.be-ccompose) .be-cpop-actions .be-btn svg { width: 21px; height: 21px; }
.be-cpop:not(.be-ccompose) .be-cpop-actions .be-btn:hover { background: var(--fill); }
.be-cpop:not(.be-ccompose) .be-cpop-actions .be-btn.danger:hover { background: rgba(239,68,68,.16); color: var(--danger); }
.be-ccompose .be-cauthor { height: 34px; margin-bottom: 8px; }
.be-ccompose .be-ctext { min-height: 70px; resize: vertical; }

/* Selection + handles */
#beOverlay { position: absolute; inset: 0; pointer-events: none; z-index: 21; }   /* above the align bar (z-index:20) so the rotate handle isn't hidden */
#beOverlay .be-handle { pointer-events: auto; }
#beOverlay .be-rotate { pointer-events: auto; }
#beOverlay .be-canchor { pointer-events: auto; }
/* Big INVISIBLE hitbox around a smaller visible triangle (::before) — easy to grab + room to swing the cursor for
   picking nearby candidates. Raised z-index so the hitbox sits ABOVE every block (the overlay is already above the
   world layer; this keeps it above sibling handles too). */
.be-canchor {
    position: absolute; width: 40px; height: 40px; transform: translate(-50%, -50%);
    background: transparent; cursor: crosshair; z-index: 40;
}
.be-canchor::before {
    content: ''; position: absolute; left: 50%; top: 50%; width: 15px; height: 15px; transform: translate(-50%, -50%);
    background: var(--gold); transition: filter .1s, transform .12s; z-index: 1;
}
/* Circular hitbox halo on hover (sits BEHIND the triangle) — shows the active grab area. */
.be-canchor::after {
    content: ''; position: absolute; left: 50%; top: 50%; width: 38px; height: 38px;
    transform: translate(-50%, -50%) scale(.45); border-radius: 50%; background: var(--gold);
    opacity: 0; pointer-events: none; transition: opacity .12s, transform .12s;
}
.be-canchor:hover::after { opacity: .3; transform: translate(-50%, -50%) scale(1); }
.be-canchor:hover::before { transform: translate(-50%, -50%) scale(1.15); }
.be-canchor.ca-top::before    { clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.be-canchor.ca-right::before  { clip-path: polygon(0 0, 100% 50%, 0 100%); }
.be-canchor.ca-bottom::before { clip-path: polygon(0 0, 100% 0, 50% 100%); }
.be-canchor.ca-left::before   { clip-path: polygon(100% 0, 0 50%, 100% 100%); }
.be-canchor:hover::before { filter: brightness(1.25); }
/* Image block's always-visible role INPUT points (prompt / character / style) */
#beAiAnchors { position: absolute; inset: 0; pointer-events: none; }
.be-ai-anchor {
    position: absolute; width: 28px; height: 28px; transform: translate(-50%, -50%);
    border-radius: 50%; border: 2px solid #fff; color: #fff; font-size: 14px; font-weight: 800;
    display: flex; align-items: center; justify-content: center; cursor: crosshair;
    pointer-events: auto; box-shadow: 0 2px 6px rgba(0,0,0,.45); transition: transform .1s, filter .1s;
}
.be-ai-anchor:hover { transform: translate(-50%, -50%) scale(1.2); filter: brightness(1.12); }
.be-ai-anchor.filled { box-shadow: 0 0 0 3px rgba(255,255,255,.35), 0 2px 6px rgba(0,0,0,.45); }
.be-ai-anchor svg { width: 72%; height: 72%; display: block; }
.be-el.selected { outline: 1px solid var(--gold-hover); outline-offset: 0; }
/* Lines/arrows are edited via endpoint handles — no bounding-box outline */
.be-el[data-type="line"].selected, .be-el[data-type="arrow"].selected { outline: none; }
.be-handle {
    position: absolute; width: 12px; height: 12px; background: var(--bg);
    border: 2px solid var(--gold-hover); border-radius: 3px; z-index: 5;
}
.be-handle::before { content: ''; position: absolute; inset: -8px; }   /* enlarge the grab target without growing the dot */
.be-handle.nw { left: -6px; top: -6px; cursor: nwse-resize; }
.be-handle.ne { right: -6px; top: -6px; cursor: nesw-resize; }
.be-handle.sw { left: -6px; bottom: -6px; cursor: nesw-resize; }
.be-handle.se { right: -6px; bottom: -6px; cursor: nwse-resize; }
.be-handle.n  { left: 50%; top: -6px; transform: translateX(-50%); cursor: ns-resize; }
.be-handle.s  { left: 50%; bottom: -6px; transform: translateX(-50%); cursor: ns-resize; }
.be-handle.w  { left: -6px; top: 50%; transform: translateY(-50%); cursor: ew-resize; }
.be-handle.e  { right: -6px; top: 50%; transform: translateY(-50%); cursor: ew-resize; }
/* Full-length edge resize strips (drag any side) */
#beOverlay .be-edge { pointer-events: auto; }
.be-edge { position: absolute; background: transparent; z-index: 4; }
.be-edge:hover { background: rgba(203, 167, 78, .15); }

/* ---- Image crop overlay ---- */
/* The block being cropped goes half-transparent so whatever sits BEHIND it stays visible — you can align the crop
   with the shape underneath. Reverted by exitCropMode (class scrub), never persisted. */
.be-el.be-cropping .be-el-inner { opacity: .5; }
.be-crop-layer { position: absolute; inset: 0; z-index: 30; pointer-events: auto; }
.be-crop-rect {
    position: absolute; box-sizing: border-box;
    border: 1.5px solid var(--gold-hover);
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, .55);
    cursor: crosshair; z-index: 31;
}
.be-crop-layer { cursor: crosshair; }
.be-crop-h {
    position: absolute; width: 12px; height: 12px; background: var(--bg);
    border: 2px solid var(--gold-hover); border-radius: 3px; z-index: 32;
}
.be-crop-h.nw { left: -7px; top: -7px; cursor: nwse-resize; }
.be-crop-h.ne { right: -7px; top: -7px; cursor: nesw-resize; }
.be-crop-h.sw { left: -7px; bottom: -7px; cursor: nesw-resize; }
.be-crop-h.se { right: -7px; bottom: -7px; cursor: nwse-resize; }
.be-crop-h.n  { left: 50%; top: -7px; transform: translateX(-50%); cursor: ns-resize; }
.be-crop-h.s  { left: 50%; bottom: -7px; transform: translateX(-50%); cursor: ns-resize; }
.be-crop-h.w  { left: -7px; top: 50%; transform: translateY(-50%); cursor: ew-resize; }
.be-crop-h.e  { right: -7px; top: 50%; transform: translateY(-50%); cursor: ew-resize; }
.be-crop-bar {
    position: absolute; transform: translateX(-50%); z-index: 33;
    display: flex; align-items: center; gap: 8px;
    padding: 6px 8px; background: var(--panel); border: 1px solid var(--border);
    border-radius: var(--radius-md); box-shadow: 0 6px 20px rgba(0, 0, 0, .4); white-space: nowrap;
}
.be-crop-hint { color: var(--muted); font-size: 12px; margin-right: 2px; }
.be-crop-bar .be-btn { height: 30px; padding: 0 12px; width: auto; font-size: 13px; }
.be-crop-apply { background: var(--gold); color: var(--on-gold); font-weight: 600; }
/* LOD «loading original» spinner — subtle corner badge on an image/PDF page while the full-res copy downloads.
   Counter-scaled by --be-invz so it stays a constant screen size at any zoom; dark chip reads on light PDF + dark photos. */
.be-lod-spin { position: absolute; top: 5px; right: 5px; z-index: 6; pointer-events: none; width: 20px; height: 20px; border-radius: 50%; background: rgba(20, 20, 26, .5); box-shadow: 0 1px 4px rgba(0, 0, 0, .3); display: flex; align-items: center; justify-content: center; transform: scale(var(--be-invz, 1)); transform-origin: top right; }
.be-lod-spin::after { content: ''; width: 11px; height: 11px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, .3); border-top-color: rgba(255, 255, 255, .95); animation: be-lod-spin .7s linear infinite; }
@keyframes be-lod-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .be-lod-spin::after { animation: none; } }

/* ---- Top bar ---- */
.be-topbar {
    position: absolute; top: 12px; left: 12px; right: 12px; min-height: 44px; z-index: 25;   /* above #beOverlay (z-21) so selection handles don't poke over the chrome */
    display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
    flex-wrap: wrap; pointer-events: none;
}
.be-topbar > * { pointer-events: auto; }
/* Mobile auto-hide: panels fade out after inactivity, reappear on touch */
.be-topbar, .be-toolbar, .be-props, .be-align-bar { transition: opacity .3s ease; }
.be-root.be-chrome-off .be-topbar,
.be-root.be-chrome-off .be-toolbar,
.be-root.be-chrome-off .be-props,
.be-root.be-chrome-off .be-align-bar { opacity: 0 !important; pointer-events: none !important; }
/* Десктоп-бездействие: тают только левая панель и левая часть шапки (назад + название) */
.be-toolbar, .be-topbar-left { transition: opacity .35s ease; }
.be-root.be-chrome-dim .be-toolbar, .be-root.be-chrome-dim .be-topbar-left { opacity: 0; pointer-events: none; }
/* По тому же бездействию тает и правый нижний угол: кнопки чата/ИИ/«Что нового» и строка состояния
   (просьба пользователя — один принцип на все плавающие панели).
   ⚠ ТОЛЬКО прозрачность и клики: строку «частный сервер» админ может выключить совсем — тогда её просто
   НЕТ в DOM (updateLoadInfo удаляет узел при showLoadInfo=false), и никакое правило её не воскресит. */
.be-chat-fab, .be-ai-fab, .be-wn-fab, .be-loadinfo { transition: opacity .35s ease; }
.be-root.be-chrome-dim .be-chat-fab,
.be-root.be-chrome-dim .be-ai-fab,
.be-root.be-chrome-dim .be-wn-fab,
.be-root.be-chrome-dim .be-loadinfo { opacity: 0; pointer-events: none; }
.be-topbar-left { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* Desktop: when the board content no longer fits the screen, the brand+name panel (.be-pub-titlepanel) collapses to
   declutter — the «Мои доски» button (.be-pub-back) stays. Both owner & guest pages share this structure now; the
   actual collapse rules live with .be-pub-titlepanel below (next to the guest-page rules). */
/* Right cluster wraps within the viewport instead of running off the right edge */
.be-topbar-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; row-gap: 8px; }
.be-panel {
    background: rgba(10,10,12,.92); border: 1px solid var(--border-ring);
    border-radius: var(--radius-md); box-shadow: var(--shadow-md);
    backdrop-filter: blur(10px); display: flex; align-items: center;
}
/* Top panel on boards: SOLID tone fill (same --popover-bg as the «Вид доски» popup) instead of a translucent frosted
   pill — no drop-shadow, no backdrop blur. Light-canvas keeps its own solid light override below. */
.be-topbar .be-panel { box-shadow: none; background: var(--popover-bg); backdrop-filter: none; }
.be-title-text {
    color: var(--text); font-weight: 700; font-size: 14px; padding: 0 18px 0 8px;
    line-height: 44px; max-width: 260px; white-space: nowrap; overflow: hidden;
    text-overflow: ellipsis; cursor: text; outline: none;
}
.be-title-text.editing { overflow: visible; text-overflow: clip; max-width: 60vw; }
.be-zoom { padding: 0 10px; height: 44px; display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 12px; }
/* ── Collapsible top-toolbar group: the action buttons (undo…share) share ONE pill — same подложка as the zoom pill —
   instead of each carrying its own tile. On DESKTOP it collapses to a single ⋯ trigger and expands on click; on MOBILE
   it stays fully expanded (only the shared подложка). The voice button lives OUTSIDE this group (kept separate). */
.be-topgroup { height: 44px; padding: 0 44px 0 2px; gap: 2px; position: relative; }   /* правое поле — место под приколотый «⋯» */
.be-topgroup .be-btn:not(.active):not(.primary) { background: transparent !important; border-color: transparent !important; box-shadow: none !important; }
.be-topgroup .be-btn:not(.active):not(.primary):hover { background: rgba(255,255,255,.08) !important; }
.be-root.be-canvas-light .be-topgroup .be-btn:not(.active):not(.primary):hover { background: rgba(0,0,0,.06) !important; }
/* Collapsible top-toolbar group works on ALL sizes (incl. mobile). The ⋯ trigger was already visible on phones
   (`.be-btn`'s later `display:inline-flex` overrode this rule's old `display:none`), but the fold CSS below used to be
   gated to `min-width:701px` → on mobile the ⋯ did nothing. Ungating it makes the dots actually collapse the pill. */
/* ⚠ Кнопка «⋯» рисуется ПОСЛЕДНЕЙ в группе (order), хотя в разметке стоит первой. Шапка прижата вправо
   (`.be-topbar-right { justify-content: flex-end }`), поэтому у растущей пилюли неподвижен ПРАВЫЙ край:
   с триггером в конце сами точки остаются на месте, а инструменты разворачиваются влево. Раньше он был
   слева и уезжал вместе с левым краем — приходилось искать кнопку глазами после каждого разворота. */
/* ⚠ Триггер ВЫНЕСЕН ИЗ ПОТОКА и приколот к правому краю пилюли. Раньше он был последним flex-элементом:
   пока ширина пилюли доезжала анимацией, кнопка оказывалась ЗА текущей шириной и обрезалась `overflow:hidden`
   — визуально пропадала и «возвращалась» в конце. Абсолютная привязка к правому краю (край при росте влево
   неподвижен) держит её на месте весь переход. Место под неё резервирует padding-right пилюли. */
.be-topgroup-tgl { display: inline-flex; height: 40px; width: 40px; min-width: 40px; padding: 0 !important;
    justify-content: center; align-items: center; border-radius: 9px; color: var(--text); cursor: pointer;
    flex: none; position: absolute; right: 2px; top: 50%; transform: translateY(-50%); z-index: 2; }
/* Поля НЕ обнуляем в свёрнутом виде: иначе правый край пилюли смещается на 2px, и «⋯» чуть-чуть прыгает
   на каждом переключении — ради этих 2px и затевалась привязка кнопки к месту. */
#beTopGroup.be-collapsed { padding: 0 44px 0 0; }   /* свёрнутая пилюля = ровно кнопка «⋯» (поля одинаковы в обоих состояниях) */
#beTopGroup.be-collapsed > :not(.be-topgroup-tgl) { display: none !important; }
#beTopGroup:not(.be-collapsed) .be-topgroup-tgl { color: var(--gold, #cba74e); }   /* lit while the group is open */
/* Разворот группы: кнопки проявляются фейдом, пока FLIP-анимация тянет ширину пилюли */
#beTopGroup { flex-wrap: nowrap; white-space: nowrap; }
/* Разделитель в шапке: действия | масштаб-вид */
.be-topgroup-sep { flex: none; width: 1px; height: 22px; margin: auto -4px auto 18px; background: var(--border); align-self: center; }
/* ⚠ Мерить надо до ИКОНОК, а не до коробок: справа стоит контейнер зум-панели со своим padding,
   поэтому при равных полях просвет справа был вдвое больше (21 vs 43px). Поля компенсируют это. */   /* auto-поля центрируют по вертикали независимо от align-items родителя */
#beTopGroup.be-collapsed .be-topgroup-sep { display: none; }
/* Процент масштаба — плашка справа от микрофона (тот же размер/вид, что у кнопок шапки) */
.be-zoomval-pill { height: 44px; min-width: 108px; display: inline-flex; align-items: center; justify-content: center;
    gap: 4px; padding: 0 6px; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; user-select: none; }
.be-zoomval-pill #beZoomVal { min-width: 40px; text-align: center; line-height: 1; }
/* − и + по бокам от процента, в одной плашке */
.be-zoomval-pill .be-zoomval-btn { width: 24px !important; min-width: 24px !important; height: 24px !important; padding: 0 !important;
    border-radius: 6px; display: inline-flex; align-items: center; justify-content: center; background: transparent !important; box-shadow: none !important; }
.be-zoomval-pill .be-zoomval-btn:hover { background: var(--panel-hover) !important; }
.be-zoomval-pill .be-zoomval-btn svg { width: 13px; height: 13px; }
/* Один размер кнопок (и их ховер-подсветки) по всей верхней группе: инлайновые 44px и зумные 36px разнобоили */
#beTopGroup .be-btn, #beTopGroup .be-topgroup-tgl { width: 40px !important; min-width: 40px !important; height: 40px !important; padding: 0 !important; border-radius: 9px; justify-content: center; }
#beTopGroup.be-topgroup-in > :not(.be-topgroup-tgl) { animation: tgFadeIn .30s ease both; }
/* ⚠ Пока ширина пилюли едет, содержимое прижимаем ВПРАВО — к неподвижному краю у «⋯». Иначе кнопки
   раскладываются от левого края узкой пилюли и на первых кадрах оказываются ПОД триггером и ПРАВЕЕ него
   (замер: 11 кнопок правее кнопки на первом кадре) — это и читалось как мельтешение. Теперь они
   «выезжают» из-под правого края влево, ровно как растёт сама пилюля. */
#beTopGroup.be-topgroup-in { justify-content: flex-end; }
@keyframes tgFadeIn { from { opacity: 0; } to { opacity: 1; } }
/* Zoom/view pill collapsible on MOBILE only: the ⋯ trigger folds away the secondary buttons (fit/center/view/settings),
   the zoom −/%/+ stays usable. Desktop shows the whole pill (trigger hidden). `.be-zoombar > .be-zoombar-tgl` (0-2-0)
   outranks the later `.be-btn { display:inline-flex }` (0-1-0) so the trigger isn't force-shown on desktop. */
.be-zoombar > .be-zoombar-tgl { display: none; }
/* Зум-пилюля внутри группы «•••» (десктоп): без собственной рамки-капсулы и без своего тумблера */
.be-topgroup .be-zoombar { border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 2px; height: 44px; }
.be-topgroup .be-zoombar > .be-zoombar-tgl { display: none !important; }
@media (max-width: 700px) {
    .be-zoombar > .be-zoombar-tgl { display: inline-flex; }
    .be-zoombar.be-collapsed > :not(.be-zoom):not(.be-zoombar-tgl) { display: none !important; }
    .be-zoombar:not(.be-collapsed) > .be-zoombar-tgl { color: var(--gold, #cba74e); }   /* lit while expanded */
}
.be-save-state { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; color: var(--muted-2); padding: 0 10px; height: 28px; border-radius: 8px; white-space: nowrap; pointer-events: none; opacity: 0; transform: translateY(-3px); transition: opacity .25s ease, transform .25s ease, background .2s, color .2s; }
.be-save-state.show { opacity: 1; transform: none; }
.be-save-state:empty { padding: 0; }
.be-save-state::before { content: ''; width: 7px; height: 7px; border-radius: 50%; flex: none; background: currentColor; opacity: .9; }
.be-save-state[data-state="saving"] { color: var(--muted); }
.be-save-state[data-state="saving"]::before { background: var(--gold, #cba74e); animation: be-save-pulse 1s ease-in-out infinite; }
.be-save-state[data-state="saved"] { color: #5fb87a; background: rgba(74,170,110,.10); }
.be-save-state[data-state="saved"]::before { background: #5fb87a; }
.be-save-state[data-state="error"] { color: #ef6a63; background: rgba(239,68,68,.12); }
.be-save-state[data-state="error"]::before { background: #ef6a63; }
/* Narrow desktop (701–1366): the «save» indicator becomes a CONSTANT-width colour dot (no text) so toggling it never
   grows/shrinks the topbar — which on those widths was tipping it into a wrap and making the panels jump. On normal/wide
   screens the full text shows as before (there's room, no wrap). Fully hidden on mobile (below). gap:0 keeps the dot
   centred (the hidden text node + flex gap was pushing it left). */
@media (min-width: 701px) and (max-width: 1366px) {
    .be-save-state, .be-save-state.show, .be-save-state:empty { font-size: 0; width: 24px; min-width: 24px; padding: 0; gap: 0; justify-content: center; }
}
/* When the board content no longer fits, the brand+name panel hides; hovering the «Мои доски» button reveals it as a
   FLOATING overlay to the RIGHT of the button (where it normally sits) — it lays on top of everything and never
   reflows/pushes the top toolbar. The panel is absolute (out of flow), so .be-topbar-left shrinks to the back button's
   width → left:100% lands exactly at the button's right edge. The «back» panel stays put. */
.be-pub-titlepanel { transition: opacity .18s ease; }
/* Owner board with no title → don't render an empty pill (the panel holds only #beTitle there; guest pages always have
   the brand, so this never hides them). Universal across all resolutions. */
.be-pub-titlepanel:has(> .be-title-text:only-child:empty) { display: none !important; }
@media (min-width: 701px) {
    body.be-fit-hide-title .be-topbar-left { position: relative; }
    body.be-fit-hide-title .be-pub-titlepanel {
        position: absolute; left: 100%; top: 0; z-index: 6; width: max-content; max-width: 60vw; margin-left: 8px;
        opacity: 0; transform: translateX(-4px); pointer-events: none;
        transition: opacity .18s ease, transform .18s ease;
    }
    body.be-fit-hide-title .be-topbar-left:hover .be-pub-titlepanel { opacity: 1; transform: none; pointer-events: auto; }
}
@keyframes be-save-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }

/* ---- Segmented choice buttons (portal panel style) ---- */
.be-segbtns { display: flex; gap: 6px; margin: 0 0 4px; }
.be-segbtn { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; padding: 9px 10px; font-size: 13px; font-weight: 600; color: var(--text, #e8e8ea); background: var(--panel-3, #26262c); border: 1px solid var(--border, #3a3a42); border-radius: 9px; cursor: pointer; transition: background .12s, border-color .12s, color .12s; }
.be-segbtn:hover { background: var(--panel-hover, #2e2e36); }
.be-segbtn.active { background: var(--gold, #cba74e); border-color: var(--gold, #cba74e); color: #1a1712; }
.be-segbtn-sub { font-size: 10px; font-weight: 500; opacity: .7; }
.be-segbtn.active .be-segbtn-sub { opacity: .8; }

/* ---- Board-tone match offer (guests/shared) ---- */
.be-tone-offer { position: fixed; left: 50%; top: 14px; transform: translateX(-50%); z-index: 240; display: flex; flex-wrap: wrap; align-items: stretch; gap: 10px; padding: 12px 14px; font-size: 13px; color: var(--text, #e8e8ea); background: var(--popover-bg, #1a1a1f); border: 1px solid var(--border-ring, #333); border-radius: 14px; box-shadow: var(--shadow-lg, 0 8px 30px rgba(0, 0, 0, .5)); backdrop-filter: blur(8px); width: min(320px, 92vw); }
.be-tone-offer span { flex: 1 0 100%; line-height: 1.35; }   /* подпись на своей строке, кнопки переносятся на ряд ниже */
.portal-notice-fixed ~ .be-tone-offer { top: 52px; }
.be-tone-offer button { flex: 1; border: none; border-radius: 9px; padding: 9px 12px; font-size: 13px; font-weight: 600; cursor: pointer; }
.be-tone-offer .be-tone-yes { background: var(--gold, #cba74e); color: #1a1712; }
.be-tone-offer .be-tone-no { background: var(--fill-soft); color: var(--text, #e8e8ea); }

/* ---- Photo album block ---- */
.be-album-el .be-album-head { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 8px; background: rgba(255, 255, 255, .06); border-bottom: 1px solid var(--border-ring, rgba(255, 255, 255, .12)); color: var(--text, #e8e8ea); font-size: 13px; box-sizing: border-box; }
.be-album-head-ic { width: 18px; height: 18px; flex: none; opacity: .85; }
.be-album-title { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.be-album-count { font-size: 11px; opacity: .7; background: rgba(255, 255, 255, .1); border-radius: 10px; padding: 1px 7px; }
.be-album-sp { flex: 1; }
.be-album-btn { width: 26px; height: 26px; border: none; background: rgba(255, 255, 255, .08); color: var(--text, #e8e8ea); border-radius: 7px; cursor: pointer; font-size: 16px; line-height: 1; display: flex; align-items: center; justify-content: center; flex: none; }
.be-album-btn:hover { background: rgba(255, 255, 255, .18); }
.be-album-grid { position: absolute; left: 0; right: 0; top: 34px; bottom: 0; overflow-y: auto; display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); grid-auto-rows: 92px; gap: 4px; padding: 6px; box-sizing: border-box; }
.be-album-cell { position: relative; overflow: hidden; border-radius: 8px; background: rgba(0, 0, 0, .25); }
.be-album-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.be-album-fcell { background: rgba(255, 255, 255, .05); }
.be-album-file { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; width: 100%; height: 100%; padding: 8px; box-sizing: border-box; color: var(--gold, #cba74e); text-decoration: none; }
.be-album-file svg { width: 30px; height: 30px; flex: none; }
.be-album-fname { font-size: 11px; line-height: 1.2; color: var(--text, #e8e8ea); text-align: center; max-width: 100%; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; word-break: break-word; }
.be-album-cell-ov { position: absolute; top: 3px; right: 3px; display: flex; gap: 3px; opacity: 0; transition: opacity .12s; }
.be-album-cell:hover .be-album-cell-ov { opacity: 1; }
.be-album-cell-btn { width: 22px; height: 22px; border: none; border-radius: 6px; background: rgba(0, 0, 0, .6); color: #fff; cursor: pointer; font-size: 12px; line-height: 1; display: flex; align-items: center; justify-content: center; }
.be-album-cell-btn:hover { background: rgba(0, 0, 0, .85); }
.be-album-empty { grid-column: 1 / -1; display: flex; align-items: center; justify-content: center; min-height: 120px; color: var(--muted, #9a9aa3); font-size: 13px; text-align: center; padding: 20px; }
.be-album-folder { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; cursor: pointer; color: var(--gold, #cba74e); }
.be-album-folder-ic { width: 46%; max-width: 120px; height: auto; }
.be-album-folder-badge { position: absolute; top: 16%; right: 24%; background: #ef4444; color: #fff; font-size: 12px; font-weight: 700; border-radius: 11px; padding: 1px 8px; }
.be-album-folder-title { color: var(--text, #e8e8ea); font-size: 13px; font-weight: 600; max-width: 90%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---- Toolbar (left, vertical) ---- */
.be-toolbar.be-toolbar-anim { transition: top .28s cubic-bezier(.2, .8, .2, 1), opacity .28s ease; }   /* glide + fade when clamped into view */
/* Multi-select layers panel: floating list of selected objects, drag a row to reorder (top = top layer). */
.be-layer-panel { position: fixed; right: 12px; top: 110px; width: 212px; max-height: 46vh; display: none; flex-direction: column; background: var(--popover-bg, #1b1b1f); color: var(--text, #edf3ff); border: 1px solid var(--border-ring, #34343d); border-radius: 10px; box-shadow: 0 14px 40px rgba(0,0,0,.45); z-index: 55; font-size: 12px; overflow: hidden; }
.be-layer-head { padding: 8px 10px; font-weight: 600; opacity: .85; border-bottom: 1px solid var(--border, rgba(255,255,255,.08)); flex: none; }
.be-layer-body { overflow-y: auto; padding: 4px; }
.be-layer-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 6px; cursor: grab; user-select: none; }
.be-layer-row:hover { background: var(--fill-soft, rgba(255,255,255,.07)); }
.be-layer-row.be-layer-drag { background: var(--fill-soft, rgba(255,255,255,.12)); cursor: grabbing; }
.be-layer-grip { color: var(--muted, #9a9aa2); flex: none; font-size: 14px; line-height: 1; }
.be-layer-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Rename (pencil) button in layer/component rows. */
.be-row-ren { flex: 0 0 auto; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: 6px; background: transparent; color: var(--muted, #9a9aa3); cursor: pointer; opacity: .6; }
.be-row-ren:hover { background: var(--fill-soft, rgba(255,255,255,.08)); color: var(--text, #eee); opacity: 1; }
.be-el.be-layer-hi { outline: 2px solid var(--gold, #cba74e); outline-offset: 1px; }
/* Block lock: corner badge (click to unlock) marks a locked block — no outline, the badge is enough. */
.be-lock-badge { position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; border-radius: 50%; background: var(--accent, #cba74e); color: #1a1712; display: flex; align-items: center; justify-content: center; cursor: pointer; z-index: 14; box-shadow: 0 2px 6px rgba(0, 0, 0, .35); }
.be-lock-badge svg { width: 13px; height: 13px; }
.be-lock-badge:hover { filter: brightness(1.12); }
#beLock.active { background: var(--accent, #cba74e); color: #1a1712; box-shadow: inset 0 0 0 1px var(--accent, #cba74e); }
.be-toolbar {
    position: absolute; left: 12px; top: 50%; transform: translateY(-50%); z-index: 25;   /* above #beOverlay (z-21) — handles must not cover the tools */
    display: flex; flex-direction: column; gap: 4px; padding: 6px;
    background: var(--popover-bg); border: 1px solid var(--border-ring);
    border-radius: var(--radius-md); box-shadow: var(--shadow-md); backdrop-filter: blur(8px);
    /* When there isn't enough vertical room, flow tools into a second column. */
    flex-wrap: wrap; align-content: flex-start;
    max-height: calc(100vh - 96px);
}
.be-tool {
    width: 40px; height: 40px; min-width: 40px; min-height: 40px; flex: 0 0 auto; border-radius: var(--radius-sm); border: none;
    background: transparent; color: var(--muted); display: flex; align-items: center; justify-content: center;
    transition: all var(--transition);
}
/* Never let the toolbar squeeze its buttons into micro-icons: keep size (min-* survives buggy flex engines too), wrap instead. */
.be-toolbar > .be-tool, .be-toolbar > .be-tool-wrap { flex: 0 0 auto; }
/* Inline SVGs in the toolbar have a viewBox but NO width/height attrs → some engines (old Android WebView / Firefox /
   Samsung Internet) collapse them to ~0 inside a flex button. Force a non-shrinkable explicit size. */
.be-tool svg, .be-tool-wrap svg { flex: 0 0 auto; min-width: 20px; min-height: 20px; }
.be-tool:hover { background: var(--fill-soft); color: var(--text); }
.be-tool.active { background: var(--gold-bg); color: var(--gold); }
.be-tool svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.be-tool-sep { display: none; }

/* ---- Mobile (phones): compact the board chrome so the many top-bar icons fit cleanly ---- */
/* ── Mobile board chrome (BOTH the logged-in board AND the public-link guest view) ──
   Unified idea: no brand / board-title header; every topbar control sits in ONE
   compact, horizontally-scrollable row; the whole chrome is scaled down. Each view
   keeps its OWN button set (the markup decides which buttons exist) — we only lay
   them out + size them here.
   Breakpoint 700px (not 640): switches the editor to the mobile bottom-scroll BEFORE the
   desktop panel gets cramped enough to wrap controls awkwardly. Touch-first tablets (iPad,
   pointer:coarse, ≤1366px) also use this mobile layout. Keep in sync with isMobileView() in board.js. */
/* + (max-height: 640px): on any SHORT viewport the left toolbar can't fit one column → switch to the mobile editor
   layout (bottom scroll-strip panel) instead of letting the toolbar wrap/overflow. */
@media (max-width: 700px), (pointer: coarse) and (max-width: 1366px), (max-height: 640px) {
    /* Topbar container: tight to the edges, never wrap to a second row */
    .be-topbar { top: 4px; left: 4px; right: 4px; gap: 4px; flex-wrap: nowrap; }
    /* Flat chrome on mobile — dark drop-shadows look bad over a light canvas */
    .be-panel, .be-toolbar, .be-props, .be-tool-flyout, .be-align-bar, .be-conn-pop { box-shadow: none !important; }
    /* Keep the toolbar/topbar ABOVE the selection overlay (#beOverlay z-21) so a dragged block's resize
       handles can't poke over the left toolbar / top panel (same fix the bottom props strip got). */
    .be-toolbar, .be-topbar { z-index: 31; }

    /* Both views share the structure: «Мои доски» button (.be-pub-back) + brand/title panel (.be-pub-titlepanel).
       On small screens: hide the brand/title panel and collapse «Мои доски» to just its arrow, at the width of the
       toolbar column below it (mobile toolbar = 36px button + 2×4px pad = 44px). */
    .be-pub-titlepanel { display: none !important; }
    .be-pub-back span { display: none; }
    .be-pub-back { height: 32px !important; width: 44px !important; padding: 0 !important; justify-content: center; gap: 0 !important; }
    .be-title-text { display: none; }
    /* (the title panel is hidden above; we DON'T hide the whole guest .be-topbar-left anymore, so a logged-in guest keeps
       the «Мои доски» back arrow — same as the owner page) */
    .be-mode-hint { display: none !important; }  /* mode hint («Режим редактирования по ссылке» etc.) — inline display:flex needs !important to override */
    .be-save-state { display: none; }            /* free up the row */

    /* Right cluster → one horizontal scrollable row, centred (falls back to start-aligned when it overflows) */
    .be-topbar-right {
        flex: 1 1 auto; min-width: 0;   /* fill the row so the buttons actually centre on screen */
        flex-wrap: nowrap; gap: 3px; row-gap: 0; justify-content: safe center;
        max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; touch-action: pan-x; scrollbar-width: none;
    }
    .be-topbar-right::-webkit-scrollbar { display: none; }
    .be-topbar-right > * { flex-shrink: 0; }   /* keep buttons full size — overflow scrolls instead of squeezing */

    /* Smaller scale for the whole top chrome */
    .be-topbar .be-btn { height: 32px !important; width: 32px !important; min-width: 32px !important; padding: 0 !important; }
    .be-topbar .be-btn svg { width: 15px; height: 15px; }
    .be-topbar .be-panel { height: 32px; }
    .be-zoom { height: 32px; padding: 0 4px; gap: 3px; font-size: 10px; }
    .be-zoom #beZoomVal { min-width: 28px; }
    .be-collab { padding-right: 2px; }
    .be-ava { width: 22px; height: 22px; font-size: 11px; margin-left: -6px; }
    /* Count / notification badges: small + corner-pinned so they don't smother the 15px icon on the 32px buttons. */
    .be-topbar .be-count-badge, .be-topbar .notif-badge { min-width: 13px; height: 13px; padding: 0 2px; font-size: 8px; top: 1px; right: 1px; }
    .be-topbar .be-new-badge { min-width: 13px; height: 13px; padding: 0 2px; font-size: 8px; top: 1px; left: 1px; box-shadow: none; animation: none; }

    /* Left toolbar (edit modes) + properties bar — scaled down to match */
    .be-toolbar { left: 4px; padding: 4px; gap: 3px; max-height: calc(100dvh - 72px); }   /* left:4px == topbar left → the «Мои доски» arrow (44px) sits in a clean column above the 44px toolbar */
    .be-tool { width: 36px; height: 36px; min-width: 36px; min-height: 36px; }
    .be-tool svg, .be-tool-wrap svg { width: 19px; height: 19px; min-width: 19px; min-height: 19px; }
    .be-tool-wrap { width: 36px; height: 36px; }
    .notif-menu, #beChatPanel.notif-menu, #beVoicePanel.notif-menu { width: min(420px, calc(100vw - 16px)); max-width: calc(100vw - 16px); }   /* phones: full width; tablets (iPad): capped */

    /* ── Block-editing panel = ONE horizontal scroll row on mobile ──
       Full-width strip docked at the bottom; ALL controls on a single line, swipe sideways.
       (Dropdown menus are lifted to position:fixed in JS so the overflow can't clip them.)
       Prefixed with `.be-root` to outrank the desktop `.be-props` rules that come later in the file. */
    .be-root .be-props {
        position: fixed; left: 0; right: 0; bottom: 0; top: auto; transform: none;
        z-index: 30;   /* above the selection overlay (#beOverlay z-21) so handles of a block dragged under the strip don't poke through */
        width: 100%; max-width: 100%; max-height: none;
        flex-direction: row !important; flex-wrap: nowrap !important; align-items: center; justify-content: safe center !important; gap: 8px;
        border-radius: 14px 14px 0 0; padding: 12px 14px calc(12px + env(safe-area-inset-bottom, 0px));
        overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; touch-action: pan-x;
        scrollbar-width: none; box-shadow: 0 -8px 24px rgba(0, 0, 0, .45);
    }
    .be-root .be-props::-webkit-scrollbar { display: none; }
    .be-root .be-props::after { content: ''; flex: 0 0 6px; }   /* trailing air so the last control isn't flush at scroll-end */
    /* Each row is a normal flex box that doesn't shrink (reliable scrollWidth — display:contents
       miscomputes it on some browsers). The rows + their controls all flow into the scroll strip.
       NO !important on display: JS toggles row visibility via inline display:none/'' and that must win. */
    .be-root .be-props-row { display: flex; flex: 0 0 auto; width: auto; align-items: center; flex-wrap: nowrap; gap: 6px; overflow: visible; }
    .be-root .be-props .be-swatches, .be-root .be-props .be-text-ctrls, .be-root .be-props .be-shape-ctrls, .be-root .be-props .be-media-ctrls { flex-wrap: nowrap !important; align-items: center; }
    .be-root .be-props-row > *, .be-root .be-props .be-text-ctrls > *, .be-root .be-props .be-swatches > *, .be-root .be-props .be-shape-ctrls > *, .be-root .be-props .be-media-ctrls > * { flex-shrink: 0; }
    .be-root .be-props .be-props-sep { display: none; }   /* dividers add noise in the flat strip */
    .be-props-grab { display: none !important; }   /* no expand/collapse in single-row mode */
    /* Connector/arrow edit popup → same single-row bottom scroll strip as the block panel (was a floating popup). */
    .be-root .be-conn-pop {
        position: fixed !important; left: 0 !important; right: 0 !important; bottom: 0 !important; top: auto !important;
        transform: none !important; width: 100% !important; max-width: 100% !important;
        z-index: 30; border-radius: 14px 14px 0 0; padding: 12px 14px calc(12px + env(safe-area-inset-bottom, 0px));
        display: flex; flex-direction: row; flex-wrap: nowrap; align-items: center; justify-content: safe center; gap: 10px;
        overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; touch-action: pan-x;
        scrollbar-width: none; box-shadow: 0 -8px 24px rgba(0,0,0,.45);
    }
    .be-root .be-conn-pop::-webkit-scrollbar { display: none; }
    .be-root .be-conn-pop::after { content: ''; flex: 0 0 6px; }   /* trailing air at scroll-end */
    .be-root .be-conn-pop > * { flex: 0 0 auto; margin-top: 0 !important; }
    .be-root .be-conn-pop .be-conn-row { flex-wrap: nowrap; }
    .be-root .be-conn-pop .be-conn-row > * { flex-shrink: 0; }
    .be-root .be-conn-pop .form-input { width: 170px !important; }   /* label input: fixed width instead of 100% in the strip */
    .be-root .be-conn-pop .be-conn-style-menu { z-index: 40; }       /* lifted (fixed) above the strip */
    .be-conn-style-menu .be-btn { width: 28px; height: 26px; }
    /* Alignment / group bar */
    .be-align-bar { padding: 4px; gap: 2px; }
    .be-align-bar .be-fmt-btn { width: 26px; height: 26px; }
    .be-align-bar .be-fmt-btn svg { width: 16px; height: 16px; }
}

/* Collapsible geometry group + its flyout */
.be-tool-wrap { position: relative; width: 40px; height: 40px; }
.be-tool-caret {
    position: absolute; right: 3px; bottom: 3px; width: 0; height: 0;
    border-left: 4px solid transparent; border-bottom: 4px solid currentColor;
    opacity: .55; pointer-events: none;
}
.be-tool-flyout {
    position: absolute; left: calc(100% + 8px); top: 0; z-index: 25;
    display: none; flex-direction: column; gap: 4px; padding: 6px;
    background: var(--popover-bg); border: 1px solid var(--border-ring);
    border-radius: var(--radius-md); box-shadow: var(--shadow-md); backdrop-filter: blur(8px);
}
.be-tool-flyout.open { display: flex; }

/* Free-draw tool settings popover */
.be-draw-settings {
    position: absolute; left: 64px; top: 50%; transform: translateY(-50%); z-index: 21;
    display: none; flex-direction: column; gap: 10px; padding: 12px 14px; width: 224px; box-sizing: border-box; max-width: calc(100vw - 80px);
    background: var(--popover-bg); border: 1px solid var(--border-ring);
    border-radius: var(--radius-md); box-shadow: var(--shadow-md); backdrop-filter: blur(8px); overflow: hidden;
}
.be-draw-settings.open { display: flex; }
.be-draw-title { font-size: 12px; font-weight: 600; color: var(--text); }
.be-draw-swatches { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; place-items: center; }   /* same style as the colour dropdown */
/* Gradient editor (shared: pencil panel + colorControl dropdown) */
.be-grad-ed { display: flex; flex-direction: column; gap: 8px; padding: 8px 0 2px; min-width: 0; width: 100%; box-sizing: border-box; }
.be-dd-menu.be-ddc.open .be-swatch { width: 30px; height: 30px; }   /* bigger colour dots */
.be-dd-menu.be-ddc.open .be-grad-ed { grid-column: 1 / -1; justify-self: stretch; min-width: 0; padding-left: 6px; padding-right: 6px; box-sizing: border-box; }
.be-dd-menu.be-ddc.open .be-grad-bar { margin: 0 10px; }   /* inset so the end stop-handles stay inside the panel */
/* Hex value + copy row at the bottom of the colour menu. */
.be-dd-menu.be-ddc.open .be-cc-hexrow { grid-column: 1 / -1; justify-self: stretch; display: flex; align-items: center; gap: 5px; padding: 4px 6px 2px; box-sizing: border-box; }
.be-cc-hexrow .be-cc-hex { flex: 1; min-width: 0; height: 28px; padding: 0 8px; border: 1px solid var(--border); border-radius: 6px; background: var(--panel-3, #26262c); color: var(--text); font: 12px ui-monospace, "SF Mono", monospace; outline: none; }
.be-cc-hexrow .be-cc-hex:focus { border-color: var(--blue); }
.be-cc-hexrow .be-cc-copy { flex: 0 0 auto; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--border); border-radius: 6px; background: var(--panel-3, #26262c); color: var(--muted); cursor: pointer; }
.be-cc-hexrow .be-cc-copy:hover { color: var(--text); }
.be-cc-hexrow .be-cc-copy.be-cc-copied { color: #22c55e; border-color: #22c55e; }
/* Text-colour opacity slider (opts.alpha) — sits at the bottom of the colour dropdown. */
.be-dd-menu.be-ddc.open .be-cc-alpharow { grid-column: 1 / -1; justify-self: stretch; display: flex; align-items: center; gap: 7px; padding: 2px 6px 4px; box-sizing: border-box; }
.be-cc-alpharow .be-cc-alphacap { flex: 0 0 auto; font-size: 11px; color: var(--muted); }
.be-cc-alpharow .be-cc-alpha { flex: 1; min-width: 0; accent-color: var(--blue); }
.be-cc-alpharow .be-cc-alphaval { flex: 0 0 auto; width: 34px; text-align: right; font: 11px ui-monospace, monospace; color: var(--text); }
/* Custom font picker rows — each previews its own typeface. */
/* ⚠ Название шрифта показывается САМИМ шрифтом, а ширина у гарнитур разная: длинное имя
   (Merriweather, Yanone Kaffeesatz) распирало ряд настолько, что панель ломалась на две строки.
   Жёсткий потолок + многоточие; полное название остаётся в подсказке кнопки. */
.be-dd-fonts .be-font-trigtxt { display: inline-block; min-width: 46px; max-width: 84px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
.be-dd-menu.be-dds.be-dd-fonts { max-height: 320px; overflow-y: auto; min-width: 180px; }
.be-font-item { display: block; width: 100%; text-align: left; padding: 7px 12px; border: 0; background: none; color: var(--text); font-size: 16px; line-height: 1.15; cursor: pointer; border-radius: 6px; white-space: nowrap; }
.be-font-item:hover { background: var(--fill-soft); }
/* ⚠ Было `background: var(--blue); color: #fff` — а в этой теме акцент БЕЛЫЙ (`--blue: #ffffff`),
   то есть выбранный шрифт рисовался белым по белому и пропадал (чаще всего — первая строка «Aa», шрифт по умолчанию).
   Пара `--gold`/`--on-gold` ЗНАЕТ про тон: на тёмном она белая с тёмным текстом, на светлом — тёмно-золотая с белым. */
.be-font-item.active { background: var(--gold); color: var(--on-gold); }
/* Регистр текста блока. ⚠ Делаем ВИДОМ, а не правкой содержимого: правка текста иначе сохраняла бы
   преобразованные буквы, и вернуть исходные было бы нечем. Канвас (скриншот/PDF/офлайн) повторяет то же
   преобразование в `applyTextCaseRuns` — иначе регистр молча пропадал бы в экспорте.
   «Как в предложениях» = строчные + прописная первая буква КАЖДОГО АБЗАЦА (ровно то, что умеет ::first-letter);
   предложения после точки внутри абзаца не поднимаются — и на ковре, и в экспорте одинаково. */
.be-el[data-case="upper"] .be-el-inner { text-transform: uppercase; }
.be-el[data-case="lower"] .be-el-inner { text-transform: lowercase; }
.be-el[data-case="sentence"] .be-el-inner { text-transform: lowercase; }
.be-el[data-case="sentence"] .be-el-inner p::first-letter,
.be-el[data-case="sentence"] .be-el-inner div::first-letter,
.be-el[data-case="sentence"] .be-el-inner li::first-letter,
.be-el[data-case="sentence"] .be-el-inner > .be-text::first-letter { text-transform: uppercase; }
.be-grad-bar { position: relative; height: 18px; width: auto; margin: 0 14px; border-radius: 6px; border: 1px solid var(--border-ring); cursor: copy; box-sizing: border-box; }
.be-grad-stops { position: absolute; inset: 0; }
.be-grad-stop { position: absolute; top: 50%; width: 14px; height: 14px; transform: translate(-50%, -50%); border-radius: 50%; border: 2px solid #fff; box-shadow: 0 0 0 1.5px rgba(0,0,0,.85), 0 1px 3px rgba(0,0,0,.5); cursor: grab; }
.be-grad-stop.sel { transform: translate(-50%, -50%) scale(1.18); }   /* same outline; selection shown by size only */
.be-grad-ctrls { display: flex; align-items: center; gap: 6px; min-width: 0; }
.be-grad-ctrls .be-draw-range { flex: 1; min-width: 70px; }
.be-grad-rotval { font-size: 12px; color: var(--muted); min-width: 30px; text-align: right; flex: none; }
/* hide selection points/handles while a colour panel is open (so the line colour is visible) */
.be-overlay-hidden { opacity: 0 !important; pointer-events: none !important; }
.be-draw-settings .be-swatch { width: 30px; height: 30px; border-radius: 50%; cursor: pointer; border: 1px solid rgba(128,128,128,.45); box-sizing: border-box; }
.be-draw-settings .be-swatch.active { border-color: var(--text); box-shadow: 0 0 0 2px var(--gold); }
/* gradient swatches get the same ring as solid colours (in both the pencil panel and the colour dropdown) */
.be-grad-swatch { border: 1px solid rgba(128,128,128,.45); box-sizing: border-box; }
.be-grad-swatch.active { border-color: var(--text); box-shadow: 0 0 0 2px var(--gold); }
.be-draw-settings .be-draw-pick { margin: 0; width: 30px; height: 30px; }
.be-draw-width { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); }
.be-draw-range {
    -webkit-appearance: none; appearance: none; flex: 1; min-width: 0; height: 4px;
    border-radius: 2px; background: var(--line); outline: none; cursor: pointer; margin: 0;
}
.be-draw-range::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none; width: 14px; height: 14px; border-radius: 50%;
    background: var(--gold); border: 2px solid var(--panel-2); cursor: pointer;
}
.be-draw-range::-moz-range-thumb {
    width: 14px; height: 14px; border-radius: 50%; background: var(--gold);
    border: 2px solid var(--panel-2); cursor: pointer;
}
.be-draw-wval { min-width: 16px; flex: 0 0 auto; text-align: right; color: var(--text); }

/* Video-host embed block: iframe is inert until the block is selected (so you can drag/select it) */
.be-el[data-type="embed"] .be-el-inner { overflow: hidden; border-radius: var(--radius-xs); background: #000; }
/* iframe inert by default → block is draggable; double-click to interact (play/seek). */
.be-el[data-type="embed"] .be-el-inner iframe { pointer-events: none; }
.be-el[data-type="embed"].be-embed-live .be-el-inner iframe { pointer-events: auto; }
.be-el[data-type="embed"].be-embed-live .be-el-inner { outline: 2px solid var(--gold); outline-offset: -2px; }
/* Follow / watch-together mode: every social-video iframe is directly controllable (no double-click drill-in). */
body.be-follow-active .be-el[data-type="embed"] .be-el-inner iframe { pointer-events: auto; }
/* Public landing page: embedded players (YouTube/Vimeo/…) are interactive right away — single-click play, no drill-in. */
body.be-landing-view .be-el[data-type="embed"] .be-el-inner iframe { pointer-events: auto; }
/* Лендинг: видео играбельно сразу (выделения блоков там нет → контролы иначе не показать), а попап комментария виден поверх страницы. */
body.be-landing-view .be-el[data-type="video"] video { pointer-events: auto !important; }
body.be-landing-view .be-el[data-type="video"] video::-webkit-media-controls,
body.be-landing-view .be-el[data-type="video"] video::-webkit-media-controls-enclosure,
body.be-landing-view .be-el[data-type="video"] video::-webkit-media-controls-panel { display: flex !important; opacity: 1 !important; }
/* Плашка «ВИДЕО» скрывается у ВЫДЕЛЕННОГО блока, но на лендинге выделения нет → она висела поверх
   плеера и перехватывала первый клик. На публичной странице она не нужна вовсе. */
body.be-landing-view .be-vid-tag { display: none !important; }
/* Кнопки скрина/обложки и прочий редакторский хром на лендинге тоже не нужны. */
body.be-landing-view .be-vid-bar { display: none !important; }
body.be-landing-view .be-el[data-type="video"] video::-webkit-media-controls-enclosure { display: flex !important; }
/* Комментарии на лендинге ВИДНЫ: гость, оставивший булавку правым кликом, должен видеть и её, и чужие
   (раньше слой был скрыт целиком, и комментарий будто пропадал). Прозрачность слоя и кликабельность
   берутся из базовых правил #beComments; здесь — только подъём попапа над содержимым страницы. */
body.be-landing-view #beComments > .be-cpop { z-index: 100002; }
/* На лендинге комментарий не сворачивается в булавку — это записка с текстом, которую любой посетитель
   может перетащить куда угодно. touch-action:none, иначе тач-драг перехватит прокрутка страницы. */
.be-lnote { position: absolute; transform: translate(-50%, -100%); max-width: 250px; min-width: 186px;   /* имя + дата в одну строку */
    padding: 8px 10px; background: var(--popover-bg); border: 1px solid var(--border-ring);
    border-radius: var(--radius-md); box-shadow: var(--shadow-lg); backdrop-filter: blur(8px);
    cursor: grab; touch-action: none; user-select: none; z-index: 13; }
.be-lnote.dragging { cursor: grabbing; box-shadow: var(--shadow-lg), 0 0 0 2px var(--gold); }
.be-lnote::after { content: ''; position: absolute; left: 50%; bottom: -7px; width: 12px; height: 12px;
    transform: translateX(-50%) rotate(45deg); background: var(--popover-bg);
    border-right: 1px solid var(--border-ring); border-bottom: 1px solid var(--border-ring); }
.be-lnote-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 3px; }
.be-lnote-who { font-size: 11px; font-weight: 700; color: var(--gold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.be-lnote-date { font-size: 10px; color: var(--muted-2); white-space: nowrap; font-variant-numeric: tabular-nums; }
.be-lnote-text { font-size: 12.5px; line-height: 1.4; color: var(--text); white-space: pre-wrap; word-break: break-word;
    max-height: 132px; overflow: hidden; }
.be-lnote.resolved { opacity: .72; }
.be-lnote.resolved .be-lnote-who { color: var(--green); }
.be-lnote.be-lnote-new { box-shadow: var(--shadow-lg), 0 0 0 2px color-mix(in srgb, var(--danger) 85%, transparent); }

/* Generic iframe block (any web page): inert by default (drag/select the block), interactive after a double-click. */
.be-el[data-type="iframe"] .be-el-inner { overflow: hidden; border-radius: var(--radius-xs); background: #fff; }
.be-el[data-type="iframe"] .be-el-inner iframe { pointer-events: none; }
.be-el[data-type="iframe"].be-embed-live .be-el-inner iframe { pointer-events: auto; }
.be-el[data-type="iframe"].be-embed-live .be-el-inner { outline: 2px solid var(--gold); outline-offset: -2px; }
body.be-follow-active .be-el[data-type="iframe"] .be-el-inner iframe { pointer-events: auto; }
body.be-landing-view .be-el[data-type="iframe"] .be-el-inner iframe { pointer-events: auto; }
.be-iframe-reload { position: absolute; top: 6px; right: 6px; z-index: 6; width: 26px; height: 26px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border: none; border-radius: 7px; background: rgba(0,0,0,.5); color: #fff; cursor: pointer; opacity: 0; transition: opacity .12s; }
.be-el[data-type="iframe"]:hover > .be-iframe-reload, .be-el[data-type="iframe"].selected > .be-iframe-reload, .be-el[data-type="iframe"].be-embed-live > .be-iframe-reload { opacity: .92; }
.be-iframe-reload:hover { opacity: 1 !important; background: rgba(0,0,0,.8); }
/* Component badge — ◆ master / ◇ copy — top-left of the root element. */
/* Component badge — ◆ master (gold) / ◇ copy (purple). Shown ONLY while selected, and set OUT to the left of the
   top edge so the corner rotation handle (which sits just outside the top-left corner) doesn't cover it. */
/* Admin Sega controls image — sits just below the game block, follows it (in-world), matches its width. */
.be-sega-keys-img { position: absolute; top: 100%; left: 0; width: 100%; height: auto; margin-top: 8px; display: block; border-radius: 6px; pointer-events: none; user-select: none; -webkit-user-drag: none; }
.be-comp-badge { display: none; position: absolute; width: 18px; height: 18px; align-items: center; justify-content: center; font-size: 12px; line-height: 1; border-radius: 5px; background: #6d4bd8; color: #fff; box-shadow: 0 1px 4px rgba(0,0,0,.45); cursor: pointer; user-select: none; }
/* Overlay copy (screen space) — floats above all blocks, constant size, like the resize handles. */
.be-comp-badge-ov { z-index: 13; transform-origin: center; }
.be-comp-badge.is-main { background: var(--gold, #cba74e); color: #1a1a1e; }
.be-el.selected > .be-comp-badge { display: flex; }
/* Dashed frame only while selected (less clutter). */
.be-el.selected[data-comp="inst"] > .be-el-inner { outline: 1px dashed rgba(109,75,216,.7); outline-offset: 6px; }
.be-el.selected[data-comp="main"] > .be-el-inner { outline: 1px dashed rgba(203,167,78,.75); outline-offset: 6px; }
/* Whole component selected → drop the per-element gold outlines; only the group box + dashed component frame remain. */
.be-root.be-comp-sel .be-el.selected { outline: none; }
.be-layer-row.be-layer-sel { background: rgba(109,75,216,.22); }
/* Components panel (toolbar button → list of masters, drag a row onto the board). */
.be-comp-panel { position: fixed; right: 234px; top: 110px; z-index: 56; width: 200px; max-height: 46vh; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; padding: 8px; background: var(--popover-bg, #1b1b1f); border: 1px solid var(--border-ring, #34343d); border-radius: 10px; box-shadow: 0 14px 40px rgba(0,0,0,.45); }
.be-comp-phead { font-size: 12px; font-weight: 700; color: var(--muted, #9a9aa3); padding: 2px 4px 6px; }
.be-comp-empty { font-size: 12px; color: var(--muted, #9a9aa3); padding: 6px 4px; }
.be-comp-row { display: flex; align-items: center; gap: 6px; padding: 7px 8px; border-radius: 7px; cursor: grab; user-select: none; }
.be-comp-row:hover { background: var(--fill-soft, rgba(255,255,255,.06)); }
.be-comp-row.be-comp-drop { box-shadow: inset 0 2px 0 var(--gold); }        /* drag-reorder: drop ABOVE this row */
.be-comp-row.be-comp-drop-end { box-shadow: inset 0 -2px 0 var(--gold); }   /* drag-reorder: drop at the very end */
.be-comp-rowname { flex: 1; min-width: 0; font-size: 13px; color: var(--text, #eee); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.be-comp-del { flex: 0 0 auto; width: 22px; height: 22px; border: 0; border-radius: 6px; background: transparent; color: var(--muted, #9a9aa3); font-size: 13px; cursor: pointer; }
.be-comp-del:hover { background: rgba(220,60,60,.18); color: #ff6b6b; }
.be-comp-ghost { position: fixed; z-index: 99999; pointer-events: none; padding: 5px 11px; border-radius: 8px; background: rgba(10,10,12,.92); color: #fff; border: 1px solid var(--gold, #cba74e); font-size: 12px; box-shadow: 0 6px 20px rgba(0,0,0,.4); }
/* Mobile: no room beside the layers panel — dock the components panel top-left, clamped to the viewport. */
@media (max-width: 700px), (pointer: coarse) and (max-width: 1024px), (max-height: 640px) {
    .be-comp-panel { right: auto; left: 8px; top: 60px; width: min(220px, calc(100vw - 16px)); max-height: 50vh; }
}
.be-embed-shot { position: absolute; top: 6px; right: 6px; z-index: 5; width: 28px; height: 28px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border: none; border-radius: 7px; background: rgba(0,0,0,.62); color: #fff; cursor: pointer; opacity: .85; }
.be-embed-shot:hover { opacity: 1; background: rgba(0,0,0,.8); }
/* Follower's one-tap «▶ Смотреть вместе» gate — the real gesture browsers need to start synced playback with sound. */
.be-embed-unmute { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 6; padding: 13px 24px; border: none; border-radius: 999px; background: var(--gold, #cba74e); color: #1a1a1a; font-size: 14px; font-weight: 800; cursor: pointer; box-shadow: 0 8px 26px rgba(0,0,0,.55); white-space: nowrap; }
.be-embed-unmute:hover { filter: brightness(1.07); }
/* Offline-export progress overlay */
.be-export-ov { position: fixed; inset: 0; z-index: 320; background: rgba(0,0,0,.55); display: flex; align-items: center; justify-content: center; backdrop-filter: blur(2px); }
.be-export-card { width: 92vw; max-width: 420px; background: var(--popover-bg, #1a1a1f); border: 1px solid var(--border-ring, #333); border-radius: var(--radius-lg); padding: 22px; box-shadow: var(--shadow-lg); text-align: center; }
.be-export-title { font-size: 14px; color: var(--text); margin-bottom: 14px; }
.be-export-track { height: 8px; border-radius: 5px; background: var(--line, #333); overflow: hidden; }
.be-export-fill { height: 100%; width: 0; background: var(--gold); border-radius: 5px; transition: width .2s ease; }
.be-export-fill.indet { width: 40% !important; animation: beExpIndet 1.1s ease-in-out infinite; }
@keyframes beExpIndet { 0% { margin-left: -40%; } 100% { margin-left: 100%; } }
.be-export-pct { margin-top: 10px; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.be-export-cancel { margin-top: 14px; padding: 7px 18px; font-size: 13px; border-radius: 9px; border: 1px solid var(--border-ring, #333); background: transparent; color: var(--muted); cursor: pointer; transition: all .15s; }
.be-export-cancel:hover { color: var(--text); border-color: var(--muted); background: var(--fill-soft, rgba(255,255,255,.06)); }

/* Save / transfer menu (offline copy · export · import · templates) */
.be-io-pop { position: fixed; z-index: 330; width: 320px; max-width: calc(100vw - 16px); background: var(--popover-bg, #1a1a1f); border: 1px solid var(--border-ring, #333); border-radius: 12px; padding: 6px; box-shadow: var(--shadow-lg); }
.be-io-item { display: flex; align-items: flex-start; gap: 10px; width: 100%; text-align: left; padding: 9px 10px; border: 0; background: transparent; border-radius: 9px; cursor: pointer; color: var(--text); }
.be-io-item:hover { background: var(--fill-soft, rgba(255,255,255,.07)); }
.be-io-ico { flex: 0 0 22px; display: flex; align-items: center; justify-content: center; color: var(--text); margin-top: 1px; }
.be-io-ico svg { width: 18px; height: 18px; fill: currentColor; }
.be-io-tx { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.be-io-tx b { font-size: 13px; font-weight: 600; }
.be-io-tx i { font-size: 11px; color: var(--muted); font-style: normal; line-height: 1.35; }
.be-io-sep { height: 1px; background: var(--line, #333); margin: 5px 8px; }
.be-io-modal { position: fixed; inset: 0; z-index: 330; background: rgba(0,0,0,.55); display: flex; align-items: center; justify-content: center; backdrop-filter: blur(2px); }
.be-io-mcard { width: 92vw; max-width: 520px; max-height: 80vh; display: flex; flex-direction: column; background: var(--popover-bg, #1a1a1f); border: 1px solid var(--border-ring, #333); border-radius: var(--radius-lg, 14px); box-shadow: var(--shadow-lg); overflow: hidden; }
.be-io-mhead { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--line, #333); color: var(--text); }
.be-io-mhead b { font-size: 15px; }
.be-io-x { border: 0; background: transparent; color: var(--muted); font-size: 16px; cursor: pointer; padding: 4px 8px; border-radius: 8px; }
.be-io-x:hover { color: var(--text); background: var(--fill-soft, rgba(255,255,255,.07)); }
.be-io-mbody { padding: 8px; overflow-y: auto; }
.be-io-trow { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 12px; border-radius: 10px; }
.be-io-trow:hover { background: var(--fill-soft, rgba(255,255,255,.05)); }
.be-io-tinfo { min-width: 0; }
.be-io-tinfo b { display: block; font-size: 13px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.be-io-tinfo i { font-size: 11px; color: var(--muted); font-style: normal; }
.be-io-tact { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.be-io-create { padding: 6px 12px; font-size: 12px; border-radius: 8px; border: 1px solid var(--gold); background: transparent; color: var(--gold); cursor: pointer; }
.be-io-create:hover { background: var(--gold); color: #000; }
.be-io-create:disabled { opacity: .6; cursor: default; }
/* Portal-style trash button: monochrome (ч/б), rounded square. */
.be-io-del { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; padding: 0; border: 1px solid var(--border, rgba(255,255,255,.18)); background: transparent; color: var(--muted, #9a9aa3); cursor: pointer; border-radius: 8px; }
.be-io-del svg { width: 15px; height: 15px; display: block; }
.be-io-del:hover { background: var(--fill-soft, rgba(255,255,255,.08)); color: var(--text, #edf3ff); border-color: var(--text, #edf3ff); }
.be-io-empty { padding: 28px 16px; text-align: center; color: var(--muted); font-size: 13px; }
/* Personal element-templates panel — compact 3-column grid of square thumbnails */
.be-tpl-mcard { max-width: 480px; }
.be-tpl-body { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; padding: 12px; max-height: 72vh; overflow-y: auto; }   /* minmax(0,…) → a long unbreakable name can't blow the column wider than 1/3 */
.be-tpl-body:focus, .be-tpl-body:focus-visible { outline: none; }   /* Chrome makes overflow:auto keyboard-focusable → kills the stray rectangular focus ring on click */
.be-tpl-body .be-io-empty { grid-column: 1 / -1; }   /* empty-state text spans the full width instead of a 1/3 cell */
.be-tpl-item { position: relative; min-width: 0; display: flex; flex-direction: column; border: 1px solid var(--line, #333); border-radius: 10px; overflow: hidden; background: var(--fill-soft, rgba(255,255,255,.03)); }
.be-tpl-thumb { aspect-ratio: 1 / 1; width: 100%; display: flex; align-items: center; justify-content: center; background: var(--panel-2, #101014); overflow: hidden; }
.be-tpl-thumb[title] { cursor: pointer; }
.be-tpl-thumb img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.be-tpl-item:hover { border-color: var(--gold); }
.be-tpl-noimg { color: var(--muted); font-size: 10px; }
.be-tpl-meta { padding: 4px 6px; min-width: 0; }
.be-tpl-name { display: block; max-width: 100%; font-size: 11px; font-weight: 600; color: var(--text); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }   /* display:block → text-overflow:ellipsis actually clips (an inline <b> wouldn't) */
.be-tpl-acts { position: absolute; top: 4px; right: 4px; display: flex; gap: 3px; opacity: 0; transition: opacity .12s; }
.be-tpl-item:hover .be-tpl-acts { opacity: 1; }
.be-tpl-acts button { width: 22px; height: 22px; padding: 0; border: 0; border-radius: 6px; background: rgba(12,12,15,.66); color: #eee; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.be-tpl-acts button:hover { background: rgba(12,12,15,.9); }
.be-tpl-del:hover { color: #e5645a; }
.be-seltypes-tpl { border-style: dashed; }   /* «＋ В шаблоны» chip in the selection panel */
/* Board files/media manager */
.be-files-group { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); padding: 12px 12px 5px; border-bottom: 1px solid var(--border); margin-bottom: 4px; cursor: pointer; user-select: none; }
.be-files-group:hover { color: var(--text); }
.be-files-group:first-child { padding-top: 4px; }
.be-files-garr { width: 13px; height: 13px; flex: none; transition: transform .15s; }
.be-files-gzip { margin-left: auto; display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border: none; border-radius: 7px; background: transparent; color: var(--muted); cursor: pointer; }
.be-files-gzip:hover { background: var(--fill-soft); color: var(--text); }
.be-files-gzip svg { width: 15px; height: 15px; }
.be-files-group.closed .be-files-garr { transform: rotate(-90deg); }
.be-files-grows.closed { display: none; }
.be-files-row { display: flex; align-items: center; gap: 12px; padding: 8px 12px; border-radius: 10px; }
.be-files-row:hover { background: var(--fill-soft, rgba(255,255,255,.05)); }
.be-files-thumb { flex: 0 0 48px; width: 48px; height: 48px; border-radius: 8px; overflow: hidden; background: var(--panel-3, #26262c); display: flex; align-items: center; justify-content: center; color: var(--muted); cursor: pointer; }
.be-files-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.be-files-thumb svg { width: 22px; height: 22px; }
.be-files-info { flex: 1; min-width: 0; }
.be-files-info b { display: block; font-size: 13px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.be-files-info i { font-size: 11px; color: var(--muted); font-style: normal; }
.be-files-act { flex: 0 0 auto; display: flex; gap: 6px; }
.be-files-act button { width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--border); border-radius: 8px; background: transparent; color: var(--text); cursor: pointer; }
.be-files-act button:hover { border-color: var(--gold); }
.be-files-act .be-files-del:hover { border-color: var(--danger, #e05656); color: var(--danger, #e05656); }
.be-files-act svg { width: 16px; height: 16px; }

.be-embed-modal { position: fixed; inset: 0; z-index: 300; background: rgba(0,0,0,.55); display: flex; align-items: center; justify-content: center; backdrop-filter: blur(2px); }
.be-embed-box { width: 92vw; max-width: 560px; background: var(--popover-bg, #1a1a1f); border: 1px solid var(--border-ring, #333); border-radius: var(--radius-lg); padding: 18px 18px 16px; box-shadow: var(--shadow-lg); }
.be-embed-title { font-size: 15px; font-weight: 600; color: var(--text); margin-bottom: 12px; }
.be-embed-input { width: 100%; min-height: 40px; padding: 9px 12px; font: inherit; font-size: 14px; line-height: 1.4; resize: vertical; background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-md); color: var(--text); }
.be-embed-hint { font-size: 12px; color: var(--muted); margin-top: 10px; }
.be-embed-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; margin-top: 12px; flex-wrap: nowrap; }
.be-embed-actions .btn { white-space: nowrap; }

/* White rounded icon for audio/video items in the comments list */
.be-citem-media .be-citem-head { display: flex; align-items: center; gap: 8px; }
.be-citem-ic { width: 26px; height: 26px; border-radius: 8px; background: #34343c; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.be-citem-ic svg { width: 15px; height: 15px; fill: none; stroke: #c5c5cf; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Audio/video transcript (Whisper) — transcribe button + collapsible block */
/* Stack below a block: caption + one collapsible bar (transcript + replies + project comments) */
/* Fixed-size comment bar, centred under the block — same size regardless of block size or zoom */
.be-belowstack { position: absolute; top: 100%; left: 50%; transform: translateX(-50%) scale(var(--be-invz, 1)); transform-origin: top center; width: 280px; margin-top: 8px; display: flex; flex-direction: column; gap: 6px; z-index: 4; }
/* When the block is selected the bottom rotate handle sits ~26px below it → drop the comment stack below the dot. */
.be-el.selected .be-belowstack { margin-top: 46px; }
.be-tr-wrap { display: flex; flex-direction: column; gap: 4px; order: 1; }
.be-onboard-replies { display: flex; flex-direction: column; gap: 6px; order: 2; }
.be-onboard-pcomments { order: 3; }
.be-onboard-replies .be-replies { max-height: 240px; overflow: auto; }
.be-creply.resolved { opacity: .5; }
.be-sec-title { font-size: 11px; font-weight: 700; color: var(--muted-2); text-transform: uppercase; letter-spacing: .03em; }
/* Narrow collapsible bar */
.be-bar { order: 2; border: 1px solid var(--border); border-radius: 8px; background: var(--panel-2); overflow: hidden; display: none; }
/* The per-block comment bar (inside .be-belowstack) appears ONLY when the block is selected or its bar is open
   (not on hover). A multi/group selection hides them all via .be-root.be-multi below. Unseen comments still glow. */
.be-el.selected .be-bar, .be-el.be-bar-open .be-bar { display: block; }
/* Unseen comment under a block → keep the bar visible (with a red dot) until the user opens it */
.be-el[data-unseen="1"] .be-bar { display: block; border-color: var(--gold); }
.be-el[data-unseen="1"] .be-bar-ic { position: relative; }
.be-el[data-unseen="1"] .be-bar-ic::after { content: ''; position: absolute; top: -3px; right: -3px; width: 8px; height: 8px; border-radius: 50%; background: var(--danger); border: 1.5px solid var(--panel-2); }
.be-bar-head { display: flex; align-items: center; gap: 8px; padding: 5px 9px; cursor: pointer; font-size: 12px; color: var(--muted); user-select: none; }
.be-bar-head:hover { color: var(--text); }
.be-bar-ic { width: 18px; height: 18px; border-radius: 6px; background: #34343c; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; }
.be-bar-ic svg { width: 11px; height: 11px; fill: none; stroke: #c5c5cf; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.be-bar-title { flex: 1 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.be-bar-badges { display: flex; align-items: center; gap: 5px; flex: 0 0 auto; }
.be-bar-badge { min-width: 18px; height: 17px; padding: 0 5px; display: inline-flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 700; border-radius: 999px; color: #fff; }
.be-bar-badge.b-r { background: var(--gold); color: var(--on-gold); }
.be-bar-badge.b-p { background: #4a6da7; }
.be-bar-chev { flex: 0 0 auto; display: inline-flex; color: var(--muted-2); transition: transform .15s; }
.be-bar-chev svg { width: 14px; height: 14px; }
.be-bar.open .be-bar-chev { transform: rotate(180deg); }
.be-bar-body { flex-direction: column; gap: 10px; padding: 8px 9px; border-top: 1px solid var(--border); }
.be-tr-btn { display: inline-flex; align-items: center; gap: 6px; align-self: flex-start; background: var(--gold-bg); color: var(--gold); border: 1px solid var(--border); border-radius: 8px; padding: 4px 10px; font-size: 12px; cursor: pointer; }
.be-tr-btn:hover { background: var(--fill-soft); }
.be-tr-loading { opacity: .7; pointer-events: none; align-self: stretch; max-width: 100%; box-sizing: border-box; }
.be-tr-loading .be-pill-tx { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.be-proc-log { font-size: 11px; color: var(--muted); line-height: 1.55; padding: 3px 2px 0; }
.be-proc-line { display: flex; gap: 5px; align-items: baseline; }
/* Admin → background workers panel */
.wk-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 8px; margin-bottom: 6px; font-size: 13px; }
.wk-txt { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
.wk-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--muted-2); flex: none; }
.wk-dot.on { background: #22c55e; box-shadow: 0 0 7px rgba(34,197,94,.7); }
/* Low-disk-space warning badge (portal + board top bar) */
.stor-badge { display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 10px; border-radius: 8px; font-size: 12px; font-weight: 600; text-decoration: none; white-space: nowrap; background: rgba(245,158,11,.16); color: #f59e0b; border: 1px solid rgba(245,158,11,.45); }
.stor-badge.critical { background: rgba(239,68,68,.16); color: #ef4444; border-color: rgba(239,68,68,.5); animation: beRecPulse 1.6s infinite; }
.stor-badge svg { flex: none; }
.stor-badge:hover { filter: brightness(1.12); }
@media (max-width: 700px) { .stor-badge span { display: none; } .stor-badge { padding: 0 8px; } }
/* "Recording in progress" indicator shown to EVERYONE on the board */
.be-rec-ind { position: fixed; bottom: 14px; left: 14px; top: auto; transform: none; z-index: 60; display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px; border-radius: 999px; background: rgba(239,68,68,.92); color: #fff; font-size: 12px; font-weight: 800; letter-spacing: .06em; box-shadow: 0 6px 20px rgba(239,68,68,.4); pointer-events: none; }
.be-rec-ind-dot { width: 10px; height: 10px; border-radius: 50%; background: #fff; box-shadow: 0 0 0 0 rgba(255,255,255,.6); animation: beRecPulse 1.3s infinite; }
.be-rec-ind-time { font-variant-numeric: tabular-nums; font-weight: 700; letter-spacing: .02em; }
.be-pub-back { transition: color .12s; }
.be-pub-back:hover { color: var(--gold) !important; }
.be-transcript { background: var(--panel-2); border: 1px solid var(--border); border-radius: 8px; padding: 7px 9px; font-size: 12px; color: var(--text); line-height: 1.4; }
.be-transcript-text { white-space: pre-wrap; word-break: break-word; }
.be-transcript-text.clamped { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.be-sum-btn { margin-left: 6px; }
.be-tr-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.be-tr-actions .be-sum-btn { margin-left: 0; }
.be-tr-actions .be-tr-btn { font-size: 11.5px; padding: 4px 9px; align-self: auto; }
.be-tr-row { display: flex; gap: 6px; align-items: stretch; }
.be-tr-row .be-tr-btn { flex: 1 1 0; min-width: 0; justify-content: center; align-self: stretch; margin: 0; }
.be-tr-row .be-tr-btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.be-sum-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.be-sum-chip { background: var(--panel-3); border: 1px solid var(--line); color: var(--text); border-radius: 999px; padding: 5px 11px; font-size: 12px; cursor: pointer; }
.be-sum-chip:hover { border-color: var(--gold); }

/* Live collaboration: avatar stack + remote cursors */
.be-collab { display: flex; align-items: center; padding-right: 4px; }
.be-collab:empty { display: none; }
.be-ava {
    width: 30px; height: 30px; border-radius: 50%; border: 2px solid var(--gold);
    background: var(--panel-2); display: flex; align-items: center; justify-content: center;
    font-size: 15px; margin-left: -8px; box-shadow: 0 1px 5px rgba(0,0,0,.45);
}
.be-ava:first-child { margin-left: 0; }
.be-ava-self:hover { filter: brightness(1.12); }
/* animal picker (click your own avatar to change it) */
.be-ava-picker { position: fixed; z-index: 100000; display: grid; grid-template-columns: repeat(6, 1fr); gap: 2px; padding: 8px; background: var(--popover-bg); border: 1px solid var(--border-ring); border-radius: 12px; box-shadow: var(--shadow-lg); }
.be-ava-picker button { width: 34px; height: 34px; font-size: 19px; line-height: 1; background: none; border: 1px solid transparent; border-radius: 8px; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.be-ava-picker button:hover { background: var(--fill-soft); }
.be-ava-picker button.cur { border-color: var(--gold); }
.be-cursor { position: absolute; top: 0; left: 0; will-change: transform; pointer-events: none; z-index: 24; }
.be-cursor svg { display: block; filter: drop-shadow(0 1px 2px rgba(0,0,0,.45)); }
.be-cursor-label {
    position: absolute; left: 16px; top: 16px; white-space: nowrap; color: #fff;
    font-size: 11px; font-weight: 600; padding: 2px 7px; border-radius: 10px; box-shadow: 0 1px 4px rgba(0,0,0,.4);
}
/* Speaking on the board → green halo on the speaker's cursor label (mirrors the comms-panel highlight). */
.be-cursor.be-cur-speaking .be-cursor-label { box-shadow: 0 0 0 3px rgba(34,197,94,.65), 0 1px 4px rgba(0,0,0,.4); animation: beCurSpk 1s ease-in-out infinite; }
@keyframes beCurSpk { 0%,100% { box-shadow: 0 0 0 3px rgba(34,197,94,.5), 0 1px 4px rgba(0,0,0,.4); } 50% { box-shadow: 0 0 0 5px rgba(34,197,94,.3), 0 1px 4px rgba(0,0,0,.4); } }
/* Cursor chat (ephemeral message bubble + input) */
/* «Point to me» attention (press "/") — accent-coloured arrow at peers' cursors + «!» over the presser's cursor */
.be-point-arrow, .be-point-bang { position: absolute; left: 0; top: 0; pointer-events: none; will-change: transform, opacity; color: var(--gold, #cba74e); filter: drop-shadow(0 2px 7px rgba(0,0,0,.5)); z-index: 26; }
.be-point-arrow { width: 74px; height: 32px; }
.be-point-bang { width: 26px; height: 40px; }
.be-point-arrow svg, .be-point-bang svg { width: 100%; height: 100%; display: block; }
.be-rsel {
    position: absolute; top: 0; left: 0; box-sizing: border-box;
    border: 2px solid var(--gold); border-radius: 4px; pointer-events: none; z-index: 23;
}
.be-rsel-label {
    position: absolute; top: -9px; left: -2px; font-size: 10px; line-height: 16px;
    padding: 0 4px; border-radius: 6px; color: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.4);
}

/* Comment-count badge on the topbar comments button */
.be-count-badge {
    position: absolute; top: 3px; right: 3px;
    min-width: 16px; height: 16px; padding: 0 4px;
    display: flex; align-items: center; justify-content: center;
    font-size: 10px; font-weight: 700; line-height: 1;
    color: var(--on-gold); background: var(--gold); border-radius: 999px; pointer-events: none;
}
/* "New / unviewed comments" badge (red, top-left so it doesn't clash with the gold total) */
.be-new-badge {
    position: absolute; top: 3px; left: 3px;
    min-width: 16px; height: 16px; padding: 0 4px;
    display: flex; align-items: center; justify-content: center;
    font-size: 10px; font-weight: 700; line-height: 1;
    color: #fff; background: var(--danger); border-radius: 999px; pointer-events: none;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger) 25%, transparent); animation: be-newpulse 1.8s ease-in-out infinite;
}
@keyframes be-newpulse { 0%,100% { box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger) 30%, transparent); } 50% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--danger) 0%, transparent); } }
.be-citem-new { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: #fff; background: var(--danger); border-radius: 6px; padding: 1px 5px; margin-right: 6px; }
/* new/unseen comment pin on the canvas — danger-coloured glow ring (respects the portal «опасное» colour) */
.be-pin.be-pin-new { box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 90%, transparent), 0 0 12px 2px color-mix(in srgb, var(--danger) 55%, transparent); animation: be-newpulse 1.8s ease-in-out infinite; }
/* Slides — 16:9 sheets with a soft shadow + corner number + skip-export badge */
.be-el[data-type="slide"] .be-el-inner { box-shadow: 0 3px 18px rgba(0,0,0,.20); overflow: hidden; }
.be-slide-num { position: absolute; top: 6px; left: 9px; font-size: 12px; font-weight: 700; pointer-events: none; user-select: none; z-index: 3; }
.be-slide-skip { position: absolute; top: 5px; right: 6px; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; background: rgba(127,127,127,.18); border: none; border-radius: 7px; cursor: pointer; padding: 0; z-index: 3; transition: background .15s; }
.be-slide-skip:hover { background: rgba(127,127,127,.36); }
.be-slide-skip.on { background: rgba(239,68,68,.92); }

/* Keyboard shortcuts help modal */
.be-help-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 9px 24px; margin: 6px 0 4px; }
.be-help-row { display: grid; grid-template-columns: 116px 1fr; align-items: center; gap: 12px; font-size: 13px; }
.be-help-keys { display: inline-flex; flex-wrap: wrap; gap: 4px; align-content: center; }
.be-help-row span:last-child { color: var(--muted); }
.be-help-grid kbd {
    font-family: inherit; font-size: 11px; font-weight: 600; line-height: 1;
    color: var(--gold); background: var(--gold-bg); border: 1px solid var(--border);
    border-radius: 5px; padding: 3px 7px; min-width: 16px; text-align: center; white-space: nowrap;
}
@media (max-width: 600px) { .be-help-grid { grid-template-columns: 1fr; } }

/* Video element overlay bar (comment count + project/review link) */
.be-vid-bar {
    position: absolute; top: 0; left: 0; right: 0; display: none; align-items: center;
    justify-content: space-between; gap: 8px; padding: 5px 7px; pointer-events: none;
}
.be-el.selected .be-vid-bar { display: flex; }   /* screenshot / cover / frame buttons show only while the video block is selected */
.be-el.be-vid-play .be-vid-bar { display: none !important; }   /* …but hide them while the clip is playing so they don't cover the video */
/* Ревью-блок: справа колонка комментариев — кнопки скрина/обложки должны висеть над ВИДЕО, а не над ней. */
.be-el.be-vreview .be-vid-bar { right: calc(300px + 6px); }
.be-vid-chip {
    display: inline-flex; align-items: center; gap: 4px; pointer-events: auto;
    background: rgba(0,0,0,.5); color: #fff; font-size: 11px; padding: 2px 7px; border-radius: 10px;
}
.be-vid-open {
    pointer-events: auto; cursor: pointer; border: none; background: var(--gold); color: var(--on-gold, #1a1712);
    display: inline-flex; align-items: center; justify-content: center; gap: 5px;
    font-size: 11px; font-weight: 600; padding: 3px 9px; border-radius: var(--radius-sm); white-space: nowrap;
}
.be-vid-open:hover { filter: brightness(1.08); }
.be-vid-open svg { display: block; }

/* Comments list panel */
/* Comments dropdown reuses the notifications window (.topbar-menu.notif-menu); just the scrollable list inside. */
#beCommentsPanel.notif-menu { padding: 0; }
.be-comments-body { padding: 6px; overflow-y: auto; max-height: min(60vh, 460px); display: flex; flex-direction: column; gap: 9px; }
.be-comments-empty { color: var(--muted); font-size: 13px; padding: 16px 4px; text-align: center; }

/* ===== Board chat panel (reuses the notifications dropdown window) ===== */
#beChatPanel.notif-menu, #beVoicePanel.notif-menu { padding: 0; }
.be-chat-note { padding: 7px 12px; font-size: 11px; line-height: 1.45; color: var(--muted-2); background: var(--fill-soft); border-bottom: 1px solid var(--border); text-align: center; text-wrap: balance; }
.be-chat-body { padding: 8px; overflow-y: auto; min-height: 120px; max-height: min(46vh, 420px); display: flex; flex-direction: column; gap: 8px; }
/* Drag grip at the TOP of the chat window to change its height (the panel is bottom-anchored → it grows upward). */
.be-chat-resize { height: 15px; flex: none; cursor: ns-resize; display: flex; align-items: center; justify-content: center; touch-action: none; border-top-left-radius: inherit; border-top-right-radius: inherit; }
.be-chat-resize::before { content: ''; width: 36px; height: 4px; border-radius: 999px; background: var(--border-strong); opacity: .65; transition: opacity .12s; }
.be-chat-resize:hover::before, .be-chat-resize.dragging::before { opacity: 1; }
.be-chat-msg { display: flex; flex-direction: column; gap: 2px; max-width: 86%; align-self: flex-start; position: relative; }
/* Superadmin per-message moderation toolbar — hidden until row hover */
.be-chat-adm { position: absolute; top: -6px; right: 0; display: none; gap: 4px; z-index: 2; }
.be-chat-msg.own .be-chat-adm { right: auto; left: 0; }
.be-chat-msg:hover .be-chat-adm { display: flex; }
.be-chat-adm-btn { width: 22px; height: 22px; padding: 0; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; line-height: 1; border: 1px solid var(--border); border-radius: 6px; background: var(--panel-2, #1c1c22); color: var(--text); cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,.35); }
.be-chat-adm-btn.del:hover { border-color: #c0564f; color: #e0736b; }
.be-chat-msg.own { align-self: flex-end; align-items: flex-end; }
.be-chat-meta { font-size: 10px; color: var(--muted-2); padding: 0 4px; }
.be-chat-bub { background: var(--fill-soft); border: 1px solid var(--border); border-radius: 12px; padding: 6px 10px; font-size: 13px; line-height: 1.35; color: var(--text); white-space: pre-wrap; word-break: break-word; }
.be-chat-msg.own .be-chat-bub { background: var(--gold-bg, rgba(203,167,78,.16)); border-color: rgba(203,167,78,.4); }
.be-chat-form { display: flex; align-items: flex-end; gap: 6px; padding: 8px; border-top: 1px solid var(--border); }
.be-chat-input { flex: 1; resize: vertical; min-height: 36px; background: var(--fill-soft); border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; color: var(--text); font-size: 13px; line-height: 1.35; max-height: 60vh; outline: none; font-family: inherit; }
.be-chat-input:focus { border-color: var(--border-strong); }
.be-chat-send { flex: none; width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center; border: none; border-radius: 10px; background: var(--gold, #cba74e); color: var(--on-gold, #161616); cursor: pointer; }
.be-chat-send:hover { filter: brightness(1.08); }
/* @bug/@idea attachment tools (record screen video / screenshot) + pending-media preview */
.be-fb-tools { display: flex; align-items: center; gap: 4px; flex: none; }
.be-fb-btn { width: 34px; height: 36px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--border); border-radius: 10px; background: var(--panel-2, rgba(255,255,255,.04)); color: var(--muted, #9aa0ab); cursor: pointer; }
.be-fb-btn:hover { color: var(--gold, #cba74e); border-color: var(--gold, #cba74e); }
.be-fb-preview { display: flex; gap: 8px; padding: 8px 8px 0; flex-wrap: wrap; }
.be-fb-pv-cell { position: relative; width: 84px; height: 56px; border-radius: 8px; overflow: hidden; border: 1px solid var(--border); background: #000; }
.be-fb-pv-cell video, .be-fb-pv-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.be-fb-pv-tag { position: absolute; left: 4px; bottom: 3px; font-size: 9px; font-weight: 700; color: #fff; background: rgba(0,0,0,.55); padding: 1px 5px; border-radius: 5px; }
.be-fb-pv-x { position: absolute; top: 3px; right: 3px; width: 18px; height: 18px; border: none; border-radius: 50%; background: rgba(0,0,0,.6); color: #fff; font-size: 11px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.be-fb-pv-x:hover { background: var(--danger, #e5484d); }
/* @bug/@idea media shown inline in the chat bubble */
.be-chat-media { margin-top: 4px; max-width: 240px; }
.be-chat-msg.own .be-chat-media { margin-left: auto; }
.be-chat-media img, .be-chat-media video { display: block; width: 100%; max-height: 200px; object-fit: cover; border-radius: 10px; border: 1px solid var(--border); background: #000; }
.be-chat-media video { object-fit: contain; }
/* admin-resolved @bug/@idea: «Выполнено» badge over the original text kept small */
.be-chat-bub.be-chat-resolved { border-left: 3px solid var(--green, #4ea34a); }
.be-chat-done { font-size: 12px; font-weight: 700; color: var(--green, #4ea34a); }
.be-chat-orig { font-size: 11px; opacity: .6; margin-top: 2px; white-space: pre-wrap; word-break: break-word; }

/* ===== Voice panel ===== */
.be-voice-body { padding: 10px; display: flex; flex-direction: column; gap: 10px; }
.be-voice-empty { color: var(--muted); font-size: 13px; text-align: center; padding: 6px 2px; }
.be-voice-join { width: 100%; padding: 10px; border: none; border-radius: 10px; background: var(--gold, #cba74e); color: var(--on-gold, #161616); font-size: 13px; font-weight: 600; cursor: pointer; }
.be-voice-join:hover { filter: brightness(1.08); }
.be-voice-join:disabled { opacity: .6; cursor: default; }
.be-voice-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; max-height: 320px; overflow-y: auto; }   /* ~8 участников, дальше скролл */
.be-voice-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 8px; font-size: 13px; color: var(--text); }
.be-voice-invh { margin: 10px 2px 4px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.be-voice-invlist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.be-voice-invlist li { display: flex; align-items: center; gap: 8px; padding: 4px 8px; font-size: 13px; color: var(--text); }
.be-voice-inv { margin-left: auto; padding: 3px 9px; border: 1px solid var(--gold, #cba74e); background: transparent; color: var(--gold, #cba74e); border-radius: 7px; font-size: 12px; cursor: pointer; white-space: nowrap; }
.be-voice-inv:hover:not(:disabled) { background: var(--gold, #cba74e); color: var(--on-gold, #161616); }
.be-voice-inv:disabled { opacity: .55; cursor: default; }
.be-voice-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong, #4a4a52); transition: background .12s, box-shadow .12s; }
.be-voice-row.speaking .be-voice-dot { background: #22c55e; box-shadow: 0 0 0 3px rgba(34,197,94,.25); }
.be-voice-row.speaking { background: var(--fill-soft); }
.be-voice-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.be-voice-mic { flex: none; font-size: 13px; opacity: .85; }
.be-voice-vol { flex: none; width: 64px; height: 18px; cursor: pointer; accent-color: var(--gold); }
.be-voice-lmute { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; border: 1px solid var(--line); border-radius: 7px; background: var(--panel-3); color: var(--muted); cursor: pointer; }
.be-voice-lmute:hover { border-color: var(--gold); color: var(--text); }
.be-voice-lmute.on { color: var(--danger); border-color: var(--danger); }
.be-voice-follow { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; border: 1px solid var(--line); border-radius: 7px; background: var(--panel-3); color: var(--muted); cursor: pointer; }
.be-voice-follow:hover { border-color: var(--gold); color: var(--text); }
.be-voice-follow.on { color: var(--gold); border-color: var(--gold); background: var(--gold-bg); }
.be-voice-follow:disabled { opacity: .35; cursor: default; }
.be-voice-follow:disabled:hover { border-color: var(--line); color: var(--muted); }
.be-voice-req { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; border: 1px solid var(--line); border-radius: 7px; background: var(--panel-3); color: var(--muted); cursor: pointer; }
.be-voice-req:hover { border-color: var(--gold); color: var(--text); }
.be-voice-animal { flex: none; border: none; background: transparent; cursor: pointer; font-size: 15px; line-height: 1; padding: 0; }
.be-voice-animal:hover { transform: scale(1.18); }
.be-voice-edit { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; padding: 0; border: none; background: transparent; color: var(--muted); cursor: pointer; opacity: .55; }
.be-voice-edit:hover { color: var(--gold); opacity: 1; }
.be-voice-edit svg { width: 13px; height: 13px; }
.be-voice-mir { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; border: 1px solid var(--line); border-radius: 7px; background: var(--panel-3); color: var(--muted); cursor: pointer; }
.be-voice-mir:hover { color: var(--gold); }
.be-voice-mir.on { color: var(--gold); border-color: var(--gold); }
.be-voice-mir svg { width: 14px; height: 14px; }
/* «Be Right Back»: camera is off → the tile placeholder shows this text instead of the animal emoji. */
.be-rtc-tile.be-rtc-brb .be-rtc-emoji { display: none; }
.be-rtc-tile.be-rtc-brb .be-rtc-ph::after { content: 'Be Right Back'; font-size: 15px; font-weight: 700; letter-spacing: .03em; color: #fff; text-align: center; padding: 0 8px; }
/* Per-viewer camera mirror (local horizontal flip). */
.be-rtc-tile video.be-rtc-mirror { transform: scaleX(-1); }
.be-voice-hand { flex: none; margin-left: 2px; font-size: 14px; line-height: 1; }
/* Raise-hand badge on a camera tile (the ✋ emoji is content; the surrounding chip is monochrome). */
.be-rtc-hand { position: absolute; bottom: 8px; right: 10px; top: auto; left: auto; display: none; align-items: center; justify-content: center; font-size: clamp(32px, 26%, 64px); line-height: 1; z-index: 4; pointer-events: none; filter: drop-shadow(0 2px 6px rgba(0,0,0,.55)); }
.be-rtc-tile.be-rtc-raised .be-rtc-hand { display: flex; animation: be-hand-wave 1.2s ease-in-out infinite; transform-origin: 60% 90%; }
@keyframes be-hand-wave { 0%, 100% { transform: rotate(-8deg); } 50% { transform: rotate(10deg); } }
/* Floating emoji reaction on a tile */
.be-rtc-react { position: absolute; left: 50%; bottom: 34px; font-size: 40px; line-height: 1; pointer-events: none; z-index: 5; animation: be-react-float 1.7s ease-out forwards; }
@keyframes be-react-float { 0% { opacity: 0; transform: translate(-50%, 12px) scale(.6); } 16% { opacity: 1; transform: translate(-50%, 0) scale(1.12); } 32% { transform: translate(-50%, -8px) scale(1); } 100% { opacity: 0; transform: translate(-50%, -76px) scale(1); } }
/* Emoji palette popover above the reactions button */
.be-rtc-reactbar { position: absolute; bottom: 56px; right: 12px; display: flex; flex-wrap: wrap; justify-content: center; max-width: min(94vw, 344px); gap: 4px; background: var(--panel-2, #1c1c20); border: 1px solid var(--line); border-radius: 12px; padding: 6px; z-index: 6; box-shadow: 0 6px 20px rgba(0,0,0,.4); }
.be-rtc-reactbar button { border: none; background: transparent; font-size: 20px; line-height: 1; cursor: pointer; padding: 4px; border-radius: 8px; }
.be-rtc-reactbar button:hover { background: var(--panel-3); }
.be-rtc-reactbar.be-rtc-reactbar-float { position: fixed; bottom: auto; right: auto; z-index: 100002; }
/* On-tile controls: raise-hand / reaction (own camera) · screenshot (screen-share) — shown on hover */
.be-rtc-tctrls { position: absolute; top: 6px; right: 6px; display: flex; gap: 5px; z-index: 6; opacity: 0; pointer-events: none; transition: opacity .12s; }
.be-rtc-tile:hover .be-rtc-tctrls, .be-rtc-tile.be-show-ctrls .be-rtc-tctrls, .be-rtc-tctrls:focus-within { opacity: 1; pointer-events: auto; }
.be-rtc-tbtn { width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center; border: none; border-radius: 8px; cursor: pointer; color: #fff; background: rgba(0,0,0,.55); backdrop-filter: blur(2px); }
.be-rtc-tbtn:hover { background: rgba(0,0,0,.78); }
.be-rtc-tbtn.on { background: var(--gold, #cba74e); color: #1a1305; }
.be-rtc-tbtn svg { width: 16px; height: 16px; }
/* touch: controls hidden by default so they don't cover the (small) video — tap the tile to reveal (be-show-ctrls); slightly smaller buttons when shown */
@media (pointer: coarse) { .be-rtc-tbtn { width: 26px; height: 26px; } .be-rtc-tbtn svg { width: 14px; height: 14px; }
    /* small tiles: let the on-tile buttons (hand, reaction, …) wrap within the tile instead of overflowing off the edge */
    .be-rtc-tctrls { flex-wrap: wrap; justify-content: flex-end; gap: 4px; max-width: calc(100% - 10px); } }
/* Sound controls on the OBS/RTMP stream tile (always visible — the stream is the focal point). */
.be-rtmp-audio { position: absolute; left: 8px; bottom: 8px; z-index: 6; display: flex; align-items: center; gap: 7px; padding: 4px 10px 4px 4px; background: rgba(18,18,24,.72); border-radius: 22px; backdrop-filter: blur(4px); }
.be-rtmp-audio .be-rtc-tbtn { width: 28px; height: 28px; background: rgba(255,255,255,.18); color: #fff !important; }
.be-rtmp-audio .be-rtc-tbtn svg { color: #fff; }                       /* keep the icon clearly white (muted state) on any tile background */
.be-rtmp-audio .be-rtc-tbtn:hover { background: rgba(255,255,255,.32); }
.be-rtmp-audio .be-rtc-tbtn.on { background: var(--gold, #cba74e); color: #1a1305 !important; }   /* sound ON → gold */
.be-rtmp-audio .be-rtc-tbtn.on svg { color: #1a1305; }
.be-rtmp-vol { width: 84px; height: 16px; accent-color: var(--gold, #cba74e); cursor: pointer; }
.be-rtmp-audio.be-noaudio .be-rtc-tbtn { background: rgba(255,255,255,.12); }   /* no audio in stream: keep button visible, just hide the slider */
.be-rtmp-audio.be-noaudio .be-rtmp-vol { display: none; }
/* "Follow the presenter" status banner (top centre) */
.be-follow-bar {
    position: fixed; top: 58px; left: 50%; transform: translateX(-50%); z-index: 199;
    display: flex; align-items: center; gap: 10px; padding: 7px 10px 7px 13px; max-width: 90vw;
    background: var(--popover-bg, #1a1a1f); border: 1px solid var(--gold, #cba74e);
    border-radius: 999px; box-shadow: var(--shadow-md, 0 6px 20px rgba(0,0,0,.4)); backdrop-filter: blur(8px);
    font-size: 12px; color: var(--text); white-space: nowrap;
}
.be-follow-bar.lead { border-color: var(--border-ring, #333); }
/* While an upload bar is showing, drop the follow-bar below it so its «Выйти/Прекратить» button is never covered. */
body.be-uploading .be-follow-bar { top: 92px; }
body.be-uploading .portal-notice-fixed ~ .be-follow-bar { top: 130px; }
.be-follow-ic { display: inline-flex; color: var(--gold, #cba74e); }
.be-follow-exit { flex: none; border: none; background: var(--gold, #cba74e); color: var(--on-gold, #161616); font-size: 12px; font-weight: 600; padding: 4px 12px; border-radius: 999px; cursor: pointer; }
.be-follow-exit:hover { filter: brightness(1.08); }
.be-voice-btn { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; padding: 9px 12px; border: 1px solid var(--border); border-radius: 9px; background: var(--fill-soft); color: var(--text); font-size: 13px; line-height: 1; white-space: nowrap; cursor: pointer; }
.be-voice-btn svg { flex: none; }
.be-voice-join { display: flex; align-items: center; justify-content: center; gap: 8px; }
.be-voice-btn:hover { background: var(--panel-3, #26262c); }
.be-voice-btn.danger { color: #ef4444; border-color: rgba(239,68,68,.4); }
.be-voice-btn.danger:hover { background: rgba(239,68,68,.12); }
#beVoiceBtn.be-voice-live { color: #22c55e; }
/* someone else is in the audio room (you're not) — gentle green pulse so you notice */
#beVoiceBtn.be-voice-others { color: #22c55e; animation: be-voice-pulse 1.6s ease-in-out infinite; }
@keyframes be-voice-pulse { 0%,100% { box-shadow: 0 0 0 0 rgba(34,197,94,.45); } 50% { box-shadow: 0 0 0 5px rgba(34,197,94,0); } }
#beVoiceBtn.be-voice-others .be-count-badge { background: #22c55e; color: #04210f; }
.be-feat-off { margin-left: auto; background: none; border: none; color: var(--muted); font-size: 11px; cursor: pointer; text-decoration: underline; }
/* ── Communication: control row + canvas video tiles + settings ── */
/* Meeting recording bar (single elected recorder) */
.be-rtc-recbar { width: 100%; box-sizing: border-box; display: flex; align-items: center; justify-content: center; gap: 8px; margin: 6px 0 2px; padding: 9px 12px; border-radius: 10px; border: 1px solid var(--border); background: var(--fill-soft); color: var(--text); font-size: 13px; font-weight: 600; cursor: pointer; }
.be-rtc-recbar:hover { background: var(--panel-3); }
.be-rtc-recbar.on { background: rgba(239,68,68,.16); border-color: rgba(239,68,68,.5); color: #ef4444; }
.be-rtc-recbar.busy { background: rgba(239,68,68,.08); border-style: dashed; cursor: default; }
.be-rtc-recbar .be-rec-dot { width: 10px; height: 10px; border-radius: 50%; background: #ef4444; flex: none; box-shadow: 0 0 0 0 rgba(239,68,68,.5); animation: beRecPulse 1.4s infinite; }
@keyframes beRecPulse { 0% { box-shadow: 0 0 0 0 rgba(239,68,68,.5); } 70% { box-shadow: 0 0 0 7px rgba(239,68,68,0); } 100% { box-shadow: 0 0 0 0 rgba(239,68,68,0); } }
.be-rtc-controls { display: grid; grid-template-columns: repeat(auto-fill, 42px); gap: 6px; justify-content: center; padding-top: 2px; }   /* square buttons → as many per row as the (now wider) panel fits */
.be-rtc-controls .be-rtc-cbtn { width: 42px; }
.be-rtc-cbtn { display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px; border: 1px solid var(--border); border-radius: 10px; background: var(--fill-soft); color: var(--text); cursor: pointer; }
.be-rtc-cbtn svg { width: 21px; height: 21px; }
.be-rtc-cbtn:hover { background: var(--panel-3, #26262c); }
.be-rtc-cbtn.on { background: var(--gold, #cba74e); color: var(--on-gold, #161616); border-color: transparent; }
.be-rtc-cbtn.danger { color: #ef4444; border-color: rgba(239,68,68,.4); }
.be-rtc-cbtn:disabled { opacity: .4; cursor: default; }

/* Owner comms-admin floating window — portal-style monochrome, rounded */
.be-rtcadm { position: fixed; z-index: 56; width: 860px; max-width: calc(100vw - 24px); background: var(--panel-2, #1c1c22); color: var(--text, #e8e8ee);
    border: 1px solid var(--border, #2c2c34); border-radius: 14px; box-shadow: 0 14px 40px rgba(0,0,0,.5); overflow: hidden; font-size: 13px; }
.be-rtcadm-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 12px; font-weight: 600;
    background: var(--fill-soft, #23232a); border-bottom: 1px solid var(--border, #2c2c34); cursor: move; user-select: none; }
.be-rtcadm-head > span { flex: 1 1 auto; min-width: 0; }   /* title takes the slack → the head buttons group at the right instead of spreading */
.be-rtcadm-x { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border: none; border-radius: 8px;
    background: transparent; color: var(--muted, #9a9aa6); cursor: pointer; }
.be-rtcadm-x:hover { background: var(--panel-3, #26262c); color: var(--text, #e8e8ee); }
.be-rtcadm-body { padding: 8px; max-height: 60vh; overflow-y: auto; }
.be-rtcadm-empty { padding: 16px 10px; text-align: center; color: var(--muted, #9a9aa6); }
.be-rtcadm-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.be-rtcadm-row { display: flex; align-items: center; gap: 8px; padding: 6px 6px 6px 10px; border-radius: 10px; background: var(--fill-soft, #23232a); }
.be-rtcadm-name { flex: 1; min-width: 150px; display: flex; align-items: center; gap: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.be-rtcadm-mob { display: inline-flex; align-items: center; color: var(--muted, #9a9aa6); flex: none; }
.be-rtcadm-mob svg { width: 13px; height: 13px; }
.be-rtcadm-btns { display: inline-flex; align-items: center; flex-wrap: wrap; justify-content: flex-end; gap: 4px; flex: none; }
/* Button groups: «выключить» | «попросить включить» | прочие — разделены тонкой чертой. */
.be-rtcadm-grp { display: inline-flex; align-items: center; gap: 4px; padding-right: 8px; border-right: 1px solid var(--border, #2c2c34); }
.be-rtcadm-btns > .be-rtcadm-grp:last-child { border-right: none; padding-right: 0; }
/* «Заблокировать вход» — красноватая, всегда крайняя справа. */
.be-rtcadm-banbtn { color: var(--danger, #e05656); border-color: rgba(224,86,86,.45); margin-left: 6px; }
.be-rtcadm-banbtn:hover { background: var(--danger, #e05656); color: #fff; border-color: var(--danger, #e05656); }
.be-rtcadm-btn { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border: 1px solid var(--border, #2c2c34);
    border-radius: 9px; background: var(--panel-2, #1c1c22); color: var(--text, #e8e8ee); cursor: pointer; }
.be-rtcadm-btn svg { width: 16px; height: 16px; }
.be-rtcadm-btn:hover { background: var(--panel-3, #26262c); }
.be-rtcadm-btn:disabled { opacity: .3; cursor: default; }
.be-rtcadm-btn.on { background: var(--gold, #cba74e); color: var(--on-gold, #161616); border-color: transparent; }
/* Owner force-locked fullscreen on a speaker → hide the dock head buttons (fs/collapse/canvas) so they can't exit. */
.be-rtc-dock.be-rtc-fs-locked .be-rtc-dock-btn { display: none; }
/* …кроме шестерёнки: она не выпускает из полноэкранного режима, а вот запертый без выбора микрофона участник
   иначе останется неслышным и починить это не сможет. */
.be-rtc-dock.be-rtc-fs-locked .be-rtc-dock-btn[data-a="settings"] { display: inline-flex; }
/* Locked fullscreen (forced or call-only link) → no following from inside it. */
.be-rtc-dock.be-rtc-fs-locked .be-rtc-tbtn[data-t="finvite"], .be-rtc-dock.be-rtc-fs-locked .be-rtc-tbtn[data-t="freq"] { display: none; }
.be-rtcadm-row.banned { opacity: .9; }
.be-rtcadm-row.banned .be-rtcadm-name { color: var(--muted, #9a9aa6); }
.be-rtcadm-banflag { margin-left: 7px; font-size: 10px; text-transform: uppercase; letter-spacing: .03em; color: var(--danger, #e05656); }
.be-rtcadm-unbanbtn { color: var(--gold, #cba74e) !important; border-color: var(--gold, #cba74e) !important; opacity: 1 !important; }
.be-rtcadm-unbanbtn:hover { background: var(--gold, #cba74e); color: var(--on-gold, #161616) !important; }
body.be-canvas-light .be-rtcadm { background: #fff; color: #2a2a30; border-color: #e4e4ea; }
body.be-canvas-light .be-rtcadm-head { background: #f4f4f7; border-color: #e4e4ea; }
body.be-canvas-light .be-rtcadm-row { background: #f4f4f7; }
body.be-canvas-light .be-rtcadm-btn { background: #fff; border-color: #e4e4ea; color: #2a2a30; }
body.be-canvas-light .be-rtcadm-grp { border-right-color: #e4e4ea; }
body.be-canvas-light .be-rtcadm-banbtn { color: var(--danger, #e05656); border-color: rgba(224,86,86,.45); }
/* Mobile: panel fills the width and the controls wrap onto their own line below the name. */
@media (max-width: 700px) { .be-rtcadm { width: calc(100vw - 24px); right: 12px !important; }
    .be-rtcadm-row { flex-wrap: wrap; }
    .be-rtcadm-name { min-width: 0; flex: 1 1 100%; }
    .be-rtcadm-btns { flex: 1 1 100%; justify-content: flex-start; } }
.be-rtc-settings { gap: 12px; }
.be-rtc-settings label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }
.be-rtc-settings select { padding: 7px 9px; border: 1px solid var(--border); border-radius: 8px; background: var(--panel-3, #26262c); color: var(--text); font-size: 13px; }
.be-rtc-settings .be-rtc-chk { flex-direction: row; align-items: center; gap: 8px; color: var(--text); font-size: 13px; cursor: pointer; }
.be-rtc-settings .be-rtc-chk input { width: auto; margin: 0; flex: none; }
/* Эквалайзер микрофона: свёрнутая секция (открыта, если что-то накручено); строки полос — ГОРИЗОНТАЛЬНЫЕ,
   специфичный селектор перебивает колонку .be-rtc-settings label. */
.be-rtc-eq { border: 1px solid var(--border); border-radius: 10px; padding: 8px 11px; }
.be-rtc-eq summary { cursor: pointer; font-size: 13px; font-weight: 600; color: var(--text); user-select: none; }
.be-rtc-eq-presets { display: flex; gap: 6px; flex-wrap: wrap; margin: 10px 0 8px; }
.be-rtc-eqp { padding: 5px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--fill-soft, #23232a); color: var(--muted); font-size: 12px; cursor: pointer; transition: color .12s, border-color .12s; }
.be-rtc-eqp:hover { border-color: var(--gold, #cba74e); }
.be-rtc-eqp.on { border-color: var(--gold, #cba74e); color: var(--gold, #cba74e); }
.be-rtc-settings .be-rtc-eq-row { flex-direction: row; align-items: center; gap: 8px; margin: 3px 0; font-size: 12px; }
.be-rtc-eq-row span { width: 50px; flex: none; }
.be-rtc-eq-row input[type=range] { flex: 1; accent-color: var(--gold, #cba74e); }
.be-rtc-eq-row b { width: 28px; flex: none; text-align: right; color: var(--text); font-size: 12px; }
.be-rtc-selfmon { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; padding: 9px 12px; border: 1px solid var(--border); border-radius: 9px; background: var(--panel-3, #26262c); color: var(--text); font-size: 13px; cursor: pointer; transition: all .15s; }
.be-rtc-selfmon:hover { border-color: var(--gold); }
.be-rtc-selfmon.on { background: var(--gold); color: var(--on-gold, #1a1712); border-color: var(--gold); }
.be-rtc-note { font-size: 11px; color: var(--muted-2); }
/* Плашка «Включить звук»: автоплей заблокирован политикой браузера (вход в связь без жеста — монитор-ссылка,
   автоподключение) — участник видел говорящих, но молча ничего не слышал. Поверх дока и его фуллскрина. */
#beAudioUnlock { position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%); z-index: 10010; display: inline-flex; align-items: center; gap: 8px; padding: 11px 20px; border: 1px solid var(--gold, #cba74e); border-radius: 24px; background: var(--panel-2, #17171b); color: var(--gold, #cba74e); font-size: 14px; font-weight: 600; cursor: pointer; box-shadow: 0 8px 30px rgba(0,0,0,.55); }
#beAudioUnlock:hover { background: var(--gold, #cba74e); color: var(--on-gold, #1a1712); }
/* Те же настройки, открытые модалкой по шестерёнке дока. Список длинный (устройства + качество + режим звука +
   три галочки обработки), поэтому телу дают прокрутку — иначе на ноутбучном экране кнопка «Готово» уезжает за край. */
.be-rtc-setmodal { max-width: 380px; }
.be-rtc-setmodal .be-rtc-settings { padding: 12px 0 0; max-height: min(62vh, 520px); overflow-y: auto; }
/* Video tiles live in the world layer → they pan/zoom with the canvas (adaptiveStream uses their on-screen size). */
.be-rtc-tile { border-radius: 10px; overflow: hidden; background: #000; box-shadow: 0 6px 20px rgba(0,0,0,.5); border: 1px solid rgba(255,255,255,.12); display: flex; flex-direction: column; cursor: grab; }
.be-rtc-tile:active { cursor: grabbing; }
.be-rtc-tile.be-rtc-self { border-color: var(--gold, #cba74e); }
.be-rtc-bar { display: flex; align-items: center; gap: 6px; padding: 4px 8px; background: rgba(0,0,0,.55); cursor: grab; font-size: 12px; color: #fff; flex: none; }
.be-rtc-bar:active { cursor: grabbing; }
.be-rtc-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.be-rtc-tile video { flex: 1; width: 100%; height: 100%; object-fit: cover; background: #000; display: block; min-height: 0; }
.be-rtc-tile.be-rtc-screen video { object-fit: contain; }
/* Sega co-op host stream overlay: portrait → push below the ping plaque so the controller has room beneath; landscape (phone on its side) → anchor to the top (the 4:3 image already fills the height). */
.be-rtc-stream { object-position: center 64px; }
@media (orientation: landscape) { .be-rtc-stream { object-position: center top; } }
/* Camera-off presence tile: show the participant's animal emoji until a camera track attaches. */
.be-rtc-tile:not(.be-rtc-has-video) video { display: none; }
.be-rtc-ph { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; background: radial-gradient(circle at 50% 38%, #2a2a30, #161619); container-type: size; }
.be-rtc-tile.be-rtc-has-video .be-rtc-ph { display: none; }
/* "Подключение к трансляции…" — overlay shown on the OBS stream tile until the first video frame arrives. */
.be-rtc-connecting { position: absolute; inset: 0; z-index: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 11px; padding: 10px; text-align: center; background: radial-gradient(circle at 50% 38%, #20202a, #0e0e12); color: #cbd5e1; font-size: 12.5px; font-weight: 600; }
.be-rtc-conn-spin { width: 26px; height: 26px; border-radius: 50%; border: 3px solid rgba(168,85,247,.25); border-top-color: #a855f7; animation: beRtcSpin .8s linear infinite; }
@keyframes beRtcSpin { to { transform: rotate(360deg); } }
.be-rtc-tile.be-rtc-has-video .be-rtc-connecting { display: none; }
.be-root.be-canvas-light .be-rtc-connecting { background: radial-gradient(circle at 50% 38%, #f2f2f6, #e4e4ea); color: #44464d; }
.be-rtc-emoji { font-size: clamp(44px, 52cqmin, 200px); line-height: 1; user-select: none; filter: drop-shadow(0 2px 6px rgba(0,0,0,.4)); }
/* Mic-off badge in the tile header (monochrome, rounded — on the always-dark bar). */
.be-rtc-bar .be-rtc-mic { display: inline-flex; align-items: center; margin-left: auto; color: #fff; opacity: .9; flex: none; }
.be-rtc-bar .be-rtc-mic svg { width: 15px; height: 15px; }
/* Which room a participant is in (shown on their tile) */
.be-rtc-bar .be-rtc-room { font-size: 10px; color: #fff; background: rgba(255,255,255,.18); border-radius: 5px; padding: 1px 6px; margin-left: 6px; max-width: 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: none; }
/* Room zone element (a rect flagged props.room) — its name chip at the top-left. */
.be-room-tag { position: absolute; top: 6px; left: 8px; font-size: 12px; font-weight: 600; color: var(--text); background: color-mix(in srgb, var(--gold) 14%, transparent); border: 1px solid color-mix(in srgb, var(--gold) 45%, transparent); padding: 2px 9px; border-radius: 9px; pointer-events: none; max-width: 70%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; z-index: 2; }
/* Light board: var(--text) is light → unreadable. Use a readable chip on light tone. */
.be-root.be-canvas-light .be-room-tag { color: #1a1712; background: rgba(255,255,255,.85); border-color: rgba(0,0,0,.16); }
/* Secret room: a private zone whose content only the creator sees until revealed. Purple accent + "who/when" chip. */
.be-room-secret .be-room-tag { display: flex; flex-direction: column; gap: 1px; max-width: 84%; white-space: normal; line-height: 1.2;
    color: #fff; background: linear-gradient(135deg, rgba(168,85,247,.92), rgba(124,58,237,.92)); border-color: rgba(168,85,247,.6); }
.be-room-secret .be-room-tag-name { font-weight: 700; font-size: 12px; }
.be-room-secret .be-room-tag-sub { font-weight: 500; font-size: 10.5px; opacity: .85; }
.be-room-secret-revealed .be-room-tag { background: linear-gradient(135deg, rgba(132,180,120,.92), rgba(90,150,90,.92)); border-color: rgba(120,180,110,.6); }
/* "Reveal/hide for everyone" eye — top-right of the secret room, only rendered for the creator + board owner. */
.be-secret-eye { position: absolute; top: 6px; right: 8px; z-index: 3; width: 28px; height: 28px; display: flex; align-items: center; justify-content: center;
    border: 1px solid rgba(168,85,247,.55); background: rgba(24,18,34,.78); color: #d8b4fe; border-radius: 8px; cursor: pointer; padding: 0; }
.be-secret-eye:hover { background: rgba(168,85,247,.9); color: #fff; }
.be-secret-eye.on { background: rgba(132,180,120,.9); border-color: rgba(120,180,110,.7); color: #fff; }
.be-root.be-canvas-light .be-secret-eye { background: rgba(255,255,255,.92); color: #7c3aed; }
.be-voice-hand svg { width: 14px; height: 14px; vertical-align: middle; }
/* Rounded-bubble tooltips (replace native title hints) */
.be-tip { position: fixed; z-index: 100001; pointer-events: none; display: none; max-width: 240px; padding: 5px 10px; border-radius: 10px; background: rgba(22,22,26,.96); color: #fff; font: 500 12px/1.35 Inter, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; text-align: center; white-space: pre-line; box-shadow: 0 6px 18px rgba(0,0,0,.4); }
.be-tip::after { content: ''; position: absolute; left: 50%; transform: translateX(-50%); border: 5px solid transparent; }
.be-tip:not(.be-tip-below)::after { top: 100%; border-top-color: rgba(22,22,26,.96); }
.be-tip.be-tip-below::after { bottom: 100%; border-bottom-color: rgba(22,22,26,.96); }
/* Shift+Space tool spotlight */
.be-spot-ov { position: fixed; inset: 0; z-index: 100002; display: flex; align-items: flex-start; justify-content: center; background: rgba(0,0,0,.18); }
.be-spot { margin-top: 12vh; width: min(440px, 92vw); background: var(--panel-2, #1c1c20); border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 16px 50px rgba(0,0,0,.5); overflow: hidden; }
.be-spot-input { width: 100%; box-sizing: border-box; border: none; outline: none; background: transparent; color: var(--text); font-size: 16px; padding: 14px 16px; }
.be-spot-list { max-height: 320px; overflow-y: auto; }
.be-spot-list:not(:empty) { border-top: 1px solid var(--line); }
.be-spot-item { padding: 9px 16px; font-size: 14px; color: var(--text); cursor: pointer; }
.be-spot-item.sel, .be-spot-item:hover { background: var(--gold-bg, rgba(255,255,255,.08)); }
.be-spot-empty { padding: 12px 16px; font-size: 13px; color: var(--muted); }
body.be-canvas-light .be-spot { background: rgba(248,248,250,.99); border-color: rgba(0,0,0,.14); }
body.be-canvas-light .be-spot-input, body.be-canvas-light .be-spot-item { color: #1a1a1e; }
.be-rtc-resize { position: absolute; right: 0; bottom: 0; width: 18px; height: 18px; cursor: nwse-resize; z-index: 3; touch-action: none; }
.be-rtc-resize::after { content: ''; position: absolute; right: 3px; bottom: 3px; width: 9px; height: 9px; border-right: 2px solid rgba(255,255,255,.7); border-bottom: 2px solid rgba(255,255,255,.7); border-bottom-right-radius: 2px; }
/* Live call tiles are ephemeral overlays — never part of a board screenshot/snapshot. */
.be-rtc-hidden .be-rtc-tile { display: none !important; }
/* Alternative layout: dock the same tiles in an orderly bottom-right panel (screen full-width on top, cameras in a 2-col grid). */
.be-rtc-dock { position: fixed; right: 14px; bottom: 14px; width: 392px; max-width: calc(100vw - 12px); max-height: calc(100vh - 12px); display: none; flex-direction: column; background: var(--panel-2, #17171b); border: 1px solid var(--border); border-radius: 14px; box-shadow: 0 12px 40px rgba(0,0,0,.5); z-index: 65; overflow: hidden; }   /* width fits two ≥180px tiles side by side so on-tile buttons (raise hand etc.) fit from the start */
/* With a screen share present the dock is a wide block — screen on the LEFT, cameras stacked on the RIGHT.
   Freely resizable via the corner handle (default size below). */
.be-rtc-dock.has-screen { width: 460px; height: 300px; }
.be-rtc-dock-head { display: flex; align-items: center; gap: 4px; padding: 7px 10px; background: var(--panel-3, #202026); cursor: grab; user-select: none; flex: none; touch-action: none; }
.be-rtc-dock-head:active { cursor: grabbing; }
/* Заголовок ужимается первым, кнопки — никогда: их шесть, и на узком доке они иначе сплющиваются в нечитаемые полоски. */
.be-rtc-dock-title { font-size: 12px; font-weight: 600; color: var(--text); margin-right: auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.be-rtc-dock-head .be-rtc-dock-btn { flex: none; }
.be-rtc-timer { font-size: 11px; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; padding: 1px 6px; border-radius: 6px; background: var(--fill-soft, rgba(255,255,255,.06)); }
.be-rtc-dock-btn { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border: none; background: transparent; color: var(--muted); border-radius: 7px; cursor: pointer; }
.be-rtc-dock-btn:hover { background: var(--fill-soft); color: var(--text); }
.be-rtc-dock-btn svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.be-rtc-dock-body { display: flex; flex-direction: column; gap: 6px; padding: 8px; overflow-y: auto; min-height: 0; flex: 1 1 auto; }
.be-rtc-dock.collapsed .be-rtc-dock-body { display: none; }
.be-rtc-dock.collapsed .be-rtc-dock-resize { display: none; }
/* Every tile keeps a definite aspect-ratio so it's ALWAYS visible (screen 16:9, cameras 4:3 below). */
.be-rtc-dock-body .be-rtc-tile { position: relative !important; left: auto !important; top: auto !important; width: 100% !important; height: auto !important; aspect-ratio: 16 / 9; cursor: default; box-shadow: none; min-width: 0; flex: none; }
.be-rtc-dock-body .be-rtc-tile.be-rtc-screen video { object-fit: contain; }
/* cameras sit in their own row UNDER the screen tile → block flow keeps them from overlapping it */
.be-rtc-dock-cams { display: flex; flex-wrap: wrap; gap: 6px; flex: none; align-content: flex-start; align-items: flex-start; }   /* don't stretch tiles vertically — keep their aspect-ratio (4:3) on resize / fullscreen */
.be-rtc-dock-cams .be-rtc-tile { flex: 0 1 calc(50% - 3px); width: auto !important; min-width: 84px; aspect-ratio: 4 / 3; }   /* don't grow: a lone odd tile stays 50%, never balloons full-width */
.be-rtc-dock-cams.one .be-rtc-tile { flex-basis: 100%; }
/* Desktop fullscreen OR a user-resized corner dock: JS (rtcFitCams) sets the grid columns/rows so the 4/3 tiles fill the
   box; they scroll only once shrunk to the minimum. An untouched corner dock and mobile keep the flex layout above. */
@media (min-width: 701px) {
    .be-rtc-dock-cams.be-rtc-fit { display: grid !important; gap: 6px; min-height: 0; overflow: hidden !important; justify-content: center; align-content: center; }
    .be-rtc-dock:not(.has-screen) .be-rtc-dock-cams.be-rtc-fit { flex: 1 1 auto !important; }   /* grid mode fills the dock; the screen-side column keeps its own width */
    .be-rtc-dock-cams.be-rtc-fit .be-rtc-tile { flex: none !important; width: 100% !important; height: 100% !important; min-width: 0; aspect-ratio: auto !important; }
    .be-rtc-dock-cams.be-rtc-fit .be-rtc-tile video { width: 100%; height: 100%; object-fit: cover; }
    .be-rtc-dock-cams.be-rtc-fit.be-rtc-fit-scroll { overflow-y: auto !important; align-content: start; }   /* tiles hit the min size → scroll instead of shrinking under the buttons */
}
/* With a screen present: ROW layout — big screen LEFT (fills, min size), cameras stacked in a column RIGHT (min size). */
.be-rtc-dock.has-screen .be-rtc-dock-body { flex-direction: row; align-items: stretch; overflow: hidden; }
.be-rtc-dock.has-screen .be-rtc-dock-body .be-rtc-tile.be-rtc-screen { flex: 1 1 0; min-width: 160px; min-height: 0; width: auto !important; aspect-ratio: auto; }
.be-rtc-dock.has-screen .be-rtc-dock-cams { flex: 0 0 var(--rtc-cams-w, 132px); min-width: 90px; flex-direction: column; flex-wrap: nowrap; overflow-y: auto; gap: 6px; }
/* Draggable partition between screen/stream and the camera column */
.be-rtc-split { flex: 0 0 8px; align-self: stretch; cursor: ew-resize; position: relative; touch-action: none; }
.be-rtc-split::after { content: ''; position: absolute; left: 3px; top: 0; bottom: 0; width: 2px; background: var(--border); border-radius: 2px; }
.be-rtc-split:hover::after { background: var(--gold, #cba74e); }
/* Fullscreen the comms dock */
.be-rtc-dock.be-rtc-fs { left: 0 !important; top: 0 !important; right: 0; bottom: 0; width: 100vw !important; height: 100vh !important; max-width: none; max-height: none; border-radius: 0; z-index: 9999; }
.be-rtc-dock.be-rtc-fs .be-rtc-dock-head { cursor: default; }
.be-rtc-dock.be-rtc-fs .be-rtc-dock-resize { display: none; }
/* Popped out: the REAL dock is moved into the PiP document and fills it, so tiles get the exact corner/fullscreen
   layout (rtcFitCams treats .be-rtc-pip like .be-rtc-fs). Chrome that only makes sense on the board is hidden:
   dragging, resizing, fullscreen, collapse and «камеры на ковер» have no meaning inside the pop-out window. */
.be-rtc-dock.be-rtc-pip { position: static; width: 100%; height: 100vh; max-width: none; max-height: none; border: 0; border-radius: 0; box-shadow: none; display: flex; }
.be-rtc-dock.be-rtc-pip .be-rtc-dock-head { cursor: default; }
.be-rtc-dock.be-rtc-pip .be-rtc-dock-resize,
.be-rtc-dock.be-rtc-pip .be-rtc-dock-btn[data-a="fs"],
.be-rtc-dock.be-rtc-pip .be-rtc-dock-btn[data-a="collapse"],
.be-rtc-dock.be-rtc-pip .be-rtc-dock-btn[data-a="popout"],
/* Шестерёнка: док уехал в отдельное окно, а модалка настроек живёт в главном — клик из окошка открывал бы её
   там, где на неё никто не смотрит. В откреплённом режиме главное окно рядом, настройки берут из панели. */
.be-rtc-dock.be-rtc-pip .be-rtc-dock-btn[data-a="settings"],
.be-rtc-dock.be-rtc-pip .be-rtc-dock-btn[data-a="canvas"] { display: none; }
.be-rtc-dock.be-rtc-pip.has-screen { width: 100%; height: 100vh; }   /* beat `.has-screen { width:460px; height:300px }` */
.be-rtc-dock.has-screen .be-rtc-dock-cams .be-rtc-tile { flex: 0 0 auto; width: 100% !important; height: auto !important; aspect-ratio: 4 / 3; min-height: 64px; }
/* When the camera column is JS-fitted, tiles fill their exact grid cell (override the auto-height rule above). */
.be-rtc-dock.has-screen .be-rtc-dock-cams.be-rtc-fit .be-rtc-tile { width: 100% !important; height: 100% !important; aspect-ratio: auto !important; min-height: 0 !important; }
/* Mobile/touch fullscreen: cameras in two 4/3 columns (1 → full width, 2 → stacked) that scroll, keeping their aspect. */
@media (max-width: 700px), (pointer: coarse) {
    .be-rtc-dock.be-rtc-fs { height: 100dvh !important; }   /* exclude the browser's bottom bar from the height */
    .be-rtc-dock.be-rtc-fs .be-rtc-dock-cams { flex-direction: row !important; flex-wrap: wrap !important; overflow-y: auto; gap: 6px; padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 80px); align-content: flex-start; justify-content: center; }   /* extra bottom space so the last row clears the browser bar (scrollable) */
    .be-rtc-dock.be-rtc-fs .be-rtc-dock-cams .be-rtc-tile { flex: 0 0 calc(50% - 3px) !important; width: calc(50% - 3px) !important; max-width: calc(50% - 3px) !important; aspect-ratio: 4 / 3 !important; height: auto !important; min-height: 0; }
    .be-rtc-dock.be-rtc-fs .be-rtc-dock-cams.one .be-rtc-tile { flex-basis: 100% !important; width: 100% !important; max-width: 100% !important; aspect-ratio: 4 / 3 !important; }   /* single camera fills the width, stays 4:3 */
    .be-rtc-dock.be-rtc-fs .be-rtc-dock-cams.two .be-rtc-tile { flex-basis: 100% !important; width: 100% !important; max-width: 100% !important; aspect-ratio: 16 / 9 !important; }   /* exactly 2 cameras → full-width, stacked one under the other */
    /* Name bar overlays the video (instead of eating layout height) so the camera fills the whole tile — fullscreen and corner. */
    .be-rtc-dock.be-rtc-fs .be-rtc-dock-cams .be-rtc-tile .be-rtc-bar,
    .be-rtc-dock:not(.be-rtc-fs) .be-rtc-dock-cams .be-rtc-tile .be-rtc-bar { position: absolute; top: 0; left: 0; right: 0; z-index: 3; background: linear-gradient(180deg, rgba(0,0,0,.6), transparent); }
    /* Forced fullscreen on mobile: hide the follow buttons on tiles (speakers can't initiate following). */
    .be-rtc-dock.be-rtc-fs-locked .be-rtc-tbtn[data-t="finvite"], .be-rtc-dock.be-rtc-fs-locked .be-rtc-tbtn[data-t="freq"] { display: none; }
    /* Reorder tiles in the fullscreen dock by dragging their name-bar (touch); the rest of the tile still scrolls the list. */
    .be-rtc-dock.be-rtc-fs .be-rtc-bar { touch-action: none; cursor: grab; }
    .be-rtc-dock.be-rtc-fs .be-rtc-tile.be-rtc-dragtile { opacity: .75; outline: 2px solid var(--gold, #cba74e); outline-offset: -2px; z-index: 5; }
    /* Mobile: stack screen shares VERTICALLY (not side-by-side) — body becomes a column, screens full-width, no partition. */
    .be-rtc-dock.has-screen .be-rtc-dock-body { flex-direction: column !important; overflow-y: auto !important; }
    .be-rtc-dock.has-screen .be-rtc-dock-body .be-rtc-tile.be-rtc-screen { flex: 0 0 auto !important; width: 100% !important; min-width: 0 !important; aspect-ratio: 16 / 9; }
    .be-rtc-dock.has-screen .be-rtc-split { display: none !important; }
    .be-rtc-dock.has-screen .be-rtc-dock-cams { flex: 0 0 auto !important; width: 100% !important; }
}
/* ---- Pop-out (Document PiP) window: a DESKTOP surface no matter how small the user makes it ----
   The cloned stylesheets are evaluated against the PIP window's own width, so a 640px pop-out matched the ≤700px
   phone block: the screen share and the cameras stacked vertically and the fit-grid rules (gated at ≥701px) never
   applied. These rules re-assert the desktop arrangement for `.be-rtc-pip` only — cameras ALWAYS in a column on the
   right of the screen share — and are deliberately placed after both media blocks so they win by order too.
   Minimums are relaxed so the window can genuinely be dragged to any size instead of jamming on a wide screen tile. */
.be-rtc-dock.be-rtc-pip.has-screen .be-rtc-dock-body { flex-direction: row !important; align-items: stretch !important; overflow: hidden !important; }
.be-rtc-dock.be-rtc-pip.has-screen .be-rtc-dock-body .be-rtc-tile.be-rtc-screen { flex: 1 1 0 !important; width: auto !important; min-width: 60px !important; min-height: 0 !important; aspect-ratio: auto !important; }
.be-rtc-dock.be-rtc-pip.has-screen .be-rtc-split { display: block !important; }
.be-rtc-dock.be-rtc-pip.has-screen .be-rtc-dock-cams { flex: 0 0 var(--rtc-cams-w, 132px) !important; width: auto !important; min-width: 56px !important;
    flex-direction: column !important; flex-wrap: nowrap !important; overflow-y: auto !important; gap: 6px; }
.be-rtc-dock.be-rtc-pip .be-rtc-dock-cams.be-rtc-fit { display: grid !important; gap: 6px; min-height: 0; overflow: hidden !important; justify-content: center; align-content: center; }
.be-rtc-dock.be-rtc-pip:not(.has-screen) .be-rtc-dock-cams.be-rtc-fit { flex: 1 1 auto !important; }
.be-rtc-dock.be-rtc-pip .be-rtc-dock-cams.be-rtc-fit .be-rtc-tile { flex: none !important; width: 100% !important; height: 100% !important; min-width: 0 !important; min-height: 0 !important; aspect-ratio: auto !important; }
.be-rtc-dock.be-rtc-pip .be-rtc-dock-cams.be-rtc-fit .be-rtc-tile video { width: 100%; height: 100%; object-fit: cover; }
.be-rtc-dock.be-rtc-pip .be-rtc-dock-cams.be-rtc-fit.be-rtc-fit-scroll { overflow-y: auto !important; align-content: start; }

/* ---- Collapsed corner dock = a small pill with a microphone, not an empty grey panel ---- */
.be-rtc-dock-mic { display: none; }
.be-rtc-dock.collapsed { width: auto !important; height: auto !important; min-width: 0 !important; border-radius: 999px; }
.be-rtc-dock.collapsed .be-rtc-dock-head { padding: 4px; gap: 3px; background: transparent; border-radius: 999px; }
.be-rtc-dock.collapsed .be-rtc-dock-title,
.be-rtc-dock.collapsed .be-rtc-dock-btn:not(.be-rtc-dock-mic) { display: none; }
.be-rtc-dock.collapsed .be-rtc-timer { font-size: 11px; padding: 0 8px 0 2px; margin: 0; }
.be-rtc-dock.collapsed .be-rtc-dock-mic { display: inline-flex; width: 34px; height: 34px; border-radius: 50%; background: var(--panel-3, #26262c); color: var(--text); }
.be-rtc-dock.collapsed .be-rtc-dock-mic:hover { background: var(--gold, #cba74e); color: var(--on-gold, #161616); }
.be-rtc-dock.collapsed .be-rtc-dock-mic.live { background: rgba(34,197,94,.18); color: #22c55e; }   /* mic is actually open */

/* Share-board modal — create-link form + link list (responsive: stacks cleanly on mobile). */
.be-share-form { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 12px; }
.be-share-r1 { display: flex; gap: 8px; align-items: center; }   /* download toggle + mode select share one row (button on the left) */
.be-share-form .be-share-sel { max-width: 240px; }
.be-share-form .be-share-pw { max-width: 200px; height: 38px; font-size: 13px; }
.be-share-form .be-share-go { margin-left: auto; }
.be-share-dl { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 38px; padding: 0; border: 1px solid var(--border); border-radius: 9px; background: var(--fill-soft); color: var(--muted); cursor: pointer; }
.be-share-dl:hover { color: var(--text); border-color: var(--gold); }
.be-share-dl.on { background: var(--gold); color: var(--on-gold, #161616); border-color: transparent; }
.be-share-list { display: flex; flex-direction: column; gap: 8px; max-height: 46vh; overflow-y: auto; }
.be-share-link { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 8px 9px; border: 1px solid var(--border); border-radius: 10px; background: var(--fill-soft); }
.be-share-link-url { flex: 1 1 100%; min-width: 0; height: 36px; font-size: 12.5px; font-family: ui-monospace, monospace; }
.be-share-link-tag { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--gold); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.be-share-link-copy { flex: 0 0 auto; }
.be-share-link-del { flex: 0 0 auto; color: var(--danger); }
@media (max-width: 700px) {
    .be-share-form { flex-direction: column; align-items: stretch; }
    .be-share-form .be-share-pw, .be-share-form .be-share-go { max-width: none; width: 100%; margin-left: 0; }
    .be-share-r1 { width: 100%; }
    .be-share-r1 .be-share-sel { flex: 1; width: auto; max-width: none; min-width: 0; }   /* select fills the row next to the 42px button */
    /* Compact link row: тег (режим + скачивание) на строке; ниже «Копировать» слева и «✕» справа. URL прячем — копируется кнопкой. */
    .be-share-link-url { display: none; }
    .be-share-link-tag { flex: 1 1 100%; white-space: normal; }
    .be-share-link-copy { flex: 0 0 auto; }
    .be-share-link-del { margin-left: auto; }
}
/* Pre-join chooser: mic/camera as two horizontal toggle buttons (accent when on, grey when off). */
.be-join-toggles { display: flex; gap: 10px; margin: 4px 0 14px; }
.be-join-tgl { flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 13px 10px;
    border: 1px solid var(--border, #2c2c34); border-radius: 12px; background: var(--fill-soft, #23232a); color: var(--muted, #9a9aa6);
    cursor: pointer; font-size: 14px; font-weight: 600; transition: background .12s, color .12s, border-color .12s; }
.be-join-tgl svg { width: 20px; height: 20px; }
.be-join-tgl:hover { border-color: var(--gold, #cba74e); }
.be-join-tgl.on { background: var(--gold, #cba74e); color: var(--on-gold, #161616); border-color: transparent; }
/* Выбор раскладки камер в окне входа: три КАРТОЧКИ, описание видно у каждой сразу (не только у выбранной).
   Выбранная — золотая рамка + подсвеченный заголовок; заливать целиком нельзя — описание стало бы нечитаемым. */
.be-join-lay { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 0 0 12px; }
.be-join-lay-btn { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; text-align: left; padding: 10px 11px; border: 1px solid var(--border, #2c2c34); border-radius: 10px; background: var(--fill-soft, #23232a); cursor: pointer; transition: border-color .12s, background .12s; }
.be-join-lay-btn svg { width: 46px; height: 32px; color: var(--muted, #9a9aa6); flex: none; }
.be-join-lay-btn.on svg { color: var(--gold, #cba74e); }
.be-join-lay-btn b { font-size: 13px; font-weight: 700; color: var(--text, #e8e8ea); }
.be-join-lay-btn span { font-size: 11.5px; font-weight: 400; color: var(--muted, #9a9aa6); line-height: 1.4; }
.be-join-lay-btn:hover { border-color: var(--gold, #cba74e); }
.be-join-lay-btn.on { border-color: var(--gold, #cba74e); background: color-mix(in srgb, var(--gold, #cba74e) 12%, var(--fill-soft, #23232a)); }
.be-join-lay-btn.on b { color: var(--gold, #cba74e); }
@media (max-width: 700px) { .be-join-lay { grid-template-columns: 1fr; } }   /* телефон: карточки в столбик — описания не ужимаются в нечитаемую колонку */
/* Call-only link: hide the board itself — only the comms dock + join chooser (both on <body>) are shown. */
body.be-call-only #beRoot { display: none !important; }
body.be-call-only { background: var(--bg, #0f0f12); }
.be-call-hint { position: fixed; inset: 0; z-index: 40; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px; color: var(--text, #e8e8ee); }
.be-call-hint-title { font-size: 20px; font-weight: 700; color: var(--gold, #cba74e); }
/* Hidden-monitor audio-level meter on speaker tiles (jumping bars: is there sound and how loud). */
/* Sound + connection-quality bars grouped in the BOTTOM-LEFT of camera tiles; shown via the toggle (monitor / admin). */
.be-rtc-status { position: absolute; left: 6px; bottom: 6px; z-index: 5; display: none; gap: 6px; align-items: flex-end; pointer-events: none; }
body.be-show-quality .be-rtc-status { display: flex; }
.be-rtc-meter { display: flex; align-items: flex-end; gap: 2px; height: 18px; padding: 3px 5px; background: rgba(0,0,0,.42); border-radius: 5px; }
.be-rtc-meter span { flex: 0 0 4px; width: 4px; height: 4px; background: rgba(255,255,255,.35); border-radius: 1px; transition: height .08s linear, background .08s linear; }
.be-rtc-meter span.on { background: #22c55e; height: 11px; }
/* Connection-quality signal bars — hidden unless monitor mode or the admin/subadmin toggle is on (class on <body>). */
.be-rtc-q { display: flex; align-items: flex-end; gap: 3px; height: 18px; padding: 3px 6px; background: rgba(0,0,0,.45); border-radius: 6px; }
.be-rtc-q span { flex: 0 0 4px; width: 4px; border-radius: 1px; background: rgba(255,255,255,.4); }
.be-rtc-q span:nth-child(1) { height: 4px; } .be-rtc-q span:nth-child(2) { height: 6px; } .be-rtc-q span:nth-child(3) { height: 8px; }
.be-rtc-tile[data-q="excellent"] .be-rtc-q span { background: #46d369; }
.be-rtc-tile[data-q="good"] .be-rtc-q span:nth-child(-n+2) { background: #46d369; }
.be-rtc-tile[data-q="poor"] .be-rtc-q span:nth-child(1) { background: #f0a23a; }
.be-rtc-tile[data-q="lost"] .be-rtc-q span:nth-child(1) { background: #e2575c; }
/* Chat overlay inside the fullscreen comms dock (so chat stays visible while the dock covers the screen). */
.be-rtc-fschat { position: absolute; left: 12px; bottom: 12px; z-index: 6; display: flex; flex-direction: column; gap: 5px; max-width: min(72%, 540px); pointer-events: none; }
.be-rtc-fschat-line { background: rgba(0,0,0,.62); color: #fff; font-size: 13px; line-height: 1.3; padding: 5px 10px; border-radius: 9px; word-break: break-word; }
.be-rtc-fschat-line b { color: var(--gold, #cba74e); font-weight: 600; }
/* Speaking highlight on the video tile — works BOTH in the corner dock and on the board (canvas). */
.be-rtc-tile.be-spk { outline: 3px solid #22c55e; outline-offset: -1px; box-shadow: 0 0 0 4px rgba(34,197,94,.4), 0 6px 22px rgba(0,0,0,.5); }
.be-rtc-dock-body .be-rtc-tile .be-rtc-resize { display: none; }
.be-rtc-dock-body .be-rtc-bar { cursor: default; }
.be-rtc-dock-resize { position: absolute; left: 0; top: 0; width: 18px; height: 18px; cursor: nwse-resize; z-index: 6; touch-action: none; }
.be-rtc-dock-resize::after { content: ''; position: absolute; left: 4px; top: 4px; width: 8px; height: 8px; border-left: 2px solid var(--muted); border-top: 2px solid var(--muted); border-top-left-radius: 2px; }
/* Touch: a bigger, clearly visible grab corner so the dock can actually be resized on phones/tablets. */
@media (max-width: 700px), (pointer: coarse) {
    .be-rtc-dock-resize { width: 34px; height: 34px; }
    .be-rtc-dock-resize::after { left: 7px; top: 7px; width: 14px; height: 14px; border-left: 3px solid var(--gold, #cba74e); border-top: 3px solid var(--gold, #cba74e); }
    /* keep the title clear of the bigger touch resize corner (top-left), but tucked close to it */
    .be-rtc-dock:not(.collapsed):not(.be-rtc-fs) .be-rtc-dock-head { padding-left: 26px; }
}
@media (max-width: 700px) { .be-rtc-dock { width: 210px; right: 8px; bottom: 8px; } }
.be-feat-off:hover { color: #ef4444; }
.be-btn.be-feat-disabled { color: var(--muted-2); opacity: .55; }
.be-btn.be-feat-disabled:hover { opacity: .9; color: var(--text); }
/* Comment list items styled like the notifications list: clean rows, hover, gold tint when unseen. */
.be-citem { border: none; border-radius: var(--radius-sm); padding: 9px 10px; background: transparent; cursor: pointer; }
.be-citem.be-citem-unseen { background: color-mix(in srgb, var(--danger) 14%, transparent); border-left: 3px solid var(--danger); }
.be-citem.resolved { opacity: .55; }
.be-citem-head { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }   /* icon (fixed left) → «новый» badge → title; date floats right */
.be-citem-author { font-size: 12px; font-weight: 600; color: var(--text); }
.be-citem-date { font-size: 10px; color: var(--muted-2); margin-left: auto; }
.be-citem-new { margin-right: 0; }   /* sits right after the icon, before the title */
.be-citem-text { font-size: 12px; color: var(--muted); line-height: 1.4; white-space: pre-wrap; word-break: break-word; }
.be-citem-actions { display: flex; gap: 6px; margin-top: 6px; }
/* Threaded replies in the comments panel */
.be-reply-toggle { margin-top: 8px; background: none; border: none; color: var(--gold); font-size: 11px; cursor: pointer; padding: 2px 0; }
.be-reply-toggle:hover { text-decoration: underline; }
.be-replies { margin-top: 8px; border-top: 1px solid var(--border); padding-top: 10px; display: flex; flex-direction: column; gap: 4px; }
.be-reply-load { font-size: 11px; color: var(--muted-2); }
.be-creply { background: var(--panel-3, rgba(255,255,255,.03)); border-radius: var(--radius-xs); padding: 9px 11px; border-left: 2px solid var(--border-strong); }
.be-creply-head { display: flex; align-items: center; gap: 6px; margin-bottom: 2px; }
.be-creply-author { font-size: 11px; font-weight: 600; color: var(--text); margin-right: auto; }
.be-creply-date { font-size: 10px; color: var(--muted-2); }
.be-creply-del { flex: none; background: none; border: none; color: var(--muted-2); cursor: pointer; padding: 1px 3px; border-radius: 4px; line-height: 0; }
.be-creply-del:hover { color: var(--danger); background: var(--fill-soft); }
.be-creply-text { font-size: 12px; color: var(--muted); line-height: 1.4; white-space: pre-wrap; word-break: break-word; }
/* Light tone: the panel flips text colours to dark but --panel-3 (the bubble bg) stays dark → dark-on-dark.
   Give the reply bubble a light background so the author + text are readable. */
body.be-canvas-light .be-creply { background: #ececf0; border-left-color: rgba(0,0,0,.18); }
.be-reply-form { display: flex; flex-direction: column; gap: 6px; }
.be-reply-input { width: 100%; font-size: 12px; padding: 8px 10px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 10px; color: var(--text); resize: vertical; box-sizing: border-box; outline: none; transition: border-color var(--transition); }
.be-reply-input:focus { outline: none; border-color: var(--border-strong); box-shadow: none; }
.be-reply-send { align-self: flex-end; background: var(--gold); color: var(--on-gold, #1a1712); border: none; border-radius: var(--radius-xs); padding: 5px 12px; font-size: 12px; font-weight: 600; cursor: pointer; }
.be-reply-send:disabled { opacity: .6; cursor: default; }
.be-cpager { display: flex; align-items: center; justify-content: center; gap: 12px; padding: 8px 0 2px; font-size: 12px; color: var(--muted); }
.be-cpager button { width: 30px; height: 28px; border-radius: var(--radius-xs); border: 1px solid var(--border); background: var(--panel-2); color: var(--text); cursor: pointer; font-size: 16px; }
.be-cpager button:disabled { opacity: .4; cursor: default; }
.be-citem-actions button { font-size: 11px; padding: 3px 8px; border-radius: var(--radius-sm); border: 1px solid var(--border); background: transparent; color: var(--muted); cursor: pointer; }
.be-citem-actions button:hover { background: var(--fill-soft); color: var(--text); }
.be-citem-actions button.danger:hover { color: var(--danger); }

/* Admin impersonation banner */
.impersonate-banner {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    background: var(--gold-bg); color: var(--gold); border-bottom: 1px solid var(--border);
    padding: 8px 16px; font-size: 13px;
}
.impersonate-banner b { color: var(--text); }
.impersonate-banner button {
    background: var(--gold); color: var(--on-gold, #1a1712); border: none; cursor: pointer;
    padding: 4px 12px; border-radius: var(--radius-sm); font-size: 12px; font-weight: 600;
}
.impersonate-banner button:hover { filter: brightness(1.08); }

/* Admin-authored global notice banner (shown on every portal page, like the storage-limit notice) */
/* One fixed, theme-independent look everywhere — portal, dashboard AND boards, in any tone. Never changes color. */
/* One identical bar everywhere. BOTH variants are position:fixed so the centred text lands at true viewport centre
   on every page — a page scrollbar can't shift it (which is what made the dashboard→board jump happen). */
.portal-notice, .portal-notice-fixed {
    position: fixed; top: 0; left: 0; right: 0; z-index: 100002;
    display: flex; align-items: center; justify-content: center; gap: 9px;
    background: #f6ecd4; border-bottom: 1px solid rgba(0,0,0,.1); padding: 9px 16px;
    font-size: 13px; line-height: 1.35; text-align: center; white-space: nowrap;
}
.portal-notice svg, .portal-notice-fixed svg { flex: none; color: #cf971f; filter: none; }
.portal-notice span, .portal-notice-fixed span { color: #3a3026; font-weight: 500; text-shadow: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Push the page content below the fixed bar (board uses .be-root's top; other pages push the next block). */
.portal-notice-fixed ~ .be-root { top: 38px; }
.portal-notice:not(.portal-notice-fixed) + * { margin-top: 38px; }
/* Same banner inside the admin live-preview */
.tp-notice {
    display: flex; align-items: center; justify-content: center; gap: 6px;
    background: rgba(245,158,11,.14); color: var(--tp-text, #1a1a1e);
    border-bottom: 1px solid var(--tp-border, rgba(0,0,0,.1)); padding: 5px 10px; font-size: 11px;
    text-align: center; white-space: pre-wrap;
}

/* Generic icon button used in bars */
.be-btn {
    height: 36px; min-width: 36px; padding: 0 10px; border-radius: var(--radius-sm); border: none;
    background: transparent; color: var(--muted); display: inline-flex; align-items: center; gap: 6px;
    justify-content: center; transition: all var(--transition); font-size: 12px;
}
.be-btn:hover { background: var(--fill-soft); color: var(--text); }
/* Top-bar action icons read clearly over light photos/video (was the faint --muted). */
.be-topbar .be-btn { color: var(--text); }
.be-btn:disabled { opacity: .35; cursor: default; pointer-events: none; }
.be-btn svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.be-btn.danger:hover { color: var(--danger); }

/* ---- Properties bar (appears on selection, bottom-center) ---- */
.be-props {
    position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%); z-index: 25;   /* above #beOverlay (z-21) so resize handles don't cover the props panel */
    display: none; flex-direction: column; align-items: center; justify-content: center; gap: 6px; padding: 6px;
    width: max-content; max-width: min(96vw, 1300px);
    background: var(--popover-bg); border: 1px solid var(--border-ring);
    border-radius: var(--radius-md); box-shadow: var(--shadow-md); backdrop-filter: blur(8px);
}
/* Two logical rows: (1) text & colour, (2) frame/shape & actions.
   Keep each row on ONE line — the panel widens (width:max-content) to fit instead of wrapping controls
   onto extra rows. */
.be-props-row { display: flex; align-items: flex-start; justify-content: center; gap: 4px; flex-wrap: nowrap; }
.be-props-row:empty { display: none; }
/* 3rd (full-width) row: its label sits next to one control, so centre them vertically
   (rows 1-2 are top-aligned for the slider/caption layout, which we don't want here). */
#beExtraRow, #beExtraRow .be-media-ctrls { align-items: center; }
/* Keep each control group intact on one line so wrapping splits between groups, not inside them */
.be-swatches, .be-text-ctrls, .be-shape-ctrls { flex-wrap: nowrap; }
/* Controls NEVER wrap onto a new line — when the panel gets wider than the screen it switches to the mobile bottom
   scroll-strip (.be-force-mstrip) instead. Keeps every block-edit panel a stable single-row-per-group layout. */
.be-media-ctrls { flex-wrap: nowrap; row-gap: 6px; }
.be-props.show { display: flex; }
/* Desktop: when the format panel is wider than the screen, switch it to the SAME bottom scroll-strip layout as real
   mobile (single horizontal row, full width, scrolls). Toggled by JS (syncPropsFit) via `.be-force-mstrip` on the root.
   Panel dropdowns lift into <body> on every platform, so the strip's overflow never clips them. */
.be-root.be-force-mstrip .be-props {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; transform: none; z-index: 30;
    width: 100%; max-width: 100%; max-height: none;
    flex-direction: row !important; flex-wrap: nowrap !important; align-items: center; justify-content: safe center !important; gap: 8px;
    border-radius: 14px 14px 0 0; padding: 12px 14px calc(12px + env(safe-area-inset-bottom, 0px));
    overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; touch-action: pan-x;
    scrollbar-width: none; box-shadow: 0 -8px 24px rgba(0,0,0,.45);
}
.be-root.be-force-mstrip .be-props::-webkit-scrollbar { display: none; }
.be-root.be-force-mstrip .be-props::after { content: ''; flex: 0 0 6px; }
.be-root.be-force-mstrip .be-props-row { display: flex; flex: 0 0 auto; width: auto; align-items: center; flex-wrap: nowrap; gap: 6px; overflow: visible; }
.be-root.be-force-mstrip .be-props .be-swatches, .be-root.be-force-mstrip .be-props .be-text-ctrls, .be-root.be-force-mstrip .be-props .be-shape-ctrls, .be-root.be-force-mstrip .be-props .be-media-ctrls { flex-wrap: nowrap !important; align-items: center; }
.be-root.be-force-mstrip .be-props-row > *, .be-root.be-force-mstrip .be-props .be-text-ctrls > *, .be-root.be-force-mstrip .be-props .be-swatches > *, .be-root.be-force-mstrip .be-props .be-shape-ctrls > *, .be-root.be-force-mstrip .be-props .be-media-ctrls > * { flex-shrink: 0; }
.be-root.be-force-mstrip .be-props .be-props-sep { display: none; }
.be-root.be-force-mstrip .be-props-grab { display: none !important; }
.be-root.be-dragging .be-props { display: none !important; }   /* hide the format bar while dragging a block */
.be-props.be-props-scrolling { opacity: 0; pointer-events: none; transition: opacity .08s ease; }   /* hidden while scrolling/zooming the canvas */
.be-root.be-dragging .be-bar { display: none !important; }     /* hide per-block comment bars while dragging */
.be-root.be-multi .be-el:not([data-unseen="1"]) .be-bar { display: none !important; }   /* group (multi) selection hides per-block bars, but keep UNSEEN ones glowing */
/* Smooth (soft) block movement: a short ease on the dragged node so grid/object snapping glides instead of
   jumping. The selection overlay is hidden during the move so its (instant) handles can't lead the eased block. */
.be-el.be-drag-anim { transition: left .085s cubic-bezier(.22,.61,.36,1), top .085s cubic-bezier(.22,.61,.36,1); }
/* Hide the selection handles/box while dragging (they'd lead the smoothly-eased block). The snap guide lines
   live in #beSnapGuides (separate layer), so they stay visible — that's the alignment feedback while moving. */
.be-root.be-dragging #beOverlay { opacity: 0; }
.be-props-grab { display: none; }   /* mobile-only grab handle (bottom sheet) — shown in the 640px media query */
/* Uniform 30×30 hit/background size for every button in the block panels (matches .be-fmt-btn) */
.be-props .be-btn { height: 30px; min-width: 30px; padding: 0 7px; }
.be-props .be-fmt-btn, .be-props .be-dd-trig { width: 30px; min-width: 30px; height: 30px; }
/* Floating block panel: positioned above the selected element (left/top set inline by JS) */
.be-props.be-props-float { position: fixed; bottom: auto; transform: none; z-index: 30; animation: be-props-pop .15s ease; overflow: visible; }
/* Drag handle (tab above the float panel) — one-shot move while the block stays selected. */
.be-props.be-props-float .be-props-grip { position: absolute; top: -13px; left: 50%; transform: translateX(-50%); width: 36px; height: 14px; display: flex; align-items: center; justify-content: center; background: var(--popover-bg); border: 1px solid var(--border-ring); border-bottom: none; border-radius: 7px 7px 0 0; color: var(--muted); cursor: grab; touch-action: none; }   /* тень убрана — как у ручки панели стрелки */
.be-props.be-props-float .be-props-grip:hover { color: var(--text); }
.be-props.be-props-dragging { cursor: grabbing; user-select: none; }
.be-props.be-props-dragging .be-props-grip { cursor: grabbing; }
/* Soft fade-in for the under-block edit panel (opacity only — must NOT touch transform, which centres the panel). */
@keyframes be-props-pop { from { opacity: 0; } to { opacity: 1; } }
/* Right-click context menu */
.be-ctx {
    position: fixed; z-index: 100000; min-width: 188px; padding: 6px;
    background: var(--popover-bg); border: 1px solid var(--border-ring);
    border-radius: var(--radius-md); box-shadow: var(--shadow-md); backdrop-filter: blur(8px);
    display: flex; flex-direction: column; gap: 1px;
}
.be-ctx-item {
    display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 11px; border: none; background: none;
    cursor: pointer; color: var(--text); font-size: 13px; text-align: left; border-radius: 7px;
}
.be-ctx-item:hover { background: var(--gold-bg); }
.be-ctx-item svg { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; opacity: .85; }
.be-ctx-item.be-ctx-has-sub { padding-right: 6px; }
.be-ctx-item.be-ctx-has-sub .be-ctx-arrow { margin-left: auto; opacity: .6; }
.be-ctx-submenu { animation: none; }
/* Hotkey remap modal */
.be-hk-list { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 4px; }
.be-hk-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 13px; color: var(--text); }
.be-hk-key { min-width: 96px; font-variant-numeric: tabular-nums; }
.be-hk-key.be-hk-wait { color: var(--gold); }
.be-hk-fixed { font-size: 11px; color: var(--muted); background: var(--panel-3); border: 1px solid var(--line); border-radius: 6px; padding: 3px 8px; white-space: nowrap; }
.be-ctx-item.danger svg { opacity: 1; }
.be-ctx-item.danger { color: var(--danger); }
.be-ctx-item.danger:hover { background: rgba(220,60,60,.12); }
.be-ctx-sep { height: 1px; background: var(--border); margin: 4px; }
.be-ctx-tools { display: flex; gap: 4px; padding: 2px; }
.be-ctx-tool { flex: 1; height: 34px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--border); background: var(--panel-2); border-radius: 7px; cursor: pointer; color: var(--muted); }
.be-ctx-tool:hover { color: var(--text); background: var(--gold-bg); }
.be-ctx-tool.active { color: var(--on-gold); background: var(--gold); border-color: var(--gold); }
.be-ctx-tool svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.be-swatches { display: flex; align-items: flex-start; gap: 4px; padding: 0; }   /* единый шаг 4px, паддинг ломал стык контейнеров */
.be-swatch { width: 22px; height: 22px; border-radius: 50%; border: 1px solid rgba(128,128,128,.45); cursor: pointer; box-sizing: border-box; }   /* subtle neutral ring — readable on dark AND light */
.be-swatch:hover { transform: scale(1.12); }
.be-swatch.active { border-color: var(--text); box-shadow: 0 0 0 1px var(--text); }
/* «No colour» preset — diagonal hatch = transparent (opacity 0) */
.be-swatch-none { background: repeating-linear-gradient(45deg, rgba(130,130,140,.6) 0 2px, transparent 2px 5px); }
.be-props-sep { width: 1px; height: 24px; background: var(--border); margin: 0; }
/* Keep the layer/delete icons in a tight cluster (no separators, small gap) */
.be-props .be-props-sep { display: none; }
.be-props #beFront, .be-props #beBack, .be-props #beDelete { margin: 0; }
.be-text-ctrls { display: flex; align-items: flex-start; gap: 4px; }   /* единый шаг 4px во всех строках панели */
.be-fmt-btn {
    width: 30px; height: 30px; border-radius: var(--radius-sm); border: none; background: transparent;
    color: var(--text); font-size: 14px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
}
.be-fmt-btn:hover { background: var(--fill-soft); }
.be-fmt-btn.active { background: var(--gold-bg); color: var(--gold); }
/* Idle selector/toolbar buttons (line form, arrowhead form, B/I/U folds, etc.) get a subtle dark fill so the rounded
   button is visible even when not selected. Hover/active still brighten (selectors below keep matching specificity). */
.be-conn-pop .be-btn:not(.primary):not(.danger),
.be-conn-pop .be-fmt-btn:not(.active),
.be-conn-pop .be-dd-trig,
.be-conn-style-menu .be-btn:not(.primary),
.be-props .be-fmt-btn:not(.active),
.be-props .be-ctl-top > .be-btn,
.be-props .be-dd-trig { background: var(--panel-3); box-shadow: inset 0 0 0 1px rgba(255,255,255,.06); }   /* обводка НЕяркая (было .14) */
/* Кнопки в меню групп (подняты в <body>, селекторы .be-props их не достают) — та же тусклая обводка */
.be-grp-body .be-fmt-btn:not(.active), .be-grp-body .be-ctl-top > .be-btn, .be-grp-body .be-dd-trig { background: var(--panel-3); box-shadow: inset 0 0 0 1px rgba(255,255,255,.06); }
.be-grp-body .be-fmt-btn:not(.active):hover, .be-grp-body .be-ctl-top > .be-btn:hover, .be-grp-body .be-dd-trig:hover { background: var(--panel-hover); }
.be-conn-pop .be-btn:not(.primary):not(.danger):hover,
.be-conn-pop .be-fmt-btn:not(.active):hover,
.be-conn-pop .be-dd-trig:hover,
.be-conn-style-menu .be-btn:not(.primary):hover,
.be-props .be-fmt-btn:not(.active):hover,
.be-props .be-ctl-top > .be-btn:hover,
.be-props .be-dd-trig:hover { background: var(--panel-hover); }
.be-root.be-canvas-light .be-conn-pop .be-btn:not(.primary):not(.danger),
.be-root.be-canvas-light .be-conn-pop .be-fmt-btn:not(.active),
.be-root.be-canvas-light .be-conn-pop .be-dd-trig,
.be-root.be-canvas-light .be-conn-style-menu .be-btn:not(.primary),
.be-root.be-canvas-light .be-props .be-fmt-btn:not(.active),
.be-root.be-canvas-light .be-props .be-ctl-top > .be-btn,
.be-root.be-canvas-light .be-props .be-dd-trig { background: rgba(0,0,0,.05) !important; box-shadow: inset 0 0 0 1px rgba(0,0,0,.07) !important; }
body.be-canvas-light .be-grp-body .be-fmt-btn:not(.active), body.be-canvas-light .be-grp-body .be-ctl-top > .be-btn, body.be-canvas-light .be-grp-body .be-dd-trig { background: rgba(0,0,0,.05) !important; box-shadow: inset 0 0 0 1px rgba(0,0,0,.07) !important; }
/* …but NOT the colour-picker trigger — its swatch shows the colour; an oval behind it looks wrong. (Both tones.) */
.be-dd-colors .be-dd-trig { width: 30px !important; min-width: 30px !important; height: 30px; padding: 0; }   /* шарик в стандартной кнопке, как вся панель */
/* Connector label «Вид»: pill / along-line toggles share ONE grey подложка (segmented control). */
.be-lblsty-grp { display: inline-flex; align-items: center; gap: 2px; height: 30px; border-radius: var(--radius-sm); }
.be-conn-pop .be-lblsty-grp { background: var(--panel-3); box-shadow: inset 0 0 0 1px var(--border-ring, rgba(255,255,255,.14)); }
.be-conn-pop .be-lblsty-grp .be-btn:not(.primary) { background: transparent !important; box-shadow: none !important; }
.be-root.be-canvas-light .be-conn-pop .be-lblsty-grp { background: rgba(0,0,0,.06) !important; }
.be-fmt-btn > span { display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
.be-fmt-btn svg { display: block; }
.be-fmt-select {
    height: 30px; border-radius: var(--radius-sm); border: 1px solid var(--line);
    background: var(--panel-3); color: var(--text); font-size: 12px; padding: 0 18px 0 6px; cursor: pointer; outline: none;
    /* Custom light arrow — the native <select> arrow renders dark on the dark panel (esp. iOS). */
    -webkit-appearance: none; -moz-appearance: none; appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23c5c9d4' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 5px center; background-size: 9px 6px;
}
/* Plain numeric field (W×H size etc.) — portal style, no select chevron, no OS spinner. */
.be-num-input { height: 30px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--panel-3); color: var(--text); font-size: 12px; padding: 0 6px; outline: none; box-sizing: border-box; -webkit-appearance: none; appearance: textfield; }
.be-num-input:focus { border-color: var(--gold); }
.be-fmt-size { width: 54px; text-align: center; cursor: text; }   /* font-size field in the text toolbar (typeable) */
.be-props #beFront, .be-props #beBack { width: 38px; height: 38px; }
.be-props #beFront svg, .be-props #beBack svg { width: 21px; height: 21px; }

/* Caption below a geometric shape (like a connector label) */
.be-shape-label {
    order: 1; align-self: center; max-width: 100%; padding: 2px 9px; border-radius: 7px;
    background: var(--panel-2); border: 1px solid var(--border); color: var(--text);
    font-size: 12px; line-height: 1.3; text-align: center;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none;
}
.be-shape-label-input {
    height: 30px; min-width: 130px; border-radius: var(--radius-sm); border: 1px solid var(--line);
    background: var(--bg); color: var(--text); font-size: 12px; padding: 0 8px; outline: none;   /* dark like the connector caption (.form-input) */
}

/* Shape controls — fill opacity */
.be-shape-ctrls { display: flex; align-items: flex-start; gap: 4px; }
.be-fill-op { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; padding: 0 4px; }
.be-fill-op-ic { display: inline-flex; align-items: center; color: var(--muted); }
.be-fill-op-ic svg { display: block; }
.be-fill-range {
    -webkit-appearance: none; appearance: none; width: 92px; height: 4px;
    border-radius: 2px; background: var(--line); outline: none; cursor: pointer; margin: 0;
}
.be-fill-range::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none; width: 14px; height: 14px; border-radius: 50%;
    background: var(--gold); border: 2px solid var(--panel-2); cursor: pointer;
}
.be-fill-range::-moz-range-thumb {
    width: 14px; height: 14px; border-radius: 50%; background: var(--gold);
    border: 2px solid var(--panel-2); cursor: pointer;
}
.be-fill-val { font-size: 12px; color: var(--muted); min-width: 34px; text-align: right; font-variant-numeric: tabular-nums; }

/* ---- Stickers panel ---- */
.be-sticker-panel {
    position: absolute; left: 64px; top: 50%; transform: translateY(-50%); z-index: 25;
    width: 300px; max-height: 72vh; display: none; flex-direction: column;
    background: var(--popover-bg); border: 1px solid var(--border-ring);
    border-radius: var(--radius-md); box-shadow: var(--shadow-lg); backdrop-filter: blur(8px);
}
.be-sticker-panel.open { display: flex; }
.be-sticker-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 10px 10px 10px 14px; border-bottom: 1px solid var(--border);
    font-size: 13px; font-weight: 600; color: var(--text);
}
.be-sticker-body { padding: 10px 12px; overflow-y: auto; flex: 1; }
.be-sticker-loading, .be-sticker-empty { color: var(--muted); font-size: 13px; padding: 16px 4px; text-align: center; }
/* Games panel tiles (mini-games + Sega ROMs) — reuses the sticker panel container. */
.be-games-sech { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin: 4px 2px 8px; }
.be-games-sech:not(:first-child) { margin-top: 14px; }
.be-games-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.be-game-tile { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; aspect-ratio: 1 / 1; min-width: 0; overflow: hidden; padding: 8px 4px; border: 1px solid var(--border); border-radius: 10px; background: var(--fill-soft, rgba(255,255,255,.04)); color: var(--text); cursor: pointer; }
.be-games-grid > .be-game-tile { min-width: 0; }
.be-game-tile:hover { border-color: var(--gold, #cba74e); background: var(--panel-3, rgba(255,255,255,.08)); }
.be-game-ico svg { width: 30px; height: 30px; display: block; }
.be-game-name { font-size: 12px; line-height: 1.2; text-align: center; max-width: 100%; overflow: hidden; word-break: break-word; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.be-sticker-group { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted-2); margin: 6px 2px 6px; }
/* Sticker group switcher (tabs) at the top of the panel */
.be-sticker-tabs { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 8px; margin-bottom: 6px; border-bottom: 1px solid var(--border); scrollbar-width: thin; -webkit-overflow-scrolling: touch; }
.be-sticker-tabs::-webkit-scrollbar { height: 5px; }
.be-sticker-tabs::-webkit-scrollbar-thumb { background: var(--border-strong, #4a4a52); border-radius: 3px; }
.be-sticker-tabs > * { flex-shrink: 0; }   /* keep group tabs full-size so the row scrolls instead of squishing */
.be-sticker-tab { flex: 0 0 auto; padding: 4px 11px; border-radius: 999px; border: 1px solid var(--border); background: var(--panel-2); color: var(--muted); font-size: 12px; cursor: pointer; white-space: nowrap; transition: background .12s, color .12s; }
.be-sticker-tab:hover { color: var(--text); }
.be-sticker-tab.active { background: var(--gold); color: var(--on-gold); border-color: var(--gold); }
.be-sticker-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 8px; }
.be-sticker-cell {
    position: relative; aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
    background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-sm);
    cursor: pointer; padding: 6px; transition: all var(--transition);
}
.be-sticker-cell:hover { border-color: var(--gold); background: var(--fill-soft); }
.be-sticker-cell img { max-width: 100%; max-height: 100%; object-fit: contain; pointer-events: none; }
.be-sticker-subgroup { font-size: 10.5px; color: var(--muted); margin: 2px 2px 6px; padding-left: 2px; border-left: 2px solid var(--border-strong); }
.be-sticker-more {
    width: 100%; margin: 0 0 10px; padding: 7px; border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--panel-2); color: var(--muted); font-size: 12px; cursor: pointer; transition: all var(--transition);
}
.be-sticker-more:hover { color: var(--text); border-color: var(--muted); background: var(--fill-soft); }
/* Generic icon button (admin panel etc.; dashboard/boards override sizes inline). Ensures SVG/glyph is centered. */
.icon-action {
    width: 28px; height: 28px; border-radius: var(--radius-xs); border: 1px solid var(--line);
    background: var(--panel-3); color: var(--muted); cursor: pointer; padding: 0;
    display: inline-flex; align-items: center; justify-content: center; transition: all var(--transition);
}
.icon-action:hover { color: var(--text); border-color: var(--muted); }
.icon-action svg { width: 15px; height: 15px; flex: none; }   /* uniform glyph size across folder/board/video cards */
/* folder, board & video card footers — identical button size + spacing (never shrink → wrap instead) */
.project-card-footer .icon-action { width: 28px !important; height: 28px !important; flex: 0 0 auto !important; }
.project-card-footer .icon-action svg { width: 15px !important; height: 15px !important; }
.project-card-footer .board-card-actions { gap: 6px !important; }
.icon-action.danger:hover { color: var(--danger); border-color: var(--danger); }
/* Card status badge + status menu — shared by the boards and projects grids (was duplicated inline per page). */
.be-status-badge { position: absolute; top: 10px; right: 10px; font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: 999px; z-index: 1; }
.st-discussion { background: #3a3a44; color: #e6e6ee; }
.st-in_progress { background: #caa84e; color: #231d07; }
.st-done { background: #3fa05a; color: #fff; }
.st-draft { background: #46506a; color: #d6deec; }
.st-trash { background: #6e3a3a; color: #f0d4d2; }
.status-menu { position: fixed; background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: 0 8px 28px rgba(0,0,0,.45); z-index: 1000; overflow: hidden; min-width: 160px; }
.status-menu button { display: block; width: 100%; text-align: left; padding: 9px 14px; background: none; border: none; color: var(--text); font-size: 13px; cursor: pointer; }
.status-menu button:hover { background: var(--panel-3); }
/* Folder navigation (projects + boards): breadcrumbs and folder cards */
.folder-crumbs { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-bottom: 18px; font-size: 13px; }
.folder-crumbs a { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); text-decoration: none; padding: 3px 8px; border-radius: var(--radius-xs); }
.folder-crumbs a:hover { color: var(--text); background: var(--panel-2); }
.folder-crumbs a.cur { color: var(--text); font-weight: 600; }
.folder-crumbs .sep { color: var(--muted-2); }
.folder-card-icon { height: 96px; display: flex; align-items: center; justify-content: center; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-md); margin-bottom: 0; }
/* Collapsible admin cards */
.card-collapse-btn { background: none; border: none; color: var(--muted); cursor: pointer; padding: 2px 4px; display: inline-flex; align-items: center; }
.card-collapse-btn:hover { color: var(--text); }
.card-collapse-btn svg { transition: transform .2s ease; }
.card.collapsed .card-collapse-btn svg { transform: rotate(-90deg); }
.card.collapsed .ac-collapse { display: none; }
.be-sticker-acts { position: absolute; top: 3px; right: 3px; display: none; gap: 3px; z-index: 2; }
.be-sticker-cell:hover .be-sticker-acts { display: flex; }
.be-sticker-act {
    width: 19px; height: 19px; border-radius: 50%; border: none; color: #fff;
    background: rgba(20,20,24,.85); display: flex; align-items: center; justify-content: center;
    cursor: pointer; box-shadow: var(--shadow-sm); padding: 0;
}
.be-sticker-act:hover { background: var(--gold); color: var(--on-gold); }
.be-sticker-act.be-sticker-del:hover { background: var(--danger, #ef4444); color: #fff; }
.be-sticker-foot {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    padding: 10px 12px; border-top: 1px solid var(--border);
}

/* ---- Alignment bar (multi-selection, top-center) ---- */
.be-align-bar {
    position: absolute; top: 70px; left: 50%; transform: translateX(-50%); z-index: 20;
    display: none; align-items: center; gap: 3px; padding: 6px;
    background: var(--popover-bg); border: 1px solid var(--border-ring);
    border-radius: var(--radius-md); box-shadow: var(--shadow-md); backdrop-filter: blur(8px);
}
.be-align-bar.show { display: flex; }
.be-align-bar .be-fmt-btn.disabled { opacity: .3; pointer-events: none; }
.be-align-bar .be-fmt-btn svg { width: 19px; height: 19px; }
/* Draggable % resize pill (drag left/right to scale the selection) */
.be-align-scale { display: flex; align-items: center; gap: 5px; height: 30px; padding: 0 8px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--panel-3); color: var(--text); font-size: 12px; font-weight: 600; cursor: ew-resize; user-select: none; touch-action: none; }
.be-align-scale svg { width: 15px; height: 15px; opacity: .65; }
.be-align-scale span { min-width: 36px; text-align: center; }
.be-align-scale.dragging, .be-align-scale:hover { border-color: var(--gold); }
/* Calendar day cell */
.be-el[data-type="day"] .be-el-inner { padding: 0; position: relative; }
.be-day-n { line-height: 1; pointer-events: none; }
.be-day-wd { position: absolute; top: 3px; left: 4px; font-size: 8px; font-weight: 700; opacity: .8; pointer-events: none; }
.be-day-badge { position: absolute; top: 3px; right: 3px; width: 10px; height: 10px; pointer-events: none; }
.be-day-badge svg { width: 100%; height: 100%; display: block; }

/* Group (multi-selection) bounding box */
.be-group-box { position: absolute; border: 1.5px dashed var(--gold, #cba74e); background: rgba(203,167,78,.06); pointer-events: none; box-sizing: border-box; z-index: 9; }

/* While dragging a connector, hide the format bar + per-block comment/extra panels so they don't get in the way */
body.be-connecting .be-props,
body.be-connecting .be-belowstack { display: none !important; }
/* …and let media blocks act as ONE flat drop target: the native <video> controls, embeds and the custom video
   bar otherwise swallow the pointer, so an arrow dragged onto a clip wouldn't attach and just hung over it. */
body.be-connecting .be-el video,
body.be-connecting .be-el iframe,
body.be-connecting .be-el .be-vid-bar { pointer-events: none !important; }
/* «Залипание» конца коннектора после удержания 2с — пульсирующая точка (золотая над блоком, синяя на канвасе). */
.be-conn-pinhint { position: fixed; width: 16px; height: 16px; margin: -8px 0 0 -8px; border-radius: 50%; background: rgba(78,163,255,.35); border: 2px solid #4ea3ff; pointer-events: none; z-index: 100000; animation: beConnPin .8s ease-in-out infinite; }
.be-conn-pinhint.on-block { border-color: var(--gold, #cba74e); background: rgba(203,167,78,.4); }
@keyframes beConnPin { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.55); } }

/* ---- Insert dialogs (calendar / map) ---- */
.be-ins-ov { position: fixed; inset: 0; z-index: 2000; background: rgba(0,0,0,.55); display: flex; align-items: center; justify-content: center; padding: 16px; backdrop-filter: blur(2px); }
.be-ins-box { width: 100%; background: var(--popover-bg, #16161a); color: var(--text); border: 1px solid var(--border-ring, #34343d); border-radius: var(--radius-md, 12px); box-shadow: var(--shadow-lg); padding: 18px; box-sizing: border-box; }
.be-ins-title { font-size: 15px; font-weight: 700; color: var(--text); }
.be-ins-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
.be-map-search { display: flex; gap: 8px; margin: 14px 0 8px; }
.be-map-search .be-map-q { flex: 1; }
.be-map-results { max-height: 168px; overflow-y: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); margin-bottom: 10px; background: var(--panel-2); }
.be-map-r { padding: 8px 11px; font-size: 13px; color: var(--text); cursor: pointer; border-bottom: 1px solid var(--border); }
.be-map-r:last-child { border-bottom: none; }
.be-map-r:hover { background: var(--fill-soft); }
.be-map-r-empty { padding: 12px; font-size: 13px; color: var(--muted); text-align: center; }
.be-map-view { position: relative; overflow: hidden; border-radius: var(--radius-sm); border: 1px solid var(--border-ring); background: #e9e7e1; cursor: grab; max-width: 100%; touch-action: none; }
.be-map-view:active { cursor: grabbing; }
.be-map-tiles { position: absolute; inset: 0; }
.be-map-tiles img { user-select: none; }
.be-map-cross { position: absolute; left: 50%; top: 50%; width: 16px; height: 16px; margin: -8px 0 0 -8px; pointer-events: none; }
.be-map-cross::before, .be-map-cross::after { content: ''; position: absolute; background: rgba(203,40,40,.9); }
.be-map-cross::before { left: 7px; top: 0; width: 2px; height: 16px; }
.be-map-cross::after { top: 7px; left: 0; height: 2px; width: 16px; }
.be-map-zoom { position: absolute; right: 8px; top: 8px; display: flex; flex-direction: column; gap: 4px; }
.be-map-zoom button { width: 30px; height: 30px; border: none; border-radius: 7px; background: rgba(20,20,24,.86); color: #fff; font-size: 19px; line-height: 1; cursor: pointer; box-shadow: 0 2px 8px rgba(0,0,0,.3); }
.be-map-zoom button:hover { background: rgba(20,20,24,1); }
.be-map-attr { position: absolute; right: 0; bottom: 0; font-size: 10px; color: #333; background: rgba(255,255,255,.7); padding: 1px 5px; border-top-left-radius: 5px; pointer-events: none; }
.be-map-busy { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; background: rgba(10,10,12,.72); color: #fff; font-size: 13px; z-index: 6; }
.be-map-note { font-size: 12px; color: var(--muted); margin: 8px 2px 0; line-height: 1.4; }

/* ---- Table block ---- */
.be-el[data-type="table"] .be-el-inner { padding: 0; }   /* border/radius/overflow set inline per block */
.be-table { display: grid; width: 100%; height: 100%; }
.be-tcell {                                              /* border / font / margin applied inline (block-level) */
    display: flex; flex-direction: column; justify-content: flex-start;
    /* Общий отступ содержимого ячейки — настройка блока (props.cellPad) через переменную; 4/6px = прежний вид. */
    padding: var(--tcell-pad-y, 4px) var(--tcell-pad-x, 6px); min-width: 0; overflow: hidden; box-sizing: border-box;
    line-height: 1.3; word-break: break-word; position: relative;   /* anchor the fitted cell image */
}
/* Storyboard frame: a fixed-ratio box centred in the cell, image cover-cropped to fill it, with a ratio badge. */
.be-tcell-frame { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); max-width: calc(100% - var(--tcell-pad-x, 6px) * 2); max-height: calc(100% - var(--tcell-pad-y, 4px) * 2); overflow: hidden; border-radius: 3px; pointer-events: none; }
/* Сценарный план: угловая кнопка действий ячейки (видна при наведении на ячейку) */
.be-scen-more { position: absolute; top: 2px; right: 2px; width: 16px; height: 16px; padding: 0; border: none;
    border-radius: 5px; background: rgba(128,130,140,.22); color: var(--muted); display: none;
    align-items: center; justify-content: center; cursor: pointer; z-index: 3; }
.be-tcell:hover > .be-scen-more { display: inline-flex; }
.be-scen-more:hover { background: var(--gold-bg, rgba(203,167,78,.3)); color: var(--text); }
.be-tcell-aspect { position: absolute; right: 3px; bottom: 3px; font-size: 10px; line-height: 1; font-weight: 700; color: #fff; background: rgba(0,0,0,.6); padding: 2px 4px; border-radius: 3px; pointer-events: none; letter-spacing: .3px; }
/* Reserved-but-empty frame: a dashed placeholder so the planned shot + its ratio are visible before an image lands. */
.be-tcell-frame-empty { border: 1px dashed rgba(120,140,170,.6); background: rgba(120,140,170,.07); }
/* A cell with ≥2 images → adaptive grid; each tile (mini) has hover copy/delete buttons. Tiles stay interactive even
   inside a pointer-events:none frame (child `auto` overrides), so hover/buttons work while the image passes clicks through. */
.be-tcell-solo { position: absolute; inset: var(--tcell-pad-y, 4px) var(--tcell-pad-x, 6px); }
.be-tcell-grid { position: absolute; inset: var(--tcell-pad-y, 4px) var(--tcell-pad-x, 6px); display: grid; gap: 3px; grid-auto-rows: 1fr; align-content: stretch; }
.be-tcell-grid.be-tcell-grid-asp { grid-auto-rows: 1fr; align-content: stretch; justify-items: center; align-items: center; }
/* «Оригинальный размер»: фото сохраняет пропорции и НИКОГДА не обрезается — если не влезает, уменьшается.
   ⚠ Строки поэтому делят ячейку РОВНЫМИ долями (grid-auto-rows: 1fr), а не тянутся под размер картинок:
   при `min-content` большие фото распирали сетку, и лишнее срезалось краем ячейки. Вписывание даёт
   `object-fit: contain` базового правила — картинка садится внутрь своей доли целиком. */
.be-tcell-grid.be-tcell-grid-orig { grid-auto-rows: 1fr; align-content: stretch; }
/* «Не распределять»: фото стоят ВПЛОТНУЮ друг к другу, а стопка целиком — по центру ячейки по вертикали.
   ⚠ Правило обязано идти ПОСЛЕ `-asp` и `-orig`: у них та же специфичность (два класса), и стоя выше оно
   молча проигрывало — в режиме «оригинальный размер» тумблер вообще ничего не менял. */
.be-tcell-grid.be-tcell-grid-pack { grid-auto-rows: min-content; align-content: center; justify-content: start; justify-items: start; }
/* В «оригинальном размере» высоту плитке даёт САМА картинка (в обычном режиме она растянута по строке
   и позиционирована абсолютно — в min-content-строке такая плитка схлопнулась бы в ноль). */
.be-tcell-grid-orig.be-tcell-grid-pack .be-tcell-mini { height: auto; }
.be-tcell-grid-orig.be-tcell-grid-pack .be-tcell-mimg { position: static; width: 100%; height: auto; max-height: 100%; object-fit: contain; }
/* Перетаскивание фото между колонками ячейки: тянущаяся плитка бледнеет, место вставки подсвечивается краем. */
.be-tcell-dragging { cursor: grabbing; }
.be-tcell-mini.be-tcell-drag { opacity: .45; }
/* Выделенное фото внутри ячейки — та же золотая обводка, что у выделенного блока на ковре. */
.be-tcell-mini.be-cimg-sel { outline: 2px solid var(--gold, #cba74e); outline-offset: 1px; }
/* Колонка ячейки — самостоятельная стопка фото: их количество в колонках может быть РАЗНЫМ (4 и 2). */
.be-tcell-col { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.be-tcell-grid-pack .be-tcell-col { justify-content: center; }
.be-tcell-col.be-tcell-col-drop { outline: 1px dashed var(--gold, #cba74e); outline-offset: 2px; border-radius: 4px; }
/* Панель настроек фото ячейки: та же коробка, что у попапа связи, с местом под ярлычок типа. */
#beCellPhotoType { position: absolute; left: 10px; top: -19px; font-size: 10px; line-height: 1;
    background: var(--popover-bg); border: 1px solid var(--border-ring); border-bottom: none;
    border-radius: 8px 8px 0 0; padding: 3px 9px 4px; letter-spacing: .03em; color: var(--muted); }
.be-tcell-mini.be-tcell-drop-l { box-shadow: inset 3px 0 0 var(--gold, #cba74e); }
.be-tcell-mini.be-tcell-drop-r { box-shadow: inset -3px 0 0 var(--gold, #cba74e); }
.be-tcell-mini { position: relative; width: 100%; height: 100%; overflow: hidden; border-radius: 3px; pointer-events: auto; }
.be-tcell-grid-asp .be-tcell-mini { width: auto; height: auto; max-width: 100%; max-height: 100%; }
.be-tcell-mimg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; pointer-events: none; }
.be-tcell-mimg.be-cover { object-fit: cover; }
/* Кнопки картинки — в ЛЕВОМ верхнем углу: справа сверху сидит кнопка управления ячейкой,
   и они перекрывали друг друга. Значок пропорций — справа снизу, загрузка — слева снизу. */
.be-tcell-mini-btns { position: absolute; top: 2px; left: 2px; display: none; gap: 2px; z-index: 3; }
.be-tcell-mini:hover .be-tcell-mini-btns { display: flex; }
.be-tcell-mini-btn { width: 18px; height: 18px; padding: 0; border: none; border-radius: 5px; background: rgba(0,0,0,.6); color: #fff; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; pointer-events: auto; }
.be-tcell-mini-btn:hover { background: rgba(0,0,0,.85); }
.be-tcell-mini-del:hover { background: rgba(220,60,60,.92); }
.be-tcell-mini-btn svg { width: 12px; height: 12px; display: block; }
/* Cell media chips (audio/video/file dropped into a cell) — compact, below any images/text */
.be-tcell-media { display: flex; flex-direction: column; gap: 3px; width: 100%; margin-top: 3px; pointer-events: auto; }
/* «Звуки» prompt cell — a small duration field pinned to the BOTTOM-LEFT of the cell (always visible). */
.be-cell-sfx { padding-bottom: 26px; }   /* reserve room so the description text never sits under the pinned field */
/* «Музыка»/«Озвучка» cell — an upload button pinned to the BOTTOM-LEFT (like the sfx buttons). */
.be-cell-upl { padding-bottom: 26px; }
.be-cell-up { position: absolute; left: 5px; bottom: 4px; z-index: 2; pointer-events: auto; }
.be-sfx-dur { position: absolute; left: 5px; bottom: 4px; display: flex; align-items: center; gap: 4px; pointer-events: auto; z-index: 2; }
.be-sfx-dur input { width: 52px; height: 24px; box-sizing: border-box; padding: 0 6px; border: 1px solid var(--border, rgba(127,127,127,.4)); border-radius: 6px; background: #2c2c33; color: #e8e8ea; font-size: 11px; }   /* OPAQUE — was translucent → cell content showed through */
.be-sfx-dur input:focus { outline: none; border-color: var(--gold, #cba74e); }
.be-sfx-gen { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; box-sizing: border-box; padding: 0; border: 1px solid var(--border, rgba(127,127,127,.4)); border-radius: 6px; background: #2c2c33; color: var(--gold, #cba74e); cursor: pointer; flex: 0 0 auto; }
.be-sfx-gen:hover { border-color: var(--gold, #cba74e); background: #37373f; }
.be-sfx-gen svg { width: 15px; height: 15px; }
/* Light canvas → opaque LIGHT controls (they sit on light cells). */
.be-root.be-canvas-light .be-sfx-dur input, .be-root.be-canvas-light .be-sfx-gen { background: #eceef3; color: #1a1a1e; border-color: rgba(0,0,0,.18); }
.be-root.be-canvas-light .be-sfx-gen { color: #b5892f; }
.be-root.be-canvas-light .be-sfx-gen:hover { background: #dfe1ea; }
.be-tcell-chip { position: relative; display: flex; align-items: center; gap: 5px; min-height: 22px; padding: 3px 6px; border-radius: 6px; background: rgba(127,127,127,.16); font-size: 11px; line-height: 1.15; cursor: default; }
.be-tcell-chip .be-chip-ic { flex: 0 0 auto; width: 14px; height: 14px; opacity: .8; }
.be-tcell-chip .be-chip-ic svg { width: 100%; height: 100%; display: block; }
.be-tcell-chip .be-chip-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.be-tcell-chip .be-chip-act { flex: 0 0 auto; width: 20px; height: 20px; padding: 0; border: none; border-radius: 50%; background: var(--gold, #cba74e); color: #1a1a1a; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.be-tcell-chip .be-chip-act:hover { filter: brightness(1.08); }
.be-tcell-chip .be-chip-act svg { width: 12px; height: 12px; display: block; }
/* Удаление — обычная кнопка ряда (как воспроизведение/скачивание): плавающий крестик в углу спорил
   с кнопкой «⋮» ячейки. Приглушена, пока на неё не навели, — чтобы не соперничала с действиями. */
.be-tcell-chip .be-chip-act-del { background: rgba(127,127,127,.28); color: var(--text, #e8e8ea); }
.be-tcell-chip .be-chip-act-del:hover { background: rgba(220,60,60,.92); color: #fff; filter: none; }
/* ⚠ «⋮» ячейки висит в её правом верхнем углу: резервируем под неё место справа, иначе последняя кнопка
   ряда (удаление) оказывается ровно под ней — ради этого всё и затевалось. Резерв даём ВСЕМ строкам
   вложений, а не только верхней: иначе правые края кнопок в столбце разъезжаются. */
.be-tcell:has(> .be-scen-more) .be-tcell-media > .be-tcell-chip { padding-right: 22px; }
/* Fullscreen player for a cell video */
.be-media-lightbox { position: fixed; inset: 0; z-index: 100002; background: rgba(0,0,0,.86); display: flex; align-items: center; justify-content: center; }
.be-media-lightbox .be-ml-media { max-width: 92vw; max-height: 88vh; border-radius: 8px; background: #000; }
.be-media-lightbox .be-ml-x { position: absolute; top: 16px; right: 20px; width: 40px; height: 40px; border: none; border-radius: 50%; background: rgba(255,255,255,.14); color: #fff; font-size: 18px; cursor: pointer; }
.be-media-lightbox .be-ml-x:hover { background: rgba(255,255,255,.26); }
/* Хрон cell auto-estimated from text → stopwatch marker, bottom-right */
.be-tcell-auto { position: absolute; right: 3px; bottom: 3px; width: 13px; height: 13px; color: var(--gold, #cba74e); opacity: .85; pointer-events: none; }
.be-tcell-auto svg { width: 100%; height: 100%; display: block; }
/* Scenario header cell → column-type icon, bottom-right (subtle hint, doesn't fight the header text) */
.be-tcell-role { position: absolute; right: 3px; bottom: 3px; width: 12px; height: 12px; color: var(--muted-2, #8a8a92); opacity: .75; pointer-events: none; }
.be-tcell-role svg { width: 100%; height: 100%; display: block; }
.be-tcell.be-scen-head { font-weight: 700; }                          /* «Сценарный план» header row */
.be-tcell.be-scen-num { font-weight: 800; font-size: 1.6em; }         /* big centred scene number */
.be-tcell.be-editing-cell { outline: 2px solid #4a90e2; outline-offset: -2px; overflow: auto; cursor: text; background: rgba(74,144,226,.12); }   /* editing → clear blue tint + outline */
.be-el.be-tbl-entered .be-tcell:not(.be-editing-cell):not(.be-cell-sel):hover { background: rgba(74,144,226,.08); }   /* hover a cell — only once you've ENTERED the table (2nd click) */
.be-el.be-tbl-entered .be-tcell.be-cell-sel { background: rgba(74,144,226,.16); box-shadow: inset 0 0 0 2px #4a90e2; }   /* selected cell (entered mode) */
.be-el.be-tbl-entered { box-shadow: inset 0 0 0 1.5px rgba(74,144,226,.55); }   /* subtle «you're inside the table» cue */
.be-el.be-inst-entered { box-shadow: inset 0 0 0 1.5px rgba(212,175,55,.5); }   /* subtle «you're inside the component instance» cue (2nd click drilled in) */
.be-el.be-maskmove, .be-el.be-maskmove * { cursor: move !important; }   /* «move the mask» mode — drag repositions the mask over the photo */
.be-el.be-maskmove { box-shadow: 0 0 0 2px var(--gold, #cba74e), 0 0 0 4px rgba(212,175,55,.3); }
/* Framing a cover photo: the WHOLE photo shown ghosted behind/outside the frame (the crisp in-frame part is the normal
   clipped <img> on top). Sits before .be-el-inner in the DOM → paints underneath it; must NOT clip or catch events. */
.be-el > .be-fitghost { position: absolute; inset: 0; overflow: visible; pointer-events: none; opacity: .32; }
.be-el > .be-fitghost img { filter: grayscale(.15); }
/* Column/row resize lines — a wide invisible hit area with a thin line shown on hover/drag; only while selected. */
.be-el[data-type="table"] .be-el-inner { position: relative; }   /* anchor the absolute resize-handle layer to the table box */
.be-tbl-rz-layer { position: absolute; inset: 0; pointer-events: none; z-index: 6; display: none; }
.be-el.selected:not(.editing) .be-tbl-rz-layer { display: block; }
.be-tbl-rz { position: absolute; pointer-events: auto; touch-action: none; }
.be-tbl-rz.col { top: 0; bottom: 0; width: 11px; transform: translateX(-50%); cursor: col-resize; }
.be-tbl-rz.row { left: 0; right: 0; height: 11px; transform: translateY(-50%); cursor: row-resize; }
.be-tbl-rz::after { content: ''; position: absolute; background: transparent; transition: background .1s; }
.be-tbl-rz.col::after { top: 0; bottom: 0; left: 50%; width: 2px; transform: translateX(-50%); }
.be-tbl-rz.row::after { left: 0; right: 0; top: 50%; height: 2px; transform: translateY(-50%); }
.be-tbl-rz:hover::after, .be-tbl-rz.drag::after { background: #4a90e2; }
/* +/− add-remove row/column circles for a selected table. Live in the SCREEN overlay (#beOverlay) so they keep a
   constant size and stay fixed relative to the resize handles; position is set inline by place() (left/top + translate). */
.be-tbl-pm { position: absolute; width: 18px; height: 18px; border-radius: 50%; background: #8a8f98; color: #fff; font-size: 14px; line-height: 1; font-weight: 700; display: flex; align-items: center; justify-content: center; cursor: pointer; pointer-events: auto; box-shadow: 0 1px 3px rgba(0,0,0,.35); opacity: .85; transition: opacity .12s, background .12s; user-select: none; touch-action: none; z-index: 12; }
.be-tbl-pm:hover { opacity: 1; background: #4a90e2; }
.be-tbl-step { display: flex; align-items: center; gap: 4px; }
/* В меню группы «Таблица» степперы — друг под другом, подписи в одну колонку */
.be-grp-body .be-media-ctrls:has(.be-tbl-step) { display: flex; flex-direction: column; align-items: stretch; gap: 8px; }
.be-grp-body .be-tbl-step { justify-content: space-between; }
.be-grp-body .be-tbl-step > span:first-child { min-width: 70px; }
/* Reorder grips: a thin bar per row (left edge) / per column (top edge), shown only while the table is selected.
   The dotted texture reads as "grab me" without competing with the +/− circles. */
.be-tbl-grip { position: absolute; background: #8a8f98; border-radius: 4px; opacity: .55; pointer-events: auto; z-index: 12;
    user-select: none; touch-action: none; transition: opacity .12s, background .12s; }
.be-tbl-grip-row { width: 7px; cursor: grab; }
.be-tbl-grip-col { height: 7px; cursor: grab; }
.be-tbl-grip:hover { opacity: 1; background: #4a90e2; }
.be-tbl-grip.dragging { opacity: 1; background: #4a90e2; cursor: grabbing; }
/* Where the dragged row/column will land. */
.be-tbl-drop { position: absolute; background: #4a90e2; box-shadow: 0 0 0 1px rgba(74,144,226,.35); pointer-events: none; z-index: 13; }
.be-tbl-drop-row { height: 3px; transform: translateY(-50%); }
.be-tbl-drop-col { width: 3px; transform: translateX(-50%); }

/* ===== Roadmap block (Gantt: lanes × time) — token-based so it flips with the dark/light tone ===== */
.be-rm { position: absolute; inset: 0; font-size: 12px; color: var(--text); user-select: none; }
.be-rm-corner { position: absolute; left: 0; top: 0; display: flex; align-items: center; padding: 0 8px;
    font-weight: 700; font-size: 11.5px; letter-spacing: .01em; color: var(--text); overflow: hidden;
    white-space: nowrap; text-overflow: ellipsis; box-sizing: border-box; }
.be-rm-hcell { position: absolute; display: flex; align-items: center; justify-content: center; box-sizing: border-box; padding: 0 4px; }
.be-rm-hlbl { font-size: 11px; font-weight: 600; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.be-rm-lane { position: absolute; display: flex; align-items: center; padding: 0 8px; box-sizing: border-box; }
.be-rm-llbl { font-size: 12px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.be-rm-grid { position: absolute; }
.be-rm-cresize { position: absolute; top: 0; width: 9px; transform: translateX(-4.5px); cursor: col-resize; z-index: 4; }
.be-rm-rresize { position: absolute; left: 0; height: 9px; transform: translateY(-4.5px); cursor: row-resize; z-index: 4; }
.be-rm-cresize:hover, .be-rm-rresize:hover { background: var(--gold, #cba74e); opacity: .35; }
.be-rm-bar { position: absolute; display: flex; align-items: center; gap: 6px; padding: 0 8px; box-sizing: border-box;
    border-radius: 7px; cursor: grab; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,.25); }
.be-rm-bar:active { cursor: grabbing; }
.be-rm-bar.sel { outline: 2px solid var(--gold, #cba74e); outline-offset: 1px; }
.be-rm-bar-t { font-size: 12px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; }
.be-rm-bar-p { font-size: 10.5px; font-weight: 700; opacity: .85; flex: none; }
.be-rm-bar-rs { position: absolute; right: 0; top: 0; bottom: 0; width: 9px; cursor: ew-resize; }
.be-rm-mile { position: absolute; transform: rotate(45deg); border-radius: 3px; cursor: grab; box-shadow: 0 1px 3px rgba(0,0,0,.3); }
.be-rm-mile.sel { outline: 2px solid var(--gold, #cba74e); outline-offset: 2px; }
.be-rm-mlbl { position: absolute; top: 50%; transform: rotate(-45deg) translateY(-50%); transform-origin: left center;
    white-space: nowrap; font-size: 11.5px; font-weight: 600; color: var(--text); pointer-events: auto; }
.be-rm-edit { outline: 2px solid var(--gold, #cba74e); outline-offset: 1px; cursor: text; background: var(--panel); border-radius: 3px; padding: 0 2px; }
.be-rm-tb { position: absolute; z-index: 5; display: flex; align-items: center; gap: 3px; padding: 4px 5px;
    background: var(--popover-bg, #1c1c20); border: 1px solid var(--border-ring, var(--border)); border-radius: 9px;
    box-shadow: 0 8px 24px rgba(0,0,0,.4); }
.be-rm-sw { width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid transparent; cursor: pointer; padding: 0; }
.be-rm-sw.on { border-color: var(--text); }
.be-rm-tbtn { min-width: 20px; height: 20px; padding: 0 5px; border: 1px solid var(--border); border-radius: 6px;
    background: transparent; color: var(--text); cursor: pointer; font-size: 13px; line-height: 1; display: inline-flex; align-items: center; justify-content: center; }
.be-rm-tbtn:hover { background: var(--fill-soft); }
.be-rm-tpct { min-width: 30px; text-align: center; font-size: 11px; font-variant-numeric: tabular-nums; color: var(--text); }

/* «Взять картинку с ковра» — logo picker for the brand map */
.be-axlogo-pick { position: fixed; inset: 0; z-index: 92; background: rgba(0,0,0,.45); display: flex; align-items: center; justify-content: center; }
.be-axlogo-card { width: 560px; max-width: calc(100vw - 30px); max-height: 70vh; display: flex; flex-direction: column; background: var(--panel-2, #1c1c22); border: 1px solid var(--border, #2c2c34); border-radius: 14px; box-shadow: 0 14px 40px rgba(0,0,0,.5); overflow: hidden; }
.be-axlogo-h { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; font-size: 13px; font-weight: 600; color: var(--text); border-bottom: 1px solid var(--border, #2c2c34); }
.be-axlogo-x { border: none; background: none; color: var(--muted); cursor: pointer; font-size: 14px; width: 26px; height: 26px; border-radius: 7px; }
.be-axlogo-x:hover { background: var(--fill-soft); color: var(--text); }
.be-axlogo-grid { padding: 12px; overflow-y: auto; display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.be-axlogo-tile { border: 2px solid transparent; border-radius: 10px; padding: 0; background: var(--panel-3, #22222a); cursor: pointer; overflow: hidden; aspect-ratio: 1; }
.be-axlogo-tile:hover { border-color: var(--gold, #cba74e); }
.be-axlogo-tile img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* Feedback (@bug/@idea) upload progress inside the chat panel */
.be-fb-progress { display: grid; grid-template-columns: 1fr auto; gap: 3px 8px; align-items: center; padding: 8px 10px; margin: 0 10px 6px; background: var(--panel-3, #22222a); border: 1px solid var(--border, #2c2c34); border-radius: 10px; }
.be-fb-pr-lb { font-size: 12px; color: var(--text); }
.be-fb-pr-pc { font-size: 11px; font-weight: 600; color: var(--gold, #cba74e); font-variant-numeric: tabular-nums; }
.be-fb-pr-track { grid-column: 1 / -1; height: 5px; border-radius: 3px; background: var(--fill-soft, rgba(255,255,255,.08)); overflow: hidden; }
.be-fb-pr-fill { height: 100%; width: 0%; border-radius: 3px; background: var(--gold, #cba74e); transition: width .2s ease; }

/* ===== Encrypted-backup admin card: notice boxes =====
   Colours live HERE, not inline: the pale dark-theme inks (#e0a39c / #d8b978) were unreadable on
   the light gamma (:root.portal-light, tone >= 58). Dark defaults match the original look. */
.ycb-note { display: flex; align-items: flex-start; gap: 9px; padding: 10px 12px; border-radius: 8px; font-size: 12.5px; line-height: 1.5; }
.ycb-note svg { flex: 0 0 auto; margin-top: 1px; }
.ycb-note-danger { background: rgba(192,86,79,.10); border: 1px solid rgba(192,86,79,.35); color: #e0a39c; }
.ycb-note-danger svg { stroke: #e0736b; }
.ycb-note-amber { background: rgba(216,163,58,.10); border: 1px solid rgba(216,163,58,.35); color: #d8b978; }
.ycb-note-amber svg { stroke: #d8a33a; }
:root.portal-light .ycb-note-danger { background: rgba(192,86,79,.08); border-color: rgba(163,62,54,.45); color: #8f3b34; }
:root.portal-light .ycb-note-danger svg { stroke: #a84a42; }
:root.portal-light .ycb-note-amber { background: rgba(190,140,30,.10); border-color: rgba(160,120,30,.45); color: #7c5c12; }
:root.portal-light .ycb-note-amber svg { stroke: #96721a; }

/* iPad / узкие окна (641–1024px): правая группа кнопок шапки дашборда ковров не влезает и
   «Создать новый ковер» выезжал за край. Переносим главную кнопку на СВОЮ строку во всю ширину;
   мобильный брейкпоинт (<=640) уже разложен своими правилами выше. */
@media (max-width: 1024px) and (min-width: 641px) {
    .page-header .flex { flex-wrap: wrap; justify-content: flex-end; row-gap: 8px; }
    .page-header .flex > .btn-primary { flex: 0 0 100%; justify-content: center; order: 99; }
}

/* ==== Альбом: отметки, обложка, просмотрщик, чип в ячейке ==== */
.be-album-cell.be-alb-marked::after { content: ''; position: absolute; left: 5px; top: 5px; width: 10px; height: 10px; border-radius: 50%;
    background: #22c55e; box-shadow: 0 0 0 2px rgba(0,0,0,.45); pointer-events: none; z-index: 3; }
.be-album-cell.be-alb-cover { outline: 2px solid var(--gold, #cba74e); outline-offset: -2px; }
/* ★ главной фотографии — в ПРАВОМ НИЖНЕМ углу: сверху справа её перекрывала панель кнопок ячейки (.be-album-cell-ov). */
.be-album-cell.be-alb-cover::before { content: '★'; position: absolute; right: 5px; bottom: 3px; color: var(--gold, #cba74e);
    font-size: 13px; text-shadow: 0 1px 3px rgba(0,0,0,.7); pointer-events: none; z-index: 3; }
.be-album-cell { position: relative; }
.be-album-star, .be-album-mark, .be-album-dl { font-size: 12px; }
/* Просмотрщик альбома (клик по альбому в ячейке таблицы) */
.be-alb-viewer { position: fixed; inset: 0; z-index: 100050; background: rgba(0,0,0,.62); display: flex; align-items: center; justify-content: center; }
.be-alb-viewer-box { width: min(1100px, 92vw); height: min(760px, 86vh); display: flex; flex-direction: column;
    background: var(--popover-bg, #17171b); border: 1px solid var(--border-ring); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); overflow: hidden; }
.be-alb-viewer-head { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--border); flex: none; }
.be-alb-viewer-title { font-size: 14px; font-weight: 600; color: var(--text); }
.be-alb-viewer-grid { position: static !important; flex: 1; min-height: 0; overflow-y: auto; padding: 10px; }
/* Чип «альбом» в ячейке таблицы — обложка вместо иконки */
/* Альбом в ячейке подгоняется под РАЗМЕР ЯЧЕЙКИ: чип тянется на всю её площадь. */
.be-tcell-chip.be-chip-album { position: relative; padding: 0; overflow: hidden; cursor: pointer; flex: 1 1 auto; align-self: stretch; min-height: 46px; }
.be-tcell-media:has(.be-chip-album) { position: absolute; inset: 3px; margin: 0; display: flex; }
.be-chip-cover { width: 100%; height: 100%; min-height: 46px; object-fit: cover; display: block; }
.be-tcell-chip.be-chip-album .be-chip-name { position: absolute; left: 0; right: 0; bottom: 0; padding: 2px 5px;
    background: linear-gradient(transparent, rgba(0,0,0,.75)); color: #fff; font-size: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Крестик альбома — в ЛЕВОМ верхнем углу ячейки (просьба пользователя): не спорит с кнопкой «⋮» справа. */
/* У альбома чип — целая плитка, а не строка, поэтому крестик остаётся угловым (слева, подальше от «⋮»).
   Правило самодостаточное: общий стиль `.be-chip-del` убран вместе с плавающим крестиком у файлов. */
.be-tcell-chip.be-chip-album .be-chip-del { position: absolute; left: 3px; top: 3px; right: auto; z-index: 4; width: 18px; height: 18px;
    padding: 0; border: none; cursor: pointer; font-size: 11px; line-height: 1;
    display: inline-flex; align-items: center; justify-content: center; border-radius: 6px; background: rgba(20,20,24,.75);
    color: #fff; opacity: 0; transition: opacity .12s; }
.be-tcell-chip.be-chip-album:hover .be-chip-del { opacity: 1; }
.be-tcell-chip.be-chip-album .be-chip-del:hover { background: rgba(220,60,60,.92); }
.be-tcell:not(:hover) .be-scen-more + .be-tcell-media .be-chip-del { opacity: 0; }


/* Ползунок размера плиток — в шапке самого альбома */
.be-album-zoom { width: 74px; height: 14px; margin: 0 4px; accent-color: var(--gold, #cba74e); cursor: pointer; flex: none; }
.be-album-el:not(.selected):not(:hover) .be-album-zoom { opacity: 0; pointer-events: none; }
.be-album-zoom { transition: opacity .15s; }

/* Выбранный пункт меню — ТОЧКА СЛЕВА (вместо галочки справа) */
.be-ctx-item { position: relative; }
.be-ctx-item.be-ctx-on::before { content: ''; position: absolute; left: 4px; top: 50%; transform: translateY(-50%);
    width: 6px; height: 6px; border-radius: 50%; background: var(--gold, #cba74e); }
.be-ctx-item.be-ctx-on { color: var(--text); }

/* Подписи-подсказки у кнопок на фото альбома (нативный title под курсором не появлялся
   из-за оверлея) — рисуем свою мини-подсказку. */
/* ⚠ НЕ растягивать на всю плитку (кнопки уезжали влево) — панель прижата к ПРАВОМУ верхнему углу выше. */
.be-album-cell-btn { position: relative; }
.be-album-cell-btn::after { content: attr(title); position: absolute; left: 50%; transform: translateX(-50%); top: calc(100% + 4px);
    padding: 2px 6px; border-radius: 5px; background: rgba(20,20,24,.96); color: #fff; font-size: 10px; white-space: nowrap;
    opacity: 0; pointer-events: none; transition: opacity .12s; z-index: 20; }
.be-album-cell-btn:hover::after { opacity: 1; }

/* Меню «Добавить фото» в просмотрщике альбома */
.be-alb-addmenu { position: fixed; z-index: 100060; min-width: 180px; }
.be-alb-picker .be-album-cell { cursor: pointer; }
.be-alb-picker .be-album-cell.be-alb-marked { outline: 2px solid #22c55e; outline-offset: -2px; }

/* Иконки альбома: скруглённые кнопки портального стиля */
.be-album-btn { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px;
    padding: 0; border-radius: 8px; border: none; background: rgba(255,255,255,.06); color: var(--muted); cursor: pointer; }
.be-album-btn:hover { background: rgba(255,255,255,.14); color: var(--text); }
.be-album-btn svg { width: 15px; height: 15px; }
.be-album-cell-btn { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px;
    padding: 0; border-radius: 7px; border: none; background: rgba(20,20,24,.72); color: #fff; cursor: pointer; }
.be-album-cell-btn:hover { background: rgba(20,20,24,.92); }
.be-album-cell-btn svg { width: 14px; height: 14px; }
.be-album-cell-btn.be-album-star:hover { color: var(--gold, #cba74e); }
.be-album-cell-btn.be-album-mark:hover { color: #22c55e; }
.be-album-cell-btn.be-album-rm:hover { color: #ef6b6b; }
body.be-canvas-light .be-album-btn { background: rgba(0,0,0,.06); }

/* «Что нового» на ковре: кнопка НАД чатом, того же размера; панель — как чат */
.be-wn-fab { position: fixed; right: 18px; bottom: 146px; width: 52px; height: 52px; border-radius: 50%; z-index: 57;
    display: flex; align-items: center; justify-content: center; border: none; cursor: pointer;
    background: var(--panel-2, #1c1c21); color: var(--text); box-shadow: 0 6px 20px rgba(0,0,0,.45); }
.be-wn-fab:hover { background: var(--panel-hover); }
.be-wn-panel { position: fixed; right: 18px; bottom: 206px; width: 330px; max-height: 60vh; display: none;
    flex-direction: column; z-index: 58; background: var(--popover-bg, #17171b); border: 1px solid var(--border-ring);
    border-radius: var(--radius-md); box-shadow: var(--shadow-lg); overflow: hidden; }
.be-wn-panel.open { display: flex; }
.be-wn-head { display: flex; align-items: center; padding: 9px 12px; border-bottom: 1px solid var(--border); font-size: 13px; font-weight: 600; color: var(--text); }
.be-wn-head button { margin-left: auto; border: none; background: none; color: var(--muted); cursor: pointer; font-size: 14px; }
.be-wn-body { padding: 10px 12px; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; }
.be-wn-post { border-bottom: 1px solid var(--border); padding-bottom: 10px; }
.be-wn-date { font-size: 10px; color: var(--muted-2); margin-bottom: 4px; }
.be-wn-text { font-size: 12.5px; color: var(--text); white-space: pre-wrap; }
.be-wn-media { width: 100%; border-radius: 8px; margin-top: 6px; display: block; }
.be-wn-empty { color: var(--muted); font-size: 12px; }
/* Лента на портале внутри панели «Что нового» */
.wn-post { border-top: 1px solid var(--border); padding-top: 8px; margin-top: 8px; }
.wn-date { font-size: 10px; color: var(--muted-2); margin-bottom: 3px; }
.wn-ptext { font-size: 12.5px; white-space: pre-wrap; }
.wn-media { width: 100%; border-radius: 8px; margin-top: 6px; display: block; }
@media (max-width: 700px) { .be-wn-fab { display: none; } }

/* Режим показа фото альбома: целиком (по умолчанию) ⇄ заполнить с обрезкой */
.be-album-grid.be-alb-contain .be-album-cell img { object-fit: contain; background: rgba(0,0,0,.18); }
.be-album-grid.be-alb-cover .be-album-cell img { object-fit: cover; }
/* Обложка альбома в ячейке таблицы — тот же выбор, по умолчанию целиком */
.be-tcell-chip.be-chip-fit-contain .be-chip-cover { object-fit: contain; background: rgba(0,0,0,.18); }
.be-tcell-chip.be-chip-fit-cover .be-chip-cover { object-fit: cover; }

/* Дневники разработчика: строка состояния (таймер записи / прогресс загрузки и конвертации) */
.dl-prog { display: flex; align-items: center; gap: 10px; margin-top: 10px; font-size: 12px; color: var(--muted); }
.dl-prog .dl-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--accent, #c9a227); flex: 0 0 auto; }
.dl-prog.dl-rec .dl-dot { background: #e5484d; animation: dlPulse 1s ease-in-out infinite; }
.dl-prog .dl-label { white-space: nowrap; }
.dl-prog .dl-bar { position: relative; flex: 1 1 auto; max-width: 260px; height: 6px; border-radius: 4px;
    background: rgba(127, 127, 127, .25); overflow: hidden; }
.dl-prog .dl-bar > i { position: absolute; inset: 0 auto 0 0; width: 0; border-radius: 4px;
    background: var(--accent, #c9a227); transition: width .18s linear; }
.dl-prog .dl-bar.indet > i { width: 40%; animation: dlSlide 1.1s ease-in-out infinite; }
.dl-prog .dl-pct { min-width: 34px; text-align: right; font-variant-numeric: tabular-nums; }
@keyframes dlPulse { 50% { opacity: .25; } }
@keyframes dlSlide { 0% { left: -40%; } 100% { left: 100%; } }

/* Дневники разработчика: список записей — две карточки в ряд (на узких экранах одна) */
/* Строки равной высоты (grid-auto-rows:1fr) + потолок карточки: длинная запись не растягивает весь ряд,
   её текст скроллится внутри .dl-body. */
/* grid-auto-rows НЕ 1fr: с ним последний (неполный) ряд растягивался во всю оставшуюся высоту.
   Ряд получает высоту по содержимому, а карточки внутри ряда выравниваются друг по другу (stretch). */
.dl-grid { margin-top: 16px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-rows: min-content; gap: 10px; align-items: stretch; }
.dl-grid .dl-card { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; min-width: 0;
    height: 100%; max-height: 170px; display: flex; flex-direction: column; overflow: hidden; }
.dl-grid .dl-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding-right: 2px; }
.dl-grid .dl-card img, .dl-grid .dl-card video { max-width: 100%; }
.dl-grid .dl-card .dl-body img, .dl-grid .dl-card .dl-body video { width: 84px !important; height: 54px !important; }
@media (max-width: 900px) { .dl-grid { grid-template-columns: 1fr; } }

/* «Что нового»: постраничная навигация ленты (портал и ковёр) */
.wn-pager, .be-wn-pager { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 10px 0 2px; font-size: 12px; color: var(--muted); }
.wn-pager button, .be-wn-pager button { min-width: 26px; height: 26px; border-radius: 8px; cursor: pointer;
    border: 1px solid var(--border); background: transparent; color: inherit; font-size: 14px; line-height: 1; }
.wn-pager button:hover:not(:disabled), .be-wn-pager button:hover:not(:disabled) { background: rgba(127, 127, 127, .16); }
.wn-pager button:disabled, .be-wn-pager button:disabled { opacity: .35; cursor: default; }

/* «Что нового»: бейдж непросмотренных (акцентный цвет портала) */
.wn-badge, .be-wn-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px;
    padding: 0 5px; border-radius: 9px; background: var(--accent, #c9a227); color: var(--accent-ink, #111);
    font-size: 11px; font-weight: 700; line-height: 1; }
.wn-badge[hidden], .be-wn-badge[hidden] { display: none; }
/* ⚠ НЕ задавать .be-wn-fab position: relative — правило шло ПОЗЖЕ основного и перебивало
   position: fixed, из-за чего кнопка «Что нового» уезжала из угла и пропадала с ковра.
   fixed сам создаёт контекст для абсолютного бейджа — ничего дополнительно не нужно. */
.be-wn-badge { position: absolute; top: -4px; right: -4px; box-shadow: 0 0 0 2px var(--panel, #1a1a1a); }

/* Дневники: вложения черновика (до публикации) — превью с крестиком удаления */
.dl-pend { position: relative; width: 96px; height: 64px; border-radius: 8px; overflow: hidden; border: 1px solid var(--border); }
.dl-pend img, .dl-pend video { width: 100%; height: 100%; object-fit: cover; display: block; }
.dl-pend-x { position: absolute; top: 3px; right: 3px; width: 20px; height: 20px; border-radius: 50%; cursor: pointer;
    border: none; background: rgba(0, 0, 0, .62); color: #fff; font-size: 11px; line-height: 1; display: flex;
    align-items: center; justify-content: center; }
.dl-pend-x:hover { background: #e5484d; }
/* Плитка кликабельна — открывает полноразмерный просмотр; у видео поверх кадра значок «играть». */
.dl-pend { cursor: pointer; }
.dl-pend-play { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    pointer-events: none; color: #fff; filter: drop-shadow(0 1px 4px rgba(0, 0, 0, .65)); }
/* Вес записи в шапке карточки и вес вложения в окне просмотра */
.dl-size { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.dl-prev-meta { margin-top: 8px; font-size: 12px; color: var(--muted); word-break: break-word; }
/* Плашка режима правки над полем ввода */
.dl-editing { margin: 4px 0 6px; padding: 5px 10px; border-radius: 8px; font-size: 12px;
    background: rgba(127, 127, 127, .16); color: var(--muted);
    box-shadow: inset 0 0 0 1px var(--border-ring, transparent); }
/* Окно предпросмотра: медиа во всю ширину диалога, но не выше экрана */
.dl-prev-ov .dl-prev { max-width: 900px; width: 92vw; }
.dl-prev video, .dl-prev img { display: block; width: 100%; max-height: 72vh; border-radius: 10px; background: #000; }
.dl-draft { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
    padding: 2px 6px; border-radius: 6px; background: rgba(127, 127, 127, .22); color: var(--muted); }
