Newer
Older
client_dwatch / components / features / detail-log / CleanLogTable.module.css
/*
 * ★列幅を固定する(`table-layout: fixed`)★ — 2026-10-01 ユーザー指摘
 * 「言語切り替え時に表などの位置も動いてしまいます」。
 * 以前は列幅を中身(見出しの文字)から自動で決めていたため、見出しが英語になると
 * 列ごとの幅が最大 45px(通常表示)/ 75px(ダッシュボードの縮小表示)変わり、表が横に崩れていた。
 *
 * ★通常表示は全列に px の幅を付け、表の余った幅は ★全列に幅の比で配る★(`table-layout: fixed` の既定の配り方)★。
 *   ユーザー指示 2026-10-06「詳細ログも施設名が広すぎるので同じように調整して」(D-167)。
 *   ★旧: 施設名の列だけ幅を指定せず、余りを全部受け持っていた★(広い画面で施設名だけが極端に広くなった)。
 *   ★施設名 110 は、画面幅 1440px で縦スクロールバー(15〜17px)が出ても収まる値(110 + 1024 = 1134。入れ物は 1154px、スクロールバーが出ると 1137〜1139px)★。2026-10-19 に 126 → 110(11px の横スクロールを消すため。指示書AX 段階7)
 * ★ダッシュボードの縮小表示(`.compact`)も同じ配り方★(同日「ダッシュボードも同じように直して」。D-167 追記)。
 * 値は ★言語によらず同じ★。
 *
 * 幅の決め方: 「JP / EN の見出しの大きい方」と「セルの中身」の大きい方 + 余裕。
 *   見出しは 11px・太字・大文字化・字間 0.6px、左右の padding 12px ずつ(`.th`)を含む。
 *   ★見出しは折り返さない★(`.th` の `white-space: nowrap`)ので、ここが足りないと
 *   隣の列にはみ出す。訳語を変えたら幅も見直すこと。
 *   - 機種 92      : 見出し EN「MODEL」≒66 / 中身「PUDU CC1」(13px) ≒89
 *   - シリアル 126 : 見出し ≒66 / 中身「8111R5628060033」(等幅 11px・15文字) ≒123
 *   - 日付 64      : 見出し EN「DATE」≒53 / 中身「12/31」(12px) ≒58
 *   - 予定 100     : 見出し EN「SCHEDULED」≒94 / 中身「03:30」≒61
 *   - 事前チェック1回目 / 2回目 130 ずつ(D-178。ユーザー判断 2026-10-16「案1」):
 *       見出し JP「事前チェック1回目」≒124(JP の方が広い)/ EN「PRE-CHECK 1」≒102。
 *       中身は Pill + 何分前か(`.precheckCell`)。通常の値「Standby.」(12px) ≒63 + 間 6 + 「60分前」(11px) ≒34
 *       + padding 24 ≒127 で横並びに収まる。★Pill の値が長いと分数は Pill の下に回る★(flex-wrap。はみ出さない)。
 *       ★2列の合計は旧(1h前ST 120 + 30分前ST 140 = 260)と同じ★ — 表の最小幅 1134px を増やさないため
 *       (増やすと画面幅 1440px で横スクロールが出る)
 *   - 出発 56      : 見出し EN「DEP.」≒49 / 中身 ✓✗(18px) ≒42
 *   - 清掃結果 120 : 見出し EN「CLEAN RESULT」≒110 / 中身「出発失敗」≒76
 *   - 完了率 110   : 見出し EN「COMPLETION」≒101 / 中身「100%」≒58
 *   - 判定 96      : 見出し EN「GRADE ?」≒87 / 中身 バッジ28 + ▼ ≒66
 *
 * ★表の最小幅 = 全列の幅の合計★(`min-width` の calc)。通常表示 = 110 + 1024 = 1134px
 * (画面幅 1440px のとき入れ物は 1154px、縦スクロールバーが出ると 1137〜1139px なので横スクロールは出ない。それより広い画面では余りを全列に配る)。
 * これより狭い画面では、包んでいる `.tableWrap`(`overflow-x: auto`)が横スクロールになる。
 */
