/* 業務日報システム 共通スタイル
   対応解像度は横1280px以上のPCブラウザのみ（基本設計書 6.5#2・12.1#3）。
   レスポンシブ対応は行わない。 */

/* デザイントークン v2（design/design-tokens.json が正）。
   罫線を減らし、余白・角丸・淡い影で階層を作る。変数名は v1 のまま値だけ差し替えて
   影響範囲を閉じている（対応表は design-tokens.json の migration を参照）。 */
:root {
    --brand: #1e86eb;
    --brand-dark: #0f6bc9;
    --brand-light: #e8f3fe;

    /* 「編集」の hover の地。地の --brand-light（#e8f3fe）を一段濃くしたもので、差は 1.09。
       この地の上の --brand-ink は 6.15:1。 */
    --brand-light-hover: #d8eafd;
    --accent: #1e86eb;

    /* accent-tint（--brand-light）の上に載せる文字色。淡い地に十分なコントラストを取る。 */
    --brand-ink: #14539e;

    /* ボタンの hover の文字色。--brand-ink を一段濃くしたもので、
       hover の地（--control-bg-hover・--brand-light-hover）の上で 8.2:1。
       hover を濃い青の地＋白文字に反転させない代わりに、この濃さで変化を示す。 */
    --brand-ink-dark: #0f4179;

    --text: #22314f;
    --text-muted: #64748f;
    /* プレースホルダに使う。白地で 4.5:1 を満たす明るさが上限
       （旧 #9aa4bf は 2.49:1 で読めなかった）。本文 --text とは十分な差があり、
       未入力であることは色の濃さで見分けられる。 */
    --text-faint: #6f768a;

    /* 枠線は1種のみ。太さの違いで階層を作らない（階層は余白と影で作る）。 */
    --border: #e7ebf5;
    --border-strong: #e7ebf5;

    /* 押せる部品の輪郭。表の罫線（--border）とは役割が違うので別に持つ。
       ボタンの地（--surface-alt）とカード外の地（--page）はほぼ同色のため、
       罫線と同じ濃さ（#e7ebf5）で囲っても 1.08:1 で輪郭が見えない。

       濃さの決め方: #e7ebf5（1.08:1）は輪郭が見えず、#6f768a（4.42:1）は硬く浮く。
       その間で、対 --page 1.72:1 のグレーにしている。
       部品境界の目安 3:1 には届かないが、この画面では枠線は押せることを示す補助で、
       ボタンの文字（--brand-ink）自体は基準を満たしているため許容する。 */
    --control-border: #b8bfcd;

    /* 押せる部品の地。--surface-alt（#f5f7fc）はヘッダの白に対して 1.07 しかなく、
       白地の上ではボタンの面がほとんど見えない（枠線だけで形を保っていた）。
       少し濃くして面でも押せることが分かるようにする（対 白 1.20・対 --page 1.09）。
       --surface-alt 自体は行ホバーの地・非活性の入力欄にも使うため変えない。 */
    --control-bg: #eef0f6;

    /* ボタンの hover の地。濃い青へ反転させる代わりに一段濃くする。
       この地の上の --text は 10.4:1、--brand-ink-dark は 8.2:1。 */
    --control-bg-hover: #e2e6f0;

    /* 上より一段薄い方。同じ色が縦に何度も並ぶ場所（表の操作列・状態バッジ）で使う。
       これ以上薄くすると行 hover の地（--surface-alt）と差がなくなり、
       ボタンが行に溶けて文字だけに見える（この値で 1.09）。 */

    --surface: #ffffff;
    --surface-alt: #f5f7fc;

    /* 提出不要日のマス（.cal__day.is-off）の文字。地はボタンと同じ --control-bg で、
       --text-muted（#64748f）はその上で 4.16:1 と基準を割るため、一段濃くして 6.5:1 にしている。 */
    --text-muted-dark: #4b5570;

    /* 地はごく淡くてよい。画面の骨格は色付きのサイドメニューが受け持つため、
       地の明度で構造を作る必要がない。 */
    --page: #f2f4f9;

    /* サイドメニュー。上から下へ、濃い青から明るい青へ抜ける。
       白文字とのコントラストは 上端 #1478d4 で 4.50:1、中間 #248ce2 で 3.54:1、
       下端 #55aef0 で 2.41:1（淡い光の上ではさらに 0.2〜0.3 下がる）。
       下へ行くほど 4.5:1 を満たさなくなるが、
       トンマナを優先するデザイン判断として許容している。
       その補いとして --nav-fg は不透明度を落とさず純白にする。
       下半分に置く文字を増やすときは、この値ごと見直すこと。 */
    --grad-nav: linear-gradient(180deg, #1478d4 0%, #248ce2 55%, #55aef0 100%);
    --nav-fg: #ffffff;
    --nav-fg-muted: rgba(255, 255, 255, .82);

    --error: #f0616b;
    --error-bg: #fdebec;

    /* 赤の文字色。次の3役を兼ねるため、いずれでも 4.5:1 を満たす濃さが要る。
       ・白地の上の文字（未入力の通知見出し・必須マーク）      → 5.42:1
       ・淡い赤地（--error-bg）の上の文字（削除ボタン・エラー）→ 4.72:1
       ・地にして白文字を載せる（削除ボタンの hover）          → 5.42:1
       以前の #b3323c は基準は満たすが煉瓦色に寄って見えたため、赤を立てた。
       これ以上明るくすると淡い赤地の上で 4.5 を割る（#dc2b3a で 4.11）。 */
    --error-ink: #c92a38;

    /* 一覧の操作列の「削除」の hover。地は --error-bg を一段濃くしたもの。
       この地の上では --error-ink が 4.11:1 で基準を割るため、文字も一段濃くして 5.54:1 にする。 */
    --error-bg-hover: #fbd9db;
    --error-ink-dark: #a81f2b;
    --warning: #f7a325;
    --warning-bg: #fef3e0;
    --warning-ink: #8a5a06;
    --success: #2fc48d;
    --success-bg: #e4f8f0;
    --success-ink: #197e59;

    --radius: 10px;
    --radius-card: 16px;
    --radius-chip: 8px;

    /* グラデーションはアクティブなナビ・主ボタンの2か所だけに使う。
       ヘッダのような広い面には敷かない（色の主張が強くなりすぎるため）。
       表・カード・入力欄にも使わない（面が増えると数値が読みにくくなる）。 */
    --grad-brand: linear-gradient(135deg, #1268ce, #2e96f5);
    --grad-brand-hover: linear-gradient(135deg, #0d57ae, #1b7fe3);

    --shadow-card: 0 6px 20px rgba(34, 49, 79, .06);
    --shadow-raised: 0 12px 32px rgba(34, 49, 79, .10);
}

* {
    box-sizing: border-box;
}

html,
body {
    margin: 0;
    padding: 0;
}

body {
    min-width: 1280px;
    background: var(--page);
    color: var(--text);

    /* 和文・Latin とも Noto Sans JP で揃える（design-tokens.json の typography.fontFamily と同じ）。

       Web フォントとしては読み込まない。社内イントラから外部CDNへ出られない環境を想定し、
       「取得できなければシステムフォントへ落とす」のがトークン側の決め事（meta.notes 参照）。
       そのため端末に Noto Sans JP が入っていない場合は、後続のシステムフォントが受ける。
       全端末で確実に Noto Sans JP にしたい場合は、フォントファイルを wwwroot 配下に置いて
       @font-face で自前配信すること（外部CDNは使わない）。 */
    font-family: "Noto Sans JP", "Segoe UI Variable Text", "Segoe UI", "Yu Gothic UI",
                 "Meiryo", "Hiragino Kaku Gothic ProN", sans-serif;
    font-size: 14px;
    line-height: 1.6;

    /* 和文は字面が詰まって見えるため、全体に字間を空ける。
       0.05em は 14px で 0.70px。これ以上広げると単語の切れ目が読み取りにくくなり、
       表の列や左メニューの項目名も押し出されて折り返しが増える。
       実際、左メニューでいちばん長い「日報検索・一覧（全ユーザー）」は
       この値で 192px になり、確保してある 196px に対し余裕は 4px しかない（.app-nav 参照）。
       個別に letter-spacing を持つ規則（見出し・ラベル・表ヘッダ）も、
       この値との差が開きすぎないよう一緒に底上げしてある。 */
    letter-spacing: .05em;
    -webkit-font-smoothing: antialiased;
}

/* 桁が揃うべき値（作業時間・件数・日付・時刻）は等幅数字にする。 */
input[type="date"],
input[type="time"],
input[type="number"],
.is-numeric,
.table td,
.summary__value,
.pager__info {
    font-variant-numeric: tabular-nums;
}

/* ---- ヘッダ（基本設計書 6.5#1） ------------------------------------------ */

/* ヘッダは白地にする。色を広い面に敷くと主張が強すぎるため、ブランド色は
   アクティブなナビ・主ボタンといった小さい面にだけ残す（参考デザインと同じ考え方）。 */
.app-header {
    display: flex;
    align-items: center;
    gap: 20px;
    height: 56px;
    padding: 0 24px;
    background: var(--surface);
    color: var(--text);

    /* 影だけでは白い面の上で境目が出ない（--shadow-card は .06 の 20px ぼかし）。
       固定した列見出し（.table-sticky）がヘッダの真下に留まると、地が同じ白のため
       ヘッダと地続きに見え、どこまでがヘッダか読み取れなかった。輪郭線を1本足して分ける。
       表の見出しに面（帯）を作って分ける手もあるが、見出しは面ではなく淡い文字で示す
       という表側の決めに反するため、境目はヘッダ側で持つ。 */
    box-shadow: 0 1px 0 var(--border), var(--shadow-card);

    /* サイドメニュー・カードより手前に置き、影を下へ落とす。
       スクロールしても画面上端に留める（どの画面を見ているかと、
       ログアウトへの動線を常に見せる）。地は不透明なので本文は透けない。 */
    position: sticky;
    top: 0;
    z-index: 2;

    /* height:56px と合わせ、縮まないよう固定する（sticky で潰れるのを防ぐ）。 */
    flex: 0 0 auto;
}

/* システム名は文字そのものにグラデーションを乗せる。背景の面を作るとメニューボタンと
   同じ形になり、押せる要素に見えてしまうため。
   色は文字の線幅のぶんしか占めないので、ヘッダ全体を塗るより主張が弱い。

   font-size は 19px。WCAG の「大きな文字」（18.66px 以上の太字）に入れて、
   明るい側の色でもコントラスト比の基準を満たすようにしている。 */
.app-header__brand {
    /* background-clip が効かない環境では、この色のまま表示される（文字が消えない）。 */
    color: var(--brand-dark);

    background: linear-gradient(120deg, #0f6bc9, #2e96f5);
    background-clip: text;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;

    font-size: 19px;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-decoration: none;
}

/* ヘッダの画面名。画面名はここ1か所だけに置き、本文側には大見出しを持たない。
   ヘッダの高さ（56px）に収める必要があるので、本文の大見出しほどは大きくしない。 */
.app-header__page {
    margin: 0;
    color: var(--text);
    font-size: 17px;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.app-header__user {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-left: auto;
}

.app-header__name {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text-muted);
    font-size: 14px;
}

/* ログイン中の利用者の顔。権限ごとに絵を変える（一般・チームリーダー・管理者）。

   【重要】丸の地はこの画像そのものに含まれる。他のアイコン（.btn__icon 等）のように
   線画を CSS の丸に載せる作りではないので、background は持たせない。
   絵を差し替えるときは wwwroot/img/role-*.png を置き換えること。

   丸で囲うのは、隣のログアウトが同じ丸みのボタンで、絵だけだと「押せるもの」と
   見分けがつかないため。押せないので影や枠は付けない。

   色は権限を伝える補助でしかない。判別は名前の横の「（管理者）」が受け持つので、
   色覚に依らず区別できる（WCAG 1.4.1）。 */
.app-header__avatar {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    /* 画像は正方形で、丸はその内接円。念のため角を落としておく。 */
    border-radius: 999px;
}

/* 権限無しは業務機能を使えない状態なので、色を持たせず灰に落とす。
   専用の絵は用意せず、一般と同じ絵から色を抜いている。 */
.app-header__avatar.is-none {
    filter: grayscale(1) opacity(.8);
}

/* ヘッダ右上の2つ（利用者名・ログアウト）に添えるアイコン。
   線の指定はボタンのアイコン（.btn__icon）と揃える。色は currentColor なので、
   ログアウトが hover で文字を濃くしたとき、アイコンも一緒に濃くなる。 */
.app-header__icon {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.app-header__logout-form {
    margin: 0;
}

/* 白地に載るため、副次ボタンと同じ淡い面で分節する。 */
.app-header__logout {
    /* .btn と同じ速さで色が変わるようにする。 */
    transition: background-color .28s ease, color .28s ease;

    /* アイコンと文字を並べる。.btn と同じ 6px。 */
    display: inline-flex;
    align-items: center;
    gap: 6px;

    padding: 5px 14px;
    border: 1px solid transparent;
    border-radius: 999px;
    background: var(--control-bg);
    color: var(--brand-ink);
    font-size: 13px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
}

/* .btn と同じ hover にする。ログアウトだけ反応が違うと、同じ見た目のボタンなのに
   別の部品に見えるため。濃い青の地＋白文字へ反転させず、地と文字を一段ずつ濃くするのも
   .btn と揃えた扱い（利用者の指示）。 */
.app-header__logout:hover {
    background: var(--control-bg-hover);
    color: var(--brand-ink-dark);
}

/* ---- 本文レイアウト ------------------------------------------------------ */

/* サイドメニューが最上部まで伸びるため、外枠は画面全体の高さを持つ。 */
.app-body {
    display: flex;
    align-items: stretch;
    min-height: 100vh;
}

/* サイドメニューの右側。ヘッダと本文をこの中に積む。 */
.app-content {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-width: 0;
}

.app-nav {
    display: flex;
    /* いちばん長い「日報検索・一覧（全ユーザー）」が1行で収まる幅。
       文字に使える幅は「この値 − 84px」（本体余白28＋リンク余白28＋アイコン18＋間隔10）。
       同項目の実測は 192px（Noto Sans JP・letter-spacing .05em 込み）で、
       280px が確保する 196px に対し余裕は 4px しかない。
       余裕を切り詰めると、幅がちょうどでも閉じ括弧が行頭に来られない禁則処理で
       2行になる（240px＝余裕0で実際に折り返した）。

       **項目名を足すとき、字間やフォントを変えるときは実測して決めること。**
       フォントを Noto Sans JP にした時点で、同じ項目が 172px → 192px に伸びて
       260px では折り返した。幅もあわせて 260px → 280px にしている。 */
    flex: 0 0 280px;
    flex-direction: column;
    background: var(--grad-nav);

    /* 影で本文より手前にあることを示す。ヘッダ（z-index:2）より上に置く。 */
    box-shadow: 4px 0 16px rgba(11, 45, 90, .12);

    /* 一覧を下までスクロールしてもメニューは残す。
       flex アイテムは既定で親の高さまで伸びる（align-items:stretch）ため、
       align-self:flex-start で自身の高さを画面分に留めてから sticky を効かせる。
       項目が画面に収まらない場合はメニュー内でスクロールさせる。 */
    position: sticky;
    top: 0;
    align-self: flex-start;
    height: 100vh;
    overflow-y: auto;

    z-index: 3;
}

/* 閉じたときは細い帯だけ残す。完全に消すと開閉ボタンごと消えて開き直せなくなる。 */
.app-nav.is-collapsed {
    flex-basis: 60px;
}

/* 飾り（.app-nav__promo）も閉じたら消す。幅60pxではイラストも2行の文言も入らず、
   縮めて残しても何の絵か読み取れない。 */
.app-nav.is-collapsed .app-nav__brand,
.app-nav.is-collapsed .app-nav__body,
.app-nav.is-collapsed .app-nav__promo {
    display: none;
}

.app-nav.is-collapsed .app-nav__head {
    justify-content: center;
    padding: 0 8px;
}

/* システム名と開閉ボタンを載せる先頭の行。ヘッダと同じ高さに揃える。 */
.app-nav__head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 0 0 56px;
    padding: 0 10px 0 16px;
}

.app-nav__brand {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    gap: 8px;
    min-width: 0;
    color: #fff;
    font-size: 18px;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-decoration: none;
}

/* favicon と同じ「書類＋鉛筆」。地が濃い青なので白抜きの線画を使う
   （favicon 本体は青のグラデーション塗りで、同色の地では沈む）。 */
.app-nav__brand-icon {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* 名前が入りきらない場合は文字側だけを詰める（アイコンは縮めない）。 */
.app-nav__brand-text {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* 開閉ボタン。地が濃い青なので白抜きの三本線にする。
   開いている間はアイコンを × に変えて「押すと閉じる」ことを示す。 */
.app-nav__toggle {
    position: relative;
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 0;
    border-radius: var(--radius);
    background: transparent;
    color: #fff;
    cursor: pointer;
}

/* ホバーでは背景を変えない。アイコンが三本線から矢印に変わることで
   押せることも押した結果も伝わるため、面の変化は足さない。 */
.app-nav__toggle:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

.app-nav__toggle-icon {
    position: relative;
    display: block;
    width: 18px;
    height: 14px;
}

.app-nav__toggle-icon span {
    position: absolute;
    left: 0;
    width: 100%;
    height: 2px;
    border-radius: 1px;
    background: currentColor;
}

.app-nav__toggle-icon span:nth-child(1) { top: 0; }
.app-nav__toggle-icon span:nth-child(2) { top: 6px; }
.app-nav__toggle-icon span:nth-child(3) { top: 12px; }

/* 開閉ボタンは既定で三本線のまま。ホバー・フォーカスのときだけ矢印に差し替え、
   押すとメニューがどちらへ動くかを示す。
   三本線を×に変形させる作りだと、開いているときに「閉じる」以外の意味に読めるうえ、
   閉じているときにどちら向きに開くのかが分からないため、矢印にしている。 */
.app-nav__toggle-icon,
.app-nav__toggle-arrow {
    transition: opacity .12s ease;
}

.app-nav__toggle-arrow {
    position: absolute;
    width: 30px;
    height: 30px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.2;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: 0;
}

/* 閉じているときは右向き（開く方向）。矢印は1つだけ持ち、向きは回転で作る。 */
.app-nav.is-collapsed .app-nav__toggle-arrow {
    transform: rotate(180deg);
}

.app-nav__toggle:hover .app-nav__toggle-icon,
.app-nav__toggle:focus-visible .app-nav__toggle-icon {
    opacity: 0;
}

.app-nav__toggle:hover .app-nav__toggle-arrow,
.app-nav__toggle:focus-visible .app-nav__toggle-arrow {
    opacity: 1;
}

.app-nav__body {
    /* 項目をピル形にするため、左右に余白を持たせる。

       **上は本文（.app-main）の上パディングと同じ 24px にする。**
       サイドメニューの先頭（「日報」）と、本文の先頭（「一覧に戻る」など）が
       同じ高さから始まる。どちらも高さ 56px の行（.app-nav__head／ヘッダ）の下なので、
       同じ値にすれば揃う。片方だけ変えると、横に並ぶ2つの先頭がずれる。

       以前は 40px で、システム名の行と離す意図だったが、
       本文の先頭より 16px 低い位置から始まって横並びがずれていた。
       システム名の行は高さ 56px あって地の色も変わるため、24px でも十分に分かれる。

       **左右は 14px から動かさない。** ここは文字に使える幅を直接削る。
       .app-nav 側の計算（幅 − 84px）はここが 14px である前提の値で、
       28px にすると文字幅が 196px → 168px になり、
       管理者の長い2項目（192px・178px）が2行になる（実際に試して戻した）。 */
    padding: 24px 14px 40px;
}

/* メニュー下部の飾り（チームリーダー・一般）。項目が少なく下が大きく空くため、
   画面の性格を示す絵と一言を置いて、空白を意味のある面にする。 */
.app-nav__promo {
    /* 項目の下ではなく、メニューの下寄りに置く。
       下パディングを厚く取って、絵と文字は最下部より少し上へ浮かせる。
       上下の位置はこの下パディング1つで決まる。増やすと上がり、減らすと下がる。 */
    margin-top: auto;
    padding: 22px 14px 130px;
    text-align: center;
}

/* 文言の弧。曲げられるのは SVG の中だけなので、文字色は fill で指定する。 */
.app-nav__promo-arc {
    display: block;
    width: 100%;
    max-width: 210px;

    /* 弧の両端は空くので、そのぶんイラストへ寄せる。 */
    margin: 0 auto -6px;
}

/* 文言の左右に添える「＼ ／」。文字色と揃える。 */
.app-nav__promo-mark {
    fill: none;
    stroke: rgba(255, 255, 255, .92);
    stroke-width: 2.5;
    stroke-linecap: round;
}

.app-nav__promo-arc text {
    fill: rgba(255, 255, 255, .92);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: .08em;
}

.app-nav__promo-img {
    display: block;
    width: 100%;
    max-width: 200px;
    height: auto;
    margin: 0 auto;
}

/* グループ見出し。「日報」「管理者機能」といった大きな枠ごとに罫線で仕切る。
   地が濃い青なので、線は白の低い不透明度で引く（黒い線は沈んで見えない）。 */
/* 小見出しと、その下の項目の間隔。6px では 11px の見出しに対して詰まって見えたため
   10px に広げてある（上の 14px は、前のグループの最後の項目との間隔）。 */
.app-nav__label {
    margin: 14px 0 10px;
    padding: 20px 12px 0;
    border-top: 1px solid rgba(255, 255, 255, 0.22);
    color: var(--nav-fg-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
}

/* 管理者だけが使う項目のまとまり（管理者機能・マスタ管理・運用管理）。
   見出しが3つに分かれていて日報の項目と地続きに見えるため、薄い面と枠で1つに囲う。
   中の小見出しは残し、どの種類の機能かは引き続き分かるようにする。

   左右のパディングは置かない。項目名（最長は「日報検索・一覧（全ユーザー）」）が
   折り返さない余白がぎりぎりしかなく、内側に余白を足すと2行になるため
   （実測: 必要163px に対し、パディング8pxずつを入れると使える幅が158pxになる）。 */
.app-nav__section {
    margin: 16px 0 0;

    /* 上下の余白をそろえる。
       上は padding-top 4px ＋ 見出し（.app-nav__section-label）の margin-top 10px で 14px。
       下も 14px にするため、padding-bottom を 14px にし、
       最後の項目の margin-bottom は下で 0 に落としている。 */
    padding: 4px 0 14px;

    border: 1px solid rgba(255, 255, 255, .2);
    border-radius: 12px;
    background: rgba(255, 255, 255, .08);
}

/* 帯の中の最後の項目は下の余白を持たせない。
   項目どうしの間隔（.app-nav__link の margin-bottom）がそのまま帯の下の余白に
   足されるため、間隔を変えるたびに上下の釣り合いが崩れる。
   帯の上下は padding だけで決める。 */
.app-nav__section > .app-nav__list:last-child > li:last-child > .app-nav__link {
    margin-bottom: 0;
}

.app-nav__section-label {
    margin: 10px 0 2px;
    padding: 0 12px;
    color: var(--nav-fg);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
}

/* 帯の中では、先頭の小見出しの上に区切り線を引かない（枠が区切りになっているため）。 */
.app-nav__section .app-nav__label:first-of-type {
    margin-top: 6px;
    padding-top: 0;
    border-top: 0;
}

/* 先頭のグループの上には仕切る相手がいないので線を引かない。 */
.app-nav__label:first-child {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

.app-nav__list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.app-nav__link {
    display: flex;

    /* 「未入力日一覧（全ユーザー）」のように2行になる項目でも、
       アイコンが1行目の高さに残るよう上端で揃える。 */
    align-items: flex-start;
    gap: 10px;

    /* 項目どうしの間隔。ピル（白塗り）の高さは padding が決めるので、
       間隔を変えたいときはここだけを動かすこと。padding を足すとピルが厚くなる。
       管理者はメニューが11項目あり、画面高900pxではここが 14px を超えると
       メニュー内スクロールが出る（実測: 12px で本体820px、16px で877px）。 */
    margin-bottom: 8px;
    padding: 8px 14px;

    /* 選択中（.is-active）のピル形状に合わせる。ここだけ --radius（角丸の四角）に
       すると、hover では四角・選択すると丸帯と形が変わってしまう。
       hover は選んだ結果の予告なので、同じ形で見せる。 */
    border-radius: 999px;

    color: var(--nav-fg);
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
}

/* アイコンは線画。色は currentColor なので、現在地（白地に青）でも一緒に反転する。 */
.app-nav__icon {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;

    /* 1行目の文字の中心にアイコンの中心を合わせる（行の高さ 20.8px − 18px の半分）。 */
    margin-top: 1px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;

    /* 文字より一段控えめにして、項目名の読み取りを妨げないようにする。 */
    opacity: .82;
}

.app-nav__link.is-active .app-nav__icon {
    opacity: 1;
}

.app-nav__link-text {
    min-width: 0;
}

/* <symbol> の定義そのものは描画しない。 */
.icon-sprite {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

.app-nav__link:hover {
    background: rgba(255, 255, 255, 0.16);
    color: #fff;
}

/* 現在開いている画面。地が青のグラデーションなので、白へ反転させて示す
   （同じ青のピルでは地に埋もれる）。
   下位ページ（/Admin/Users/Edit など）を開いている間も親項目に付く。 */
.app-nav__link.is-active {
    background: #fff;
    box-shadow: 0 4px 12px rgba(11, 45, 90, .25);
    color: var(--brand-dark);
    font-weight: 700;
}

.app-nav__link.is-active:hover {
    background: #fff;
    color: var(--brand-dark);
}

/* 左右の余白は、カードと画面の端との間隔になる。ここを広げるとカード内で
   使える幅が減り、作業明細の表（列指定の合計 1008px）が窮屈になる。
   下を厚めに取っているのは、画面末尾の保存ボタンが画面の底に貼り付かないようにするため。 */
.app-main {
    flex: 1 1 auto;
    min-width: 0;
    padding: 24px 32px 48px;
}

/* ---- 見出し・カード ------------------------------------------------------ */

.page-head {
    display: flex;
    align-items: flex-end;
    gap: 16px;
    margin-bottom: 18px;
}

.page-head__title {
    margin: 0;
    font-size: 28px;
    font-weight: 700;
    letter-spacing: 0.01em;
    line-height: 1.3;
}

.page-head__actions {
    display: flex;
    gap: 10px;
    margin-left: auto;
}

/* 「一覧に戻る」と、その画面単位の操作を1行に置く枠（SCR-03）。
   space-between にしてあるので、操作が無い画面では戻る導線が左に残るだけになる
   （margin-left: auto を最後の子に当てると、1つしか無いときに右へ飛んでしまう）。
   下の余白はここが持つ。中の .back-link 側は 0 に落とす。 */
.page-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 8px;
}

.page-top .back-link {
    margin-bottom: 0;
}

/* 戻る導線（32px）と高さを揃える。.btn--small は 29px で、
   白い丸みの部品が2つ並ぶと 3px の差が段差に見えるため。 */
.page-top .btn {
    min-height: 32px;
}

/* 一覧へ戻る導線。17画面の左上に同じものが出る。

   ページ地の上に直接置くボタンなので、.btn--raised と同じ作り
   （白地＋影で縁を作る）にしてある。地の白とページ地の差は 1.10 しかないが、
   縁を作っているのは影なので不足しない。他のページ直置きボタンと語彙が揃う。

   以前は「&lt;」という文字を先頭に置いていたが、文字だと太さも高さも
   隣の日本語とずれる。線画のアイコンに替えてある。
   当たり判定も 80×21px しかなく、WCAG 2.5.8 の最小 24×24px を下回っていた。 */
.back-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 30px;
    margin-bottom: 8px;

    /* 枠線は寸法確保のために持たせ、色だけ透明にする（.btn と同じ理由。
       外すと 2px 縮む）。 */
    border: 1px solid transparent;

    border-radius: 999px;
    padding: 5px 16px 5px 12px;
    box-shadow: 0 1px 3px rgba(34, 49, 79, .18);
    background: var(--surface);
    color: var(--brand-ink);
    font-size: 13px;
    font-weight: 700;
    text-decoration: none;
}

.back-link__icon {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;

    /* 戻る向きを動きでも示す。 */
    transition: transform .15s ease;
}

/* hover は .btn と同じ扱い（利用者の指示）。白い地から濃い青へ反転させると
   地の明暗が入れ替わり（比 5.33）、一覧の上を横切っただけで面が沈んで見えるため、
   地と文字を一段ずつ濃くするに留める（比 1.25）。
   隣に並ぶ「この日報を複製」（.btn--raised）と反応を揃える意味もある。 */
.back-link:hover {
    background: var(--control-bg-hover);
    color: var(--brand-ink-dark);
}

.back-link:hover .back-link__icon {
    transform: translateX(-2px);
}

/* 押している間は影を弱めて、実際に沈んだように見せる（.btn--raised と同じ）。 */
.back-link:active {
    box-shadow: 0 1px 1px rgba(34, 49, 79, .16);
}

@media (prefers-reduced-motion: reduce) {
    .back-link__icon {
        transition: none;
    }
}

/* 本文へのスキップリンク（_Layout）。フォーカスされるまで画面外へ逃がす。
   display:none や visibility:hidden にするとフォーカスも当たらなくなるため、位置で隠す。 */
.skip-link {
    position: absolute;
    top: -60px;
    left: 8px;
    z-index: 100;
    padding: 8px 14px;
    border: 1px solid var(--accent);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--accent);
    font-size: 13px;
    font-weight: 700;
    text-decoration: none;
}

.skip-link:focus {
    top: 8px;
}

/* 飛んだ先の <main> に既定の輪郭を出さない（tabindex="-1" のための便宜的なフォーカス）。 */
.app-main:focus {
    outline: none;
}

/* 枠線ではなく淡い影で浮かせる。地（--page）が藤色寄りなので白が分離して見える。 */
/* 内側は広めに取る。中身が枠の近くにあると窮屈に見えるため。
   上下と左右で値を分けているのは、それぞれ効く先が違うから。
   ・上下（32px）… カードが3枚並ぶ日報入力の上段で、そのまま高さに乗る。
     広げすぎると主役の作業明細が画面下へ押し出される。
   ・左右（48px）… カード内で使える幅が減る。作業明細の表は列指定の合計が
     1008px あり、これ以上広げると列が潰れる。本体側の余白（.app-main）でも
     取り返しているが、そちらも詰めきっている。 */
.card {
    margin-bottom: 16px;
    padding: 32px 48px;
    border: 0;
    border-radius: var(--radius-card);
    background: var(--surface);
    box-shadow: var(--shadow-card);
}

.card__title {
    margin: 0 0 16px;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: 0.02em;
    line-height: 1.4;
}

.note {
    margin: 0;
    color: var(--text-muted);
    font-size: 13px;
}

/* ---- 条件サマリ（SCR-08 集計結果） --------------------------------------- */

/* 結果表の上に、その結果を出した条件を再掲するための定義リスト。
   ラベル列は最長ラベル「対応システム」（6文字）に合わせて固定し、値の頭を揃える。 */
.summary {
    display: grid;
    grid-template-columns: 7em 1fr;
    gap: 6px 14px;
    margin: 0 0 18px;
    padding: 14px 16px;
    border: 0;
    border-radius: var(--radius);
    background: var(--surface-alt);
    font-size: 13px;
}

.summary__label {
    margin: 0;
    font-weight: 700;
}

.summary__value {
    margin: 0;
}

/* 絞り込み未指定。値そのものではなく状態の説明なので弱めに見せる。 */
.summary__value--none {
    color: var(--text-muted);
}

/* ---- トップのメインビジュアル（SCR-02） ---------------------------------- */

/* 画面を開いて最初に目に入る帯。挨拶とイラストだけを持ち、操作は置かない。
   メニューカードは白地なので、帯は淡い青からの grad で地と分け、境目を線ではなく色で示す。 */
.hero {
    overflow: hidden;

    /* 上下とも「帯の外は48px」で揃える。
       上は .app-main の padding-top（24px）に 24px 足して 48px。
       .app-main 側を触ると全画面の余白が動くため、帯の margin で足している。 */
    margin: 24px 0 48px;
    /* 上下のパディングは持たない。イラストの下端を帯の底辺に接するように置くため、
       帯の高さは .hero__inner の min-height で決める。 */
    padding: 0 32px;
    border-radius: var(--radius-card);

    /* ごく薄く水色を差した白。下のメニューカード（純白）と面で見分けがつく。
       これ以上濃くできない。リード文（--text-muted）がこの地で 4.51:1 で、
       本文の基準 4.5:1 ぎりぎりのため（純白なら 4.73:1）。
       見出し（--brand）は 3.53:1 だが 28px の太字なので基準は 3:1。
       地（--page）との差は 1.05 しかないので、面の切り分けは影が受け持つ。
       影は自前の値を持つ（--shadow-card より浅く、帯の面積に対して主張しすぎない）。
       .hero の overflow: hidden は子（イラスト）を切るためのもので、
       自分自身の影は切らない。 */
    background: #f5faff;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .06);
}

/* 文字とイラストのまとまり。帯は全幅でも中身は幅を決めて中央に置く。
   左右の端に張り付けると、画面が広いほど真ん中だけが空いて間延びする。
   余った幅は左右へ均等に逃がし、「両端の余白」として見せる。 */
.hero__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 40px;
    /* 文字とイラストを帯の左右へ広げて置く。文字は左、イラストは右。
       広い画面でも端まで張り付かないよう上限を決め、余った幅は左右へ均等に逃がす。
       上限を下げると左右の余白が増え、そのぶん文字とイラストの間が詰まる。 */
    max-width: 1400px;
    min-height: 200px;
    margin: 0 auto;
}

.hero__body {
    padding: 24px 0;
}

.hero__title {
    margin: 0 0 10px;

    /* ブランドの青そのもの。白地に対して 3.71:1 で、
       本文の基準（4.5:1）は割るが 28px の太字は「大きな文字」の扱いになり、
       基準は 3:1 なので満たしている。小さくするならこの色は使えない。 */
    color: var(--brand);

    /* トークンの display（28px）。帯の中でいちばん大きい文字で、画面の入口だと分かる大きさにする。
       画面の見出し（h2「メニュー」20px）より大きいが、こちらは見出しではなく挨拶なので競合しない。 */
    font-size: 28px;
    font-weight: 700;
}

.hero__lead {
    /* 飾り（.hero__script）をこの文の右端から始めるための基準。
       block のままだと幅が親いっぱいになり「文の右端」が取れないので
       inline-block にして文字ぶんの幅に縮める。 */
    position: relative;
    display: inline-block;

    margin: 0;
    color: var(--text-muted);
    font-size: 16px;
}

/* イラストはまとまりの右端に置き、下端を帯の底辺と揃える。
   画像の下 12.83%（表示 220px のうち 28px）は透明なので、その分だけ帯の外へ出す。
   はみ出した分は .hero の overflow: hidden で切る。
   画像の幅・画像そのものを変えるときは、この 28px を測り直すこと
   （margin-bottom = 表示高 × 透明部分の割合）。 */
/* 「Keep going.」の書き出し（SCR-02 のみ）。
   日本語の見出しに対する飾りなので、大きさは抑える。

   色はイラストの葉と同じ #60BAAA を 70% で。青の濃淡にすると「薄くなった文字」に
   見えるが、色相を変えると添え物だと一目で分かる。背景 #f5faff に対して 1.72:1。
   読み上げから外した飾り（aria-hidden）なので、文字のコントラスト基準は適用しない。

   リード文を基準に、右上へ向かって傾けて置く（置き場所は下の2つのルール）。
   絶対配置にしているのは2つ理由がある。
   ・文字のかたまりの高さを増やさない（帯の高さが変わってしまう）
   ・文字のかたまりの幅を増やさない（イラストが押されて、横1280pxで崩れる） */
.hero__script {
    position: absolute;

    /* 狭い画面（1440px 未満）ではリード文の1行下に落とす。
       横に並べるとイラストにぶつかるため。実測した食い込み／余りは
       1366px: -18px ／ 1400px: 7px ／ 1440px: 36px ／ 1920px: 293px。 */
    top: 99%;
    left: 70%;
    color: rgba(96, 186, 170, .7);
    transform: rotate(-13deg);
    transform-origin: left top;
}

/* 横に並べるだけの幅があるときは、リード文のすぐ右に大きく置く。
   left の基準は .hero__lead の右端（inline-block なので文字ぶんの幅）。
   top: 50% ＋ translateY(-50%) で、飾りの中心をリード文1行の中心に合わせる。
   1440px を境にしているのは、これ未満だとイラストとの間隔が 36px を切るため。
   大きさ・角度を変えるときは、この境目も測り直すこと。 */
@media (min-width: 1440px) {
    .hero__script {
        top: 50%;
        left: calc(100% + 10px);
        width: 220px;
        height: 75px;
        transform: translateY(-50%) rotate(-10deg);
        transform-origin: center;
    }
}

/* 1本ずつ順に描き進めることで、ペンで書いているように見せる。
   pathLength="100" で正規化してあるので、dash の値は線の実長によらず 100 でよい。
   linear なのは、書く速さが途中で変わると「引っかかった」ように見えるため。
   繰り返さない（forwards で描き終わりに留まる）。 */
.hero__script-stroke {
    fill: none;
    stroke: currentColor;

    /* 太くすると e・o・p・g の穴が埋まってつぶれる。
       表示幅165pxに対して、これ以上太らせない。 */
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: 100;
    stroke-dashoffset: 100;
    animation: hero-write var(--hero-write-time) linear var(--hero-write-delay) forwards;
}

@keyframes hero-write {
    to {
        stroke-dashoffset: 0;
    }
}

/* 下線だけは linear から外す。1本を一息で引く線なので、
   速く出て減速して止まるほうが「引いた」動きに見える
   （文字は linear のまま。途中で速さが変わると引っかかって見えるため）。 */
.hero__script-stroke--swish {
    animation-timing-function: cubic-bezier(.15, .85, .25, 1);
}

/* 動きを減らす設定の端末では、最初から書き終わった状態で出す。 */
@media (prefers-reduced-motion: reduce) {
    .hero__script-stroke {
        stroke-dashoffset: 0;
        animation: none;
    }
}

.hero__illust {
    /* 横1280px（帯の幅972px）では、見出し1行ぶん460px と間隔を引いた残りが約410px しかない。
       画面が広いほど大きく見せたいので、360〜500px の範囲で幅に追従させる。
       段組みを切り替えるわけではないので、レイアウトそのものは画面幅によらず同じ。 */
    --hero-illust-w: clamp(360px, 27vw, 500px);

    flex: 0 0 auto;
    align-self: flex-end;

    /* 画像の下 12.83% は透明。絵の下端を帯の底辺に合わせるため、その分を帯の外へ出す
       （はみ出した分は .hero の overflow: hidden で切る）。
       表示高は幅の 1/2 なので、幅に対しては 6.42%。画像を差し替えるときは割合を測り直すこと。 */
    margin: 0 0 calc(var(--hero-illust-w) * -.0642);
    pointer-events: none;

    /* 葉の画像を背景の上に重ねるため、基準にする。 */
    position: relative;
}

.hero__illust img {
    display: block;
    width: var(--hero-illust-w);
    height: auto;
}

/* 観葉植物の葉。葉ごとに別画像（葉以外は透明）にしてあり、背景の上にぴったり重ねる。
   どれも元のイラストと同じ座標系の全面キャンバスなので、位置指定は左上合わせでよい。 */
.hero__illust-leaf {
    /* 揺れ幅。左右にこの角度ぶん振る。強さを変えるときはここだけ触ればよい。
       背景側は葉の輪郭より 8px 広く消してあるので、この範囲なら葉の跡は出ない。
       これ以上大きくするなら、葉の画像を作り直して消す幅も広げること。 */
    --hero-leaf-angle: 3deg;

    position: absolute;
    top: 0;
    left: 0;

    /* 回転の軸は茎の根本（鉢のふち）。ここを動かさないことで、葉だけがしなって見える。
       葉ごとに根本の位置が違うので、値は .cshtml 側で1枚ずつ渡している。 */
    transform-origin: var(--hero-leaf-origin);
    animation: hero-leaf-sway var(--hero-leaf-time) ease-in-out var(--hero-leaf-delay) infinite;

    /* 揺れのたびに背景まで描き直させない。 */
    will-change: transform;
}

/* そよ風程度の揺れ。0% と 100% を同じ角度（静止位置）にして、
   元のイラストと同じ形から始まるようにする。
   3枚は周期をずらしてあり、負の待ち時間で位相もずらしている
   （そろって動くと風ではなく機械仕掛けに見えるため）。 */
@keyframes hero-leaf-sway {
    0%, 100% {
        transform: rotate(0deg);
    }

    25% {
        transform: rotate(var(--hero-leaf-angle));
    }

    75% {
        transform: rotate(calc(var(--hero-leaf-angle) * -1));
    }
}

/* 動きを減らす設定の端末では揺らさない。静止位置は元のイラストと同じ。 */
@media (prefers-reduced-motion: reduce) {
    .hero__illust-leaf {
        animation: none;
    }
}

/* ---- メニューカード（SCR-02） -------------------------------------------- */

.menu-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
}

/* 項目が4枚のとき（チームリーダー）だけ2列にする。3列のままだと 3＋1 に割れ、
   最後の1枚だけが次の段に取り残されて見える。 */
.menu-grid--pairs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.menu-card {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 20px;
    border: 0;
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    background: var(--surface);
    color: var(--text);
    text-decoration: none;
}

/* アイコンは淡いブランド色のタイルに載せる。カード全体がリンクなので、
   タイル自体は押せる要素に見えないよう影を付けず、面だけで示す。 */
.menu-card__icon {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;

    /* 〇にする。カード自体が角丸の四角なので、中のタイルまで同じ形だと入れ子に見える。 */
    border-radius: 999px;
    background: var(--brand-light);
    color: var(--brand-dark);
}

.menu-card__icon svg {
    width: 22px;
    height: 22px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* ホバーでカードの地が --brand-light になるため、タイルは白へ反転させて残す。 */
.menu-card:hover .menu-card__icon {
    background: var(--surface);
}

/* 押すと開くことを示す矢印。カードの右端に寄せる。
   囲みは持たせない。アイコンのタイルと2つ面が並ぶと、どちらが押す場所か分かりにくくなる。 */
.menu-card__chevron {
    display: flex;
    flex: 0 0 auto;
    align-self: center;
    margin-left: auto;
    color: var(--text-faint);

    /* ホバーで右へ動かすため。位置だけを動かし、レイアウトは動かさない。 */
    transition: transform .15s ease;
}

.menu-card__chevron svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* ホバーで矢印が少し進む。開く方向を動きでも示す。
   3px にしているのは、これ以上動かすとカードの右端の余白（20px）に対して
   矢印が寄りすぎて、切れそうに見えるため。 */
.menu-card:hover .menu-card__chevron {
    color: var(--brand-dark);
    transform: translateX(3px);
}

@media (prefers-reduced-motion: reduce) {
    .menu-card__chevron {
        transition: none;
    }

    /* 動かさない。色の変化だけ残す（状態が読み取れなくなるため）。 */
    .menu-card:hover .menu-card__chevron {
        transform: none;
    }
}

.menu-card__body {
    min-width: 0;
}

/* ホバーの地。--brand-light（#e8f3fe）は白地に対して 1.06:1 しかなく、
   どのカードに載っているか分かりにくかったため、一段濃くしている（対 白 1.35:1）。
   --brand-light 自体はカレンダーの入力済み日・タグ欄・表の見出しなどでも使うため変えない。 */
.menu-card:hover {
    border-color: var(--accent);
    background: #d4e6fb;
}

.menu-card__title {
    display: block;
    margin: 0 0 6px;
    font-size: 16px;
    font-weight: 700;
}

/* 未入力日の件数。トップの通知カードをやめたため、件数を示すのはここだけになる。
   赤は文字にだけ使う（--error-bg の上の --error-ink で 4.72:1）。
   項目名の右に並べ、カードを2行（項目名＋説明）に収める。
   幅が足りないときは項目名の下へ折り返す（横1280pxではそうなる）。 */
.menu-card__badge {
    display: inline-flex;
    align-items: center;
    height: 20px;
    margin-left: 8px;
    padding: 0 8px;
    border-radius: 999px;
    background: var(--error-bg);
    color: var(--error-ink);
    font-size: 11px;
    font-weight: 700;

    /* 項目名（16px）の行の中で天地を合わせる。既定の baseline だと丸が下がって見える。 */
    vertical-align: middle;
}

.menu-card__desc {
    display: block;
    margin: 0;
    color: var(--text-muted);
    font-size: 13px;
}

/* ホバーの地を濃くした分、13px の説明文が --text-muted では 3.72:1 まで落ちる。
   ホバー中だけ淡いブランド地用の文字色（--brand-ink）に寄せて 5.98:1 を確保する。 */
.menu-card:hover .menu-card__desc {
    color: var(--brand-ink);
}

/* ---- 番号付きセクション（SCR-11 など） ----------------------------------- */

.section-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
}

.section-head__badge {
    display: inline-flex;
    flex: 0 0 24px;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--brand);
    color: #fff;
    font-size: 13px;
    font-weight: 700;
}

.section-head__title {
    margin: 0;
    font-size: 17px;
    font-weight: 700;
}

.section-head__actions {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-left: auto;
}

/* 操作に必要な権限の注記（「※管理者のみ」など）。 */
.permission-note {
    margin: 0 0 8px;
    color: var(--text-muted);
    font-size: 12px;
    text-align: right;
}

/* 画面内の補足説明。エラー・警告と区別するため青系にする。 */
.info-box {
    margin-top: 14px;
    padding: 10px 14px;
    border: 1px solid #b8cdf0;
    border-radius: var(--radius);
    background: var(--brand-light);
    color: var(--brand-dark);
    font-size: 13px;
}

.info-box p {
    margin: 0;
}

.info-box p + p {
    margin-top: 4px;
}

/* 一覧で選択中の行（SCR-11 の対応システム一覧）。地はホバーと同じ --surface-alt にする。
   淡い青にすると行の上の「編集」（.btn--accent の地も淡い青）が行に溶けるため（利用者の指示）。 */
.table tr.is-selected > td {
    background: var(--surface-alt);
}

.table tr.is-selectable {
    cursor: pointer;
}

.table tr.is-selectable:hover > td {
    background: var(--surface-alt);
}

/* 行内リンクを本文と同じ見た目にする（行全体が選択操作になっているため）。 */
.row-link {
    color: inherit;
    text-decoration: none;
}

.row-link:hover {
    text-decoration: underline;
}

.page-meta {
    display: flex;
    align-items: center;
    margin-bottom: 8px;
}

.page-meta__updated {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 13px;
}

/* ---- フォーム ------------------------------------------------------------ */

.field-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 18px;
}

.field {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.field__label {
    font-size: 13px;
    font-weight: 700;
}

.field__required {
    margin-left: 6px;
    color: var(--error-ink);
    font-size: 12px;
    font-weight: 700;
}

/* 入力欄を持たない「表示のみ」の値（日報ヘッダの対象ユーザーなど）。
   素の span だと文字1行分の高さしかなく、.field-row（align-items: flex-end）で
   横に並べたときに入力欄の項目より文字が下がってしまう。
   入力欄と同じ高さ（padding 6px×2 ＋ 枠線 1px×2 ＋ 文字1行 ＝ 35px）の箱にして
   中央へ置き、隣の入力欄と文字の高さをそろえる。 */
.field__value {
    display: flex;
    align-items: center;
    min-height: 35px;
    font-size: 14px;
}

/* ---- 集計の絞り込み（SCR-08。filterModal.js） ---------------------------- */

/* タグ表示＋モーダルを開く「∨」。入力欄のように見せるが値は hidden input が持つ。 */
/* 囲み全体が選択モーダルを開くクリック領域になる（filterModal.js）。
   ∨ ボタンだけでなく、タグの並びや右側の空白を押しても開く。 */
.tag-field {
    display: flex;
    align-items: center;
    gap: 6px;
    min-height: 36px;
    min-width: 260px;
    padding: 4px 6px 4px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: #fff;
    cursor: pointer;
}

.tag-field:hover {
    border-color: var(--brand);
}

/* 開くボタンが非活性なら囲みごと押せない（SCR-13 で適用範囲が「全ユーザー共通」のとき）。 */
.tag-field:has(.tag-field__open:disabled) {
    cursor: not-allowed;
}

.tag-field:has(.tag-field__open:disabled):hover {
    border-color: var(--border);
}

.tag-field__tags {
    display: flex;
    flex: 1;
    flex-wrap: wrap;
    gap: 4px;
    min-width: 0;
}

.tag-field__tag {
    padding: 2px 8px;
    border: 1px solid var(--brand-light);
    border-radius: 3px;
    background: var(--brand-light);
    color: var(--brand-dark);
    font-size: 13px;
}

.tag-field__placeholder {
    color: var(--text-muted);
    font-size: 13px;
}

/* 「開く」印は画面内で1種類に統一する。select の ::picker-icon と同じ寸法・同じ線の
   太さでシェブロンを描くこと（文字の「∨」を置くとフォント依存で形も太さも揃わない）。
   select 側は枠のない線だけなので、こちらも枠と地色を持たせない。 */
.tag-field__open {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-chip);
    background: transparent;
    cursor: pointer;

    /* 矢印は ::after だけで描く。ボタンの中に文字（かつて置いていた「∨」）が
       残っていても矢印が二重に見えないよう、文字は出さない。 */
    font-size: 0;
}

.tag-field__open::after {
    content: "";
    width: 9px;
    height: 9px;
    border-right: 1.6px solid var(--text-muted);
    border-bottom: 1.6px solid var(--text-muted);
    transform: translateY(-2px) rotate(45deg);
}

.tag-field__open:hover {
    background: var(--brand-light);
}

/* SCR-13 で適用範囲が「全ユーザー共通」のときの非活性（2.14.2#2）。
   囲みごと薄くする制御は画面側（nonSubmissionDayScope.js）が行うため、
   ここでは押せないことがカーソルで分かるようにするだけに留める。 */
.tag-field__open:disabled,
.tag-field__open:disabled:hover {
    background: transparent;
    cursor: not-allowed;
}

/* モーダル本体。外側のクリックでは閉じない（2.9.2a#9）ため、
   オーバーレイは背面を覆うだけで閉じる操作は持たせない。 */
.modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(28, 31, 35, 0.45);
}

.modal {
    display: flex;
    flex-direction: column;
    width: 720px;
    max-height: 80vh;
    padding: 18px 20px;
    border-radius: var(--radius);
    background: var(--surface);
}

.modal__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}

