/*
 * スタイル仕様書.md（2026-09-07版）に基づく。色・字号・間隔・現場での押しやすさ最優先の
 * 各原則をそのまま数値化したもの。border-radius は 2px を既定、Primary ボタンのみ 6px、
 * ドットのみ 50%（旧仕様の値を踏襲。現行のスタイル仕様書はトークン集のため実装値はここで確定させる）。
 */

:root {
    --bg-page: #e7e9ec;
    --bg-card: #ffffff;
    --text-primary: #16191d;
    --text-secondary: #2b3138;
    --text-tertiary: #4a525c;
    --text-aux: #5a636e;
    --border-main: #d5d9de;
    --border-sub: #e4e7ea;
    --surface: #f2f3f5;
    --surface-hover: #f7f8f9;
    --dashed: #bfc5cd;
    --accent-blue: #123f9c;
    --accent-green: #0b5c2a;
    --confirm-bg: #e4e7ea;
    /* 2026-09-09新設: 状態ブロックの背景に使う、状態色と連動した淡い色。区画ごとの背景を
       全部白にすると境界が分かりにくい、というユーザー指摘への対応（ブロック区分の改善案）。
       toneOf() の tone 名（moving/active/neutral/done）と1対1で対応させる。 */
    --wash-moving: #eaf0fc;
    --wash-active: #eaf5ee;
    --wash-neutral: #e9ebee; /* --surface(#f2f3f5)よりわずかに濃く、中性状態でも予定ブロックとの境目が見えるように */
    --wash-done: #ececee;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--bg-page);
    color: var(--text-primary);
    font-family: "Noto Sans JP", "Hiragino Kaku Gothic ProN", sans-serif;
    -webkit-font-smoothing: antialiased;
}

[x-cloak] { display: none !important; }

.tnum {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

.page {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* ---- DEV バー（§10 開発用パネル） ---- */
.dev-bar {
    width: 100%;
    max-width: 440px;
    background: #16191d;
    color: #e4e7ea;
    padding: 9px 16px;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    position: sticky;
    top: 0;
    z-index: 30;
}
.dev-bar__label {
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .08em;
    color: #8b93a0;
    margin-right: 4px;
}
.dev-bar__chip {
    height: 28px;
    padding: 0 11px;
    border-radius: 2px;
    font-size: 12px;
    font-weight: 700;
    background: transparent;
    border: 1px solid #5a636e;
    color: #e4e7ea;
    cursor: pointer;
}
.dev-bar__chip--active {
    background: #fff;
    border-color: #fff;
    color: #16191d;
    font-weight: 800;
}
/* 2026-09-12新設: 打刻Eventの実DB削除を伴う操作のため、他のシナリオ切替ボタンと
   見た目で区別する（誤タップ防止）。 */
.dev-bar__chip--reset {
    margin-left: auto;
    border-color: #a33;
    color: #f2a0a0;
}

/* ---- カード ---- */
.card {
    width: 100%;
    max-width: 440px;
    min-height: calc(100vh - 40px);
    background: var(--bg-card);
    border-left: 1px solid var(--border-main);
    border-right: 1px solid var(--border-main);
    display: flex;
    flex-direction: column;
    padding-bottom: 40px;
}

/* ---- バナー共通 ---- */
.banner {
    padding: 12px 20px;
    font-size: 13.5px;
    font-weight: 700;
    border-bottom: 1px solid var(--border-main);
}
.banner--sync {
    background: var(--surface);
    color: var(--text-tertiary);
}
.banner--confirm {
    background: var(--confirm-bg);
    color: var(--text-primary);
}

/* ---- ヘッダ ---- */
.header {
    padding: 18px 20px 14px;
    border-bottom: 1px solid var(--border-main);
}
/* 2026-09-15新設: 氏名とリセットボタンを同じ行の左右に配置する。 */
.header__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
.header__name {
    font-size: 16px;
    font-weight: 700;
    letter-spacing: .01em;
}
/* 2026-09-15新設: テストしやすさのための常設リセットボタン（ユーザー指摘）。
   誤タップしても即実行されないよう控えめな見た目にし、実際の削除は確認モーダル側で行う。 */
.header__reset-btn {
    flex-shrink: 0;
    font-size: 12px;
    font-weight: 700;
    color: var(--text-tertiary);
    background: var(--surface);
    border: 1px solid var(--border-main);
    border-radius: 999px;
    padding: 4px 12px;
    cursor: pointer;
}
.header__reset-btn:hover {
    color: var(--text-secondary);
    background: var(--surface-hover);
}
.header__date {
    font-size: 15px;
    font-weight: 500;
    color: var(--text-secondary);
    margin-top: 3px;
}
.header__next-day {
    font-weight: 700;
    color: var(--accent-blue);
    margin-left: 6px;
}

/* ---- 休暇バナー ---- */
.leave-banner {
    padding: 10px 20px;
    background: var(--surface);
    font-size: 15.5px;
    font-weight: 700;
    color: var(--text-secondary);
    border-bottom: 1px solid var(--border-main);
}

/* ---- 状態ブロック ---- */
/*
 * 2026-09-09新設: 状態に応じた淡い背景色（tone連動）。区画の白一色で境界が分かりにくい、
 * という指摘への対応——状態ドット/ラベルの色分けと同じ toneOf() をそのまま流用し、
 * 「今どういう状態か」を離れた距離からでも色で判別できるようにする（ブロック区分の改善案）。
 */
.status-block {
    padding: 22px 20px 20px;
    border-bottom: 1px solid var(--border-main);
    background: var(--wash-neutral);
}
.status-block--moving { background: var(--wash-moving); }
.status-block--active { background: var(--wash-active); }
.status-block--neutral { background: var(--wash-neutral); }
.status-block--done { background: var(--wash-done); }
.status-block__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 9px;
    /* 2026-09-09: stbeat（登場フェード）はここに移した（旧: .status-block 本体）。
       .status-block__elapsed の高さ過渡アニメーション（下記）を効かせるには、
       状態が変わっても .status-block__elapsed 自体は同じ要素のまま保たれる必要があり、
       :key による作り直しの対象を .status-block__row（ドット・ラベルの行）だけに絞った。 */
    animation: stbeat .22s ease-out;
}
/* 2026-09-11新設: ドット＋ラベルをまとめる左側グループ。.status-block__row が
   justify-content: space-between で左（状態）と右（現在地）に分かれるようにした
   （下記 .status-block__location 参照）。 */
.status-block__row-left {
    display: flex;
    align-items: center;
    gap: 9px;
    min-width: 0;
}
.status-block__dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    flex-shrink: 0;
}
.status-block__dot--moving { background: var(--accent-blue); }
.status-block__dot--active { background: var(--accent-green); }
.status-block__dot--neutral { background: var(--text-tertiary); }
.status-block__dot--done { background: var(--text-primary); }

