/* =========================================================================
   components.css — 部品（ボタン・入力・カード・バッジ・表の見た目 …）
   ------------------------------------------------------------------------
   ★読み込み順： tokens.css（値）→ shell.css（器）→ **components.css**（部品）→ parts.css（画面固有）
   ★このファイルも tokens.css の var(--…) だけを使う。色・サイズの値を直書きしない。
   ★部品の「役割と状態」は アプリ構造規格.md §9、「見た目の値」は design.md §5 が正本。
     ここはその2つを実装したもの。
   ========================================================================= */

/* ★表・モーダル・トーストは shell.css が持ち主（アプリ構造規格 §10・§11）。
   ここには置かない。2箇所に書くと、片方だけ直して食い違う。 */
/* =========================================================================
   3. 部品（標準§6）
   ========================================================================= */
.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:var(--s2);
  height:40px; padding:0 var(--s4); border-radius:var(--r-md); border:1px solid transparent;
  font-size:var(--fs-body); font-weight:700; cursor:pointer; white-space:nowrap;
  transition:background .15s,border-color .15s,transform .05s,box-shadow .15s;
}
.btn svg { width:18px; height:18px; flex:none; stroke:currentColor; fill:none; stroke-width:2; }
.btn:active { transform:scale(.97); }
.btn:disabled, .btn[aria-disabled="true"] { opacity:.45; cursor:not-allowed; }
.btn:disabled:active, .btn[aria-disabled="true"]:active { transform:none; }
.btn--primary {
  background:var(--brand-grad); color:var(--on-brand);
  box-shadow:var(--shadow-sm);
}
/* 地が brand→brand-strong になったので、hover は下端色の一色（旧 hover と同じグラデのままだと変化が出ない） */
.btn--primary:hover { background:var(--brand-strong); }
.btn--secondary { background:var(--surface); color:var(--ink); border-color:var(--border-strong); }
.btn--secondary:hover { background:var(--surface-hover); }
.btn--danger { background:var(--danger); color:var(--on-danger); }
.btn--ghost { background:transparent; color:var(--ink-sub); }
.btn--ghost:hover { background:var(--surface-hover); color:var(--ink); }
.btn--sm { height:32px; padding:0 var(--s3); font-size:var(--fs-sub); }
.btn--icon { width:40px; padding:0; }
.btn--icon.btn--sm { width:32px; }

/* 入力 */
.field { display:flex; flex-direction:column; gap:var(--s2); }
.field > label { font-size:var(--fs-label); font-weight:700; color:var(--ink-sub); }
.field .hint { font-size:var(--fs-caption); color:var(--ink-mute); }
.field .err { font-size:var(--fs-label); color:var(--danger); font-weight:700; }
.req { display:inline-flex; align-items:center; height:18px; padding:0 6px; margin-left:6px;
  border-radius:var(--r-sm); background:var(--danger-soft); color:var(--danger);
  font-size:var(--fs-caption); font-weight:700; }
.opt { display:inline-flex; align-items:center; height:18px; padding:0 6px; margin-left:6px;
  border-radius:var(--r-sm); background:var(--neutral-soft); color:var(--neutral);
  font-size:var(--fs-caption); font-weight:700; }
.input, .select, textarea.input {
  height:40px; padding:0 var(--s3); width:100%;
  border:1px solid var(--border-control); border-radius:var(--r-sm);
  background:var(--surface); color:var(--ink); font-family:inherit; font-size:var(--fs-body);
  transition:border-color .15s, box-shadow .15s;
}
textarea.input { height:auto; min-height:80px; padding:var(--s3); line-height:var(--lh-body); resize:vertical; }
.input:focus, .select:focus, textarea.input:focus {
  outline:none; border-color:var(--brand); box-shadow:0 0 0 2px var(--brand-soft);
}
.input:disabled, .select:disabled { background:var(--surface-sub); color:var(--ink-mute); cursor:not-allowed; }
.select {
  appearance:none; padding-right:34px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2355617A' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 12px center;
}
.check { display:inline-flex; align-items:center; gap:var(--s2); font-size:var(--fs-body); cursor:pointer; }
.check input { width:18px; height:18px; accent-color:var(--brand); flex:none; cursor:pointer; }