.modal__title {
    margin: 0;
    font-size: 17px;
    font-weight: 700;
}

.modal__description {
    margin: 4px 0 0;
    color: var(--text-muted);
    font-size: 13px;
}

.modal__close {
    border: none;
    background: none;
    color: var(--text-muted);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}

.modal__toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 14px 0 10px;
}

.modal__search {
    flex: 1;
}

.modal__count {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 13px;
    white-space: nowrap;
}

.modal__body {
    flex: 1;
    overflow-y: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.modal__empty {
    margin: 0;
    padding: 24px;
    color: var(--text-muted);
    font-size: 13px;
    text-align: center;
}

.modal__note {
    margin: 10px 0 0;
    color: var(--text-muted);
    font-size: 12px;
}

.modal__foot {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 14px;
}

.modal-group + .modal-group {
    border-top: 1px solid var(--border);
}

/* 子の行（.modal-child）と同じく、行のどこを押しても切り替わる。
   押せることをカーソルでも示す。 */
.modal-group__head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    background: var(--surface-alt);
    cursor: pointer;
}

.modal-group__name {
    font-weight: 700;
    font-size: 14px;
}

.modal-group__count {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 12px;
}

.modal-group__children {
    padding: 6px 0;
}

.modal-child {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 14px 5px 34px;
    font-size: 14px;
    cursor: pointer;
}