.status-block__label {
    font-size: 27px;
    font-weight: 900;
    letter-spacing: .02em;
    line-height: 1.1;
}
.status-block__label--moving { color: var(--accent-blue); }
.status-block__label--active { color: var(--accent-green); }
.status-block__label--neutral { color: var(--text-tertiary); }
.status-block__label--done { color: var(--text-primary); }

/*
 * 2026-09-09新設: 出勤/退勤の瞬間、状態ブロックが1行⇔2行に切り替わる際の高さ変化を
 * 「パッ」と跳ねさせず、滑らかに過渡させる方針だった（動的な高さ＋max-height過渡アニメーション、
 * 0⇔23px）。2026-09-15改訂: secondary-list/history-block__list/undo-linkの位置固定と同じ
 * 理由——「状態区域（status-block）の高さもStateによって変動し、全体のレイアウトが動く」と
 * ユーザーから指摘され、この要素の高さ変化が最後に残った可変要因だったため修正した。
 * max-height 0⇔23pxのアニメーションをやめ、height自体を常に23px固定で確保し、
 * 表示/非表示はopacityだけで切り替える——state.elapsedが無いState（NOT_CLOCKED_IN等）でも
 * 同じ高さの空行が常にある（他の固定高さ要素と同じ「位置優先」方針）。
 */
.status-block__elapsed {
    padding-left: 23px;
    font-size: 16px;
    font-weight: 500;
    line-height: 1.4;
    color: var(--text-secondary);
    height: 23px; /* 16px × line-height 1.4 = 22.4px を切り上げ */
    margin-top: 7px;
    opacity: 0;
    overflow: hidden;
    transition: opacity .2s ease-out;
}
/* 2026-10-07新設、同日改訂: 移動中だけ、.status-block__elapsed（固定高さ1行）の中に経過時間の代わりに出す
   「起点 → 終点」。1行に収め、長い名前は起点を先に縮めて（flex-shrinkを大きく）「…」で省略し、
   終点はなるべく全部見せる——正しい移動かを確かめるのに大事なのは行き先のため。 */
