Newer
Older
client_dwatch / components / features / reports / ReportsScreen.module.css
/* レポート画面(F-04)。モック d-watch-mock.jsx:654-828 のインラインスタイルを移植。
   色は app/globals.css の CSS変数(`[data-theme]` で切り替わる)を参照し、
   JS 側で色を持たない(KpiCard / ProgressBar と同じ流儀)。
   例外はエラーレベルのバッジ色だけで、`levelColor + "18"` の半透明合成が
   CSS変数では書けないため画面側で `THEME_TOKENS` を使っている。 */

.page {
  min-width: 0;
}

/* ---- ヘッダ(モック:657-660) ---- */

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  gap: 12px;
}

.title {
  font-size: 22px;
  font-weight: 700;
  margin: 0;
}

/*
 * ★CSVエクスポート(施設別パフォーマンス。D-163)★
 * `<a download>` なのでリンクの下線を消し、清掃詳細ログの `.csvBtn` と同じ押せる見た目にする。
 * ★色は app/globals.css の CSS変数だけを使う★。★`font-family` をここで宣言しないこと★
 * (宣言すると和文フォントが落ちて漢字が中華字形になる。CLAUDE.md §0-3)。
 */
.exportBtn {
  display: inline-block;
  font-size: 12px;
  color: var(--pr);
  background: var(--pr-d);
  border: none;
  border-radius: 6px;
  padding: 6px 14px;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}

.exportBtn:hover {
  opacity: 0.85;
}

/* ---- フィルタ行(モック:661-680) ---- */

.toolbar {
  display: flex;
  gap: 10px;
  margin-bottom: 16px;
  flex-wrap: wrap;
  align-items: center;
}

.input {
  font-size: 12px;
  padding: 6px 12px;
  border-radius: 6px;
  border: 1px solid var(--bd);
  background: var(--sf-h);
  color: var(--tx);
  width: 140px;
}

.select {
  font-size: 12px;
  padding: 6px 10px;
  border-radius: 6px;
  border: 1px solid var(--bd);
  background: var(--sf-h);
  color: var(--tx);
}

/* ホールディングス / 顧客のセレクトは★幅を固定する★(ユーザー指示 2026-10-06。D-162)—
   選んだ名前の長さで幅が変わり、ツールバーの並びがずれるため。切れた名前は title(ホバー)で読む */