.modal-child:hover {
    background: var(--brand-light);
}

/* 無効化済みのマスタ（2.9.2a#12）。選択はできるが状態が分かるようにする。 */
.modal-child__badge {
    padding: 1px 6px;
    border-radius: 3px;
    background: var(--surface-alt);
    color: var(--text-muted);
    font-size: 11px;
}

/* ---- 日報の作業明細（SCR-03） ------------------------------------------- */

/* 明細行の入力欄。同じ幅指定が既存行と <template>（行の追加用）の両方に現れるため、
   マークアップに書かずここでまとめて持つ。片方だけ直す事故を防ぐ。 */
#detailTable .detail-start,
#detailTable .detail-end {
    width: 96px;
}

#detailTable .detail-task,
#detailTable .detail-system,
#detailTable .detail-version,
#detailTable .detail-remarks {
    width: 100%;
}

/* 明細表のプルダウンだけ、ブラウザ既定の描画に戻す。

   appearance: base-select（下の @supports）は中身を flex で並べるため、
   選択中の文字が匿名アイテムになり min-width: auto で縮まない。
   列が狭いと文字が矢印を右へ押し出し、overflow: hidden で矢印が切れる
   （実測: 中身126pxで「選択してください」を選ぶと矢印が完全に消えた）。

   既定の描画なら文字が「選択して…」と詰まり、矢印は余白ごと残る（実測で確認）。
   開いたときの一覧はOS既定の見た目になるが、矢印が消えるよりは良い。

   **列幅を広げても根本は直らない。** 長い選択肢を選べば同じことが起きる。 */
