:root{--label-w:170px;--lane-h:38px;--line:#d9dde3;--head-year:#cfdcf0;--head-quarter:#e3ebf7;--head-month:#f3f6fb;--accent:#e67e22}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{color:#1f2430;background:#fff;font:13px/1.35 system-ui,-apple-system,Segoe UI,sans-serif}button,select,input,textarea{font:inherit}button{cursor:pointer;background:#fff;border:1px solid #b9c0cb;border-radius:4px;padding:3px 9px}button:hover:not(:disabled){background:#f1f4f8}button:disabled{opacity:.45;cursor:default}.center{color:#667;justify-content:center;align-items:center;height:100%;display:flex}.login{border:1px solid var(--line);border-radius:8px;gap:10px;width:300px;margin:14vh auto 0;padding:24px;display:grid}.login .logo{width:200px;max-width:100%;height:auto;margin:4px auto 10px;display:block}.login h1{text-align:center;margin:0 0 6px;font-size:20px}.login input{border:1px solid #b9c0cb;border-radius:4px;padding:6px 8px}.login .google-btn{color:inherit;text-align:center;background:#fff;border:1px solid #b9c0cb;border-radius:4px;padding:8px;font-weight:600;text-decoration:none;display:block}.login .google-btn:hover{background:#f1f4f8}.login-or{text-align:center;color:#667;font-size:12px}.error{color:#c0392b}.app{flex-direction:column;height:100%;display:flex}.toolbar{border-bottom:1px solid var(--line);background:#f7f8fa;flex-wrap:wrap;align-items:center;gap:8px;padding:8px 12px;display:flex}.toolbar .logo{width:auto;height:22px;display:block}.toolbar .title{border-left:1px solid var(--line);margin-right:8px;padding-left:8px;font-size:16px;font-weight:600}.toolbar .spacer{flex:1}.toolbar .group{align-items:center;gap:4px;display:flex}.monthfield{gap:2px;display:inline-flex}.monthfield select,.monthfield input{background:#fff;border:1px solid #b9c0cb;border-radius:4px;padding:2px 4px}.monthfield input{width:64px}.menu{position:relative}.menu-pop{z-index:30;border:1px solid var(--line);background:#fff;border-radius:6px;min-width:150px;padding:4px;display:grid;position:absolute;top:100%;right:0;box-shadow:0 6px 18px #00000026}.menu-pop button{text-align:left;border:0;border-radius:4px}.timeline{flex:1;position:relative;overflow:auto}.tl-inner{position:relative}.tl-header{z-index:12;position:sticky;top:0}.hrow{display:flex}.hcorner{z-index:14;width:var(--label-w);border-right:1px solid var(--line);border-bottom:1px solid var(--line);background:#fff;flex:none;position:sticky;left:0}.hcell{text-align:center;border-right:1px solid var(--line);border-bottom:1px solid var(--line);white-space:nowrap;flex:none;padding:3px 0;position:relative;overflow:hidden}.hcell.year{background:var(--head-year);font-weight:600}.hcell.quarter{background:var(--head-quarter)}.hcell.month{background:var(--head-month);color:#555}.resizer{cursor:col-resize;width:6px;position:absolute;top:0;bottom:0;right:0}.resizer:hover{background:#3a7bd559}.product{border-bottom:2px solid #c7ccd4;display:flex}.product-label{z-index:10;width:var(--label-w);border-right:1px solid var(--line);background:#fff7e6;flex:none;justify-content:space-between;align-items:flex-start;gap:4px;padding:6px 8px;font-weight:600;display:flex;position:sticky;left:0}.product-label .swatch{border-radius:2px;width:10px;height:10px;margin-right:6px;display:inline-block}.lanes{flex:none;position:relative}.group-head{border-bottom:1px solid var(--line);color:#556;background:#eef1f6;height:20px;font-size:11px;font-weight:600;position:relative}.group-head span{left:calc(var(--label-w) + 6px);line-height:20px;position:sticky}.lane-group[data-group=promises] .group-head{border-top:1px solid var(--line);background:#f3eefb}.gridlines{pointer-events:none;position:absolute;inset:0}.gridlines i{background:var(--line);width:1px;position:absolute;top:0;bottom:0}.lane{border-bottom:1px solid var(--line);position:relative}.lane-resizer{cursor:row-resize;z-index:5;height:6px;position:absolute;bottom:-3px;left:0;right:0}.lane-resizer:hover{background:#3a7bd559}.add-lane{height:24px;position:relative}.add-lane button,.lane .del-lane{left:calc(var(--label-w) + 6px);color:#667;background:0 0;border:0;font-size:11px;position:sticky}.lane .del-lane{z-index:2;opacity:0;position:absolute;top:8px;left:6px}.lane:hover .del-lane{opacity:1}.bar{color:#fff;cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none;border-radius:4px;align-items:center;padding:0 8px;line-height:17px;display:flex;position:absolute;top:4px;overflow:hidden;box-shadow:0 1px 2px #00000040}.bar.dragging{opacity:.3}.bar.done:after{content:"";pointer-events:none;background:repeating-linear-gradient(135deg,#ffffff47 0 5px,#0000 5px 10px);position:absolute;inset:0}.bar .check{font-weight:700}.bar.ghost{opacity:.8;pointer-events:none;z-index:6;outline:2px dashed #1f2430}.bar .handle{cursor:ew-resize;background:#ffffff59;width:7px;position:absolute;top:0;bottom:0;right:0}.today-line{z-index:8;pointer-events:none;background:#e74c3c;width:2px;position:absolute;top:0;bottom:0}.backdrop{z-index:40;background:#14192366;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.dialog{background:#fff;border-radius:8px;gap:10px;width:min(460px,94vw);padding:18px;display:grid;box-shadow:0 12px 40px #0000004d}.dialog h2{margin:0;font-size:16px}.dialog label{gap:3px;font-weight:600;display:grid}.dialog input[type=text],.dialog select,.dialog textarea{border:1px solid #b9c0cb;border-radius:4px;padding:6px 8px;font-weight:400}.dialog textarea{resize:vertical;min-height:80px}.dialog label.check-row{align-items:center;gap:8px;display:flex}.dialog .row{gap:12px;display:flex}.dialog .actions{justify-content:flex-end;gap:8px;margin-top:4px;display:flex}.dialog .actions .danger{color:#c0392b;border-color:#e0b4ae;margin-right:auto}.toast{color:#fff;z-index:60;background:#1f2430;border-radius:6px;max-width:90vw;padding:9px 16px;position:fixed;bottom:16px;left:50%;transform:translate(-50%)}.bar .label .name,.bar .label .desc{display:block}.bar .label .desc{opacity:.85;white-space:pre-line;font-size:11px}.bar .label{-webkit-line-clamp:var(--lines,1);overflow-wrap:anywhere;pointer-events:none;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}