.status-block__route {
    display: flex;
    align-items: baseline;
    min-width: 0;
    white-space: nowrap;
    font-size: 15px;
    font-weight: 700;
    color: var(--accent-blue);
}
.status-block__route-origin {
    flex: 0 4 auto;
    min-width: 2.5em;
    overflow: hidden;
    text-overflow: ellipsis;
}
.status-block__route-arrow {
    flex: none;
    margin: 0 6px;
}
.status-block__route-dest {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}
.status-block__elapsed--visible {
    opacity: 1;
}

/*
 * 2026-09-11新設: 「現在地」表示。ユーザー指摘により、後続の計算に関わる重要な情報として
 * 状態区域に醒目に置く——elapsedより一段階強い配色（アクセント色＋太字）にして、
 * 「ただの補足情報」ではなく「確認・訂正してほしい値」であることを視覚的に伝える。
 * 2026-09-11再改訂: 当初はラベル行の下に独立した行（max-height過渡で表示/非表示）として
 * 置いたが、ユーザー指摘で状態ラベルと同じ行の右側（.status-block__row-left の隣）に
 * 移した——見た目上「今の状態」と「今の場所」が一つの塊として読める。表示/非表示は
 * x-text が空文字になる（非表示State）だけで幅がゼロになるため、高さ過渡は不要。
 * flex-shrink: 0 でラベルに押し潰されないようにしつつ、極端に狭い画面向けに
 * min-width: 0 + text-overflow で安全弁を入れてある。
 * 2026-09-14新設、2026-09-15改訂: 一時期GPSバッジ（📡）と縦に2行並べていたが、
 * システム予測とGPS実況が一致する場面で情報が二重表示になる、とユーザー指摘。
 * 予測表示を廃止しGPS実況（旧gpsAreaLabel()）だけをこの1行に表示するよう統合した
 * ——スタイルはそのまま（醒目な現在地表示という役割自体は変わらないため）。
 */
.status-block__location {
    flex-shrink: 0;
    max-width: 55%;
    font-size: 15px;
    font-weight: 800;
    line-height: 1.4;
    color: var(--accent-blue);
    text-align: right;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    opacity: 0;
    transition: opacity .18s ease-out;
}
.status-block__location--visible {
    opacity: 1;
}

@keyframes stbeat {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}
/* 2026-09-11新設: 本日の記録に新しい行が追加されたときのフェード+スライドイン（.history-block__row）。 */
@keyframes history-row-in {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    .status-block__row { animation: none; }
    .history-block__row { animation: none; }
    * { transition: none !important; }
}

/* ---- 予定/実績ブロック ---- */
.context-block {
    padding: 18px 20px;
    border-bottom: 1px solid var(--border-main);
    background: var(--surface); /* 2026-09-09新設: 状態ブロックの色つき背景、本日の記録の白と挟んで区画を分かりやすくする */
    display: flex;
    flex-direction: column;
    gap: 5px;
}
.context-block__project {
    font-size: 17px;
    font-weight: 900;
}
/* 2026-10-06改訂: 最大2行、超えた分は「…」で省略する。TVSFA17の現場（向先）名は最長44文字
   （例:「(株)豊国エンジニアリング－使用先：鹿児島県…」）あり、そのまま折り返すと3行以上になって
   下の本日の記録・主ボタンを押し下げてしまう（ユーザー指摘「预定区的现场名最多显示1～2行，
   超出部分用省略号」）。全文は予定変更シートと本日の記録の行で確認できる。 */
.context-block__site {
    font-size: 16px;
    font-weight: 700;
    color: var(--text-secondary);
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    word-break: break-all;
}
/* 2026-09-11改訂: 場所の値を表示しなくなった（状態区域の現在地バッジと重複するため）ので、
   強調色（700 weight）ではなく eta/next と同じ控えめなトーン（tertiary）に落とした。 */