#detailTable select {
    appearance: auto;
    display: inline-block;
}

/* 備考はテキストエリア（2.3.3#12）。インライン要素のままだとベースライン分の隙間が
   セルの下に出て行が高くなるため、ブロックにして高さをテキストエリア自身に合わせる。 */
#detailTable .detail-remarks {
    display: block;
}

/* 合計作業時間。行の右端へ寄せる。 */
.detail-total {
    margin-left: auto;
    font-weight: 700;
}

/* 残り文字数の注意書き（site.js）。上限に近づいたときだけ出る。 */
.char-count {
    display: block;
    margin-top: 2px;
    color: var(--warning);
    font-size: 12px;
}

/* display を指定すると、ブラウザ既定の [hidden] { display:none } を上書きしてしまう。
   hidden 属性で隠す前提の要素なので、明示的に戻す。 */
.char-count[hidden] {
    display: none;
}

.char-count--limit {
    font-weight: 700;
}

.field__hint {
    color: var(--text-muted);
    font-size: 12px;
}

/* type を1つでも書き漏らすと、その入力欄だけブラウザ既定の見た目になる
   （search を漏らしてモーダルの検索欄だけ枠が違っていた）。入力欄を増やすときはここに追加する。 */
input[type="text"],
input[type="password"],
input[type="search"],
input[type="date"],
input[type="time"],
input[type="number"],
select,
textarea {
    padding: 6px 11px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: #fff;
    color: var(--text);
    font-family: inherit;
    font-size: 14px;
}