/* 検索欄（アイコン内包） */
.search { position:relative; }
.search svg {
  position:absolute; left:12px; top:50%; transform:translateY(-50%);
  width:18px; height:18px; stroke:var(--ink-mute); fill:none; stroke-width:2; pointer-events:none;
}
.search .input { padding-left:38px; }

/* カード */
.card {
  background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg);
  padding:var(--s6); box-shadow:var(--shadow-md);
}
.card--tight { padding:var(--s4); }
.card--tap { cursor:pointer; transition:transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.card--tap:hover { transform:translateY(-2px); box-shadow:var(--shadow-lg); border-color:var(--brand-soft); }
.card-head { display:flex; align-items:center; justify-content:space-between; gap:var(--s3); margin-bottom:var(--s4); }

/* パネル（淡面） */
.panel { background:var(--surface-sub); border:1px solid var(--border); border-radius:var(--r-lg); padding:var(--s5); }
.panel--brand { background:var(--brand-tint); border-color:var(--brand-soft); }
.panel--brand .label { color:var(--brand-fg); }

/* KPI（無地一色にしない） */
.kpi-row { display:grid; grid-template-columns:repeat(4,1fr); gap:var(--s4); }
.kpi {
  position:relative; overflow:hidden; min-width:0;
  background:linear-gradient(160deg,var(--surface) 55%,var(--brand-tint));
  border:1px solid var(--border); border-radius:var(--r-lg); padding:var(--s5);
  box-shadow:var(--shadow-sm);
}
.kpi::after {
  content:""; position:absolute; right:-28px; top:-28px; width:92px; height:92px;
  border-radius:50%; background:var(--brand-deco); opacity:.12; pointer-events:none;
}
.kpi .k-label { display:block; font-size:var(--fs-sub); color:var(--ink-sub); font-weight:500; }
.kpi .k-val {
  display:block;
  font-family:var(--font-num); font-size:var(--fs-kpi); font-weight:800; line-height:1;
  margin-top:var(--s3); letter-spacing:-.02em; overflow-wrap:anywhere;
  font-variant-numeric:tabular-nums; color:var(--ink);
}
.kpi .k-val .unit { font-family:var(--font-jp); font-size:var(--fs-h3); font-weight:500; color:var(--ink-sub); margin-left:2px; }
@media (max-width:1023px){ .kpi-row { grid-template-columns:1fr 1fr; } }
@media (max-width:767px){ .kpi-row { grid-template-columns:1fr; } }

/* バッジ・チップ */
.badge {
  display:inline-flex; align-items:center; gap:5px; height:22px; padding:0 var(--s2);
  border-radius:var(--r-sm); font-size:var(--fs-label); font-weight:700; line-height:1;
  white-space:nowrap;
}
.badge .dot { width:7px; height:7px; border-radius:50%; background:currentColor; flex:none; }
.badge--ok { color:var(--ok); background:var(--ok-soft); }
.badge--warn { color:var(--warn); background:var(--warn-soft); }
.badge--danger { color:var(--danger); background:var(--danger-soft); }
.badge--info { color:var(--info); background:var(--info-soft); }
.badge--neutral { color:var(--neutral); background:var(--neutral-soft); }
.badge--brand { color:var(--brand-fg); background:var(--brand-soft); }
.badge--demo { color:var(--ink-mute); background:var(--surface-sub); border:1px dashed var(--border-strong); }

.chips { display:flex; gap:var(--s2); flex-wrap:wrap; }
.chip {
  display:inline-flex; align-items:center; gap:6px; height:32px; padding:0 var(--s3);
  border-radius:var(--r-sm); border:1px solid var(--border); background:var(--surface);
  font-size:var(--fs-label); font-weight:700; color:var(--ink-sub); cursor:pointer;
  white-space:nowrap; transition:background .15s,border-color .15s,color .15s;
}
.chip:hover { background:var(--surface-hover); }
.chip[aria-pressed="true"] { background:var(--brand-tint); border-color:var(--brand-soft); color:var(--brand-fg); }
.chip .n { font-family:var(--font-num); }

/* 会社の識別ドット（色だけで意味を伝えないよう必ず文字を併記する） */
.orgdot { width:8px; height:8px; border-radius:50%; flex:none; display:inline-block; }

.avatar {
  width:36px; height:36px; border-radius:50%; flex:none; display:grid; place-items:center;
  background:var(--brand-soft); color:var(--brand-fg); font-size:var(--fs-label); font-weight:700;
}
.avatar--sm { width:28px; height:28px; font-size:var(--fs-caption); }

/* ★列数の多い表は「折り返さず、表の中で横スクロール」にする。
   1024pxのノートPCでは サイド240px＋余白48px を引くと本文が736pxしか無く、
   7列を押し込むと和文が**1文字ずつ縦に割れる**（実測：「西村 亮太」が5行になった）。
   CJKは任意の位置で改行できるため、幅が足りないと単語ではなく文字単位で割れる。
   幅を配るのではなく、列に自然幅を持たせて器の側をスクロールさせるのが確実。 */
.table--wide th, .table--wide td { white-space:nowrap; }
.table--wide .wrapok { white-space:normal; }
.table thead th {
  text-align:left; font-size:var(--fs-label); font-weight:700; color:var(--ink-sub);
  background:var(--surface-sub); padding:var(--s3) var(--s4);
  border-bottom:1px solid var(--border); white-space:nowrap;
}
.table tbody td { padding:var(--s3) var(--s4); border-bottom:1px solid var(--border); vertical-align:middle; }
.table tbody tr:last-child td { border-bottom:0; }
.table tbody tr { transition:background .12s; }
.table tbody tr:hover { background:var(--surface-hover); }
.table tbody tr[aria-selected="true"] { background:var(--brand-soft); }
.table .num { font-family:var(--font-num); }
/* 表セル内の入力は固有幅を持たせる。width:100% は「セル幅に従う」宣言で
   固有幅0扱いになり、他列が広がるとその列ごと潰れる（§15・ビューポート幅に無関係） */
.table .input, .table .select { min-width:112px; }
/* 操作列は絶対に折り返さない（縦積みは行高が跳ね、削除の誤爆を誘発する・§15） */
.table td.actions, .table th.actions { width:1%; white-space:nowrap; }
.table td.actions .row { flex-wrap:nowrap; gap:var(--s2); }

/* --- SP：ワイド表はカード化（横スクロールで詰め込まない） --- */
@media (max-width:767px){
  .table-wrap { border:0; background:transparent; overflow:visible; }
  .table, .table tbody, .table tr, .table td { display:block; width:100%; }
  .table thead { display:none; }
  .table tbody tr {
    background:var(--surface); border:1px solid var(--border); border-radius:var(--r-lg);
    box-shadow:var(--shadow-sm); padding:var(--s4); margin-bottom:var(--s3);
  }
  .table tbody tr:hover { background:var(--surface); }
  .table tbody td { border:0; padding:var(--s1) 0; display:flex; gap:var(--s3); align-items:center; }
  .table tbody td::before {
    content:attr(data-label); flex:none; min-width:6em;
    font-size:var(--fs-label); font-weight:700; color:var(--ink-mute);
  }
  .table tbody td[data-label=""]::before, .table tbody td:not([data-label])::before { content:none; }
  /* カード化したら1行に収める必要はないので nowrap を解除する */
  .table--wide th, .table--wide td { white-space:normal; }
  .table td.actions { width:auto; padding-top:var(--s3); }
  .table td.actions .row { flex-wrap:nowrap; }
  .badge { white-space:nowrap; }  /* 「送/信/済」と縦割れさせない */
}
/* 細いコンテナ（分割の左ペイン・ドロワー）の中は無条件でカード化する。
   @media はビューポート幅で効くため、1440pxの画面に置いた幅360pxのペインでは一度も発火しない（§実測） */
.pane-list .table, .pane-list .table tbody, .pane-list .table tr, .pane-list .table td { display:block; width:100%; }
.pane-list .table thead { display:none; }

/* 空状態 */
.empty { text-align:center; padding:var(--s7) var(--s5); color:var(--ink-sub); }
.empty .icon {
  width:56px; height:56px; margin:0 auto var(--s4); border-radius:var(--r-lg);
  background:var(--brand-tint); color:var(--brand-fg); display:grid; place-items:center;
}
.empty .icon svg { width:26px; height:26px; stroke:currentColor; fill:none; stroke-width:2; }
.empty h4 { font-size:var(--fs-h3); font-weight:700; color:var(--ink); margin-bottom:var(--s2); }
.empty p { font-size:var(--fs-sub); margin-bottom:var(--s4); }

/* 項目6以上のフォームは2列＋節見出し。auto-fit の入れ子は親の細さを継承して黙って1列に潰れるため、
   単一グリッド＋ grid-column:1/-1 の span で組む（§実測） */
.form-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:var(--s4); }
.form-grid > .span-all { grid-column:1 / -1; }
.form-grid > .sec {
  grid-column:1 / -1; font-size:var(--fs-label); font-weight:700; color:var(--brand-fg);
  padding-top:var(--s3); border-top:1px solid var(--border);
}
.form-grid > .sec:first-child { padding-top:0; border-top:0; }
/* 送信ボタンは常に無スクロールで押せる位置に固定する（§実測：390幅で629px下に隠れた） */
.modal__foot {
  flex:none; position:sticky; bottom:0; background:var(--surface);
  display:flex; justify-content:flex-end; gap:var(--s3);
  padding:var(--s4) var(--s6); border-top:1px solid var(--border);
  border-radius:0 0 var(--r-lg) var(--r-lg);
}
@media (max-width:767px){
  /* ★既定は「中身なりの高さで中央」。
     2行しかない確認ダイアログまで全画面にすると 600px の空白が生まれ、
     しかも「退職にする」のような日常操作で毎回それが出る（独立監査R3の致命指摘）。
     全画面が要るのは項目の多いフォームだけなので、そちらに --sheet を付けて明示する。 */
  .modal-backdrop { padding:var(--s4); align-items:center; }
  .modal { width:100%; max-height:calc(100vh - 32px); border-radius:var(--r-lg); margin:auto; }
  .modal__head, .modal__body { padding:var(--s4); }
  .modal__foot { padding:var(--s3) var(--s4); }
  /* 項目の多いフォームだけ全画面シートにする */
  .modal-backdrop--sheet { padding:0; align-items:stretch; }
  .modal-backdrop--sheet .modal { max-height:100vh; border-radius:0; margin:0; }
  .modal-backdrop--sheet .modal__foot { border-radius:0; }
}