.table {
  --col-facility: 110px;
  --col-model: 92px;
  --col-serial: 126px;
  --col-date: 64px;
  --col-scheduled: 100px;
  --col-precheck-1: 130px;
  --col-precheck-2: 130px;
  --col-departed: 56px;
  --col-result: 120px;
  --col-rate: 110px;
  --col-grade: 96px;
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  min-width: calc(
    var(--col-facility) + var(--col-model) + var(--col-serial) + var(--col-date) +
      var(--col-scheduled) + var(--col-precheck-1) + var(--col-precheck-2) +
      var(--col-departed) + var(--col-result) + var(--col-rate) + var(--col-grade)
  );
}

/*
 * ダッシュボードの縮小表示(5列: 施設名 / 予定 / 出発 / 完了率 / 判定)。
 * 列が少ないので、見出しの必要幅(上の表と同じ)より広めに取る。最小幅 = 240 + 760 = 1000px(従来の `min-width` と同じ)。
 * ★施設名も 240px の幅を持ち、余りは5列に幅の比で配る★(D-167 追記。旧: 施設名だけが余りを受け持ち、1920px で ≒833px)。
 */
.compact {
  --col-facility: 240px;
  --col-scheduled: 200px;
  --col-departed: 160px;
  --col-rate: 200px;
  --col-grade: 200px;
  min-width: calc(
    var(--col-facility) + var(--col-scheduled) + var(--col-departed) + var(--col-rate) +
      var(--col-grade)
  );
}

.colFacility {
  width: var(--col-facility);
}

.colModel {
  width: var(--col-model);
}

.colSerial {
  width: var(--col-serial);
}

.colDate {
  width: var(--col-date);
}

.colScheduled {
  width: var(--col-scheduled);
}

.colPrecheck1 {
  width: var(--col-precheck-1);
}

.colPrecheck2 {
  width: var(--col-precheck-2);
}

.colDeparted {
  width: var(--col-departed);
}

.colResult {
  width: var(--col-result);
}

.colRate {
  width: var(--col-rate);
}

.colGrade {
  width: var(--col-grade);
}

.th {
  padding: 10px 12px;
  font-size: 11px;
  color: var(--tx-m);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  border-bottom: 1px solid var(--bd);
  white-space: nowrap;
  font-weight: 600;
}

/* ★固定レイアウトでは列が中身に合わせて広がらない★ので、長い値は列の中で折り返す
   (折り返さないと隣の列に重なる)。施設名・清掃結果など。機種は `.tdMuted`、シリアルは `.tdSerial` に同じ指定 */
.td {
  padding: 12px;
  font-size: 13px;
  color: var(--tx);
  overflow-wrap: anywhere;
}

/* 事前チェック(1回目 / 2回目。D-178)の Pill。値は DB の生値で長さが読めない
   (例「セキュリティ有効」「Handrail Lifted」)。Pill 自体は `nowrap` なので、
   列幅を超える値は Pill の中で折り返させる。
   `.tdStatus > span` は Pill だけのセル(分数が無いとき)と「-」、
   `.precheckCell > span:first-child` は Pill + 分数のセルの Pill */