/* 値を「選ぶ」欄はクリックで開く操作が主なので、押せることをカーソルで示す。
   タグ欄（.tag-field）が pointer なのに、隣の集計軸・集計期間だけ変わらないと
   同じ「選ぶ」操作に見えない。 */
select,
input[type="date"],
input[type="time"] {
    cursor: pointer;
}

/* 日付・時刻欄の中身（カレンダー／時計アイコンと、年月日の文字部分）はブラウザが
   Shadow DOM で描く別要素で、上の cursor を継承しない。欄のどこを指しても同じ
   カーソルになるよう、内部要素にも明示する。 */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="date"]::-webkit-datetime-edit,
input[type="time"]::-webkit-datetime-edit {
    cursor: pointer;
}

input::placeholder,
textarea::placeholder {
    color: var(--text-faint);
}

/* フォーカスはブラウザ既定の輪郭ではなく、アクセント色の枠＋淡いリングで示す。 */
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(46, 150, 245, .18);
}

input:disabled,
select:disabled,
textarea:disabled {
    background: var(--surface-alt);
    color: var(--text-muted);
}

/* 時刻・日付のピッカー（時計アイコン／カレンダーアイコン）はブラウザ標準のまま残す。
   開いたときのパネルは OS が描く領域で CSS が効かず、角の取れた全体のデザインから
   浮いてしまうが、マウスで選べる利便性を優先する運用判断
   （時計アイコンを消す案を一度入れたが撤回した。仕様変更ログ 2026-09-07_05）。 */

/* ---- プルダウンを開いたときのリスト -------------------------------------
   従来このリストはブラウザ（OS）が描くもので CSS が一切効かず、角の立った
   四角いリストになっていた。Chrome / Edge の customizable select を使って
   全体の角の取れたデザインにそろえる。

   対応していないブラウザでは @supports により何も適用されず、従来どおりの
   OS 既定のリストになる（対応ブラウザは最新版のみ。NFR-04・基本設計書12.1#4）。 */
@supports (appearance: base-select) {
    select,
    ::picker(select) {
        appearance: base-select;
    }

    /* 閉じているときの見た目は入力欄と同じに保つ。
       appearance を変えると UA の既定描画が外れるため、寸法を明示し直す。 */
    select {
        display: flex;
        align-items: center;
        gap: 8px;
        box-sizing: border-box;

        /* 入力欄と同じ高さ（padding 6px×2 ＋ 枠線 1px×2 ＋ 文字1行21px ＝ 35px）。
           そろえないと .field-row で日付・テキスト欄と縦位置がずれる。 */
        min-height: 35px;
        line-height: 21px;
        text-align: left;

        /* 明細表の狭い列で選択中の値が折り返すと行の高さが変わるため、1行に収める。

           幅が足りないときは文字側を詰める。text-overflow が無いと、
           文字がそのまま矢印を右へ押し出し、矢印が枠に食い込む（実測: 幅106pxで発生）。 */
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* 既定の塗りつぶし三角ではなく、細いシェブロンにする（開いたら反転）。

       margin-right が要る。45度回すと、9px の正方形の角が箱の外へ約1.9px はみ出す
       （対角線 12.7px の半分 6.36px − 元の半分 4.5px）。
       margin-left: auto で右端に寄せているため、その分だけ枠へ食い込んで見える。 */
    select::picker-icon {
        width: 9px;
        height: 9px;
        margin-left: auto;
        margin-right: 3px;
        border-right: 1.6px solid var(--text-muted);
        border-bottom: 1.6px solid var(--text-muted);
        color: transparent;
        transform: translateY(-2px) rotate(45deg);
        transition: transform .15s ease;
    }

    select:open::picker-icon {
        transform: translateY(2px) rotate(225deg);
    }

    /* リスト本体。カードと同じ角丸・淡い影にそろえる。
       選択肢は全文を見せたいので、必要ならプルダウンより横に広げる。 */
    ::picker(select) {
        min-width: anchor-size(width);
        width: max-content;
        max-width: 420px;
        margin-top: 4px;
        padding: 6px;
        border: 1px solid var(--border);
        border-radius: var(--radius);
        background: var(--surface);
        box-shadow: var(--shadow-raised);
    }

    select option {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 7px 10px;
        border-radius: var(--radius-chip);
        color: var(--text);
        font-size: 14px;
        white-space: nowrap;
    }

    select option:hover,
    select option:focus {
        background: var(--surface-alt);
    }

    select option:checked {
        background: var(--brand-light);
        color: var(--brand-ink);
        font-weight: 700;
    }

    /* 選択済みを示す既定のチェックマークは左に余白を作るため出さない
       （背景色と太字で十分に区別できる）。 */
    select option::checkmark {
        display: none;
    }
}

input.input-validation-error,
select.input-validation-error,
textarea.input-validation-error {
    border-color: var(--error);
    background: var(--error-bg);
}

textarea {
    resize: vertical;
}

/* 入力欄の下に出す注意書き。エラー（赤・保存を止める）ではなく、
   このままだと保存できないことを先に知らせるためのもの。 */
.field__hint--warning {
    color: var(--warning-ink);
}

.field-validation-error {
    color: var(--error-ink);
    font-size: 12px;
}

/* メッセージが無いときは flex アイテムから外す。空のまま残すと .field の gap 4px 分だけ
   下に余白ができ、.field-row（align-items: flex-end）で入力欄の位置が
   検証メッセージを持たない項目とずれる。 */
.field-validation-error:empty,
.field-validation-valid:empty {
    display: none;
}

.checkbox {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
}

/* ---- ボタン -------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 7px 18px;

    /* 枠線は寸法確保のために必ず持たせる（外すとボタンが 2px 縮み、行の高さが揃わない）。
       色も付けておく。地の --surface-alt はカード外の背景 --page とほぼ同色で、
       透明のままだとページ直置きのボタン（一括取込・カテゴリの管理など）が背景に沈む。 */
    border: 1px solid var(--control-border);

    border-radius: 999px;
    background: var(--control-bg);
    color: var(--brand-ink);
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;

    /* <button> は line-height を継承せず既定の normal になるため、指定しないと
       同じ .btn でも <a> と <button> で高さがずれる（一覧の「編集」と「削除」）。 */
    line-height: inherit;

    text-decoration: none;
    cursor: pointer;

    /* 列幅が足りないとき、ラベルが語中で折り返して「削 除」のように崩れる。
       ボタンの文言は短く折り返す意味がないため、はみ出させて指定漏れに気付けるようにする。 */
    white-space: nowrap;

    /* hover の色変化が一瞬だと点滅して見えるため、0.28秒かけて変える。
       対象は色だけに絞る（all にすると寸法や影まで乗って動きが重くなる）。
       .btn--primary の地はグラデーションで、CSS は色の補間ができないため即時に切り替わる。 */
    transition: background-color .28s ease, border-color .28s ease, color .28s ease;
}

/* hover は白へ反転させない（利用者の指示）。地を濃い青に変えると、一覧の操作列のように
   ボタンが並ぶ場所でカーソルの動きに合わせて面が明滅して見えるため。
   代わりに地と文字を一段ずつ濃くする。--brand-ink-dark はこの地の上で 8.2:1。
   無効時は変えない。押せる合図を押せないボタンに与えないため。
   役割を持つボタン（.btn--accent・.btn--neutral・.btn--danger・.btn--primary）は
   それぞれの色で同じことをするので、この後に自分の hover を持っている。 */
.btn:hover:not(:disabled) {
    background: var(--control-bg-hover);
    color: var(--brand-ink-dark);
}

/* 主操作。1画面に1つを原則とし、ここだけグラデーションを使う。 */
.btn--primary {
    /* 自前の濃い地を持つので、既定ボタンの枠線は消す（縁が浮いて見えるため）。
       寸法を保つため border 自体は残し、色だけ透明にする。 */
    border-color: transparent;

    background: var(--grad-brand);
    color: #fff;
}

/* 主操作だけは hover で地を濃いグラデーションに切り替える。1画面に1つの主役で、
   淡い地にすると他のボタンと見分けが付かなくなるため。
   色は2つとも要る。:not(:disabled) は .btn:hover:not(:disabled) と詳細度を揃えるためで、
   外すと既定ボタンの hover に上書きされてグラデーションが消え、
   color を書かないと文字だけが既定ボタンの青に引きずられる。 */
.btn--primary:hover:not(:disabled) {
    background: var(--grad-brand-hover);
    color: #fff;
}

/* カードの外（--page の上）に直接置くボタンのうち、枠線を出したくないもの。
   1px の線の代わりに影で縁を作る。カード・ヘッダーにも影を使っているので馴染む。
   地は白。ページ地との差は 1.10 しかないが、縁を作っているのは影なので不足しない。
   カードと同じ白を浮かせる形になり、ページの上に置かれた部品だと読み取れる。 */
.btn--raised {
    border-color: transparent;
    box-shadow: 0 1px 3px rgba(34, 49, 79, .18);
    background: var(--surface);
}