.context-block__no-schedule {
    font-size: 15px;
    font-weight: 500;
    color: var(--text-tertiary);
}
.context-block__route {
    font-size: 15.5px;
    font-weight: 500;
    color: var(--text-secondary);
}
.context-block__eta,
.context-block__next {
    font-size: 15px;
    font-weight: 500;
    color: var(--text-tertiary);
}
/* 2026-09-14新設、2026-09-15撤去: 「予定変更」常設リンクはここにあったが、
   context-blockを完全に静的な表示専用エリアに戻すため撤去した（clock-home.html参照）。 */

/* ---- 本日の記録（履歴） ---- */
.history-block {
    padding: 16px 20px 4px;
    border-bottom: 1px solid var(--border-main);
}
.history-block__title {
    font-size: 12px;
    font-weight: 800;
    letter-spacing: .04em;
    color: var(--text-tertiary);
    margin-bottom: 8px;
}
.history-block__list {
    list-style: none;
    margin: 0;
    padding: 0;
    /* 2026-09-08新設時はmax-heightだったが、それは「上限のみ・件数が少なければ箱自体が縮む」
       挙動のため、secondary-listと全く同じ理由で「行数が増減するたびに箱の高さが変わり、
       ページ全体がその分ずれる」問題を抱えていた（旧コメントの「固定高さのため位置に影響しない」
       という説明は誤りだった——max-heightは固定高さではない）。2026-09-15改訂: ユーザー指摘
       「本日记录动区域的高度还是可变的，还是会导致整体布局抖动」を受け、secondary-listと同じ
       固定height方式に変更した——約4行ぶん（176px）を常に確保し、件数が少ないときは下に
       空白が残る（ユーザー確認済みの「位置優先」方針をここにも適用）。 */
    height: 176px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}