/* セグメント切替 */
.segmented {
  display:inline-flex; background:var(--surface-sub); border:1px solid var(--border);
  border-radius:var(--r-md); padding:3px; gap:2px;
}
.segmented button {
  border:0; background:transparent; color:var(--ink-sub); font:inherit;
  font-size:var(--fs-label); font-weight:700; height:30px; padding:0 var(--s3);
  border-radius:var(--r-sm); cursor:pointer; white-space:nowrap; transition:background .15s,color .15s;
}
.segmented button[aria-pressed="true"] { background:var(--surface); color:var(--brand-fg); box-shadow:var(--shadow-sm); }

/* =========================================================================
   5. レイアウト補助（画面固有のグリッドはここに集約し、画面側にCSSを書かない）
   ========================================================================= */
.grid-2 { display:grid; grid-template-columns:1fr 1fr; gap:var(--s4); }
.grid-3 { display:grid; grid-template-columns:repeat(3,1fr); gap:var(--s4); }
.grid-auto { display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:var(--s4); }
@media (max-width:1023px){ .grid-3 { grid-template-columns:1fr 1fr; } }
@media (max-width:767px){ .grid-2, .grid-3 { grid-template-columns:1fr; } }

/* 導出値であることを示す（自動採番・自動投入の欄。手入力させない値の見せ方）
   → アプリ構造規格 §12「導出できる値は手入力させない」 */
.derived {
  display:inline-flex; align-items:center; gap:6px; height:34px; padding:0 var(--s3);
  border-radius:var(--r-sm); background:var(--surface-sub); border:1px dashed var(--border-strong);
  font-size:var(--fs-sub); color:var(--ink-sub); font-family:var(--font-num);
}