/* 押している間は影を弱めて、実際に沈んだように見せる。 */
.btn--raised:active:not(:disabled) {
    box-shadow: 0 1px 1px rgba(34, 49, 79, .16);
}

/* 主役ではない操作（検索条件のリセットなど）。地だけで押せることを示し、枠線は持たせない。
   検索ボタンの隣に同じ強さの箱が並ぶと、どちらが主かが読み取れなくなるため。
   枠線は寸法確保のために残し、色だけ透明にする（外すとボタンが 2px 縮み、行の高さが揃わない）。 */
.btn--quiet {
    border-color: transparent;
}

/* 一覧の「編集」と集計の「CSV出力」。淡い水色の地と青い文字・アイコンで役割を示す（利用者の指示）。
   .btn--danger（赤）と対になる指定。--brand-ink はこの地に載せる前提で決めた色なので、
   文字色は .btn の既定と同じ値のまま明示している。
   同じ行に並ぶ「複製」は地を変えない（--control-bg のまま）。地の違いで編集を見分けられるようにする。
   枠線は寸法確保のために残し、色だけ透明にする（外すとボタンが 2px 縮み、行の高さが揃わない）。 */
.btn--accent {
    border-color: transparent;
    background: var(--brand-light);
    color: var(--brand-ink);
}

.btn--accent:hover:not(:disabled) {
    background: var(--brand-light-hover);
    color: var(--brand-ink-dark);
}

/* 一覧の操作列の「複製」など、色で役割を示さないボタン。.btn の既定の青は
   編集（.btn--accent）に取ってあるため、青を持たせず本文色にする（利用者の指示）。 */
.btn--neutral {
    border-color: transparent;
    color: var(--text);
}

/* 文字は通常時のまま。--text はもともと濃く、これ以上濃くしても変化が読み取れないため、
   地だけを一段濃くする。 */
.btn--neutral:hover:not(:disabled) {
    background: var(--control-bg-hover);
    color: var(--text);
}

/* .btn--sunken（地に --border を敷いて一段沈ませる）は廃止した。
   --control-bg を #eef0f6 にしたことで白との差が 1.14 になり、
   既定の地のままでも面として読めるようになったため。
   「行を追加する」もヘッダのログアウトと同じ地になる。 */

.btn--danger {
    /* 淡い赤の地が識別色。灰色の枠が付くと色が濁るため透明に戻す。 */
    border-color: transparent;

    background: var(--error-bg);
    color: var(--error-ink);
}

/* hover は白へ反転させず、地と文字を一段ずつ濃くする（ボタン共通の扱い・利用者の指示）。
   濃くした地（--error-bg-hover）の上では --error-ink が 4.11:1 で 4.5 を割るため、
   文字も一段濃い --error-ink-dark にする（5.54:1）。
   :not(:disabled) は .btn:hover:not(:disabled) と詳細度を揃えるために要る。
   外すと削除ボタンが既定ボタンの hover に上書きされ、青い文字になる。 */
.btn--danger:hover:not(:disabled) {
    background: var(--error-bg-hover);
    color: var(--error-ink-dark);
}

.btn--small {
    padding: 4px 14px;
    font-size: 12px;
}

/* ボタンのラベルに添えるアイコン。文字との間隔は .btn の gap 6px が作るので、
   ここでは余白を持たせない。線の指定はナビ・メニューカードのアイコンと揃える。
   色は currentColor なので、hover で文字が一段濃くなるときアイコンも一緒に濃くなる。 */
.btn__icon {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.btn:disabled {
    opacity: 0.55;
    cursor: default;
}

.button-row {
    display: flex;
    gap: 10px;
    margin-top: 18px;
}

/* ---- テーブル ------------------------------------------------------------ */

.table {
    width: 100%;
    border-collapse: collapse;
    background: var(--surface);
}

/* 外枠と縦罫を廃し、行区切りだけで読ませる。枠が減るぶん中身が前に出る。 */
.table th,
.table td {
    padding: 11px 12px;
    border: 0;
    border-top: 1px solid var(--border);
    text-align: left;
    vertical-align: middle;
}

/* ゆったり版（SCR-04 日報一覧）。列数が少なく1行の情報量も少ない表で、
   既定の余白だと行が詰まって見えるため、上下を 11px から 14px に広げる。

   **左右（12px）は広げない。** 横1280px では表に使える幅が 840px しかなく、
   列指定の合計（190+170+120+230＝710px）と操作列の最小（約327px）で既に足りない。
   左右を 16px にすると1列あたり 8px 食い込み、「通常勤務」が2行に折り返して
   行の高さが 58px → 74px に増えた。横の間隔は列幅の指定で作ること。

   **既定（.table）は変えない。** 作業明細の表（SCR-03）は列が8つあり
   列指定の合計が 1008px ある。余白を広げるとその幅に食い込んで列が潰れる。

   .table を重ねて詳細度を上げてある。.table--roomy th だけだと、
   後ろにある .table thead th と同じ詳細度になり、負けて効かない。 */
.table.table--roomy th,
.table.table--roomy td {
    padding: 14px 12px;
}

.table.table--roomy thead th {
    padding: 0 12px 12px;
}

/* ヘッダは面ではなく小さな淡い文字で示す。行と同じ高さの帯は作らないが、
   見出しと最初のデータ行の境目が分からなくなるため、下の罫線だけは引く。 */
.table thead th {
    padding: 0 12px 10px;
    border: 0;
    border-bottom: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

/* 見出しを押して並び替える列（SCR-09）。見出しの見た目は変えず、押せることは
   ホバーの色変化とカーソルで示す。現在の並び替えキーには ▲▼ を出す。 */
.table__sort {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}

.table__sort:hover {
    color: var(--brand-dark);
}

/* 並び替えていない列は薄い ⇅、並び替え中の列は濃い ▲▼。幅を固定して、
   押すたびに見出しの位置がずれないようにする。 */
.table__sort-mark {
    display: inline-block;
    min-width: 10px;
    color: var(--text-faint);
    font-size: 10px;
}

.table__sort-mark.is-active {
    color: var(--brand);
    font-size: 9px;
}

.table__sort:hover .table__sort-mark {
    color: var(--brand-dark);
}

/* 揃えは「文字は左・数値は右」の2種類だけとする。中央揃えは使わない。
   中央揃えは左右どちらの縁も不揃いになり、列が増えると視線の拠り所が無くなるため。
   見出しの寄せはその列のデータに合わせる（マークアップ側で th にも is-numeric を付けている）。 */
.table thead th {
    text-align: left;
}

.table th.is-numeric {
    text-align: right;
}

/* 「10時間00分（10.00）」のように時分と小数を並べた値は、列幅が足りないと
   括弧の前で折り返して2行になる（下の padding-right:24px のぶん実効幅が狭い）。
   数値のかたまりは1行で読ませたいので折り返さない。
   .table は table-layout:auto なので、幅が足りなければ列側が広がる。 */
.table th.is-numeric,
.table td.is-numeric {
    white-space: nowrap;
}

/* 日付のように書式の決まった値も1行で読ませる。折り返すと「2026/09/15」と
   「（火）」が分かれて、2行ぶんの行高になる。

   数値列と分けているのは、揃えが違うため（数値は右、日付は左）。
   .is-numeric を付けると右揃えになってしまう。 */
.table th.is-nowrap,
.table td.is-nowrap {
    white-space: nowrap;
}

/* 前の列との間を広げる。左揃えの列同士が並ぶと、値の右端と次の列の左端が
   余白（12px×2）ぶんしか離れず、どこまでが同じ列か読み取りにくくなる。
   右揃えの数値列が使っている padding-right: 24px と同じ考え方を、
   境目の手前側ではなく後ろ側に当てたもの。 */
.table th.is-gap-before,
.table td.is-gap-before {
    padding-left: 32px;
}

/* 操作列を「中身が入るだけの幅」に縮める。

   width: 1% は table-layout: auto に対する定石で、指定が小さすぎるため
   内容の最小幅まで戻される。結果この列は広がらず、余った幅は他の列が
   指定幅の比で分け合う。値が横いっぱいに散り、操作は右端に寄る。

   これを付けないと、最後の列（操作）が余りを全部もらってボタンの右に
   大きな空白ができる（横1825px で 465px ほど）。

   nowrap は、縮めた結果ボタンが縦に折り返さないようにするため。 */
.table th.is-fit,
.table td.is-fit {
    width: 1%;
    white-space: nowrap;
}

/* 見出し側にも同じ左余白を効かせる。
   .table.table--roomy thead th（クラス2・要素2）は .table th.is-gap-before（クラス2・要素1）より
   詳細度が高く、そのままだと見出しだけ 12px に戻ってしまう。
   実際に見出しと値が 20px ずれた（32 − 12）。 */
.table.table--roomy thead th.is-gap-before {
    padding-left: 32px;
}

/* 右揃えの数値は「値の右端」で列が終わり、次の列は「内容の左端」から始まるため、
   セルの余白（12px×2）しか間が空かず、他の列間と比べて極端に詰まって見える。
   境目の両側に余白を足し、数値のかたまりと次の列を切り離す。
   最終列の数値は次の列が無いので広げない（表の右端から不自然に浮くため）。 */
.table th.is-numeric:not(:last-child),
.table td.is-numeric:not(:last-child) {
    padding-right: 24px;
}

.table th.is-numeric + th,
.table td.is-numeric + td {
    padding-left: 24px;
}


/* 見出し直下の最初の行には区切り線を引かない（ヘッダとの境界が二重になる）。 */
.table tbody tr:first-child > th,
.table tbody tr:first-child > td {
    border-top: 0;
}

.table tbody tr:hover > td {
    background: var(--surface-alt);
}

/* 行の網掛けは「この行に対して何かできる」という合図。集計結果のように
   読むだけの表では操作の余地がないため、網掛けを出さない。 */
.table--static tbody tr:hover > td {
    background: transparent;
}

/* かつて、行 hover の間だけ操作列のボタンの地を白へ逃がしていた。
   ボタンの地が行 hover の地（--surface-alt）と同色で、ボタンの輪郭が消えたため。
   ボタンの地を --control-bg（#e6eaf4）に分けた時点で不要になったので外した。
   いま行 hover 中のボタンは 1.12:1 で地から分かれており、白へ逃がしていた頃（1.07:1）より
   むしろ見やすい。行より明るくなって浮く副作用も無くなっている。 */

.table td.is-numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
}


.table__actions {
    display: flex;

    /* アイコンを付けたぶん、ボタンが隣同士でくっついて1つの帯に見える。
       6px から広げてある。 */
    gap: 10px;

    /* 他の列と同じく左に寄せる（中央揃えは全廃）。 */
    justify-content: flex-start;

    /* 「削除」は <form> に包まれている。既定の stretch では form が行の高さまで
       伸び、その中でボタンが上寄せになるため、隣の「編集」と縦位置がずれる。 */
    align-items: center;
}

/* 操作列のボタンは枠線を持たせない。--control-border はカード外（--page の上）で
   地に沈むボタンの輪郭を出すためのもので、白地の表の中では不要。行ごとに枠が並ぶと
   数値や氏名より操作が目立ってしまう。

   行 hover 時の白い地で輪郭は保たれる。 */
/* 操作列のボタンは枠線を持たせない。行ごとに枠が並ぶと、数値や氏名より操作が目立つため。
   形は地の色の差だけで保っている。 */
.table__actions .btn {
    border-color: transparent;

    /* .btn--small の左右 14px より広げる。アイコンが入って中身が詰まったため。
       上下は変えない（行の高さ 52px は今までどおり）。 */
    padding-right: 18px;
    padding-left: 18px;
}

/* 行を hover しても操作列に枠は出さない（利用者の指示）。
   ボタンの地（--control-bg #eef0f6）と行 hover の地（--surface-alt #f5f7fc）の差は
   1.06 で、溶けない下限として置いていた 1.07 をわずかに割る。
   カーソルを乗せた行では編集・複製の面が見えにくくなるが、
   枠が出るほうが気になるとの判断でこうしている。
   直すなら枠ではなく、--control-bg を少し濃くするか行 hover の地を変えること。 */

/* 操作列のボタンの地は .btn の既定（--control-bg）のまま。
   以前はここで一段薄い色に上書きしていたが、--control-bg 自体を
   淡い青にしたので、上書きは不要になった（同じ色になるため）。 */

/* 未入力日一覧（全ユーザー）の、日報入力画面へ移動する日付・氏名。
   数が多く1セルに並ぶため、区切り文字ではなく折り返す並びとして扱う。 */
.day-links {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 10px;
}

/* 数十個が横に並ぶため、通常時は本文と同じ色にする。全部を青くすると
   一覧が読みにくく、日付そのものが頭に入らない。押せることは hover で示す。 */
.day-link {
    padding: 1px 5px;
    border-radius: var(--radius-chip);
    color: var(--text);
    text-decoration: none;
    white-space: nowrap;
}

/* 数十個が並ぶため、hover は下線ではなく色で示す。
   下線だと重なったときに罫線のように見えて、一覧が読みにくくなる。
   通常時は本文と同じ色なので、押せるかどうかはこの反応だけが手がかりになる。
   移動先を決められない .is-plain（span）には反応させない。 */
a.day-link:hover {
    background: var(--brand-light);
    color: var(--brand-ink);
}

/* 台帳の UserId を引けず、移動先を決められない場合。
   色は本文と同じ（.day-link と同値）。hover に反応しないことで押せないと分かる。 */
.day-link.is-plain {
    cursor: default;
}

/* 上限を超えた分の畳み。日付のリンクと同じ色・同じ形だと「もう1件の日付」に見えるため、
   色を落として矢印を添え、開く操作だと分かるようにする。 */
.day-more {
    margin-top: 8px;
}

.day-more > summary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text-muted);
    font-size: 12px;
    cursor: pointer;

    /* 既定の三角マーカーを消して、下のシェブロンに置き換える。 */
    list-style: none;
}

