Files
chktime/web/style.css
T
yoshikazuandClaude Opus 5 4692043106 ガントにターン単位の表示を追加
1セッション内のターンを絶対時刻の共通軸に並べる表示を、ガントタブの
タスク/ターン切替として追加。やりとりタブのタイムライン列は行ごとに
正規化されていて長さを比較できないため、実時間で並べられるようにした。

- 軸・背景・枠組みをタスク単位の描画と共通化 (timeScale/axisSvg/gridSvg/ganttFrame)
- 目盛りを秒単位まで拡張し、開始位置を step の単位で切り捨てるよう修正
- 行クリックでやりとりタブの該当ターンへ移動 (一時ハイライト)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 09:26:49 +09:00

285 lines
10 KiB
CSS

:root {
--bg: #14161a;
--pane: #1a1d23;
--pane2: #20242c;
--line: #2c313b;
--fg: #e6e9ef;
--dim: #8f98a8;
--accent: #7aa2f7;
--user: #7aa2f7;
--work: #9ece6a;
--idle: #3d4350;
--warn: #e0af68;
--cmd: #bb9af7;
font-synthesis: none;
}
* { box-sizing: border-box; }
body {
margin: 0;
height: 100vh;
display: flex;
flex-direction: column;
background: var(--bg);
color: var(--fg);
font: 13px/1.5 "Segoe UI", "Yu Gothic UI", system-ui, sans-serif;
}
header {
display: flex;
align-items: center;
gap: 12px;
padding: 8px 14px;
background: var(--pane);
border-bottom: 1px solid var(--line);
}
header h1 { margin: 0; font-size: 15px; letter-spacing: .04em; }
header .sub { color: var(--dim); font-size: 11px; }
header .spacer { flex: 1; }
.chk { color: var(--dim); user-select: none; cursor: pointer; }
/* 自動追従の状態表示 */
.fstate { color: var(--dim); font-size: 11px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.fstate:not(.off):not(:empty)::before {
content: "●";
font-size: 9px;
margin-right: 4px;
vertical-align: 1px;
}
.fstate.live::before { color: var(--work); }
.fstate.busy::before { color: var(--accent); }
.fstate.wait::before { color: var(--warn); }
.fstate.err { color: var(--warn); }
.fstate.err::before { color: var(--warn); }
button, .btn {
background: var(--pane2);
color: var(--fg);
border: 1px solid var(--line);
border-radius: 5px;
padding: 3px 10px;
font: inherit;
font-size: 12px;
cursor: pointer;
text-decoration: none;
}
button:hover, .btn:hover { border-color: var(--accent); color: var(--accent); }
main { flex: 1; display: flex; min-height: 0; }
.pane { display: flex; flex-direction: column; min-width: 0; border-right: 1px solid var(--line); }
#projects { width: 220px; flex: none; resize: horizontal; overflow: hidden; }
#sessions { width: 330px; flex: none; resize: horizontal; overflow: hidden; }
#detail { flex: 1; border-right: none; }
.pane-head {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
font-size: 11px;
letter-spacing: .08em;
color: var(--dim);
text-transform: uppercase;
background: var(--pane);
border-bottom: 1px solid var(--line);
}
.pane-head > span:first-child { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#detail-title { text-transform: none; } /* タイトルやパスをそのまま出す */
#filter {
flex: 1 1 120px;
min-width: 80px;
background: var(--bg);
border: 1px solid var(--line);
border-radius: 5px;
color: var(--fg);
padding: 3px 8px;
font: inherit;
font-size: 12px;
}
.scroll { flex: 1; overflow: auto; }
/* プロジェクト一覧 */
#project-list { list-style: none; margin: 0; padding: 0; overflow: auto; }
#project-list li { padding: 7px 10px; border-bottom: 1px solid var(--line); cursor: pointer; }
#project-list li:hover { background: var(--pane2); }
#project-list li.sel { background: var(--pane2); box-shadow: inset 3px 0 var(--accent); }
#project-list .p-path { font-size: 12px; word-break: break-all; }
#project-list .p-meta { color: var(--dim); font-size: 11px; }
/* セッション一覧 */
table { width: 100%; border-collapse: collapse; }
#session-table tr { border-bottom: 1px solid var(--line); cursor: pointer; }
#session-table tr:hover { background: var(--pane2); }
#session-table tr.sel { background: var(--pane2); box-shadow: inset 3px 0 var(--accent); }
#session-table td { padding: 6px 10px; vertical-align: top; }
.s-title { font-size: 12.5px; margin-bottom: 2px; }
.s-meta { color: var(--dim); font-size: 11px; display: flex; gap: 10px; flex-wrap: wrap; }
.s-when { white-space: nowrap; }
/* 詳細 */
#detail-body { padding: 0 0 40px; }
.empty, .loading { color: var(--dim); padding: 20px; }
.err { color: #f7768e; padding: 20px; white-space: pre-wrap; }
.sum {
display: flex;
flex-wrap: wrap;
gap: 18px;
padding: 10px 14px;
background: var(--pane);
border-bottom: 1px solid var(--line);
position: sticky;
top: 0;
z-index: 2;
}
.sum div { display: flex; flex-direction: column; }
.sum .k { color: var(--dim); font-size: 10.5px; letter-spacing: .06em; }
.sum .v { font-size: 13px; }
#turns { width: 100%; border-collapse: collapse; }
#turns th {
position: sticky;
top: 0;
background: var(--pane);
border-bottom: 1px solid var(--line);
color: var(--dim);
font-weight: 500;
font-size: 11px;
text-align: left;
padding: 6px 8px;
white-space: nowrap;
z-index: 1;
}
#turns td { padding: 6px 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
#turns tr:hover td { background: var(--pane2); }
#turns .num, #turns .n { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
#turns .time { font-variant-numeric: tabular-nums; white-space: nowrap; }
#turns .done { color: var(--dim); }
#turns .d { color: var(--dim); font-size: 11px; margin-right: 1px; }
#turns .msg { width: 40%; min-width: 160px; cursor: pointer; }
#turns .small { color: var(--dim); font-size: 11px; }
#turns .small .u { font-size: 9px; opacity: .65; margin: 0 3px 0 1px; }
#turns .msg .txt { white-space: pre-wrap; word-break: break-word; max-height: 3em; overflow: hidden; }
#turns tr.open .msg .txt { max-height: none; }
#turns .tools { color: var(--dim); font-size: 11px; margin-top: 3px; word-break: break-all; }
.kind { font-size: 10px; padding: 0 5px; border-radius: 3px; border: 1px solid var(--line); color: var(--dim); }
.kind.command { color: var(--cmd); border-color: var(--cmd); }
.kind.resume { color: var(--warn); border-color: var(--warn); }
.int { color: var(--warn); font-size: 11px; }
.ovl { color: var(--cmd); font-size: 11px; cursor: help; }
.bar { display: flex; align-items: center; gap: 2px; height: 12px; min-width: 95px; }
.bar i { display: block; height: 8px; border-radius: 2px; }
.bar .b-idle { background: var(--idle); }
.bar .b-wait { background: var(--user); }
.bar .b-work { background: var(--work); }
/* プロジェクト横断モード */
#project-list li.all { border-bottom: 2px solid var(--line); }
#project-list li.all .p-path::before { content: "▦ "; color: var(--dim); }
.s-proj { color: var(--dim); font-size: 10.5px; margin-bottom: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 日別集計 */
.tabs { display: flex; gap: 4px; flex: none; }
.tab { padding: 2px 9px; font-size: 11px; letter-spacing: normal; text-transform: none; }
.tab.sel { color: var(--accent); border-color: var(--accent); }
.chart-bar {
display: flex;
align-items: center;
gap: 12px;
padding: 8px 14px 0;
flex-wrap: wrap;
}
.rngs { display: flex; gap: 4px; }
.rng { font-size: 11px; padding: 2px 8px; }
.rng.sel { color: var(--accent); border-color: var(--accent); }
.chart-bar .note { color: var(--dim); font-size: 10.5px; }
.chart { padding: 4px 14px 0; overflow-x: auto; }
.chart svg text.ax { fill: var(--dim); font-size: 10px; }
.chart svg text.ax.we { fill: var(--warn); }
.chart svg line.grid { stroke: var(--line); stroke-width: 1; }
.chart svg line.axis { stroke: var(--dim); stroke-width: 1; opacity: .5; }
.chart svg rect.wk { fill: #ffffff; opacity: .028; }
.chart svg rect.hit { fill: transparent; }
.chart svg rect.hit:hover { fill: #ffffff; opacity: .06; }
.legend { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 8px 14px 2px; font-size: 11px; color: var(--dim); }
.legend .lg { display: flex; align-items: center; gap: 5px; white-space: nowrap; }
.legend .lg i, .pj-i i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; flex: none; }
.legend .lg b { color: var(--fg); font-weight: 500; }
#daily-table { margin-top: 8px; }
#daily-table th {
position: sticky; top: 0; background: var(--pane); border-bottom: 1px solid var(--line);
color: var(--dim); font-weight: 500; font-size: 11px; text-align: left; padding: 6px 10px; white-space: nowrap; z-index: 1;
}
#daily-table td { padding: 5px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
#daily-table tr:hover td { background: var(--pane2); }
#daily-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
#daily-table .time { font-variant-numeric: tabular-nums; white-space: nowrap; }
#daily-table .time.we { color: var(--warn); }
#daily-table .d { color: var(--dim); font-size: 11px; }
#daily-table .pj { display: flex; flex-wrap: wrap; gap: 3px 12px; font-size: 11px; color: var(--dim); }
.pj-i { display: flex; align-items: center; gap: 4px; white-space: nowrap; }
/* ガント */
.sum.flat { position: static; }
.gantt { padding: 4px 14px 0; }
.gantt .g-head {
display: flex;
align-items: flex-end;
position: sticky;
top: 0;
z-index: 2;
background: var(--bg);
border-bottom: 1px solid var(--line);
}
.gantt .g-lab-h {
width: var(--labw);
flex: none;
color: var(--dim);
font-size: 10.5px;
padding-bottom: 5px;
}
.gantt .g-body { display: flex; }
.gantt .g-labels { width: var(--labw); flex: none; }
.gantt .g-lab-row {
height: 22px;
display: flex;
align-items: center;
gap: 6px;
padding-right: 8px;
font-size: 11px;
cursor: pointer;
overflow: hidden;
}
.gantt .g-lab-row:nth-child(even) { background: rgba(255, 255, 255, .02); }
.gantt .g-lab-row:hover { background: var(--pane2); }
.gantt .g-lab-row.sel { box-shadow: inset 3px 0 var(--accent); }
.gantt .g-lab-row i { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.gantt .g-when { color: var(--dim); font-variant-numeric: tabular-nums; white-space: nowrap; }
.gantt .g-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gantt svg text.ax { fill: var(--dim); font-size: 10px; }
.gantt svg text.ax.hi { fill: var(--fg); }
.gantt svg line.grid { stroke: var(--line); stroke-width: 1; }
.gantt svg line.day { stroke: var(--line); stroke-width: 1; }
.gantt svg line.now { stroke: var(--warn); stroke-width: 1; stroke-dasharray: 3 3; }
.gantt svg rect.wk { fill: #ffffff; opacity: .028; }
.gantt svg rect.stripe { fill: #ffffff; opacity: .02; }
.gantt svg rect.g-hit { fill: transparent; cursor: pointer; }
.gantt svg rect.g-hit:hover { fill: #ffffff; opacity: .07; }
/* ガント (ターン単位) */
.gantt .g-no { color: var(--dim); font-variant-numeric: tabular-nums; white-space: nowrap; }
.gantt svg rect.t-wait { fill: var(--user); }
.gantt svg rect.t-work { fill: var(--work); }
.gantt svg rect.t-none { fill: var(--idle); }
#turns tr.hi td { background: rgba(122, 162, 247, .18); }