:root{
    --bg:#1e1f21;
    --canvas:#0b0c0d;
    --gap:10px;
    --seg-gap:8px;
    --bg-soft:#26272a;
    --surface:#2a2b2e;
    --surface-2:#323337;
    --line:#47484f;
    --line-soft:#2c2d31;
    --text:#e9e9ea;
    --text-dim:#9a9b9f;
    --text-faint:#6c6d72;
    --today:#6f7bf7;
    --accent:#cc73c7;         /* accent = cursor-dot color; user-changeable in Параметры (persisted) */
    --accent-hover:#de85d9;
    --modal-panel:47,48,51;   /* modal panel fill (= #2f3033 as RGB) */
    --modal-alpha:1;           /* modal panel opacity (1 = solid, lower = more see-through) */
    /* role identity colours (М / А / И) — used on the Состав toggles, its legend, the editor
       role labels and the sort-menu dots. Change here to recolour every role badge at once. */
    --role-m:#ED5761;          /* Менеджер */
    --role-a:#404B62;          /* Арт */
    --role-i:#161515;          /* Исполнитель */
    --role-neutral:#5c5d63;    /* аватар человека без выбранной роли */
    --sidebar-w:200px;
    --header-h:50px;
    --toolbar-h:52px;
    --row-task:45px;
    --row-group:50px;
    --weekend:#232427;
    --radius:5px;
    font-synthesis:none;
  }
  *{box-sizing:border-box}
  html,body{height:100%;margin:0}
  body{
    background:var(--canvas);
    color:var(--text);
    font-family:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
    font-size:13px;
    overflow:hidden;
  }
  /* custom trailing cursor (dot + lagging ring); native cursor hidden only once it's running */
  body.cursor-live, body.cursor-live *{cursor:none !important}
  .cursor-dot,.cursor-dot-outline{pointer-events:none;position:fixed;top:0;left:0;border-radius:50%;
    transform:translate(-50%,-50%);opacity:0;will-change:transform,top,left;
    transition:opacity .3s ease, transform .18s ease}
  .cursor-dot{z-index:99999999;width:8px;height:8px;background:color-mix(in srgb, var(--accent) 85%, transparent)}
  .cursor-dot-outline{z-index:99999998;width:36px;height:36px;background:rgba(169,169,222,.25)}
  .app{display:flex;flex-direction:column;height:100vh;padding:var(--gap);gap:var(--gap);background:var(--canvas)}

  /* segments float on the dark canvas */
  .seg{background:var(--bg);border:1px solid var(--line);border-radius:12px}

  .workspace{flex:1 1 auto;min-height:0;display:grid;
    grid-template-columns:var(--sidebar-w) 1fr;
    grid-template-rows:var(--header-h) 1fr;gap:var(--gap)}
  .head-left{display:flex;align-items:center;padding:0;border-radius:12px;overflow:hidden;
    color:var(--text-faint);font-size:11px;letter-spacing:.06em;text-transform:uppercase}
  /* Logo doubles as a "reset view" button (clear sort + collapse projects + jump to today).
     The button fills the whole header cell so it's a big, obvious target. */
  .logo-btn{display:flex;align-items:center;justify-content:center;gap:10px;
    width:100%;height:100%;padding:0 14px;
    background:transparent;border:none;border-radius:12px;cursor:pointer;
    transition:background .12s}
  .logo-btn:hover{background:var(--surface-2)}       /* subtle hover, same feel as the toolbar buttons */
  .logo-btn:active{background:var(--surface)}
  /* Text wordmark (IBM Plex Mono): "BAK" bold caps + "studio" light lowercase. Tune sizes/spacing here. */
  .logo-word{display:inline-flex;align-items:baseline;gap:5px;white-space:nowrap;
    font-family:inherit;font-weight:700;font-size:20px;letter-spacing:.09em;
    text-transform:uppercase;line-height:1;color:var(--text);user-select:none}
  .logo-word .sub{font-weight:400;font-size:15px;letter-spacing:.12em;
    text-transform:lowercase;color:var(--text-dim)}
  .head-right{overflow:hidden;position:relative}
  .head-track{position:relative;height:100%}
  .body-left{overflow:hidden;border:none;background:transparent}
  .body-right{overflow:auto;position:relative;z-index:0;grid-column:2;grid-row:2}   /* z-index:0 -> own stacking context so the custom scrollbar layer (same cell) sits above it */
  .body-right{scrollbar-width:none}                        /* hide native scrollbars — custom ones replace them */
  .body-right::-webkit-scrollbar{width:0;height:0;display:none}
  /* custom scrollbars: layer occupies the same grid cell as .body-right, overlaid on top.
     pointer-events:none so it doesn't block the timeline; only the thumbs/tracks catch input. */
  .cscroll-layer{grid-column:2;grid-row:2;position:relative;z-index:1;pointer-events:none;
    overflow:hidden;border-radius:12px}
  .cscroll-layer .cbar{position:absolute;pointer-events:auto}
  .cscroll-layer .cbar.h{left:8px;right:8px;bottom:3px;height:10px}
  .cscroll-layer .cbar.v{top:8px;bottom:8px;right:3px;width:10px}
  .cscroll-layer .cbar.off{display:none}                   /* hidden when that axis doesn't overflow */
  .cscroll-layer .cthumb{position:absolute;background:rgba(255,255,255,.22);border-radius:6px;
    cursor:pointer;transition:background .12s;touch-action:none}
  .cscroll-layer .cbar.h .cthumb{top:0;bottom:0}           /* width & left set by JS */
  .cscroll-layer .cbar.v .cthumb{left:0;right:0}           /* height & top set by JS */
  .cscroll-layer .cthumb:hover{background:rgba(255,255,255,.34)}
  .cscroll-layer .cthumb.drag{background:rgba(255,255,255,.34)}   /* stay light while dragging (same as hover) */
  .col-left{display:flex;flex-direction:column;min-height:100%}
  .lgroup{flex:0 0 auto;margin:0 0 var(--seg-gap) 0;border-radius:12px;
    box-shadow:inset 0 0 0 1px var(--line)}
  .rgroup{flex:0 0 auto;position:relative;z-index:1;margin-bottom:var(--seg-gap)}
  .rgroup::after{content:"";position:absolute;left:0;right:0;bottom:-4px;
    height:1px;background:var(--line)}
  /* add-client footer */
  .add-client{flex:0 0 auto;padding:4px 8px 14px}
  .add-client-btn{display:flex;align-items:center;gap:9px;width:100%;height:42px;
    background:transparent;border:1px dashed var(--line);border-radius:12px;
    color:var(--text-faint);font-size:13px;font-family:inherit;cursor:pointer;
    padding:0 13px;transition:background .12s,color .12s,border-color .12s}
  .add-client-btn:hover{background:var(--bg-soft);color:var(--text);border-color:var(--text-faint)}
  .add-client-btn svg{width:16px;height:16px;flex:0 0 auto}
  .add-client-input{width:100%;height:42px;background:var(--bg);border:1px solid var(--accent);
    border-radius:12px;color:var(--text);padding:0 13px;font-size:13px;font-family:inherit}
  .add-client-input:focus{outline:none}
  .lcell{display:flex;align-items:center}
  /* Client/person card row pins to the top while you scroll through that client's task rows,
     so the client's frame + name never scrolls out of view (was: it got clipped at the top edge).
     Sticky range is the parent .lgroup, so a card can't overlap the next client — the following
     card pushes it up on handoff. z-index keeps the pinned card above the (empty) task cells behind it. */
  .lcell-group{height:var(--row-group);position:sticky;top:0;z-index:5}
  .lcell-task{height:var(--row-task)}
  .rrow{position:relative;flex:0 0 auto}
  .rrow-group{height:var(--row-group)}
  .rrow-task{height:var(--row-task)}

  /* ---------- Toolbar ---------- */
  .toolbar{
    height:var(--toolbar-h);
    flex:0 0 auto;
    display:flex;align-items:center;gap:var(--gap);
    padding:0 14px 0 0;
    position:relative;z-index:40;
  }
  /* left zone matches the sidebar column width so the add button centers over it,
     and everything after it lines up with the right timeline panel */
  .tb-left{flex:0 0 var(--sidebar-w);display:flex;justify-content:center;align-items:center}
  .btn{
    display:inline-flex;align-items:center;gap:7px;
    height:32px;padding:0 12px;
    background:var(--surface);
    border:1px solid var(--line);
    color:var(--text);
    border-radius:7px;cursor:pointer;
    font-family:inherit;font-size:12.5px;line-height:1;
    transition:background .12s,border-color .12s;
    white-space:nowrap;
  }
  .btn:hover{background:var(--surface-2)}
  .btn svg{width:14px;height:14px;flex:0 0 auto}
  .btn-primary{background:var(--accent);border-color:var(--accent);color:#1c1c1e;font-weight:600}
  .btn-primary:hover{background:var(--accent-hover)}
  /* "Добавить проект": looks like the right-hand toolbar buttons (surface fill, light text, hover
     surface-2 — all inherited from .btn) but keeps an accent-coloured contour that tracks the
     Параметры accent colour. border-color wins over .btn's --line because this rule comes later. */
  .btn-add{border-color:var(--accent)}
  .btn.active{background:var(--accent);border-color:var(--accent);color:#1c1c1e}
  .btn.active:hover{background:var(--accent-hover)}
  .sort-clear{display:inline-flex;align-items:center;justify-content:center;margin-left:2px;
    width:17px;height:17px;border-radius:50%;font-size:10px;background:rgba(255,255,255,.22)}
  .sort-clear:hover{background:rgba(255,255,255,.38)}
  .btn-icon{width:32px;padding:0;justify-content:center}
  .btn-ghost{background:transparent;border-color:transparent}
  .btn-ghost:hover{background:var(--surface)}
  .btn:disabled{opacity:.32;cursor:default;pointer-events:none}
  .toolbar .spacer{flex:1 1 auto}
  .nav-today{display:flex;align-items:center;gap:2px}
  .nav-today .lbl{padding:0 8px;color:var(--text);font-size:12.5px;cursor:pointer}
  .nav-today .lbl:hover{color:var(--text)}
  .zoom{display:flex;align-items:center;gap:6px;color:var(--text);font-size:12.5px}
  .zoom>span{margin-right:5px}
  .zoom .btn-icon{width:28px;height:28px}

  /* ---------- Right timeline grid ---------- */
  .grid{position:relative;width:max-content;min-width:100%;min-height:100%;display:flex;flex-direction:column}
  .bg-grid{position:absolute;top:0;bottom:0;z-index:0;pointer-events:none}

  .row{display:flex;align-items:stretch;position:relative;flex:0 0 auto}
  .row-filler{flex:1 1 auto;min-height:40px}
  .cell-side{
    width:var(--sidebar-w);flex:0 0 var(--sidebar-w);
    position:sticky;left:0;z-index:20;
    background:var(--bg);
    border-right:1px solid var(--line);
    display:flex;align-items:center;
  }
  .cell-lane{position:relative;flex:1 1 auto}

  /* header */
  .row-head{position:sticky;top:0;z-index:30;height:var(--header-h)}
  .row-head .cell-side{
    z-index:35;border-bottom:1px solid var(--line);
    align-items:flex-end;padding:0 0 6px 14px;
    color:var(--text-faint);font-size:11px;letter-spacing:.04em;text-transform:uppercase;
  }
  .head-lane{position:relative;flex:1 1 auto;border-bottom:1px solid var(--line);background:var(--bg)}
  .months{position:absolute;top:0;left:0;height:26px;width:100%}
  .month{position:absolute;top:0;height:26px;display:flex;align-items:center;padding-left:10px;
    color:var(--text);font-size:14px;font-weight:600;border-left:1px solid var(--line)}
  .weeks{position:absolute;top:28px;left:0;height:28px;width:100%}
  .week{position:absolute;top:0;height:28px;display:flex;align-items:center;gap:7px;
    padding-left:8px;padding-bottom:10px;
    color:var(--text-dim);font-size:12px}
  .week::before{content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);
    width:1px;height:25px;background:var(--line-soft)}
  .week .wn{color:var(--text-faint);font-size:12px}

  /* group header row */
  .row-group{height:var(--row-group)}
  .row-group .cell-side{padding:0;display:flex;align-items:center}

  /* Telegram-style project card */
  /* client card styled like the right-hand toolbar buttons: always filled + bordered,
     hover just lightens the fill a touch (same --surface / --surface-2 / --line tokens).
     align-self:flex-start — the bordered card is a touch taller than its 50px row, so we pin
     its TOP to the row top (instead of centering). That makes the card's top corners coincide
     exactly with the lgroup frame's rounded corners (same 12px radius), so the two borders merge
     into one clean line; the few extra px spill downward into the empty task area where there
     are no corners to expose. Centering instead let the card poke 3px above the frame and
     uncovered the frame's corner -> the dark shading you saw on the top corners. */
  .proj-card{flex:1;min-width:0;display:flex;align-items:center;gap:11px;
    margin:0;padding:7px 8px;border-radius:12px;cursor:grab;align-self:flex-start;
    background:var(--surface);border:1px solid var(--line);
    transition:background .12s,border-color .12s}
  .proj-card:hover{background:var(--surface-2)}
  .proj-card.sel{background:var(--surface-2)}
  .proj-card.drag-src{opacity:.35;cursor:grabbing}
  .proj-card.drop-before{box-shadow:inset 0 3px 0 0 var(--accent)}
  .proj-card.drop-after{box-shadow:inset 0 -3px 0 0 var(--accent)}
  .proj-av{width:15px;height:15px;border-radius:50%;flex:0 0 auto;
    box-shadow:0 1px 2px rgba(0,0,0,.25)}
  .proj-av.clickable{cursor:pointer;transition:box-shadow .12s}
  .proj-av.clickable:hover{box-shadow:0 0 0 3px rgba(255,255,255,.22)}
  .proj-main{min-width:0;flex:1;display:flex;flex-direction:column;gap:2px}
  .proj-name{font-weight:600;font-size:14px;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .proj-name-input{width:100%;min-width:0;background:var(--bg);border:1px solid var(--accent);border-radius:6px;
    color:var(--text);font-weight:600;font-size:14px;font-family:inherit;padding:1px 6px;margin:-2px 0}
  .proj-name-input:focus{outline:none}
  .proj-sub{font-size:12px;color:var(--text-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .proj-chevron{flex:0 0 auto;width:22px;height:22px;border-radius:6px;color:var(--text-faint);
    display:flex;align-items:center;justify-content:center;transition:transform .15s,color .12s,background .12s}
  .proj-chevron:hover{color:var(--text);background:rgba(255,255,255,.08)}
  .proj-chevron.collapsed{transform:rotate(-90deg)}
  .proj-menu{flex:0 0 auto;width:22px;height:22px;padding:0;border:none;background:transparent;border-radius:6px;
    color:var(--text-faint);cursor:pointer;display:flex;align-items:center;justify-content:center;
    opacity:0;transition:opacity .12s,color .12s,background .12s}
  .proj-card:hover .proj-menu{opacity:1}
  .proj-menu:hover{color:var(--text);background:rgba(255,255,255,.08)}
  .client-menu{min-width:180px}

  .gdot{width:9px;height:9px;border-radius:3px;flex:0 0 auto}
  .gdot.clickable{cursor:pointer;transition:box-shadow .12s,transform .12s}
  .gdot.clickable:hover{transform:scale(1.25);box-shadow:0 0 0 3px rgba(255,255,255,.16)}

  /* shared smooth appearance for every popover — colour picker, calendar, custom dropdowns and the
     Сортировка / Параметры menus. Fade + slight rise/scale via visibility (not display) so they
     animate in AND out. Tune the speed / rise / scale here in one place for all of them. */
  .color-pop,.datepop,.selectpop,.menu{
    opacity:0;visibility:hidden;transform:translateY(-5px) scale(.85);transform-origin:top center;
    transition:opacity .3s ease,transform .3s ease,visibility .3s ease}
  .color-pop.on,.datepop.on,.selectpop.on,.menu.on{opacity:1;visibility:visible;transform:none}
  /* color picker popover */
  .color-pop{position:fixed;z-index:160;background:var(--surface);border:1px solid var(--line);
    border-radius:12px;box-shadow:0 18px 55px rgba(0,0,0,.6);padding:11px}
  .color-pop .swatches{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;justify-items:center}
  .color-pop .swatch{width:24px;height:24px;border-radius:50%;cursor:pointer;
    box-shadow:0 0 0 2px transparent;transition:transform .1s,box-shadow .1s}
  .color-pop .swatch:hover{transform:scale(1.18)}
  .color-pop .swatch.sel{box-shadow:0 0 0 2px var(--surface),0 0 0 4px #fff}
  .color-pop .custom{display:flex;align-items:center;gap:9px;margin-top:11px;padding-top:11px;
    border-top:1px solid var(--line);color:var(--text-dim);font-size:12px;cursor:pointer}
  .color-pop .custom:hover{color:var(--text)}
  .color-pop .custom .cp-mini{width:30px;height:30px;border:1px solid var(--line);
    border-radius:8px;flex:0 0 auto}   /* preview of the current custom color */

  /* custom color picker (our own; replaces the native <input type=color> dialog).
     Layout: saturation/value square, hue slider, then preview swatch + hex field. */
  .cpicker{position:fixed;z-index:170;display:none;width:212px;padding:11px;background:var(--surface);
    border:1px solid var(--line);border-radius:12px;box-shadow:0 18px 55px rgba(0,0,0,.6)}
  .cpicker.on{display:block}
  /* SV area: base hue set inline via background-color; white(→right)+black(→bottom) overlays on top */
  .cp-sv{position:relative;width:100%;height:130px;border-radius:8px;cursor:crosshair;
    background-image:linear-gradient(to top,#000,rgba(0,0,0,0)),linear-gradient(to right,#fff,rgba(255,255,255,0))}
  .cp-sv-h{position:absolute;width:12px;height:12px;border-radius:50%;border:2px solid #fff;
    box-shadow:0 0 0 1px rgba(0,0,0,.5);transform:translate(-50%,-50%);pointer-events:none}
  .cp-hue{position:relative;width:100%;height:12px;margin-top:11px;border-radius:6px;cursor:pointer;
    background:linear-gradient(to right,#f00,#ff0,#0f0,#0ff,#00f,#f0f,#f00)}
  .cp-hue-h{position:absolute;top:50%;width:14px;height:14px;border-radius:50%;background:#fff;
    box-shadow:0 0 0 1px rgba(0,0,0,.5);transform:translate(-50%,-50%);pointer-events:none}
  .cp-row{display:flex;align-items:center;gap:9px;margin-top:11px}
  .cp-prev{width:28px;height:28px;border-radius:6px;border:1px solid var(--line);flex:0 0 auto}
  .cp-hex{flex:1;min-width:0;height:30px;background:var(--bg);border:1px solid var(--line);border-radius:7px;
    color:var(--text);padding:0 10px;font-size:13px;font-family:inherit;text-transform:uppercase}
  .cp-hex:focus{outline:none;border-color:var(--accent)}
  .av.clickable{cursor:pointer;transition:box-shadow .12s}
  .av.clickable:hover{box-shadow:0 0 0 3px rgba(255,255,255,.18)}
  .gname{font-weight:600;font-size:13px;color:var(--text)}
  .gcount{color:var(--text-faint);font-size:11px;margin-left:2px}
  .row-group .cell-lane,.row-group .head-lane{}

  /* root row (MR group) */
  .row-root{height:44px}
  .row-root .cell-side{gap:8px;padding-left:8px;cursor:pointer;font-weight:700;font-size:14px}
  .row-root .gicon{width:22px;height:22px;border-radius:6px;background:var(--surface-2);
    display:flex;align-items:center;justify-content:center;color:var(--text-dim);flex:0 0 auto}

  /* task row */
  .row-task{height:var(--row-task)}

  /* lane backgrounds (week grid + weekend) drawn via pseudo layer */
  .gridlines{position:absolute;inset:0;pointer-events:none;z-index:0}
  .gl{position:absolute;top:0;bottom:0;width:1px;background:var(--line-soft)}
  .gl.day{background:rgba(255,255,255,.038)}
  .wknd{position:absolute;top:0;bottom:0;background:var(--weekend)}

  /* today line */
  .today-line{position:absolute;top:0;bottom:0;width:1px;background:var(--today);
    z-index:15;pointer-events:none;opacity:.5}
  .today-line::before{content:"";position:absolute;top:-5px;left:-4px;width:10px;height:10px;
    border-radius:50%;background:var(--today)}

  /* executor vacation: suitcase toggle on the card + framed period on the timeline */
  .vac-btn{flex:0 0 auto;width:22px;height:22px;padding:0;border:none;background:transparent;
    border-radius:6px;color:var(--text-faint);cursor:pointer;display:flex;align-items:center;
    justify-content:center;transition:color .12s,background .12s}
  .vac-btn:hover{color:var(--text);background:rgba(255,255,255,.08)}
  .vac-btn.on{color:#1c1c1e;background:var(--accent)}   /* draw mode active */
  .vac-btn svg{width:15px;height:15px}
  /* frame sits UNDER the bars (z-index below .bar's 5); still draggable where no bar covers it —
     body moves it, edge grips resize it. translucent fill lets the grid show through. */
  .vac-frame{position:absolute;top:3px;bottom:3px;z-index:2;border:1px solid var(--accent);border-radius:6px;
    background:rgba(255,255,255,.12);cursor:move;overflow:hidden;touch-action:none}   /* light-grey translucent fill */
  .vac-frame.dragging{z-index:3;cursor:grabbing}
  .vac-grip{position:absolute;top:0;bottom:0;width:8px;cursor:ew-resize;z-index:1;touch-action:none}
  .vac-grip.l{left:0}.vac-grip.r{right:0}
  .vac-frame .vac-label{position:absolute;top:3px;left:7px;font-size:10px;font-weight:600;letter-spacing:.04em;
    text-transform:uppercase;color:var(--accent)}
  .vac-frame .vac-del{position:absolute;top:3px;right:3px;width:16px;height:16px;border:none;border-radius:50%;
    background:rgba(0,0,0,.32);color:#fff;font-size:9px;line-height:1;cursor:pointer;opacity:.6;
    display:flex;align-items:center;justify-content:center;pointer-events:auto;transition:opacity .12s,background .12s}
  .vac-frame .vac-del:hover{opacity:1;background:#e06b6b}
  .vac-preview{border-style:dashed}                    /* live frame while dragging */
  .vac-draw-layer{position:absolute;inset:0;z-index:8;cursor:crosshair;touch-action:none}
  /* Пауза на проекте: та же механика, что у отпуска, но рамка сидит НАД баром (видна на строке проекта)
     и тёплого (янтарного) цвета, чтобы отличать от отпуска (акцент). Полупрозрачная — бар просвечивает. */
  /* точно по геометрии бара (top:4.5px, height:36px, border-box) — чтобы пауза лежала ровно на линии проекта, не торча выше/ниже */
  .pause-frame{position:absolute;top:4.5px;height:36px;box-sizing:border-box;z-index:8;border:1.5px dashed #f0b45e;border-radius:6px;
    background:rgba(0,0,0,.42);cursor:move;overflow:hidden;touch-action:none}   /* тёмная заливка затемняет участок «на паузе» → видно на любом баре; янтарная пунктирная рамка = идентичность паузы */
  .pause-frame.dragging{z-index:9;cursor:grabbing}
  .pause-frame .pause-label{position:absolute;top:3px;left:7px;font-size:10px;font-weight:600;letter-spacing:.04em;
    text-transform:uppercase;color:#e0a75b}
  .pause-frame .vac-del{position:absolute;top:3px;right:3px;width:16px;height:16px;border:none;border-radius:50%;
    background:rgba(0,0,0,.32);color:#fff;font-size:9px;line-height:1;cursor:pointer;opacity:.6;
    display:flex;align-items:center;justify-content:center;pointer-events:auto;transition:opacity .12s,background .12s}
  .pause-frame .vac-del:hover{opacity:1;background:#e06b6b}
  .pause-preview{border-style:dashed}
  .pause-draw-layer{position:absolute;inset:0;z-index:10;cursor:crosshair;touch-action:none}   /* поверх пауз/баров, чтобы ловить рисование */

  /* task bar */
  .bar{
    position:absolute;top:4.5px;height:36px;border-radius:var(--radius);
    display:flex;align-items:center;gap:7px;padding:0 9px 0 7px;
    cursor:grab;overflow:hidden;z-index:5;
    border:1px solid rgba(255,255,255,.5); /* light contour that reads on any bar colour */
    box-shadow:0 1px 2px rgba(0,0,0,.25);
    color:#1c1c1e;
    transition:box-shadow .12s,filter .12s;
    user-select:none;-webkit-user-select:none;
    touch-action:none;   /* touch: dragging a bar must not also pan/scroll the board (scroll via empty area / scrollbars) */
  }
  /* on hover any bar shows an 8px shading on its RIGHT edge (like the child bars' left notch) —
     it sits exactly over the right resize grip (.grip.r is also 8px at right:0), so the shaded
     strip reads as "grab here to stretch the end date". inset shadow is clipped to the bar's radius by overflow:hidden. */
  .bar:hover{filter:brightness(1.04);box-shadow:inset -8px 0 0 rgba(0,0,0,.3),0 2px 8px rgba(0,0,0,.4);z-index:6}
  .bar.dragging{cursor:grabbing;z-index:9;filter:brightness(1.06)}
  .bar.selected{outline:1px solid var(--accent);outline-offset:1px;z-index:7}
  /* Завершённый бар НЕ гасим прозрачностью (иначе сквозь него просвечивают линии-связи под барами),
     а накрываем полупрозрачной тёмной вуалью: бар остаётся непрозрачным → связь за ним больше не видна.
     Вуаль z-index:2 — над содержимым (аватар/текст), но под зелёной галочкой .bar-done (z-index:3), чтобы та оставалась яркой. */
  .bar.done{opacity:1}
  .bar.done::after{content:"";position:absolute;inset:0;border-radius:inherit;background:rgba(18,18,20,.5);pointer-events:none;z-index:2}
  /* right-edge completion toggle: hidden until hover (or always shown once done), sits just left of the resize grip */
  .bar .bar-done{position:absolute;right:17px;top:50%;transform:translateY(-50%);z-index:3;   /* 9px base + 8px to clear the hover shading strip on the right */
    width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;
    background:rgba(255,255,255,.4);color:#1c1c1e;cursor:pointer;opacity:0;transition:opacity .12s,background .12s}
  .bar:hover .bar-done{opacity:1}
  .bar .bar-done.on{opacity:1;background:#56783C;color:#fff}   /* completed: green check, always visible */
  .lasso{position:fixed;border:1px solid var(--accent);background:rgba(255,255,255,.12);border-radius:5px;z-index:60;pointer-events:none}
  /* Selection mode (toolbar «Выделение» toggle): while on, a drag on the empty grid draws a lasso
     instead of scrolling — so touch/stylus selection is reliable on iPad (no fragile long-press).
     touch-action:none stops the finger/pen from panning the board; scroll via the custom scrollbars. */
  body.select-mode #grid{touch-action:none}
  /* This is an app UI, not a document: a stray click-drag anywhere (toolbar, week labels,
     cards, lasso over the grid) should never select/highlight text blue. Kill selection
     globally, then re-enable it only inside real text fields so you can still edit values. */
  body{-webkit-user-select:none;user-select:none}
  input,textarea,[contenteditable="true"]{-webkit-user-select:text;user-select:text}

  /* Shared-board login screen (cloud mode) — full-screen gate shown until a studio session exists. */
  .login-overlay{position:fixed;inset:0;z-index:500;display:flex;align-items:center;justify-content:center;
    background:var(--canvas)}
  .login-box{width:440px;max-width:calc(100vw - 40px);background:var(--bg);border:1px solid var(--line);
    border-radius:14px;overflow:hidden;box-shadow:0 24px 70px rgba(0,0,0,.5)}
  /* шапка: слева заголовок «Sign in», справа — логотип BAK studio; снизу разделитель */
  .login-head{display:flex;align-items:center;justify-content:space-between;padding:16px 22px;border-bottom:1px solid var(--line)}
  .login-title{color:var(--text);font-size:17px;font-weight:600}
  .login-brand .logo-word{font-size:18px}
  .login-body{padding:18px 22px;display:flex;flex-direction:column;gap:14px}
  .login-field{display:flex;flex-direction:column;gap:6px}
  .login-field>span{font-size:11px;color:var(--text-dim)}
  .login-input{height:42px;background:var(--surface);border:1px solid var(--line);border-radius:10px;
    color:var(--text);padding:0 13px;font-size:14px;font-family:inherit;width:100%}
  .login-input:focus{outline:none;border-color:var(--accent)}
  /* подвал: ошибка слева, синяя кнопка «Sign in» справа; разделитель сверху */
  .login-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:14px 22px;border-top:1px solid var(--line)}
  .login-err{flex:1 1 auto;color:#e0609a;font-size:12px}
  .login-btn{height:38px;padding:0 22px;background:#5b6ef0;border:none;border-radius:9px;color:#fff;
    font-family:inherit;font-size:13px;font-weight:600;cursor:pointer}
  .login-btn:hover{background:#6d7ef5}
  .login-btn:disabled{opacity:.6;cursor:default}

  /* In-app confirmation dialog — replaces the native browser confirm() so destructive actions
     (delete client / person) match the custom UI instead of popping system chrome. */
  .confirm-overlay{position:fixed;inset:0;z-index:400;display:flex;align-items:center;justify-content:center;
    background:rgba(0,0,0,.45)}
  .confirm-box{width:340px;max-width:calc(100vw - 40px);background:var(--bg);border:1px solid var(--line);
    border-radius:14px;padding:20px;display:flex;flex-direction:column;gap:16px;box-shadow:0 20px 60px rgba(0,0,0,.45)}
  .confirm-msg{color:var(--text);font-size:14px;line-height:1.45}
  .confirm-actions{display:flex;gap:10px;justify-content:flex-end}
  .confirm-btn{height:38px;padding:0 16px;border-radius:9px;border:1px solid var(--line);background:var(--surface);
    color:var(--text);font-family:inherit;font-size:13px;cursor:pointer;transition:background .12s,filter .12s}
  .confirm-btn:hover{background:var(--surface-2)}
  .confirm-btn.danger{background:#e0574f;border-color:transparent;color:#fff;font-weight:600}   /* red = destructive */
  .confirm-btn.danger:hover{filter:brightness(1.08)}

  /* «Аналитика»: панель, выезжающая справа. Высота = рабочая область (под тулбаром, до нижнего
     отступа приложения), скругления и рамка как у сегментов. Паркуется за правым краем и въезжает. */
  .analytics-panel{
    position:fixed;
    top:calc(var(--gap)*2 + var(--toolbar-h));   /* под тулбаром, вровень с рабочей областью */
    bottom:var(--gap); right:var(--gap);
    width:490px; max-width:calc(100vw - var(--gap)*2);
    display:flex; flex-direction:column;
    background:var(--bg); border:1px solid var(--line); border-radius:12px;
    box-shadow:-14px 0 44px rgba(0,0,0,.38);
    z-index:45; overflow:hidden;
    transform:translateX(calc(100% + var(--gap)*2));   /* спрятана за правым краем */
    transition:transform .3s cubic-bezier(.4,0,.2,1);
  }
  .analytics-panel.on{transform:translateX(0)}         /* выехала */
  .ap-head{display:flex;align-items:center;justify-content:space-between;flex:0 0 auto;position:relative;
    height:calc(var(--header-h) - 1px);padding:0 8px 0 14px;border-bottom:1px solid var(--line)}   /* = шапка таймлайна минус 1px верхней рамки панели → нижние линии совпадают */
  .ap-title{font-size:14px;font-weight:600;color:var(--text)}
  .ap-close{width:28px;height:28px;display:flex;align-items:center;justify-content:center;
    background:transparent;border:none;border-radius:7px;color:var(--text-faint);
    font-size:15px;cursor:pointer;font-family:inherit;transition:background .12s,color .12s}
  .ap-close:hover{background:var(--surface-2);color:var(--text)}
  .ap-body{flex:1 1 auto;overflow:auto;padding:14px;color:var(--text)}
  /* Вкладки панели: Project / Manager / Art / Artist. Активная подчёркнута цветом своей роли. */
  .ap-tabs{display:flex;flex:0 0 auto;padding:0 6px;border-bottom:1px solid var(--line)}
  .ap-tab{flex:1 1 0;min-width:0;height:40px;background:transparent;border:none;
    color:var(--text-dim);font-family:inherit;font-size:12.5px;cursor:pointer;
    border-bottom:2px solid transparent;margin-bottom:-1px;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
    transition:color .12s,border-color .12s}
  .ap-tab:hover{color:var(--text)}
  /* Кастомные кнопки-чром не показывают браузерную рамку фокуса (появлялась, напр., при клике колёсиком по таймлайну) */
  .btn:focus,.ap-tab:focus,.ap-per-btn:focus,.ap-close:focus,.logo-btn:focus,.ap-close:focus-visible,.ap-tab:focus-visible,.btn:focus-visible{outline:none}
  /* активная вкладка подчёркнута общим акцентом (меняется в «Параметрах»), одинаково для всех вкладок */
  .ap-tab.active{color:var(--text);border-bottom-color:var(--accent)}
  .ap-empty{color:var(--text-faint);font-size:12.5px}   /* заглушка пустой вкладки */
  /* Селектор периода (год) — по центру панели (абсолютно, поверх шапки), стрелки вплотную к году. */
  .ap-period{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:flex;align-items:center;gap:7px}
  .ap-per-btn svg{width:13px;height:13px;display:block}   /* SVG-шеврон центрируется по вертикали ровно с числом */
  .ap-per-btn{width:26px;height:26px;display:flex;align-items:center;justify-content:center;
    background:transparent;border:none;border-radius:6px;color:var(--text-dim);font-size:16px;line-height:1;
    cursor:pointer;font-family:inherit;transition:background .12s,color .12s}
  .ap-per-btn:hover{background:var(--surface-2);color:var(--text)}
  .ap-per-btn:disabled{opacity:.3;cursor:default;pointer-events:none}
  .ap-per-label{font-size:13px;font-weight:600;color:var(--text);min-width:34px;text-align:center}   /* впритык под 4-значный год */
  /* Project-вкладка: KPI-плитки + список проектов */
  .ap-kpis{display:flex;gap:8px;margin-bottom:14px}
  .ap-kpi{flex:1 1 0;min-width:0;background:var(--surface);border:1px solid var(--line);border-radius:9px;
    padding:8px 4px;text-align:center;display:flex;flex-direction:column;gap:2px}
  .ap-kpi b{font-size:15px;font-weight:500;color:var(--text);line-height:1}   /* цифры чуть меньше и менее жирные */
  .ap-kpi span{font-size:12px;color:var(--text-dim)}                          /* подпись — как название проекта */
  /* цвета плиток — как метрики у менеджеров (активные/ожидает/завершено/всего) */
  .ap-kpi.act b,.ap-kpi.act span{color:#f2c544}
  .ap-kpi.plan b,.ap-kpi.plan span{color:#a892e0}
  .ap-kpi.done b,.ap-kpi.done span{color:#7fd1b5}
  .ap-kpi.tot b,.ap-kpi.tot span{color:var(--text-dim)}
  .ap-list{display:flex;flex-direction:column;gap:8px}
  .ap-proj{display:flex;gap:9px;align-items:flex-start;background:var(--surface);border:1px solid var(--line);
    border-radius:9px;padding:9px 10px}
  .ap-dot{width:9px;height:9px;border-radius:50%;flex:0 0 auto;margin-top:4px}   /* цвет клиента */
  .ap-proj-main{flex:1 1 auto;min-width:0}
  .ap-proj-name{font-size:12.5px;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .ap-proj-sub{font-size:11px;color:var(--text-dim);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .ap-bar{height:4px;background:var(--line);border-radius:2px;margin-top:7px;overflow:hidden}
  .ap-bar-fill{height:100%;background:var(--accent);border-radius:2px}
  .ap-proj-side{flex:0 0 auto;display:flex;flex-direction:column;align-items:flex-end;gap:3px}
  .ap-chip{font-size:10px;padding:2px 7px;border-radius:20px;white-space:nowrap;background:var(--surface-2);color:var(--text-dim)}
  .ap-chip.active{background:rgba(127,209,181,.16);color:#7fd1b5}   /* идёт — зелёный */
  .ap-chip.soon{background:rgba(242,197,68,.16);color:#f2c544}      /* скоро — янтарный */
  .ap-chip.overdue{background:rgba(224,87,79,.16);color:#e0574f}    /* просрочен — красный */
  .ap-chip.done{background:rgba(255,255,255,.08);color:var(--text-faint)}
  .ap-chip.upcoming{background:rgba(255,255,255,.06);color:var(--text-dim)}
  .ap-proj-days{font-size:10px;color:var(--text-faint);white-space:nowrap}
  /* Manager-вкладка: карточка человека (аватар + имя + нагрузка) и его проекты */
  .ap-mgr{margin-bottom:16px}
  .ap-mgr:last-child{margin-bottom:0}
  /* Artist / Manager / Art: отделяем людей линией — визуально видно, где кончается один и начинается следующий */
  .ap-pane[data-pane="artist"] .ap-mgr,
  .ap-pane[data-pane="manager"] .ap-mgr,
  .ap-pane[data-pane="art"] .ap-mgr{border-bottom:1px solid var(--line);padding-bottom:16px}
  .ap-pane[data-pane="artist"] .ap-mgr:last-child,
  .ap-pane[data-pane="manager"] .ap-mgr:last-child,
  .ap-pane[data-pane="art"] .ap-mgr:last-child{border-bottom:none;padding-bottom:0}
  /* Artist: имя слева (по умолчанию). Чипы + диаграмма — в общей обёртке шириной по ряду чипов,
     обёртка центрируется, а диаграмма растянута на её 100% → её края точно совпадают с краями плашек. */
  .ap-pane[data-pane="artist"] .ap-mgr-metrics{width:fit-content;max-width:100%;margin:0 auto}
  .ap-pane[data-pane="artist"] .ap-mgr-stats{margin:0 0 9px;justify-content:center}
  .ap-pane[data-pane="artist"] .ap-chart{width:100%;margin:8px 0 2px}
  .ap-mgr-head{display:flex;align-items:center;gap:9px;margin-bottom:8px}
  /* аватар как во вкладке «Состав» (.team-row .av): скруглённый квадрат, белые инициалы, тонкий контур */
  .ap-av{width:26px;height:26px;border-radius:5px;flex:0 0 auto;color:#fff;
    font-size:16px;font-weight:400;letter-spacing:.02em;box-shadow:0 0 0 1px rgba(0,0,0,.15);
    display:flex;align-items:center;justify-content:center}
  .ap-mgr-name{flex:1 1 auto;min-width:0;font-size:13px;font-weight:600;color:var(--text);
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .ap-mgr-count{font-size:11px;color:var(--text-dim);white-space:nowrap}
  /* Artist: «отпуск + даты» напротив имени — прижата вправо, тёплый акцент */
  .ap-vac{flex:0 0 auto;margin-left:auto;font-size:11px;color:#d99a5b;white-space:nowrap}
  .ap-mgr-stats{display:flex;gap:6px;margin:0 0 9px 35px;flex-wrap:wrap;align-items:center}   /* отступ слева = под имя, мимо аватара */
  .ap-mgr-stats:empty{display:none}
  /* Manager/Art: метрики блоками — подпись сверху, чипы строкой под ней (не в одну линию) */
  .ap-pane[data-pane="manager"] .ap-mgr-stats,
  .ap-pane[data-pane="art"] .ap-mgr-stats{display:block;margin-left:0}
  /* чуть больше воздуха: имя -> первая подпись */
  .ap-pane[data-pane="manager"] .ap-mgr-head,
  .ap-pane[data-pane="art"] .ap-mgr-head{margin-bottom:13px}
  .ap-metric-group{margin-bottom:15px}          /* расстояние между блоками «Проекты» и «Задачи» */
  .ap-metric-group:last-child{margin-bottom:0}
  .ap-metric-cap{font-size:10.5px;color:#c4c5c9;text-transform:uppercase;letter-spacing:.03em;margin-bottom:9px}   /* цвет как у месяцев в диаграмме Artist; подпись -> чипы */
  .ap-metric-row{display:flex;gap:6px;flex-wrap:wrap}
  /* Manager/Art: список активных проектов — кружок клиента + название + «N задач · M ракурсов» + полоска */
  .ap-mp-list{margin:11px 0 15px}   /* снизу — отступ, чтобы «ЗАДАЧИ» не приклеивались к списку проектов */
  .ap-mp-row{display:flex;gap:9px;align-items:flex-start;margin-bottom:12px}
  .ap-mp-row:last-child{margin-bottom:0}
  /* вкладка Project: те же строки, но каждая в рамке-карточке */
  .ap-mp-framed{margin:0}
  .ap-mp-framed .ap-mp-row{background:var(--surface);border:1px solid var(--line);border-radius:9px;padding:9px 10px;margin-bottom:8px}
  /* в рамке правым краем служит внутренний отступ карточки — убираем «панельный» отступ 18px */
  .ap-mp-framed .ap-mp-main .ap-bar,
  .ap-mp-framed .ap-mp-dates,
  .ap-mp-framed .ap-mp-paused{margin-right:0}
  .ap-mp-main{flex:1 1 auto;min-width:0}
  .ap-mp-name{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text);min-width:0}
  .ap-mp-title{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}   /* растягиваем имя → бейдж уходит вправо */
  /* статус «пауза» — у правого края (вровень с датами/полоской, отступ 18px), янтарная плашка как рамка паузы */
  .ap-mp-paused{flex:0 0 auto;margin-right:18px;font-size:9px;text-transform:uppercase;letter-spacing:.04em;color:#f0b45e;
    border:1px solid #f0b45e;border-radius:10px;padding:1px 7px;line-height:1.4}
  /* над полоской: слева «задачи X/Y · ракурсы X/Y», справа даты начала–конца проекта */
  .ap-mp-sub{display:flex;justify-content:space-between;align-items:baseline;gap:10px;font-size:11px;color:var(--text-dim);margin-top:2px}
  .ap-mp-counts{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .ap-mp-dates{flex:0 0 auto;font-size:10px;color:var(--text-faint);white-space:nowrap;margin-right:18px}   /* правый край дат = правому краю полоски (та же 18px) */
  .ap-mp-main .ap-bar{margin-right:18px}   /* отступ справа = левому (кружок 9 + зазор 9) */
  /* Manager/Art: под «Задачами» — артисты с активными ракурсами. Две колонки: активно / план */
  .ap-artist-list{display:flex;flex-direction:column;gap:8px;margin-top:11px;padding-right:18px}   /* правый край колонок = правому краю полосок */
  .ap-artist-head{display:flex;align-items:center;gap:8px}
  .ap-artist-sp{flex:1 1 auto}                                   /* спейсер под аватар+имя в шапке */
  .ap-artist-head .ap-artist-col{color:#c4c5c9}                  /* подписи колонок — как месяцы/подписи блоков */
  .ap-artist-row{display:flex;align-items:center;gap:8px}
  .ap-av-sm{width:20px;height:20px;border-radius:4px;font-size:12px}
  .ap-artist-name{flex:1 1 auto;min-width:0;font-size:12px;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .ap-artist-col{flex:0 0 56px;text-align:right;font-size:11px;color:var(--text-dim)}
  .ap-artist-col.act{color:#f2c544}     /* активно — янтарный, как чип «активные» */
  .ap-artist-col.started{color:#5b9df0} /* начато (в этом месяце) — синий, как чип «начато» у Artist */
  .ap-artist-col.plan{color:#a892e0}    /* план — лавандовый, как чип «план» */
  .ap-mini{font-size:12px;padding:3px 10px;border-radius:20px;background:var(--surface-2);color:var(--text-dim)}
  .ap-mini.active{color:#7fd1b5}
  .ap-mini.soon{color:#f2c544}
  .ap-mini.overdue{color:#e0574f}
  .ap-mini.done{color:#7fd1b5}   /* Artist: завершено — зелёный */
  .ap-mini.act{color:#f2c544}    /* Artist: активно — янтарный */
  .ap-mini.started{color:#5b9df0}  /* Artist: начато — синий (класс не «month», чтобы не ловить .month таймлайна) */
  .ap-mini.plan{color:#a892e0}     /* Artist: план (ещё не начатые ракурсы с назначенным исполнителем) — лавандовый */
  .ap-mini.wait{color:#93a1bd}     /* Manager · Задачи: ожидает (ракурсы из ещё не начатого проекта) — сине-серый */
  .ap-mgr-list{display:flex;flex-direction:column;gap:8px}
  /* Artist: мини-диаграмма «начатые ракурсы по месяцам» (X — месяцы, столбик — сколько начато, число сверху) */
  .ap-chart{margin:8px 0 2px 35px}   /* тот же левый отступ, что у .ap-mgr-stats — чтобы диаграмма не торчала левее плашек */
  .ap-chart-bars{display:flex;align-items:flex-end;gap:3px;height:30px}   /* высота под столбики ~16px + число сверху */
  .ap-col{flex:1 1 0;min-width:0;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:flex-end}
  .ap-col-val{font-size:9px;line-height:1;color:#c4c5c9;height:11px;margin-bottom:2px}
  .ap-col-bar{width:62%;max-width:15px;min-width:5px;background:#5b9df0;border-radius:3px 3px 0 0}  /* цвет как у чипа «начато в мес.» */
  .ap-chart-months{display:flex;gap:3px;margin-top:4px}
  .ap-month{flex:1 1 0;min-width:0;text-align:center;font-size:9px;color:#c4c5c9;overflow:hidden}
  .bar .bar-label{display:flex;align-items:center;gap:7px;min-width:0}
  /* hierarchy: chevron + add-solution on parent bars */
  .bar .bar-chevron{flex:0 0 auto;width:16px;height:16px;display:flex;align-items:center;justify-content:center;
    color:var(--text);cursor:pointer;border-radius:4px;border:1px solid var(--line);
    background:var(--surface);transition:transform .15s,background .12s,border-color .12s}
  .bar .bar-chevron:hover{background:var(--surface-2)}
  .bar .bar-chevron.collapsed{transform:rotate(-90deg)}
  .bar .bar-add{flex:0 0 auto;width:16px;height:16px;display:flex;align-items:center;justify-content:center;
    color:var(--text);cursor:pointer;border-radius:4px;
    border:1px solid var(--line);background:var(--surface);transition:border-color .12s,background .12s}
  .bar .bar-add:hover{background:var(--surface-2)}
  .bar.narrow .bar-add{display:none}
  /* child (solution) rows: subtle left accent */
  .rrow-child .bar{box-shadow:inset 8px 0 0 rgba(0,0,0,.3),0 1px 2px rgba(0,0,0,.25)}
  /* child hover: keep the permanent LEFT notch and add the RIGHT resize-handle notch on top.
     needed as its own rule because .rrow-child .bar (above) would otherwise override .bar:hover's box-shadow. */
  .rrow-child .bar:hover{box-shadow:inset 8px 0 0 rgba(0,0,0,.3),inset -8px 0 0 rgba(0,0,0,.3),0 2px 8px rgba(0,0,0,.4)}
  /* drop indicator for vertical reorder */
  .reorder-line{position:fixed;height:1px;background:var(--today);opacity:.5;z-index:50;
    pointer-events:none;border-radius:2px}
  /* highlight a lane that the dragged bar can join */
  .rrow-task.lane-join{box-shadow:inset 0 0 0 1px rgba(111,123,247,.5);border-radius:8px}
  /* parent -> children connector lines */
  .connectors .conn{fill:none;stroke:#6c6d72;stroke-width:1;stroke-linecap:round;stroke-linejoin:round}
  .bar .av{
    width:26px;height:26px;border-radius:5px;flex:0 0 auto;
    background:#1c1d20;color:#fff;font-size:16px;font-weight:400;
    display:flex;align-items:center;justify-content:center;letter-spacing:.02em;
    box-shadow:0 0 0 1px rgba(0,0,0,.15);
  }
  .rrow-child .bar .av{margin-left:10px}
  .bar .ttl{font-size:12px;font-weight:400;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* two-line solution label: project prefix on top, task name below */
  .bar .ttl2{display:flex;flex-direction:column;justify-content:center;min-width:0;line-height:1.15}
  /* hover anywhere on the bar -> its title nudges a touch bigger (scale, so no reflow / no extra clipping) */
  .bar .ttl,.bar .ttl2{transition:transform .12s ease;transform-origin:left center}
  .bar:hover .ttl,.bar:hover .ttl2{transform:scale(1.08)}
  .bar .ttl-top{font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .bar .ttl-bot{font-size:11px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .bar .grip{position:absolute;top:0;bottom:0;width:8px;cursor:ew-resize;z-index:2;touch-action:none}
  .bar .grip.l{left:0}.bar .grip.r{right:0}

  /* tooltip */
  .tip{position:fixed;z-index:200;pointer-events:none;
    background:#0f1011;border:1px solid var(--line);border-radius:8px;
    padding:9px 11px;min-width:180px;box-shadow:0 8px 30px rgba(0,0,0,.5);
    color:var(--text);font-size:12px;opacity:0;transform:translateY(4px);
    transition:opacity .1s,transform .1s}
  .tip.on{opacity:1;transform:translateY(0)}
  .tip .tname{font-weight:700;margin-bottom:6px;font-size:12.5px}
  .tip .trow{display:flex;justify-content:space-between;gap:14px;margin:3px 0;color:var(--text-dim)}
  .tip .trow b{color:var(--text);font-weight:600}
  .tip .tdates{margin-top:6px;padding-top:6px;border-top:1px solid var(--line);color:var(--text-faint);font-size:11px}

  /* ---------- Modal ---------- */
  .overlay{position:fixed;inset:0;background:rgba(0,0,0,.25);z-index:100;
    display:flex;align-items:center;justify-content:center;backdrop-filter:blur(1px);
    opacity:0;visibility:hidden;transition:opacity .16s ease,visibility .16s ease}
  .overlay.on{opacity:1;visibility:visible}
  /* one solid modal panel: header / body / footer are plain sections inside it, split only by a
     thin divider line (no separate boxes / gaps anymore). overflow:hidden clips the sections to
     the panel's rounded corners; the body scrolls on its own if the form is taller than the viewport. */
  .modal{width:480px;max-width:calc(100vw - 32px);max-height:calc(100vh - 48px);overflow:hidden;
    background:rgba(var(--modal-panel),var(--modal-alpha));
    border:1px solid rgba(255,255,255,.10);border-radius:14px;
    display:flex;flex-direction:column;
    opacity:0;transform:translateY(8px) scale(.975);transition:opacity .18s ease,transform .18s ease}
  .overlay.on .modal{opacity:1;transform:none}
  .modal h2{margin:0;padding:14px 18px;min-height:60px;font-size:15px;font-weight:500;
    border-bottom:1px solid rgba(255,255,255,.08);   /* section divider under the title */
    display:flex;align-items:center;justify-content:space-between}
  .modal h2 .x{cursor:pointer;color:var(--text-dim);width:26px;height:26px;border-radius:7px;
    display:flex;align-items:center;justify-content:center}
  .modal h2 .x:hover{background:var(--surface-2);color:var(--text)}
  .mbody{padding:16px 18px;display:flex;flex-direction:column;gap:13px;overflow:auto}
  .field{display:flex;flex-direction:column;gap:5px;min-width:0}
  .field label{font-size:11.5px;color:var(--text-dim);font-weight:600;letter-spacing:.02em}
  .field input,.field select{
    width:100%;min-width:0;
    height:36px;background:var(--bg);border:1px solid var(--line);border-radius:8px;
    color:var(--text);padding:0 11px;font-size:13px;font-family:inherit;
  }
  .field input:focus,.field select:focus{outline:none;border-color:var(--accent)}
  /* custom date field (replaces native date input) + calendar popup */
  .datefield{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;height:36px;
    background:var(--bg);border:1px solid var(--line);border-radius:8px;color:var(--text);
    padding:0 11px;font-size:13px;font-family:inherit;cursor:pointer;text-align:left}
  .datefield:hover{border-color:var(--text-faint)}
  .datefield.open{border-color:var(--accent)}
  .datefield .dfico{width:15px;height:15px;color:var(--text-dim);flex:0 0 auto}
  .datepop{position:fixed;z-index:200;width:250px;padding:10px;background:var(--surface);
    border:1px solid var(--line);border-radius:12px;box-shadow:0 16px 50px rgba(0,0,0,.55)}
  .dp-head{display:flex;align-items:center;justify-content:space-between;padding:2px 4px 8px}
  .dp-title{font-size:13px;font-weight:600;color:var(--text)}
  .dp-nav{display:flex;gap:2px}
  .dp-arrow{width:26px;height:26px;display:flex;align-items:center;justify-content:center;background:transparent;
    border:none;border-radius:6px;color:var(--text-dim);cursor:pointer;font-size:17px;line-height:1;font-family:inherit}
  .dp-arrow:hover{background:var(--surface-2);color:var(--text)}
  .dp-week{display:grid;grid-template-columns:repeat(7,1fr);margin-bottom:2px}
  .dp-wd{text-align:center;font-size:11px;color:var(--text-faint);padding:4px 0}
  .dp-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
  .dp-day{height:30px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;
    border-radius:6px;color:var(--text);font-size:12.5px;font-family:inherit;cursor:pointer}
  .dp-day:hover{background:var(--surface-2)}
  .dp-day.out{color:var(--text-faint);opacity:.5}
  .dp-day.today{outline:1px solid var(--text-faint)}
  .dp-day.sel{background:var(--accent);color:#1c1c1e;font-weight:600}
  .dp-day.sel:hover{background:var(--accent-hover)}
  .dp-foot{display:flex;justify-content:flex-end;padding-top:8px;margin-top:6px;border-top:1px solid var(--line-soft)}
  .dp-today{background:transparent;border:none;color:var(--accent);font-size:12.5px;font-family:inherit;
    cursor:pointer;padding:4px 8px;border-radius:6px}
  .dp-today:hover{background:var(--surface-2)}
  .field select option.opt-dim{color:var(--text-dim)}
  .field select:has(option.opt-dim:checked){color:var(--text-dim)}
  /* custom dropdown chevron so we control its inset from the edge */
  .field select{-webkit-appearance:none;appearance:none;padding-right:30px;
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239a9b9f' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
    background-repeat:no-repeat;background-position:right 6px center}
  /* custom <select> replacement: a .selectfield button (mirrors .datefield) + a .selectpop list
     (mirrors .datepop). The native <select> stays in the DOM, hidden, as the value source. */
  .selectfield{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;height:36px;
    background:var(--bg);border:1px solid var(--line);border-radius:8px;color:var(--text);
    padding:0 11px;font-size:13px;font-family:inherit;cursor:pointer;text-align:left}
  .selectfield:hover{border-color:var(--text-faint)}
  .selectfield.open{border-color:var(--accent)}
  .selectfield .sfval{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .selectfield .sfval.dim{color:var(--text-faint)}   /* empty value ("не выбран") shows dimmed */
  .selectfield .sfico{width:13px;height:13px;color:var(--text-dim);flex:0 0 auto;transition:transform .15s}
  .selectfield.open .sfico{transform:rotate(180deg)}
  .selectpop{position:fixed;z-index:200;max-height:240px;overflow:auto;padding:5px;
    background:var(--surface);border:1px solid var(--line);border-radius:10px;box-shadow:0 16px 50px rgba(0,0,0,.55)}
  .sopt{padding:8px 10px;border-radius:6px;cursor:pointer;font-size:13px;color:var(--text);
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .sopt:hover{background:var(--surface-2)}
  .sopt.sel{background:var(--surface-2)}
  .sopt.dim{color:var(--text-faint)}
  /* prefixed input: frozen grey "cam" + editable range */
  .angles-input{display:flex;align-items:center;height:36px;background:var(--bg);
    border:1px solid var(--line);border-radius:8px;padding:0 11px;gap:5px}
  .angles-input:focus-within{border-color:var(--accent)}
  .angles-input .pfx{color:var(--text-dim);user-select:none}
  .angles-input input{flex:1;min-width:0;height:auto;background:transparent;border:none;
    border-radius:0;padding:0;color:var(--text);font-size:13px;font-family:inherit}
  .angles-input input:focus{outline:none;border:none}
  .two{display:flex;gap:12px}.two .field{flex:1}
  .roles3{display:flex;gap:12px}.roles3 .field{flex:1}
  .roles3 .rlabel{display:flex;align-items:center;gap:6px}
  .rbadge{width:16px;height:16px;border-radius:3px;display:flex;align-items:center;justify-content:center;
    font-size:12px;font-weight:400;line-height:1;color:#fff;
    /* text-box trim -> the letter is centred by its cap height / baseline (not the font's tall line
       box), so it sits truly centred regardless of font-size. line-height:1 is the fallback. */
    text-box:trim-both cap alphabetic}
  .mfoot{padding:14px 18px;border-top:1px solid rgba(255,255,255,.08);   /* section divider above the buttons */
    display:flex;align-items:center;gap:10px}
  .mfoot .spacer{flex:1}
  .btn-danger{background:transparent;border-color:transparent;color:#e06b6b}
  .btn-danger:hover{background:rgba(224,107,107,.12)}

  /* team / состав */
  .team-legend{font-size:11.5px;color:var(--text-dim);line-height:1.6}
  .team-legend .lg{display:inline-flex;align-items:center;gap:4px;white-space:nowrap}
  .team-list{display:flex;flex-direction:column;gap:6px}
  /* В выезжающей панели список живёт внутри .ap-body (она и скроллится), поэтому свой max-height/overflow не нужен */
  .team-row{display:flex;align-items:center;gap:10px;background:var(--bg);
    border:1px solid var(--line);border-radius:9px;padding:7px 9px}
  /* drag handle to reorder people (порядок отражается в таймлайне и аналитике) */
  .team-grip{flex:0 0 auto;width:18px;height:26px;display:flex;align-items:center;justify-content:center;
    color:var(--text-faint);cursor:grab;touch-action:none;border-radius:5px;margin:-2px -4px -2px -2px}
  .team-grip:hover{color:var(--text-dim);background:var(--surface-2)}
  .team-grip:active{cursor:grabbing}
  .team-row.dragging{background:var(--surface-2);box-shadow:0 8px 22px rgba(0,0,0,.45);
    position:relative;z-index:2;border-color:var(--text-faint)}
  /* same avatar geometry as the bars (.bar .av): rounded 26px square, 16px text, subtle contour */
  .team-row .av{width:26px;height:26px;border-radius:5px;flex:0 0 auto;color:#fff;
    font-size:16px;font-weight:400;letter-spacing:.02em;box-shadow:0 0 0 1px rgba(0,0,0,.15);
    display:flex;align-items:center;justify-content:center}
  .team-row input.tname{flex:1;min-width:0;height:32px;background:transparent;border:1px solid transparent;
    border-radius:7px;color:var(--text);padding:0 8px;font-size:13px;font-family:inherit;font-weight:600}
  .team-row input.tname:hover{border-color:var(--line)}
  .team-row input.tname:focus{outline:none;border-color:var(--accent);background:var(--surface)}
  .role-toggles{display:flex;gap:5px;flex:0 0 auto}
  .rtog{width:26px;height:26px;border-radius:7px;display:flex;align-items:center;justify-content:center;
    font-size:16px;font-weight:500;line-height:1;cursor:pointer;color:var(--text-faint);
    text-box:trim-both cap alphabetic;   /* centre the letter by cap height, not the font's tall line box */
    background:var(--surface-2);border:1px solid var(--line);user-select:none;transition:.12s}
  .rtog.on{color:#fff}
  .rtog.m.on{background:var(--role-m);border-color:var(--role-m)}
  .rtog.a.on{background:var(--role-a);border-color:var(--role-a)}
  .rtog.i.on{background:var(--role-i);border-color:var(--role-i)}
  .team-del{width:30px;height:30px;border-radius:8px;flex:0 0 auto;display:flex;align-items:center;justify-content:center;
    color:var(--text-faint);cursor:pointer}
  .team-del:hover{background:rgba(224,107,107,.14);color:#e06b6b}
  /* нижняя закреплённая строка «добавить человека» — вровень с рамкой панели, отделена линией */
  .team-foot{display:flex;gap:8px;flex:0 0 auto;padding:12px 14px;border-top:1px solid var(--line)}
  .team-foot input{flex:1;height:36px;background:var(--bg);border:1px solid var(--line);border-radius:8px;
    color:var(--text);padding:0 11px;font-size:13px;font-family:inherit}
  .team-foot input:focus{outline:none;border-color:var(--accent)}
  .team-empty{color:var(--text-faint);font-size:12px;padding:10px 2px}

  /* small dropdown menu (filter/sort/params) */
  .menu{position:fixed;z-index:120;background:var(--surface);border:1px solid var(--line);
    border-radius:10px;box-shadow:0 16px 50px rgba(0,0,0,.55);padding:6px;min-width:200px}
  .menu .mhead{padding:6px 10px 4px;color:var(--text-faint);font-size:10.5px;text-transform:uppercase;letter-spacing:.05em}
  .menu .mitem{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:7px;cursor:pointer;font-size:12.5px}
  .menu .mitem:hover{background:var(--surface-2)}
  .menu .mitem .ck{margin-left:auto;color:var(--accent);opacity:0}
  .menu .mitem.sel .ck{opacity:1}
  .menu .dot{width:9px;height:9px;border-radius:50%}
  /* accent color picker row */
  .menu .mcolor{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:7px;font-size:12.5px}
  .menu .mcolor .swatch{margin-left:auto;width:26px;height:18px;padding:0;border:1px solid var(--line);
    border-radius:5px;background:var(--accent);cursor:pointer}

  .empty{position:absolute;left:calc(var(--sidebar-w) + 40px);top:120px;color:var(--text-faint);font-size:13px}
  ::-webkit-scrollbar{width:11px;height:11px}
  ::-webkit-scrollbar-thumb{background:#3a3b40;border-radius:6px;border:2px solid var(--bg)}
  ::-webkit-scrollbar-thumb:hover{background:#46474d}
  ::-webkit-scrollbar-corner{background:var(--bg)}

  /* ============================ Touch / tablet ============================ */
  /* On touch there's no hover, so controls that only appear on hover become unreachable — reveal
     them, and enlarge the small tap targets (resize grips, chevrons, delete dots) for fingers.
     (hover:none) targets touch-primary devices; a tablet with a mouse keeps the desktop behaviour.) */
  @media (hover:none){
    .proj-card .proj-menu{opacity:1}                 /* client «⋯» menu (rename/delete) always reachable */
    .bar .bar-done{opacity:1}                         /* completion checkmark always reachable */
    .bar .grip,.vac-grip{width:16px}                  /* fatter resize handles */
    .bar .bar-chevron,.bar .bar-add{width:22px;height:22px}
    .vac-frame .vac-del{width:22px;height:22px;opacity:.85}
    .vac-btn{width:26px;height:26px}
  }
  /* Narrow widths (tablet portrait): the single-row toolbar overflowed off-screen — let it wrap
     onto a second row instead of clipping «Сортировка»/«Параметры». */
  @media (max-width:920px){
    .toolbar{height:auto;min-height:var(--toolbar-h);flex-wrap:wrap;row-gap:6px;padding-bottom:6px}
    .toolbar .spacer{flex-basis:100%;height:0}       /* force a line break before the right-hand cluster */
  }