.day-more > summary::-webkit-details-marker {
    display: none;
}

/* プルダウン（select の ::picker-icon・.tag-field__open）と同じ形・同じ太さ。
   画面内の「開く」印を1種類に揃える。 */
.day-more > summary::after {
    content: "";
    width: 7px;
    height: 7px;
    border-right: 1.6px solid currentColor;
    border-bottom: 1.6px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
    transition: transform .15s ease;
}

.day-more[open] > summary::after {
    transform: translateY(1px) rotate(225deg);
}

.day-more > summary:hover {
    color: var(--brand-dark);
}

.day-more > .day-links {
    margin-top: 8px;
}

.table__empty {
    padding: 28px;
    color: var(--text-muted);
    text-align: center;
}

.badge {
    display: inline-flex;
    align-items: center;
    height: 22px;
    padding: 0 10px;
    border-radius: 999px;
    background: var(--surface-alt);
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 600;
}

.badge--active {
    background: var(--success-bg);
    color: var(--success-ink);
}

/* 一覧の「無効」。操作列のボタンと同じ地（--control-bg）にして色味を揃える。
   文字は --text-muted より一段濃くする。11px の小さい文字なので、
   この地の上では --text-muted だと基準（4.5:1）を割るため。
   この組み合わせで 4.52:1。**地をこれ以上濃くすると 4.5:1 を割る。** */
.badge--inactive {
    background: var(--control-bg);
    color: #5a6a85;
}

/* 行数の多い一覧（SCR-04 / SCR-06 / SCR-13）で、列見出しだけ画面に残す。
   ユーザー一覧は 400 件を超えることがあり（この画面にページャは無い。
   設計書 6.5#4 のページングは SCR-05 のみ）、下へ進むほどどの列を見ているのか
   分からなくなるため。

   高さは抑えない（枠の中でスクロールさせない）。表の中と画面とでスクロールが
   二重になり、ホイールが枠の中で止まる。縦の狭い端末では表の見える範囲が
   かえって狭くなる。表はページごと流し、見出しだけを残す。 */
.table-sticky .table thead th {
    position: sticky;

    /* ヘッダ（.app-header）は sticky で画面上端に留まり、高さは 56px。
       top: 0 にすると見出しがその裏へ潜って見えなくなる。 */
    top: 56px;

    /* .app-header（z-index: 2）より下に置く。見出しはヘッダの手前に出さない。 */
    z-index: 1;

    /* 地は既定で透明なので、指定しないとスクロールした行が見出しに透ける。
       上の余白も要る。既定の見出しは padding-top が 0 で、文字のすぐ上に
       不透明な帯が無く、潜り込んできた行が見出しの上端からはみ出して見える。 */
    padding-top: 12px;
    background: var(--surface);

    /* 見出し下の罫線を影で引き直す。.table は border-collapse: collapse で、
       隣のセルと共有した border は浮いた見出しには付いてこない（線が消える）。
       影は要素そのものに付くため残る。 */
    box-shadow: inset 0 -1px 0 var(--border);
}

/* ---- 日報ヘッダの3枚組（SCR-03） ---------------------------------------- */

/* 入力欄・カレンダー・まとめを同じ幅で3枚並べる。幅と間隔を揃えることで、
   下に続く作業明細との余白も含めて、すべての間隔が 16px で揃う。
   1枚のカードに同居させると、書く場所と状況を見る場所の境目が読み取れない。
   auto-fit を使うのは、幅が足りないとき自動で2列・1列へ落とすため
   （このファイルはメディアクエリを使わない方針）。 */
/* 入力欄・カレンダー・記入率を 1.4:1:1 で割る。
   入力欄は 340px で頭打ちになる（.report-top__main input の max-width）ので、
   ヘッダにそれ以上の幅を与えても余白が増えるだけ。1.4 はその上限がちょうど
   収まる比で、これより小さくすると入力欄が縮み始める。
   余った幅はカレンダーへ回す。マスの高さは固定なので、横に広がっても
   この段は高くならず、日付が読みやすくなるだけ。 */
.report-top {
    display: grid;
    grid-template-columns: 1.4fr 1fr 1fr;
    gap: 16px;
    margin-bottom: 16px;
}

/* 並べている間はカード自身の下余白を消す。グリッドの gap と二重にかかるため。
   内側の余白は .card の既定（32px）をそのまま使う。 */
.report-top > .card {
    margin-bottom: 0;
}

/* 入力欄は縦に積む。横並びだと3項目で 500px 近く要り、その幅をカレンダー側から
   奪うことになる。縦に積めばヘッダの幅を詰められ、カレンダーのマスを大きく取れる。
   ただし縦に積むと、項目の間隔が3回ぶん高さに乗る。このカードが3枚のうち
   いちばん高くなり、上段全体の高さを決めてしまうため、間隔は詰めている。 */
.report-top__main .field-row {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
}

/* ラベルは入力欄の上に置く（.field の既定のまま）。横に並べると入力欄が
   右へ押し出され、ラベルの列と入力欄の列に分かれて間延びして見える。 */
.report-top__main .field {
    gap: 4px;
}

/* 縦に積むと入力欄が左に寄って細く見えるため、枠の幅まで広げる。 */
/* 枠いっぱいに広げる。上限は、画面が広いときに入力欄だけ間延びしないため。 */
.report-top__main input[type="date"],
.report-top__main select {
    width: 100%;
    max-width: 340px;
}

/* カード見出しの既定（20px）は、3枚並べたこの段には大きすぎる。
   ただし詰めすぎると窮屈に見えるので、本文より一段大きい程度に留める。

   **入力状況カレンダーの見出しは .cal-nav の中にある**（左右に月送りボタンを置くため）。
   直下の子だけを対象にすると、そちらだけ 20px のまま取り残される（実際にそうなっていた）。 */
.report-top > .card > .card__title,
.report-top > .card > .cal-nav > .card__title {
    margin-bottom: 12px;
    font-size: 14px;
}

/* 3枚のカードは高さが揃うため、何もしないとカレンダーの下だけが空く。
   カード内で縦に伸ばし、凡例を下端へ寄せて余白を分散させる。 */
.cal-card {
    display: flex;
    flex-direction: column;
}

/* 枠いっぱいに広げる。マスの高さは固定にしてあるので（.cal__day）、
   横に広がっても縦には伸びない。画面幅でこの段の高さが変わらないのはそのため。
   月名は見出しに入れたので、ここでは持たない（1行ぶん背が縮む）。 */
.cal {
    display: flex;
    flex-direction: column;
    flex: 1;
    width: 100%;
}

/* 月名と前後への移動。月名は中央に置き、左右に同じ幅のボタンを据える。 */
/* 下の余白は中の見出し（.card__title）が持っているので、ここでは持たない。
   両方に持たせると二重にかかる。 */
.cal-nav {
    display: flex;
    align-items: center;
    gap: 4px;
}

.cal-nav__title {
    flex: 1 1 auto;
    margin: 0;
    text-align: center;

    /* 折り返させない。「入力状況（2026年10月）」のように1文字長い月で2行になると、
       カードの高さが1行ぶん跳ねる（実測: 365px → 393px）。 */
    white-space: nowrap;
}

.cal-nav__btn {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
}

.cal-nav__btn:hover:not(:disabled) {
    background: var(--control-bg);
    color: var(--brand-ink);
}

/* 端まで来たら押せなくする。消すとボタンの位置がずれて月名が動く。 */
.cal-nav__btn:disabled {
    opacity: .3;
    cursor: default;
}

.cal-nav__btn svg {
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.cal__grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));

    /* 曜日の行＋週6行ぶんを必ず確保する。月によって週の数が 5 と 6 で変わるため、
       確保しないと月を切り替えたときにカードの高さが跳ねる。 */
    grid-template-rows: auto repeat(6, minmax(32px, auto));

    gap: 2px;
}

.cal__wd {
    padding: 0 0 6px;
    text-align: center;
    font-size: 11px;
    color: var(--text-muted);
}

/* マスはリンク。押すとその日の日報を開くので a のままにしておく
   （新しいタブで開く・キーボードで辿るといった操作がそのまま効く）。
   .btn の見た目にはしないため、下線と字体は打ち消す。 */
.cal__day {
    appearance: none;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 32px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-chip);
    background: none;
    font: inherit;
    font-size: 14px;
    color: var(--text);
    text-decoration: none;
    cursor: pointer;
}

/* 空きマスも同じ高さで場所を取らせる。揃えないとその行だけ詰まって見える。 */
.cal__pad {
    min-height: 32px;
}

.cal__day.is-unentered {
    background: var(--error-bg);
    color: var(--error-ink);
    font-weight: 600;
}


/* 入力済み。画面の他の要素（ナビ・主ボタン・選択中の枠）が青系なので、
   ここだけ緑にすると色系統が1つ増えて浮く。
   赤（未入力）との組み合わせという意味でも、青のほうが見分けやすい
   （赤と緑は最も多い色覚特性で区別しにくい）。 */
.cal__day.is-entered {
    background: var(--brand-light);
    color: var(--brand-ink);
}

/* 提出不要日（土日・登録された休業日）。押せないマスなので色は落とすが、
   塗られていること自体は見える濃さにする（利用者の指示）。 */
.cal__day.is-off {
    background: var(--control-bg);
    color: var(--text-muted-dark);
}

.cal__day.is-weekend {
    color: var(--text-faint);
}

/* 複製中に選べない日（既に明細入りの日報がある）。
   色（入力済み・未入力）はその月の状況を読むために残し、薄くして押せなくする。
   is-out と違って「作れない日」ではないので、色まで落とさない。 */
.cal__day.is-taken {
    opacity: .4;
    cursor: default;
}


/* 当日より後・入力開始日より前。日報を作れない日なので、リンクにしていない。 */
.cal__day.is-out {
    color: var(--text-faint);
    opacity: .45;
    cursor: default;
}

/* 反応するのは押せるマスだけ。地の色は状態を表しているので変えず、輪郭だけ出す。
   通常はリンク（その日を開く）、複製中は button（日付欄へ入れる）の2種類がある。
   .cal__day.is-out（作れない日）は span なので、ここには当たらない。 */
a.cal__day:hover,
button.cal__day:hover {
    outline: 1px solid var(--control-border);
    outline-offset: -1px;
}

/* いま編集している日。地の色は状態（未入力・入力済み）に使っているため、
   選択中であることは輪郭で示す。 */
.cal__day.is-selected {
    outline: 2px solid var(--brand);
    outline-offset: -2px;
    font-weight: 700;
}

/* カレンダーに凡例は置かない。隣の「今月のまとめ」が同じ色の見本と名前を
   並べており、2か所に出してもこの段が1行ぶん高くなるだけだったため。
   マスの意味は title 属性（ツールチップ）でも読める。 */

/* 保存と削除を同じ行の両端に置く（SCR-03）。削除は取り消せないので、
   間隔を空けて保存から最も遠ざける。押し間違いを防ぐのが目的なので、
   ここに3つ目のボタンを足して間を詰めないこと。 */
/* 保存と削除は右端にまとめる。視線の終点に主操作（保存）が来る並び。
   gap 24px は、まとめたうえでも指が滑って隣を押さないための最低限の間隔。
   これを詰めるなら、削除側にもう一段の確認が要る。 */
.form-actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 24px;
    margin-top: 16px;
}

/* ---- カレンダーの凡例と記入率（SCR-03） --------------------------------- */

/* マスの色が何を表すかの見本。カレンダーの下端に横1行で置く。
   日数までは出さない。縦に積むとこの段が3行ぶん高くなり、
   主役である作業明細を押し下げてしまうため。 */
.cal-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 14px;
    margin: 0;
    margin-top: auto;
    padding-top: 12px;
    font-size: 11px;
    color: var(--text-muted);
}