.history-block__row {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 7px 0;
    border-top: 1px solid var(--border-sub);
    font-size: 14.5px;
    /* 2026-09-11新設: 行が追加されるたびのフェード+スライドイン。.status-block__row の stbeat と
       同じ手法——:key 付き x-for が既存行のDOMノードをそのまま保つため（末尾への追加時）、
       このアニメーションは新しく作られた行にしか適用されず、既存行が再生し直すことはない。 */
    animation: history-row-in .22s ease-out;
}
.history-block__row:first-child { border-top: none; }
/* 2026-09-14新設: 「作業再開」（WORK_PAUSE_END）の行だけタップして内容を後から編集できる。 */
.history-block__row--editable {
    cursor: pointer;
}
.history-block__row--editable .history-block__label {
    color: var(--accent-blue);
}
.history-block__time {
    flex-shrink: 0;
    width: 40px;
    color: var(--text-tertiary);
    font-weight: 700;
}
.history-block__label {
    color: var(--text-primary);
    font-weight: 500;
    /* 2026-10-07: 1行に収め、長い分は「…」で省略（ユーザー指摘「本日记录区域…过长的情况下取舍一下，不要跨行显示」）。
       予定変更の行は業務内容を先に出す並びにしてある（ClockHomeStateAssembler.scheduleChangeLabel）。 */
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.spacer { flex: 1; }

/* ---- アクションフッタ ---- */
.footer {
    padding: 18px 20px 20px;
    position: sticky;
    bottom: 0;
    background: var(--bg-card);
    display: flex;
    flex-direction: column;
    /* 2026-09-09新設: 常駐の操作ゾーンであることを示す、上向きの淡い投影。
       スクロールする内容の上に「浮いている」感覚を出す（ブロック区分の改善案）。 */
    box-shadow: 0 -4px 12px rgba(0, 0, 0, .06);
}

.primary-btn {
    min-height: 68px;
    width: 100%;
    border: none;
    border-radius: 6px;
    font-size: 21px;
    font-weight: 900;
    letter-spacing: .03em;
    line-height: 1.3;
    color: #fff;
    padding: 14px 18px;
    cursor: pointer;
}
.primary-btn--green { background: var(--accent-green); }
.primary-btn--blue { background: var(--accent-blue); }
.primary-btn:focus-visible {
    outline: 3px solid var(--accent-blue);
    outline-offset: 2px;
}

/*
 * 2026-09-08新設: 「もう押せない」ことを示す完了/不要ボタン（CLOCKED_OUT の「退勤済み」等）。
 * 通常の primary-btn と同じ寸法・同じ位置のまま色だけ落とすことで、押した直後に何かが
 * 消えたように見える違和感（点線プレースホルダー枠だった旧仕様）をなくす。
 */
.primary-btn--disabled {
    background: var(--border-main);
    color: var(--text-tertiary);
    cursor: default;
}
.primary-btn--disabled:focus-visible { outline: none; }

.empty-state {
    min-height: 68px;
    border: 1px dashed var(--dashed);
    border-radius: 2px;
    font-size: 16px;
    font-weight: 700;
    color: var(--text-tertiary);
    display: flex;
    align-items: center;
    justify-content: center;
}

/*
 * ---- 取り消し導線（A18、2026-09-11新設、§7.2） ----
 * 「誤タップ救済のための機能であり、控えめだが確実に見つかる位置に置く」——Primary Action の
 * すぐ下、中央寄せの小さなテキストリンクとして置く。カウントダウンは tnum で桁が動いても
 * 揺れないようにする。押しやすさよりも「間違って触れない」ことを優先し、secondary-list__row
 * より一回り小さいタップ領域にする（頻繁に押すボタンではないため）。
 * 2026-09-15改訂: 表示/非表示自体がprimary-btnの位置をずらさないよう、外側の.undo-slotで
 * 常時一定の高さを確保する（中身が無いときは単なる空白になる——secondary-listの固定高さ化と
 * 同じ判断、ユーザー確認済み: 「接受空白，位置优先」）。
 */
.undo-slot {
    height: 39px;
}
.undo-link {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    margin-top: 10px;
    padding: 6px;
    font-size: 13.5px;
    font-weight: 700;
    color: var(--text-tertiary);
    cursor: pointer;
}
.undo-link:hover { color: var(--text-secondary); }
.undo-link__timer {
    color: var(--accent-blue);
    font-weight: 800;
}

.secondary-list {
    list-style: none;
    margin: 0 0 18px;
    padding: 0;
    border-top: 1px solid var(--border-main);
    /* 2026-09-08新設〜2026-09-15複数回改訂の経緯: 当初はmax-height（上限のみ、項目数1〜3件の
       間は実際の高さがそのまま変動）+ clock-home.jsのFLIPアニメーションで「値を固定せず
       変化を滑らかにする」方針だった。しかしユーザーから改めて「出勤ボタンを押すと主ボタンの
       位置自体が動いて違和感がある、位置を固定したい」との指摘——全State×Contextの最大件数
       （3件）ぶんを常時確保する高さに固定し、項目が0〜2件のときは下に空白が残る形にした
       （ユーザー確認済み: 「接受空白，位置优先」）。これによりfooter自体の高さが常に一定になり、
       主ボタンの画面上の位置がState間で動かなくなる。値が変動しなくなったため、
       clock-home.jsの高さ過渡アニメーション（applyState()のFLIP処理）は不要になり削除した。 */
    height: 156px;
    overflow: hidden;
}
.secondary-list__row {
    min-height: 52px;
    display: flex;
    align-items: center;
    padding: 0 4px;
    border-top: 1px solid var(--border-sub);
    font-size: 15.5px;
    font-weight: 500;
    color: var(--text-primary);
    cursor: pointer;
}
.secondary-list__row:first-child { border-top: none; }
.secondary-list__row:hover { background: var(--surface-hover); }

/* ---- トースト ---- */
/*
 * 2026-09-08改訂: 下部→上部に変更。以前は bottom 固定だったため、footer の高さが
 * secondary の有無で変わるたびに primary-btn（拇指熱ゾーン）と重なる問題があった
 * （ユーザー指摘）。あわせて成功時は toast を出さなくなった（JS 側）ため、
 * 現状は失敗/未対応の通知専用——画面下部の操作ゾーンから完全に離しておく。
 */
.toast {
    position: fixed;
    top: 54px; /* DEV バー（表示時、約46px）の下に確実にクリアする高さ */
    left: 50%;
    transform: translateX(-50%);
    width: fit-content;
    max-width: 360px;
    background: #16191d;
    color: #fff;
    padding: 13px 20px;
    border-radius: 3px;
    font-size: 14.5px;
    font-weight: 700;
    box-shadow: 0 10px 28px rgba(0, 0, 0, .3);
    pointer-events: none;
    z-index: 50;
}

/*
 * ---- 退勤お疲れ様アニメーション（2026-09-08新設、同日改訂） ----
 * 退勤（CLOCKED_OUT に遷移した瞬間）だけに発火する、画面中央・最前面のお祝い演出。
 * z-index は toast(50) より上——退勤直後は toast は出ない設計だが、念のため常に最前面にする。
 * 操作を一切妨げないよう pointer-events:none、約2.2秒で自動的に消える（JS 側 setTimeout）。
 *
 * 改訂: 絵文字とテキストを celebrate__inner にまとめ、同じアニメーションで一緒に
 * 少しずつ拡大しながらフェードアウトする（背景色なし・黒背景の違和感を解消。
 * ユーザー指摘: 「文本内容も一緒に拡大して消えるように、背景は黒ではなく透明に」）。
 */
.celebrate {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    z-index: 60;
}
.celebrate__inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    /* 2026-09-09改訂: カクつき対策で3段階キーフレーム＋独自イージングをやめ、標準の ease-out
       1本に単純化。最大拡大率も1.7→1.35に抑え、動きの振れ幅を小さくして滑らかに見せる
       （ユーザー指摘: 「出現から消失まで、カクつき感がある」）。合成レイヤー昇格
       （will-change/translateZ）はこの祖先要素だけに付け、子要素(celebrate__text)側の
       二重の昇格は外した——ネストした昇格レイヤーがかえって再描画のもたつきの原因になりうるため。 */
    animation: celebrate-grow 1.8s ease-out forwards;
    will-change: transform, opacity;
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
}
.celebrate__emoji {
    font-size: 64px;
    line-height: 1;
}
.celebrate__text {
    /* 2026-09-08改訂: 単色(--text-primary)だと地味で沈んだ印象だったため、虹色グラデーションに
       （ユーザー指摘: 「黒色太死气沉沉」）。background-clip:text 非対応ブラウザ向けに
       まず単色の color をフォールバックとして指定しておく。 */
    color: var(--accent-blue);
    background: linear-gradient(90deg, #ff5252, #ff9800, #ffd600, #4caf50, #2196f3, #9c27b0);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    font-size: 19px;
    font-weight: 900;
    letter-spacing: .02em;
}
@keyframes celebrate-grow {
    0%   { transform: scale(.7); opacity: 0; }
    25%  { transform: scale(1); opacity: 1; }
    100% { transform: scale(1.35); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .celebrate__inner { animation: none; }
}

/*
 * ---- 予定変更 / 作業中断メモ編集モーダル（2026-09-14新設） ----
 * どちらも同じ .modal-overlay/.modal-card を共用する軽量な入力画面。
 * z-index は celebrate(60) より上——入力操作を伴うため pointer-events は有効のまま。
 */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(22, 25, 29, .45);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    z-index: 70;
}
.modal-card {
    width: 100%;
    max-width: 420px;
    background: var(--bg-card);
    border-radius: 12px 12px 0 0;
    padding: 20px 20px calc(20px + env(safe-area-inset-bottom, 0px));
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-height: 80vh;
    overflow-y: auto;
}
.modal-card__title {
    font-size: 16px;
    font-weight: 900;
    color: var(--text-primary);
}
.modal-card__field {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.modal-card__field-label {
    font-size: 12px;
    font-weight: 700;
    color: var(--text-tertiary);
}
.modal-card__select {
    font-size: 15px;
    padding: 9px 10px;
    border: 1px solid var(--border-main);
    border-radius: 6px;
    background: var(--bg-card);
    color: var(--text-primary);
}
/* 2026-09-16新設: 宿泊先の自由入力欄。.modal-card__select と同じ見た目の1行テキスト入力
   （宿泊先名は候補チップから選ぶか、無ければこちらに手打ちする）。 */
.modal-card__input {
    /* 2026-10-06: 15px→16px。iOS Safariは16px未満の入力欄にフォーカスすると画面を自動拡大し、
       閉じても戻らず操作しづらくなるため（予定変更の検索欄追加時に、宿泊先入力欄も合わせて修正）。 */
    font-size: 16px;
    font-family: inherit;
    padding: 9px 10px;
    border: 1px solid var(--border-main);
    border-radius: 6px;
    background: var(--bg-card);
    color: var(--text-primary);
    width: 100%;
    box-sizing: border-box;
}
.modal-card__readonly {
    font-size: 15px;
    font-weight: 500;
    color: var(--text-secondary);
    padding: 9px 0;
}
.modal-card__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.modal-card__chip {
    font-size: 13.5px;
    font-weight: 700;
    color: var(--text-secondary);
    background: var(--surface);
    border: 1px solid var(--border-main);
    border-radius: 999px;
    padding: 6px 14px;
    cursor: pointer;
}
/*
 * 2026-09-17新設: 「現在地を変更」（A10/A24）選択画面の4択のうち、GPSから計算した最寄りの
 * 拠点だけをこの見た目にする（ユーザー指摘: 「首先根据gps信息，计算位置，给出最优选」）。
 * アクセント色の枠線で（2026-10-06: 「おすすめ」の文字バッジはユーザー指摘により撤去）、他の3択と対等に選べることを保ったまま
 * 視線を誘導する（自動選択・自動確定はしない——4択はGPSの有無に関わらず常にどれでもタップ可能）。
 */
.modal-card__chip--recommended {
    border-color: var(--accent-blue);
    color: var(--accent-blue);
}
/*
 * 2026-09-16新設: 宿泊先の候補芯片（.modal-card__chip）専用の入れ替わりアニメーション。
 * 自由入力欄に文字を打つたび（`onLodgingNameInput()`、300msデバウンス）候補が丸ごと
 * 入れ替わるが、無地なしで一瞬でスイッチすると「ちらつき」に見える——ユーザー指摘
 * 「手动输入后到备选菜单变化的过程...加入一定平滑过渡效果」に対応。Alpineの
 * `x-transition:enter/leave`から参照するCSSクラス（休憩/私用/その他の静的な芯片には
 * 付けていない、x-forで動的に入れ替わる宿泊先候補のみ）。
 */
.modal-card__chip--transition {
    transition: opacity .15s ease-out, transform .15s ease-out;
}
.modal-card__chip--enter-start {
    opacity: 0;
    transform: scale(.9);
}
.modal-card__chip--enter-end {
    opacity: 1;
    transform: scale(1);
}
/*
 * 2026-09-16新設: 宿泊先候補欄（.modal-card__chips）専用。ユーザー指摘「备选菜单的高度，
 * 随着数量上下变动，过于晃动」——検索結果や初期GPS/直近候補は0〜4件で変動するため、
 * 高さを固定しないと候補が減るたびにモーダル全体（下のボタン行含む）が上に詰まって揺れる。
 * 候補は最大4件・1行2件想定（`LodgingSuggestionService.SUGGESTION_LIMIT`と
 * `findTop4ByNameContaining...`で揃えてある）なので、実測した2行分の高さ78px
 * （芯片35px×2 + 行間gap8px）で固定し、`align-content: flex-start`で1行だけの時も
 * 上詰めにする（無指定だと1行の芯片が縦方向に間延びして見える）。0件のときは空白のまま
 * 高さだけ確保する——他の固定高さ要素（.status-block__elapsed等）と同じ「位置優先」方針。
 */
.modal-card__chips--lodging {
    height: 78px;
    align-content: flex-start;
    overflow: hidden;
}
.modal-card__textarea {
    font-size: 15px;
    font-family: inherit;
    padding: 10px;
    border: 1px solid var(--border-main);
    border-radius: 6px;
    background: var(--bg-card);
    color: var(--text-primary);
    resize: vertical;
}
/* 2026-09-16改訂: margin-topを4px→20pxに拡大（親.modal-cardのgap:12pxと合わせて実質32px）。
   ユーザー指摘: 「输入栏和下方的两个按钮离得很近，实际场景的手机操作，会不会产生误操作」——
   直前がテキスト入力欄／テキストエリアのモーダル（宿泊先入力、作業中断メモ編集）では、
   入力直後に指がそのままボタンへ流れて誤タップする典型的な失敗パターンがあるため、
   「入力」と「確定操作」を視覚的にも間隔的にも分ける。全モーダル共通のクラスのため、
   宿泊先入力に限らず作業中断メモ編集にも同じ効果が及ぶ（同じリスクのため妥当）。 */
.modal-card__actions {
    display: flex;
    gap: 10px;
    margin-top: 20px;
}
.modal-card__btn {
    flex: 1;
    padding: 12px;
    border-radius: 8px;
    font-size: 15px;
    font-weight: 800;
    border: none;
    cursor: pointer;
}
.modal-card__btn--cancel {
    background: var(--surface);
    color: var(--text-secondary);
}
.modal-card__btn--save {
    background: var(--accent-blue);
    color: #fff;
}

/*
 * ---- 予定変更（A11）2026-10-06復活・全面改訂 ----
 * ユーザー指摘「因为是移动端，要尽量用户操作顺滑」に沿った方針:
 *   - タップ対象は高さ44px以上（業務内容・TJ行・TJボタン）
 *   - 入力欄は16px（.modal-card__input、iOSの自動拡大防止）
 *   - TJ一覧は固定高さの内部スクロール——検索結果の件数が変わってもシートの高さが揺れない
 *     （宿泊先候補欄と同じ「位置優先」方針）
 */
.modal-card--tall {
    max-height: 90vh;
}
.modal-card__chip--selected {
    border-color: var(--accent-blue);
    background: var(--accent-blue);
    color: #fff;
}
.modal-card__btn--save:disabled {
    opacity: .4;
    cursor: default;
}
.schedule-form,
.tj-picker {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.schedule-form__origin,
.schedule-form__auto-dest {
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 15px;
    font-weight: 700;
    color: var(--text-primary);
}
.schedule-form__origin {
    flex-direction: row;
    align-items: baseline;
    gap: 10px;
}
.schedule-form__hint {
    font-size: 11.5px;
    font-weight: 500;
    color: var(--text-aux);
}
.schedule-form__tj {
    display: flex;
    gap: 8px;
}
.schedule-form__tj-btn {
    flex: 1;
    min-width: 0;
    min-height: 48px;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    border: 1px solid var(--border-main);
    border-radius: 8px;
    background: var(--bg-card);
    font-family: inherit;
    text-align: left;
    cursor: pointer;
}
.schedule-form__tj-none {
    flex: 1;
    font-size: 15px;
    color: var(--text-aux);
}
.schedule-form__tj-picked {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}
.schedule-form__tj-number {
    font-size: 15px;
    font-weight: 900;
    color: var(--text-primary);
}
.schedule-form__tj-title {
    font-size: 12px;
    color: var(--text-tertiary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.schedule-form__chevron {
    font-size: 20px;
    color: var(--text-aux);
}
.schedule-form__tj-clear {
    width: 48px;
    border: 1px solid var(--border-main);
    border-radius: 8px;
    background: var(--surface);
    font-size: 18px;
    color: var(--text-tertiary);
    cursor: pointer;
}
.schedule-form__dest {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
/* 業務内容は3列グリッド——9択がちょうど3行に収まり、親指で端まで届く */
.schedule-form__business {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
}
.schedule-form__business-btn {
    min-height: 44px;
    padding: 4px;
    border: 1px solid var(--border-main);
    border-radius: 8px;
    background: var(--surface);
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.25;
    color: var(--text-secondary);
    cursor: pointer;
}
.schedule-form__business-btn--selected {
    border-color: var(--accent-blue);
    background: var(--accent-blue);
    color: #fff;
}
.tj-picker__header {
    display: flex;
    align-items: center;
    gap: 8px;
}
.tj-picker__back {
    min-height: 44px;
    padding: 0 10px 0 0;
    border: none;
    background: none;
    font-family: inherit;
    font-size: 15px;
    font-weight: 700;
    color: var(--accent-blue);
    cursor: pointer;
}
.tj-picker__caption {
    font-size: 12px;
    font-weight: 700;
    color: var(--text-tertiary);
    margin-top: -6px;
}
.tj-picker__list {
    list-style: none;
    margin: 0;
    padding: 0;
    height: 52vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    border-top: 1px solid var(--border-sub);
}
.tj-picker__row {
    min-height: 56px;
    padding: 9px 4px;
    border-bottom: 1px solid var(--border-sub);
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    cursor: pointer;
}
.tj-picker__row:active {
    background: var(--surface-hover);
}
.tj-picker__row--selected {
    background: var(--wash-moving);
}
.tj-picker__row-top {
    display: flex;
    align-items: baseline;
    gap: 8px;
    min-width: 0;
}
.tj-picker__number {
    flex: none;
    font-size: 14px;
    font-weight: 900;
    color: var(--text-primary);
}
.tj-picker__title {
    font-size: 13px;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.tj-picker__site {
    font-size: 11.5px;
    color: var(--text-aux);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* 2026-10-07新設: 移動開始から案内されて予定変更を開いたときの説明文。 */
.schedule-form__notice {
    font-size: 13px;
    font-weight: 700;
    line-height: 1.5;
    color: var(--accent-blue);
    background: var(--wash-moving);
    border-radius: 6px;
    padding: 8px 10px;
}