.masterSelect {
  width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.searchBtn {
  font-size: 12px;
  color: #fff;
  background: var(--pr);
  border: none;
  border-radius: 6px;
  padding: 6px 16px;
  cursor: pointer;
}

/* ---- 期間トグル+期間ナビ(モック:681-686 + 新規のナビ) ---- */

.periodRow {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.periodNav {
  display: flex;
  align-items: center;
  gap: 4px;
}

.navBtn {
  font-size: 16px;
  line-height: 1;
  padding: 4px 10px;
  border-radius: 6px;
  border: 1px solid var(--bd);
  background: var(--sf-h);
  color: var(--tx-d);
  cursor: pointer;
}

.navBtn:hover {
  color: var(--tx);
}

.periodLabel {
  font-size: 13px;
  font-weight: 600;
  color: var(--tx);
  min-width: 150px;
  text-align: center;
}

.periodToggle {
  display: flex;
  background: var(--sf-h);
  border-radius: 6px;
  border: 1px solid var(--bd);
  overflow: hidden;
}

.toggleBtn {
  font-size: 12px;
  padding: 6px 16px;
  border: none;
  cursor: pointer;
  background: transparent;
  color: var(--tx-d);
  font-weight: 400;
}

.toggleActive {
  background: var(--pr);
  color: #fff;
  font-weight: 600;
}

/* ---- KPIカード(モック:687-705) ---- */

.kpiGrid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 24px;
}

@media (max-width: 900px) {
  .kpiGrid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ---- 2カラム(モック:708-771) ---- */

.twoCol {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-bottom: 24px;
}

@media (max-width: 900px) {
  .twoCol {
    grid-template-columns: 1fr;
  }
}

.card {
  background: var(--sf);
  border: 1px solid var(--bd);
  border-radius: 12px;
  overflow: hidden;
  min-width: 0;
}

.cardHeader {
  padding: 14px 20px;
  border-bottom: 1px solid var(--bd);
}

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

.cardSub {
  font-size: 11px;
  color: var(--tx-m);
  margin-top: 2px;
}

.cardEmpty {
  padding: 20px;
  text-align: center;
  font-size: 12px;
  color: var(--tx-m);
}

.cardFooter {
  padding: 10px 20px;
  text-align: center;
}

.linkBtn {
  font-size: 12px;
  color: var(--pr);
  background: none;
  border: none;
  cursor: pointer;
}

.linkBtnMuted {
  font-size: 12px;
  color: var(--tx-m);
  background: none;
  border: none;
  cursor: pointer;
}

/* ---- 連続問題施設の行(モック:726-731) ---- */

.contRow {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 20px;
  border-bottom: 1px solid color-mix(in srgb, var(--bd) 35%, transparent);
}

.levelBadge {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 4px;
  font-weight: 600;
  white-space: nowrap;
}

.contFacility {
  font-size: 13px;
  font-weight: 600;
  color: var(--tx);
  white-space: nowrap;
}

.contSummary {
  font-size: 12px;
  color: var(--tx-m);
  flex: 1;
  text-align: right;
  min-width: 0;
}

/* ---- エラー種別の内訳の行(モック:760-767) ---- */

.errorRow {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 20px;
  border-bottom: 1px solid color-mix(in srgb, var(--bd) 35%, transparent);
}

.errorLabel {
  width: 110px;
  flex: none;
  font-size: 12px;
  color: var(--tx);
  /* 英語識別子は空白・ハイフンを含まないことがあるため、単語の途中でも折り返す
     (break-word は「収まらない場合のみ」の挙動が実装依存なので anywhere を使う)。
     クランプ(-webkit-line-clamp 等)は使わない — 生値を隠さない(D-077 / 指示書O 禁止事項1) */
  overflow-wrap: anywhere;
  line-height: 1.3;
}

.errorBar {
  flex: 1;
  min-width: 0;
}

.errorCount {
  width: 30px;
  flex: none;
  text-align: right;
  font-size: 13px;
  font-weight: 600;
  color: var(--tx);
}

.errorRate {
  width: 35px;
  flex: none;
  text-align: right;
  font-size: 11px;
  color: var(--tx-m);
}

/* ---- 施設別パフォーマンスのカードヘッダ(モック:775-778) ---- */

.tableCardHeader {
  padding: 16px 20px;
  border-bottom: 1px solid var(--bd);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

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

.tableCardCount {
  font-size: 12px;
  color: var(--tx-m);
  white-space: nowrap;
}

/* ---- 3段(読み込み中 / エラー)。DsAlertsScreen.module.css と同じ書式 ---- */

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

.error {
  padding: 16px 20px;
  font-size: 13px;
  color: var(--ng);
}

/* ---- ブロック単位の失敗(指示書AL 段階2 / §3-3)----
   ★4本を1本ずつ出すようにしたので、失敗はカードの中に出す★ —
   どのブロックが欠けているのかが画面から分かるようにするため。
   ★font-family は書かない★(日本語フォントは app/globals.css のスタックが正。CLAUDE.md §0-3) */

.blockError {
  padding: 20px;
  font-size: 12px;
  color: var(--ng);
  text-align: center;
}

/* ---- KPI が出せないときのカード(§3-4 の誘導)---- */

.kpiNoticeCard {
  margin-bottom: 24px;
}

.kpiNotice {
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

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

.kpiNoticeText {
  font-size: 12px;
  color: var(--tx-m);
}

.kpiNoticeActions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 2px;
}

/* ★候補の件数★。文言ではなく数で「選択肢が複数ある」ことを見せる */
.kpiNoticeCount {
  font-size: 12px;
  font-weight: 600;
  color: var(--pr);
  background: var(--pr-d);
  border-radius: 6px;
  padding: 3px 10px;
}

/* 「顧客を選んでください」と、実際に選ぶセレクトを結びつける強調 */
.selectHighlight {
  border-color: var(--pr);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pr) 30%, transparent);
}