.cal-legend__item {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

/* 既定は提出不要日の地。入力済み・未入力は修飾クラスで上書きする。 */
.cal-legend__swatch {
    width: 12px;
    height: 12px;
    border-radius: 3px;
    background: var(--control-bg);
}

.cal-legend__swatch.is-entered { background: var(--brand-light); }
.cal-legend__swatch.is-unentered { background: var(--error-bg); }

/* 記入率のドーナツ。数字は SVG の <text> ではなく上に重ねる。
   SVG 内の文字はページのフォント指定が効きにくく、他の数字と字形が揃わないため。 */
.ratio {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: auto 0 10px;
}

/* 大きさはこのカードの高さを決めるが、隣のカレンダー（5〜6行＋凡例）より
   低い間は上段の高さに影響しない。その範囲でできるだけ大きく取る。 */
.ratio__chart {
    width: 170px;
    height: 170px;

    /* きらめきは viewBox（0〜42）の外に置いてある。SVG は既定でここを切るので、
       見せるために visible にする。レイアウトには影響しない（要素の大きさは 170px のまま）。 */
    overflow: visible;
}

.ratio__track {
    fill: none;
    stroke: var(--surface-alt);
    stroke-width: 4;
}

/* 入力済みの割合なので、カレンダーの「入力済み」と同じ色を使う。
   同じ意味に別の色を当てると、2つの表示が別の話に見える。

   開くたびに 0 から現在の値まで描き進める。
   長さは stroke-dasharray（円周ぴったりの100）を固定して dashoffset を動かす。
   2値の dasharray を動かすより補間が素直で、途中で線が途切れない。
   そのぶん始点を12時へ回す役目は transform が持つ。 */
.ratio__value {
    fill: none;
    stroke: var(--brand);
    stroke-width: 4;
    stroke-linecap: round;
    stroke-dasharray: 100;
    stroke-dashoffset: 100;
    transform: rotate(-90deg);
    transform-origin: 21px 21px;
    animation: ratio-fill .9s cubic-bezier(.22, .8, .3, 1) forwards;
}

@keyframes ratio-fill {
    to {
        stroke-dashoffset: var(--ratio-rest);
    }
}

/* ここから 100% のときだけの演出。リングを描き終える .9s のあとに、
   数字が一度弾む → きらめきが出る → チェックが残る、の順で重ねる。
   繰り返さない。毎回動き続けると、入力の邪魔になるため。 */
.ratio.is-complete .ratio__label {
    animation: ratio-pop .5s cubic-bezier(.34, 1.56, .64, 1) .85s both;
}

@keyframes ratio-pop {
    0% { transform: scale(1); }
    45% { transform: scale(1.12); }
    100% { transform: scale(1); }
}

/* きらめき。transform-box: fill-box で、各自の中心を軸に拡大縮小させる
   （既定の view-box 基準だと、図全体の中心を軸に飛んでいってしまう）。 */
.ratio__spark {
    fill: var(--brand);
    opacity: 0;
    transform-box: fill-box;
    transform-origin: center;
    animation: ratio-spark 1.1s ease-out var(--ratio-delay) both;
}

/* 半分は黄。1色だと粒が揃って見えるので、青と交互に置く。
   注意の黄（--warning）を飾りとして借りている。白地で 2.05:1。
   これより淡い黄（例 #ffd65c は 1.40:1）は白地でほとんど見えない。 */
.ratio__spark--gold {
    fill: var(--warning);
}

@keyframes ratio-spark {
    0% { opacity: 0; transform: scale(.3); }
    35% { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(.85); }
}

/* 締めに残るチェック。数字の上に置く。 */
.ratio__check {
    position: absolute;
    top: 34px;
    left: 50%;
    display: flex;
    color: var(--brand);
    opacity: 0;
    transform: translateX(-50%) scale(.6);
    animation: ratio-check .45s cubic-bezier(.34, 1.56, .64, 1) 1.35s forwards;
}

.ratio__check svg {
    width: 26px;
    height: 26px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

@keyframes ratio-check {
    to {
        opacity: 1;
        transform: translateX(-50%) scale(1);
    }
}

/* 動きを減らす設定の端末では、最初から結果だけを見せる。 */
@media (prefers-reduced-motion: reduce) {
    .ratio__value {
        stroke-dashoffset: var(--ratio-rest);
        animation: none;
    }

    .ratio.is-complete .ratio__label,
    .ratio__spark,
    .ratio__check {
        animation: none;
    }

    .ratio__check {
        opacity: 1;
        transform: translateX(-50%);
    }
}

.ratio__label {
    position: absolute;
    margin: 0;
    font-size: 36px;
    font-weight: 700;
    line-height: 1;
    color: var(--text);
}

.ratio__unit {
    margin-left: 2px;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-muted);
}

/* 率の母数。下の auto と .ratio の上の auto が対になって、図と文字をまとめて
   カードの縦中央に置く。 */
.ratio__detail {
    margin: 0 0 auto;
    text-align: center;
    font-size: 12px;
    color: var(--text-muted);
}

.month-summary-card {
    display: flex;
    flex-direction: column;
}

/* ---- ページング ---------------------------------------------------------- */

.pager {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 14px;
}

/* 地は操作列のボタンと同じ --control-bg。枠線は出さない。

   ページャーはカードの中（白地）に置いている。白との差は 1.14 あり、
   枠が無くても面として読める。カード外（--page の上）へ動かすと
   差が 1.04 まで落ちて沈むので、そのときは枠を戻すこと。

   border 自体は残して色だけ透明にする（外すと 2px 縮み、現在ページの丸と高さが揃わない）。 */
.pager__link {
    transition: background-color .28s ease, border-color .28s ease, color .28s ease;

    padding: 4px 13px;
    border: 1px solid transparent;
    border-radius: 999px;
    background: var(--control-bg);
    color: var(--text);
    text-decoration: none;
}

.pager__link.is-current {
    border-color: var(--brand);
    background: var(--brand);
    color: #fff;
}

.pager__info {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 13px;
}

/* ---- メッセージ（6.5#6・6.4#3） ------------------------------------------ */

/* 枠線を廃し、淡い地の面だけで示す（罫線を減らす方針）。 */
.alert {
    display: flex;
    gap: 10px;
    margin-bottom: 16px;
    padding: 12px 16px;
    border: 0;
    border-radius: var(--radius);
}

.alert__icon {
    flex: 0 0 20px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    line-height: 20px;
    text-align: center;
}

.alert__body {
    margin: 0;
}

.alert__body p {
    margin: 0;
}

/* アラートの中に置く操作。本文を読んだあと、その場で次の操作が要るときだけ使う
   （同時実行の競合 E-3012 の「最新の内容を開き直す」）。
   .alert__body p（margin: 0）に勝たせるため、クラス2つで書いている。 */
.alert__body .alert__actions {
    margin-top: 10px;
}

.alert--error {
    background: var(--error-bg);
    color: var(--error-ink);
}

.alert--error .alert__icon {
    background: var(--error);
}

.alert--warning {
    background: var(--warning-bg);
    color: var(--warning-ink);
}

.alert--warning .alert__icon {
    background: var(--warning);
}

.alert--success {
    background: var(--success-bg);
    color: var(--success-ink);
}

.alert--success .alert__icon {
    background: var(--success);
}

/* ---- ログイン画面（SCR-01） ---------------------------------------------- */

/* ログイン画面はヘッダーを出さないので、画面の高さいっぱいで中央に寄せる
   （ヘッダー分の 56px を引いていた頃の名残で、カードが上にずれていた）。 */
.login-page {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
}

.login-card {
    width: 400px;
    padding: 32px;
    border: 0;
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    background: var(--surface);
}

.login-card__logo {
    display: block;
    width: 52px;
    height: 52px;
    margin: 0 auto 14px;
}

.login-card__title {
    margin: 0 0 6px;
    font-size: 20px;
    font-weight: 700;
    text-align: center;
}

.login-card__lead {
    margin: 0 0 22px;
    color: var(--text-muted);
    font-size: 13px;
    text-align: center;
}

.login-card .field {
    margin-bottom: 16px;
}

.login-card .field input {
    width: 100%;
}

.login-card .btn {
    width: 100%;
}

/* ---- 複数選択コンボボックス（tagSelect.js） ------------------------------ */
/* 元の select multiple は値の保持・送信のために DOM へ残し、視覚的にのみ隠す。
   display:none や hidden 属性でも送信はされるが、開発者ツールでの確認しやすさを
   優先して領域を潰す形にしている。 */
.tag-select__source {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.tag-select {
    position: relative;
}

.tag-select__control {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    min-height: 33px;
    min-width: 260px;
    max-width: 420px;
    padding: 4px 6px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: #fff;
    cursor: text;
}

.tag-select__control:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px var(--brand-light);
}

.tag-select__tags {
    display: contents;
}

.tag-select__tag {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 1px 4px 1px 8px;
    border: 1px solid var(--brand);
    border-radius: 10px;
    background: var(--brand-light);
    color: var(--brand-dark);
    font-size: 13px;
    line-height: 1.6;
}

.tag-select__remove {
    padding: 0 2px;
    border: 0;
    background: transparent;
    color: var(--brand-dark);
    font-family: inherit;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
}

.tag-select__remove:hover {
    color: var(--error);
}

/* 枠内に残った幅へ伸びる。タグが増えたら折り返して次の行を占める。 */
.tag-select__input {
    flex: 1 1 80px;
    min-width: 80px;
    padding: 2px 2px !important;
    border: 0 !important;
    border-radius: 0 !important;
    outline: none;
    font-size: 14px;
}

.tag-select__menu {
    position: absolute;
    z-index: 20;
    left: 0;
    right: 0;
    max-width: 420px;
    max-height: 220px;
    margin: 2px 0 0;
    padding: 4px 0;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: 0 4px 12px rgba(28, 31, 35, 0.14);
    list-style: none;
    overflow-y: auto;
}

.tag-select__option {
    padding: 5px 10px;
    font-size: 14px;
    cursor: pointer;
}

.tag-select__option.is-active {
    background: var(--brand-light);
    color: var(--brand-dark);
}

.tag-select__empty {
    padding: 5px 10px;
    color: var(--text-muted);
    font-size: 13px;
}

/* ---- 一覧行の並び替え（sortableRows.js） -------------------------------- */
/* 「並び替え」列。⠿ そのものだけでなくセル全体がクリックの当たり判定になる
   （押すと行が選択され、↑↓ キーで動かせる。sortableRows.js）。 */
.sortable__cell {
    white-space: nowrap;
    cursor: grab;
}

.sortable__cell:active {
    cursor: grabbing;
}

/* つかみ手。フォーカスを当てて矢印キーで動かせるよう tabindex を持つ。 */
.sortable__grip {
    display: inline-block;
    padding: 2px 6px;
    border-radius: 3px;
    color: var(--text-faint);
    font-size: 16px;
    line-height: 1.2;
    cursor: grab;
    user-select: none;
}

tr[data-sortable-row]:hover .sortable__grip {
    color: var(--brand-dark);
}

/* つかみ手にフォーカスが当たっている状態。行側でも色を変えるため、
   ここでは輪郭と色の変化だけに留める。 */
.sortable__grip:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    color: var(--brand-dark);
}

/* 矢印キーの効き先になっている行。クリックでもキーボードでも同じ見た目にするため、
   :focus-visible ではなく :focus で判定する。
   対応システム一覧の「選択中」（is-selected の淡いグレー背景）と重なっても見分けが
   付くよう、背景だけでなく輪郭と左端のバーでも示す。 */
tr[data-sortable-row]:has(.sortable__grip:focus) > td {
    background: var(--brand-light);
}

tr[data-sortable-row]:has(.sortable__grip:focus) {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

tr[data-sortable-row]:has(.sortable__grip:focus) > td:first-child {
    box-shadow: inset 4px 0 0 0 var(--brand);
}

/* 行を掴んでいる間は hover の網掛けを出さない（掴んだ行が分かりにくくなる）。 */
.table tr.is-selectable:has(.sortable__grip:focus):hover > td {
    background: var(--brand-light);
}

.sortable__grip:active {
    cursor: grabbing;
}

/* 掴んでいる行。落とす位置は行の入れ替えそのもので示すため、
   ドロップ先のガイド線は設けない。 */
tr.is-dragging {
    opacity: 0.4;
    background: var(--brand-light);
}

/* 行のどこからでも掴めるため、掴めることをカーソルで示す。
   ただし対応システム一覧（is-selectable）は行クリックでの選択が主操作なので、
   pointer のままにする。 */
table[data-sortable-rows] tr[data-sortable-row]:not(.is-selectable) {
    cursor: grab;
}

table[data-sortable-rows] tr[data-sortable-row]:active {
    cursor: grabbing;
}

table[data-sortable-rows] tr[data-sortable-row] {
    /* ドラッグ中にテキスト選択が走ると掴み損ねるため、行内の選択を抑える。 */
    user-select: none;
}

.sortable-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 12px;
}

.sortable-bar__status {
    color: var(--warning);
    font-size: 13px;
    font-weight: 700;
}