.tdStatus > span,
.precheckCell > span:first-child {
  display: inline-block;
  max-width: 100%;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* Pill + 何分前か(D-178)。横に並べ、列幅に収まらなければ分数が Pill の下に回る */
.precheckCell {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 6px;
}

/* 何分前か(「60分前」/「60 min」)。Pill より小さく控えめに。分数の途中では折り返さない */
.precheckMinutes {
  font-size: 11px;
  color: var(--tx-m);
  white-space: nowrap;
}

/* 事前チェックの予定が無い列の「-」(D-171)。Pill を出さず、色なしで控えめに */
.statusNone {
  color: var(--tx-m);
}

.tdMuted {
  padding: 12px;
  font-size: 13px;
  color: var(--tx-d);
  overflow-wrap: anywhere;
}

.tdDate {
  padding: 12px;
  font-size: 12px;
  color: var(--tx-d);
}

.tdSerial {
  padding: 12px;
  font-size: 11px;
  font-family: var(--font-geist-mono), ui-monospace, monospace;
  color: var(--tx-m);
  overflow-wrap: anywhere;
}

.tdCenter {
  padding: 12px;
  text-align: center;
}

.tdRight {
  padding: 12px;
  text-align: right;
  font-size: 13px;
  color: var(--tx);
}

.departedOk {
  font-size: 18px;
  color: var(--ok);
}

.departedNg {
  font-size: 18px;
  color: var(--ng);
}

/* ★結果待ち(D-173)★ — ✓✗ の色(ok / ng)を使わない。控えめな文字色で「…」を出す */
.departedPending {
  font-size: 18px;
  color: var(--tx-m);
}

.row {
  border-bottom: 1px solid color-mix(in srgb, var(--bd) 13%, transparent);
}

.rowClickable {
  cursor: pointer;
}

/* ★キーボードで選んだ行の枠★(指示書BC 5-4)。★表の中なので内側に描く★(外側だと隣の行・表の枠に隠れる) */
.rowClickable:focus-visible {
  outline: 2px solid var(--ac);
  outline-offset: -2px;
}

.rowExpanded {
  border-bottom: none;
  background: color-mix(in srgb, var(--pr) 3%, transparent);
}

.gradeCell {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}

.chevron {
  font-size: 10px;
  color: var(--tx-m);
}

/* アドバイスが無い行の見えない ▼(幅だけ取る)。バッジ・「-」の位置を全行で揃える(ユーザー指示 2026-10-29) */
.chevronPlaceholder {
  visibility: hidden;
}

.helpBtn {
  cursor: pointer;
  font-size: 10px;
  color: var(--pr);
  border: 1px solid color-mix(in srgb, var(--pr) 27%, transparent);
  border-radius: 50%;
  width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: middle;
  margin-left: 4px;
  background: none;
  padding: 0;
}

.legend {
  margin: 8px 0;
  padding: 12px 16px;
  background: var(--sf);
  border: 1px solid var(--bd);
  border-radius: 8px;
  display: inline-flex;
  gap: 16px;
  align-items: center;
  flex-wrap: wrap;
}

.legendTitle {
  font-size: 12px;
  font-weight: 600;
  color: var(--tx);
}

.legendOk {
  font-size: 12px;
  color: var(--ok);
}

.legendWn {
  font-size: 12px;
  color: var(--wn);
}

.legendNg {
  font-size: 12px;
  color: var(--ng);
}

.legendNote {
  font-size: 11px;
  color: var(--tx-m);
}

.legendClose {
  cursor: pointer;
  font-size: 14px;
  color: var(--tx-m);
  margin-left: 8px;
  background: none;
  border: none;
}

.adviceCell {
  padding: 0;
  border-bottom: 1px solid color-mix(in srgb, var(--bd) 13%, transparent);
}

.adviceWrap {
  padding: 12px 20px 16px;
}

.adviceWrapL1 {
  background: color-mix(in srgb, var(--pr) 2%, transparent);
}

.adviceWrapL2 {
  background: color-mix(in srgb, var(--wn) 3%, transparent);
}

.adviceWrapL3 {
  background: color-mix(in srgb, var(--ng) 3%, transparent);
}

.adviceHead {
  font-size: 12px;
  font-weight: 700;
  margin-bottom: 10px;
}

.headL1 {
  color: var(--pr);
}

.headL2 {
  color: var(--wn);
}

.headL3 {
  color: var(--ng);
}

.adviceCard {
  padding: 8px 12px;
  margin-bottom: 6px;
  border-radius: 6px;
  background: var(--sf);
  border: 1px solid var(--bd);
}

.adviceTitle {
  font-size: 12px;
  font-weight: 600;
  color: var(--tx);
}

.adviceText {
  font-size: 12px;
  color: var(--tx-d);
  margin-top: 4px;
}

.adviceActions {
  margin: 6px 0 0;
  padding-left: 18px;
  font-size: 12px;
  color: var(--tx-d);
}

.areaBtn {
  margin-top: 4px;
  font-size: 12px;
  color: var(--pr);
  background: var(--pr-d);
  border: none;
  border-radius: 6px;
  padding: 6px 14px;
  cursor: pointer;
}

.empty {
  padding: 24px;
  text-align: center;
  font-size: 13px;
  color: var(--tx-m);
}