181 lines
17 KiB
CSS
181 lines
17 KiB
CSS
/* 3. Закреплённая шапка: заголовок и действия (PageHeader), панель управления (Panel), предупреждения, легенда */
|
||
.sticky{position:sticky;top:env(safe-area-inset-top,0px);z-index:10;background:var(--color-bg-canvas);padding-block:var(--space-4) var(--space-2);margin:0 0 var(--space-2);box-shadow:0 1px 0 var(--color-border-default)}
|
||
.sticky .ui-page-header{margin-bottom:var(--space-3);gap:var(--space-2)}
|
||
.stats{font-variant-numeric:tabular-nums}
|
||
.stats b{color:var(--color-text-primary);font-weight:600}
|
||
.board-src{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-2) var(--space-3);min-height:var(--lh-body)}
|
||
.board-src:empty{display:none}
|
||
.board-src__label{font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--color-text-secondary);max-width:420px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||
.board-event{font-size:var(--fs-body);line-height:var(--lh-body);color:var(--color-text-secondary)}
|
||
.board-event--warn{color:var(--color-status-warning)}
|
||
.menu__label{display:inline-flex;align-items:center;gap:var(--space-2)}
|
||
.confirm{display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-2) var(--space-3);font-size:var(--fs-body);line-height:var(--lh-body);max-width:280px}
|
||
.confirm__row{display:flex;gap:var(--space-2)}
|
||
.menu .confirm .ui-btn{width:auto;flex:1 1 0;justify-content:center;border-radius:var(--radius-round);min-height:var(--control-h);padding:0 var(--space-3);font-weight:600}
|
||
.menu .confirm .ui-btn--danger{background:var(--color-action-danger);color:var(--color-text-on-primary)}
|
||
.menu .confirm .ui-btn--secondary{background:transparent;border:1px solid var(--color-border-strong)}
|
||
/* 5. Панель управления: выбор спринтов и исполнителей, группы «Показать» и «Режим» */
|
||
.board-controls{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-2) var(--space-3);padding:var(--space-3) var(--space-4);margin:0 0 var(--space-2)}
|
||
.board-controls__group{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-2)}
|
||
.board-controls__label{font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--color-text-secondary)}
|
||
.board-controls__sep{width:1px;align-self:stretch;min-height:var(--control-h);background:var(--color-border-default)}
|
||
.board-controls__text{font-size:var(--fs-body);color:var(--color-text-secondary)}
|
||
.multi-btn{display:inline-flex;align-items:center;justify-content:space-between;gap:var(--space-2);width:auto;min-width:180px;max-width:360px;text-align:left;cursor:pointer}
|
||
.multi-btn .lbl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||
.multi-btn[aria-expanded="true"]{border-color:var(--color-action-primary)}
|
||
.legend-box{margin:0}
|
||
.legend-head{display:flex;align-items:center;gap:var(--space-2)}
|
||
.legend{display:flex;flex-wrap:wrap;align-items:center;gap:2px 12px;margin:var(--space-1) 0 0;font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--color-text-secondary)}
|
||
.legend span{display:inline-flex;align-items:center;gap:6px}
|
||
.legend .sep{width:1px;height:14px;background:var(--color-border-default)}
|
||
.legend .hint{margin-left:auto}
|
||
.lg{font:inherit;font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--color-text-secondary);background:none;border:1px solid transparent;padding:2px 6px;border-radius:var(--radius-xs);cursor:pointer;display:inline-flex;align-items:center;gap:6px}
|
||
.lg:hover{background:var(--color-bg-hover);color:var(--color-text-primary)}
|
||
.lg:focus-visible{background:var(--color-bg-hover);color:var(--color-text-primary);border-color:var(--color-border-selected);outline:none}
|
||
.lg.off{opacity:.45;text-decoration:line-through}
|
||
.sw{width:10px;height:10px;border-radius:2px;display:inline-block}
|
||
.ln{width:26px;height:0;border-top:2px solid var(--edge-strong);display:inline-block}
|
||
.ln.dash{border-top-style:dashed;border-top-color:var(--edge)}
|
||
.ln.hand{border-top-color:var(--guide)}
|
||
.ln.crit{border-top-width:4px;border-top-color:var(--guide)}
|
||
.out-sw{width:16px;height:11px;border:1.5px dashed var(--color-text-secondary);border-radius:3px;display:inline-block}
|
||
|
||
/* 6. Доска: прокрутка только по горизонтали (вертикальная — у страницы), дорожки по эпикам, карточки абсолютные */
|
||
.stage{display:flex;gap:var(--space-3);align-items:stretch}
|
||
.wrap{flex:1 1 auto;min-width:0;overflow-x:auto;overflow-y:hidden;border:1px solid var(--color-border-default);border-radius:var(--radius-xl);background:var(--color-bg-surface);user-select:none;-webkit-user-select:none}
|
||
.board{position:relative;min-width:100%}
|
||
svg.edges,svg.guides{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
|
||
svg.guides{z-index:3}
|
||
svg.guides line{stroke:var(--guide);stroke-width:1;stroke-dasharray:4 3}
|
||
.empty{padding:40px 16px;color:var(--color-text-secondary);text-align:center}
|
||
#hubState{white-space:normal;min-width:0}
|
||
.lane{position:absolute;left:0;right:0;border-top:1px solid var(--color-border-default)}
|
||
.lane:nth-child(even of .lane){background:var(--lane-alt)}
|
||
.lane.folded{background:var(--color-bg-track);border-bottom:1px solid var(--color-border-strong);border-top-color:var(--color-border-strong)}
|
||
.lane.target{box-shadow:inset 0 3px 0 var(--color-action-primary)}
|
||
.lane.target-after{box-shadow:inset 0 -3px 0 var(--color-action-primary)}
|
||
.lane.dragging{opacity:.6}
|
||
.lane-head{position:absolute;left:8px;top:8px;display:flex;align-items:center;gap:4px;z-index:1}
|
||
.fold{width:20px;height:20px;border:0;background:none;color:var(--color-text-secondary);cursor:pointer;padding:0;border-radius:var(--radius-xs);display:inline-flex;align-items:center;justify-content:center}
|
||
.fold svg{transition:transform .15s}
|
||
.fold:hover{background:var(--color-bg-hover);color:var(--color-text-primary)}
|
||
.fold:focus-visible,.lane-tools button:focus-visible,.card .open-card:focus-visible{outline:2px solid var(--color-focus-ring);outline-offset:1px}
|
||
.lane.folded .fold svg{transform:rotate(-90deg)}
|
||
.lane-name{font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--color-text-secondary);font-weight:600;cursor:grab;padding:2px 4px;border-radius:var(--radius-xs);user-select:none;touch-action:none}
|
||
.lane-name:hover{background:var(--color-bg-hover);color:var(--color-text-primary)}
|
||
.lane-count{display:none;font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--color-text-secondary);margin-left:4px}
|
||
.lane.folded .lane-count{display:inline}
|
||
.lane-tools{display:none;gap:2px}
|
||
.lane:hover .lane-tools{display:inline-flex}
|
||
.lane-tools button{display:inline-flex;align-items:center;justify-content:center;color:var(--color-text-secondary);background:var(--color-bg-surface);border:1px solid var(--color-border-strong);border-radius:var(--radius-xs);width:22px;height:22px;cursor:pointer;padding:0}
|
||
.lane-tools button:hover{border-color:var(--color-action-primary);color:var(--color-action-primary)}
|
||
.lane-tools button:disabled{opacity:.35;cursor:default}
|
||
/* режим «по датам»: колонки по плановым датам окончания, шапка колонки над дорожками; карточки двигаются внутри своей колонки */
|
||
.dcol{position:absolute;top:0;border-left:1px solid var(--color-border-default);box-sizing:border-box;pointer-events:none}
|
||
.dcol:first-of-type{border-left:0}
|
||
.dcol.past{background:color-mix(in srgb,var(--p-crit) 5%,transparent)}
|
||
.dcol.today{background:color-mix(in srgb,var(--color-action-primary) 7%,transparent)}
|
||
/* полоса дат над доской: липнет под шапкой страницы, по горизонтали двигается вместе с доской (transform по scrollLeft) */
|
||
.dates-bar{position:sticky;top:calc(var(--head-h,0px) + env(safe-area-inset-top,0px));z-index:9;background:var(--color-bg-canvas)}
|
||
.dates-in{overflow:hidden;border:1px solid var(--color-border-default);border-bottom:0;border-radius:var(--radius-xl) var(--radius-xl) 0 0;background:var(--color-bg-surface);height:36px;box-sizing:border-box}
|
||
.dates-track{position:relative;height:100%}
|
||
.dlabel{position:absolute;top:10px;font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--color-text-primary);font-weight:600;white-space:nowrap}
|
||
.dlabel .n{font-weight:400;color:var(--color-text-secondary);margin-left:6px;font-variant-numeric:tabular-nums}
|
||
.dlabel.past{color:var(--p-crit)}
|
||
.dlabel.today{color:var(--color-action-primary)}
|
||
.dlabel.none{color:var(--color-text-secondary);font-weight:400}
|
||
.stage.bydate .wrap{border-top-left-radius:0;border-top-right-radius:0}
|
||
.dsplit{position:absolute;top:0;bottom:0;width:11px;margin-left:-5px;cursor:col-resize;z-index:1}
|
||
.dsplit::after{content:"";position:absolute;left:5px;top:6px;bottom:6px;width:1px;background:var(--color-border-default)}
|
||
.dsplit:hover::after,.dsplit.on::after{background:var(--color-action-primary);width:3px;left:4px;border-radius:2px}
|
||
.dates-in.resizing{cursor:col-resize}
|
||
/* горизонтальная прокрутка доски, прилипшая к низу окна: полоса всегда видна, скроллбар нарисован явно (на macOS системный прячется) */
|
||
.hscroll{position:sticky;bottom:0;z-index:8;overflow-x:scroll;overflow-y:hidden;height:14px;background:var(--color-bg-canvas);padding-top:2px;box-sizing:border-box;scrollbar-width:thin;scrollbar-color:var(--color-border-strong) var(--color-bg-track)}
|
||
.hscroll>div{height:1px}
|
||
.hscroll::-webkit-scrollbar{height:12px}
|
||
.hscroll::-webkit-scrollbar-track{background:var(--color-bg-track);border-radius:6px}
|
||
.hscroll::-webkit-scrollbar-thumb{background:var(--color-border-strong);border-radius:6px;border:2px solid var(--color-bg-track)}
|
||
.hscroll::-webkit-scrollbar-thumb:hover{background:var(--color-action-primary)}
|
||
/* карточка: текст выделяется, тянуть можно только за рамку (появляется при наведении) и за уголок */
|
||
.card{position:absolute;width:240px;height:120px;box-sizing:border-box;background:var(--color-bg-surface);border:1px solid var(--color-border-default);border-radius:var(--radius-lg);padding:12px;display:flex;flex-direction:column;gap:4px;overflow:hidden;cursor:default;touch-action:none}
|
||
.card:hover{border-color:var(--color-border-strong)}
|
||
.card.out{border-style:dashed;opacity:.7}
|
||
.card.closed{opacity:.4}
|
||
.card.closed:hover,.card.closed:focus-within{opacity:1}
|
||
.edges path.closed{opacity:.4}
|
||
.card.crit{box-shadow:0 0 0 2px var(--guide)}
|
||
.card.focus{box-shadow:0 0 0 2px var(--color-action-primary)}
|
||
.card.drag{cursor:grabbing;border-color:var(--color-action-primary);box-shadow:var(--shadow-popover);z-index:2}
|
||
.card .title,.card .state,.card .who,.card .meta,.card .key,.card .sprint-tag{user-select:text;-webkit-user-select:text;cursor:text;touch-action:auto}
|
||
.card .key{cursor:pointer}
|
||
.card .meta{cursor:default}
|
||
.card .grip{position:absolute;background:var(--color-action-primary);opacity:0;cursor:grab;z-index:1;transition:opacity .12s}
|
||
.card .grip.t{left:0;right:0;top:0;height:8px;border-radius:11px 11px 0 0}
|
||
.card .grip.b{left:0;right:14px;bottom:0;height:8px;border-radius:0 0 0 11px}
|
||
.card .grip.l{left:0;top:0;bottom:0;width:8px;border-radius:11px 0 0 11px}
|
||
.card .grip.r{right:0;top:0;bottom:14px;width:8px;border-radius:0 11px 0 0}
|
||
.card:hover .grip,.card.drag .grip{opacity:.6}
|
||
.card.drag .grip{cursor:grabbing}
|
||
.card .rsz{position:absolute;right:0;bottom:0;width:14px;height:14px;cursor:nwse-resize;background:linear-gradient(135deg,transparent 50%,var(--color-border-strong) 50%);border-bottom-right-radius:11px;z-index:2}
|
||
.card:hover .rsz{background:linear-gradient(135deg,transparent 50%,var(--color-action-primary) 50%)}
|
||
.head{display:flex;align-items:center;justify-content:space-between;gap:6px;min-width:0}
|
||
.card .key{font-family:var(--font-mono);font-size:13px;font-weight:600;color:var(--color-action-primary);text-decoration:none;flex:0 0 auto}
|
||
.sprint-tag{font-size:11px;line-height:1;padding:4px 7px;border-radius:var(--radius-round);background:var(--color-bg-track);color:var(--color-text-secondary);max-width:55%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:0 1 auto}
|
||
.sprint-tag.sel{background:var(--color-action-primary);color:var(--color-text-on-primary)}
|
||
.sprint-tag.none{background:transparent;border:1px dashed var(--color-border-strong)}
|
||
.title{font-size:14.5px;line-height:19px;font-weight:600;color:var(--color-text-primary);min-width:0;flex:1 1 auto;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}
|
||
.meta{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--color-text-secondary);white-space:nowrap;flex:0 0 auto}
|
||
.kind{display:inline-flex;align-items:center;gap:4px}
|
||
.kind i{width:8px;height:8px;border-radius:2px;display:inline-block}
|
||
.prio{font-weight:600}
|
||
/* состояние задачи (статус, срок, исполнитель) — отдельный блок под чертой, основным цветом: это главное после названия */
|
||
.state,.who{font-size:13px;flex:0 0 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--color-text-primary)}
|
||
.state{display:flex;align-items:center;gap:6px;margin-top:4px;padding-top:7px;border-top:1px solid var(--color-border-default)}
|
||
/* статус — вид Badge (neutral) */
|
||
.status{font-size:var(--fs-caption);line-height:var(--lh-caption);font-weight:600;padding:1px 8px;border:1px solid var(--color-border-default);border-radius:var(--radius-round);background:var(--color-bg-track);color:var(--color-text-secondary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||
.due{font-variant-numeric:tabular-nums;font-weight:600;flex:0 0 auto}
|
||
.who::before{content:"";display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--color-action-primary);margin-right:5px;vertical-align:1px}
|
||
.who.none{color:var(--color-text-secondary);font-style:italic}
|
||
.who.none::before{background:transparent;border:1px solid var(--color-text-secondary)}
|
||
|
||
/* 7. Панель проблем справа от доски, липнет под шапкой; прокручивается содержимое внутри рамки Panel */
|
||
.drawer{flex:0 0 340px;max-width:40%;box-sizing:border-box;align-self:flex-start;position:sticky;top:calc(var(--head-h,0px) + 8px);max-height:calc(100vh - var(--head-h,0px) - 24px);display:flex;font-size:var(--fs-body)}
|
||
.drawer>.ui-panel{display:flex;flex-direction:column;gap:var(--space-3);min-height:0;min-width:0;flex:1 1 auto;padding:var(--space-4) 0 var(--space-4) var(--space-4)}
|
||
.drawer-head{display:flex;justify-content:space-between;align-items:center;gap:var(--space-2);padding-right:var(--space-4)}
|
||
.drawer-body{overflow-y:auto;min-height:0;padding-right:var(--space-4)}
|
||
.board-h2{margin:0;font-size:var(--fs-lg);line-height:var(--lh-lg);font-weight:700;color:var(--color-text-primary)}
|
||
.board-h3{margin:var(--space-3) 0 var(--space-1);font-size:var(--fs-caption);line-height:var(--lh-caption);font-weight:600;color:var(--color-text-secondary)}
|
||
.board-h3:first-child{margin-top:0}
|
||
.drawer ul{margin:0;padding-left:18px}
|
||
.drawer li{margin:3px 0}
|
||
.drawer .k{font-family:var(--font-mono);font-size:13px;font-weight:600;color:var(--color-action-primary);text-decoration:none}
|
||
.drawer .ok{color:var(--color-status-success);margin:0}
|
||
.drawer .why{color:var(--color-text-secondary)}
|
||
|
||
/* 8. Экспорт JSON и таблица связей (включаются из меню «Ещё») */
|
||
.export{display:flex;flex-direction:column;gap:var(--space-2);margin:0 0 var(--space-2)}
|
||
.export__row{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-2)}
|
||
.export__hint{font-size:var(--fs-caption);line-height:var(--lh-caption);color:var(--color-text-secondary)}
|
||
.export textarea{font-family:var(--font-mono);font-size:11.5px;width:100%;box-sizing:border-box;height:180px;border:1px solid var(--color-border-default);border-radius:var(--radius-sm);background:var(--color-bg-surface);color:var(--color-text-primary);padding:8px;resize:vertical}
|
||
.link-table{margin-top:var(--space-3)}
|
||
.tbl{max-width:100%;overflow-x:auto;margin-top:var(--space-2)}
|
||
table{border-collapse:collapse;font-size:var(--fs-body);min-width:520px}
|
||
th,td{text-align:left;padding:6px 10px;border-bottom:1px solid var(--color-border-default);vertical-align:top}
|
||
th{font-size:var(--fs-caption);font-weight:600;color:var(--color-text-secondary)}
|
||
td.k{font-family:var(--font-mono);font-size:12px;white-space:nowrap;color:var(--color-action-primary)}
|
||
|
||
/* 9. Движение и узкие экраны */
|
||
@media (prefers-reduced-motion:no-preference){.card{transition:border-color .15s}}
|
||
@media (prefers-reduced-motion:reduce){.card .grip,.fold svg{transition:none}}
|
||
@media (max-width:900px){.stage{flex-direction:column}.drawer{flex:none;max-width:100%;max-height:none;position:static}}
|
||
@media (max-width:640px){.sticky{position:static}.dates-bar{position:static}}
|
||
@media (max-width:640px){.board-controls__sep,.legend .sep{display:none}}
|
||
|
||
/* «Открыть карточку» в заголовке карточки (R-1) */
|
||
.card .open-card{margin-left:6px;color:var(--color-text-secondary);text-decoration:none;display:inline-flex;align-items:center;border-radius:var(--radius-xs)}
|
||
.card .open-card:hover{color:var(--color-action-primary)}
|
||
/* слой измерения: карточки шириной CW с высотой по содержимому, невидим */
|
||
.measure{position:absolute;left:-100000px;top:0;visibility:hidden;pointer-events:none}
|
||
.measure .card{position:static;height:auto}
|
||
.measure .card .title{-webkit-line-clamp:unset}
|