﻿/* zuzu-ui 共通デザイン（Bootstrap 5 上・全 zuzu アプリ共通）
 * 改版:
 * - 2026-07-14 textarea.form-control: 1行起点・内容に応じて縦伸長（field-sizing + zuzu.js フォールバック。固定高は .zuzu-textarea-fixed）。
 * - 2026-07-08 シェルスクロール根本改修: 固定フッター時はシェル=100svh 固定＋main flex:1/min-height:0 で残り高さ充填（calc 廃止）。ヘッダー/フッター実高に非依存で二重スクロール解消。main 下端 100px の幻スクロールも除去。壊れコメント `/ *`→`/*` 修正。
 * - 2026-07-07 シェルスクロール: 固定操作フッター（-fixed）時のみ main 内スクロール。それ以外は window スクロール（二重スクロール防止）。
 * - 2026-07-01 zuzu.css: .okuchi-zuzu-safari-spacer 除去（第3層は style.css）。
 * - 2026-07-01 zuzu-time-picker: ピッカー UI を時・分 select に変更（Flatpickr スピナー非表示）。
 * - 2026-07-01 zuzu-time-picker: .old から復元し本ファイルに統合（Flatpickr 時刻のみ。zuzu-ui/js/zuzu-time-picker.js 正本）。
 * - 2026-07-01 シェルスクロール正本: 原始的（main=100svh−chrome・overflow-y:auto・フッターは main の下）。flex 鎖・patch 禁止。
 * - 2026-07-01 ドロワー付きシェル: .sample-zuzu-shell* を廃止し .zuzu-shell-drawer* に統一（sample/・home 共通正本）。
 * - 2026-06-30 .zuzu-shell-main: 上余白を zuzu.css に一本化（全画面共通骨格。HTML に py-* は付けない）。
 * - 2026-06-30 main: py-3 等の余白ユーティリティは付けない（正本は class="zuzu-shell-main" のみ）。下端 100px は zuzu.css。
 * - 2026-06-30 main 下端 100px: レガシー画面の py-* が残っている場合のみ padding-bottom !important で上書き。
 * - 2026-06-30 legacy compat ブロック全削除（.field / .z-row / .layout / .z-drawer / .z-footer-buttons 等）。正本は Bootstrap + sample。
 * - 2026-06-30 main 下端 100px 余白を zuzu.css に追加。
 * - 2026-06-18 .zuzu-form-check-row: form-control 同型の枠・padding（switch フィールドと揃える）。
 * - 2026-06-18 zuzu-date-picker: table 薄灰枠線。
 * - 2026-06-18 zuzu-date-picker: カレンダー table（土日列縦一色）。
 * - 2026-06-17 操作フッター: 768px 以上で zuzu-action-bar を拡大（スマホは 3.2rem 既定のまま）。
 * - 2026-06-03 a: 下線（text-decoration）を無効化。
 * - 2026-06-03 コメント: page-shell 参照を sample/page-shell.php に更新。
 * - 2026-06-03 zuzu-switch-field: form-control/-sm/-lg 連動・switch と状態文言の縦位置を中央揃え
 * - 2026-06-03 form-label と入力の行間 0 を .mb-3 限定から全体へ（.zuzu-switch-field 含む）
 * - 2026-06-03 ラベル付き switch: hidden 値同期（data-ok-value / data-ng-value・ymir data-on/off-label 互換）
 * - 2026-06-03 ラベル付き switch（.zuzu-switch-field + data-ok / data-ng + zuzu.js 初期化）
 * - 2026-06-03 標準シェル: ヘッダー/フッター薄グレー（zuzu-shell-header/footer）、本文白（zuzu-shell-main）。
 * - 2026-06-03 シェル/ドロワー面: zuzu-color の --zuzu-shell-header-bg / --zuzu-shell-footer-bg / --zuzu-drawer-* を参照。
 * - 2026-06-03 ヘッダー・フッター背景を個別変数で指定（chrome-bg は header へフォールバック互換）。
 * - 2026-06-08 操作フッター class を zuzu-action-bar-* に統一（他プロジェクト名 class 禁止）。
 * - 2026-06-03 zuzu-shell-main 既定は幅 100%（幅制限は .container 等を明示したときのみ）。
 * - 2026-06-03 main 直下の col-* は幅 100% に揃える（狭めるときは .zuzu-content-narrow を内側に）。
 * - 2026-06-03 Bootstrap 移行: シェル navbar・offcanvas nav（フォーム正本は form-control）。
 * - 2026-06-03 サイドナビ階層（collapse・右端＞・階層2文字頭揃え）を標準化。
 * - 2026-06-03 日本語フォント・フォームラベル密着を style.css から移管。
 * - 2026-06-03 Bootstrap 5 専用化。snackbar（zuzu-core ShowSnackbar 用）。
 * - 2026-06-03 snackbar: 画面中央表示（.center）。.top は後方互換で同位置。
 * - 2026-06-03 Bootstrap table: th は text-center で統一。td は列ごとにクラス付与。
 * - 2026-06-03 zuzu-shell 内 page-footer-fixed を layout と同型に（フッターデザイン継承）。
 * - 2026-06-04 ドロワー nav active: --bs-primary ではなく --zuzu-drawer-active-bg を参照（default で primary と drawer-bg が同色のため）
 * - 2026-06-03 暗色ドロワー: .zuzu-drawer-offcanvas（白文字・nav-pills active・collapse ボタン）をエンジン標準化。
 * - 2026-06-03 ドロワー nav active/hover: リンク幅 100%（パネル余白内で左右いっぱい）。
 * - 2026-06-03 ドロワー nav: 背景帯に小さめ角丸（--zuzu-drawer-nav-radius）。
 * - 2026-07-01 ドロワー付きシェル: .sample-zuzu-shell* を廃止し .zuzu-shell-drawer* に統一（sample/・home 共通正本）。
 * - 2026-06-03 sample 専用: .sample-zuzu-shell（lg 以上サイド常時・未満 offcanvas）を zuzu.css に追加。
 * - 2026-06-03 zuzu-action-bar。標準は non-fixed、固定は .zuzu-action-bar-fixed を追加。
 * - 2026-07-02 シェルヘッダー内 row: Bootstrap d-flex + me-auto（左: ハンバーガー・タイトル / 右: dropdown・ホーム）。dropdown クリップ防止に overflow: visible。
 * - 2026-06-16 操作バー高さを 3.2rem に調整。ボタン padding・min-width・flex gap を詰める。
 * - 2026-06-16 zuzu-shell-footer に操作バー・コピーライトを内包。固定は zuzu-shell-footer-fixed。
 * - 2026-06-16 全 zuzu-shell を 100dvh＋main 内スクロールに統一。
 * - 2026-06-16 固定フッター: position:fixed 廃止（footer はシェル下端の flex 子）。
 * - 2026-06-09 html touch-action: manipulation（ダブルタップ拡大のみ抑制・ピンチは可。appoint と同方針）。
 * - 2026-06-09 input-group 添えボタン: .zuzu-input-group-btn（primary 青・白文字）。
 * - 2026-06-08 input-group 添えボタン: .zuzu-input-group-btn（form-control 同色枠・薄背景）。
 * - 2026-06-03 ファイル input-group: .zuzu-file-pick-btn（input-group-text・枠色は form-control と同色）。
 * - 2026-06-03 ファイル: .zuzu-file-drop（複数・D&D。dragover 時は .zuzu-file-drop-active）。
 * - 2026-06-03 ファイル input: Firefox は display:none 非送信のため .zuzu-file-input-hidden（d-none 不可）。
 * - 2026-06-03 sample: zuzu-action-bar は maincol 内（flex 下段）。fixed 時も右列内（absolute）。
 * - 2026-06-03 sample: ドロワー下端テーマ色 select（.zuzu-shell-drawer-theme）。
 * - 2026-06-03 theme-color.php: 1 行 1 項目（.zuzu-theme-color-row）。
 * - 2026-06-08 checkbox/radio: .zuzu-form-check-row は flex-wrap: wrap（「改行なし」= マークアップの勝手な改行禁止。CSS nowrap ではない）。
 * - 2026-06-03 checkbox/radio 横並び: .zuzu-form-check-row（項目間に左余白）。
 *
 * 役割: 基底は bootstrap.min.css、色は zuzu-color.css、本ファイル（**zuzu 固有のみ・コアはシンプル**）、各アプリ style.css。
 * コアに技巧を足さない。複雑化＝画面ごとの融通低下。業務差はプロジェクト CSS へ。
 * main は class="zuzu-shell-main" のみ（py-3 等は付けない。下端 100px は本ファイル）。
 */

/* ダブルタップ拡大のみ抑制（ピンチズームは可）。zuzu-appoint.css と同方針。 */
html {
  touch-action: manipulation;
}

/* === シェルスクロール（正本 / 2026-07-08 改）===
 * 列: ヘッダー → main.zuzu-shell-main → footer（固定は main の直後）。
 * 固定操作フッター（.zuzu-shell-footer-fixed / 旧 .zuzu-action-bar-fixed）あり:
 *   シェル＝100svh 固定、main は flex:1 1 auto + min-height:0 で残り高さを埋め、main だけ overflow-y:auto。
 *   ヘッダー/フッターの実高（折り返し・ボーダー・note）に依存しないため二重スクロールが原理的に出ない。
 *   旧: main を calc(100svh − ヘッダー変数 − 操作バー変数) で固定していたが、実高ズレで二重化するため廃止。
 *   旧: main padding-bottom 100px（position:fixed 時代の名残）は幻のスクロールバーの原因のため通常余白に変更。
 * 固定操作フッターなし（著作権のみ・フッターなし・LP）: main は高さ自動、window スクロール（二重スクロール禁止）。
 * 禁止: body/html の overflow ロック（シェルの overflow:hidden は可）、position:fixed でフッター逃げ、壊れた上への patch。
 * html.zuzu-shell-doc は head の script 1 行（:has は補助のみ）。 */
html.zuzu-shell-doc body,
html:has(> body > .zuzu-shell) body,
html:has(> body > form > .zuzu-shell) body {
  margin: 0;
}
html.zuzu-shell-doc body > form,
html:has(> body > form > .zuzu-shell) body > form {
  display: flex;
  flex-direction: column;
  width: 100%;
  margin: 0;
}

/* 本文フォント（日本語 UI 共通） */
body {
  font-family: "Hiragino Kaku Gothic ProN", "Hiragino Kaku Gothic Pro", "Hiragino Sans", Meiryo, sans-serif;
}

a {
  text-decoration: none;
}

/* ラベル＋入力を1塊に（項目間の余白は .mb-3 ・row g-* 等で付ける） */
.form-label {
  margin-bottom: 0;
  line-height: 1.2;
}
.form-label + .form-control,
.form-label + .form-select,
.form-label + .zuzu-switch-field,
.form-label + textarea.form-control,
.form-label + .input-group,
.form-label + .zuzu-form-check-row {
  margin-top: 0;
}

/*
 * textarea: 1行起点・文字量に応じて縦に伸びて全文見える（sample/form-basic.php）
 *   rows はフォールバック用の目安。高さは内容優先（field-sizing: content）。
 *   未対応ブラウザは zuzu.js が scrollHeight で高さを合わせる。
 *   固定高さにしたいときだけ class="zuzu-textarea-fixed"（従来どおり rows 依存）。
 */
textarea.form-control:not(.zuzu-textarea-fixed) {
  field-sizing: content;
  min-height: calc(1.5em + 0.75rem + calc(var(--bs-border-width) * 2));
  max-height: none;
  overflow-x: hidden;
  overflow-y: hidden;
  resize: none;
}
textarea.form-control.form-control-sm:not(.zuzu-textarea-fixed) {
  min-height: calc(1.5em + 0.5rem + calc(var(--bs-border-width) * 2));
}
textarea.form-control.form-control-lg:not(.zuzu-textarea-fixed) {
  min-height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));
}

/*
 * checkbox / radio 横並び（zuzu 既定。sample/form-checks-radios.php が正本）
 *   <div class="mb-3">
 *     <span class="form-label d-block">見出し</span>
 *     <div class="zuzu-form-check-row">
 *       <div class="form-check"><input class="form-check-input" type="radio" name="g" id="g1" value="1"><label class="form-check-label" for="g1">A</label></div>
 *       <div class="form-check">…</div>
 *     </div>
 *   </div>
 * 枠は form-control 同型（padding・border・min-height）。zuzu-switch-field と同趣旨。
 * 縦積み（.form-check だけを縦に並べる）は sample にも置かない。
 * 表示は横並び＋幅に応じて折り返し（nowrap 禁止）。
 */
.zuzu-form-check-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 1.25rem;
  row-gap: 0.5rem;
  width: 100%;
  min-height: calc(1.5em + 0.75rem + calc(var(--bs-border-width) * 2));
  padding: 0.375rem 0.75rem;
  background-color: var(--bs-body-bg);
  border: var(--bs-border-width) solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
}
.zuzu-form-check-row > .form-check {
  margin-bottom: 0;
  flex: 0 0 auto;
}

/* ファイル選択: 左端フォルダ（input-group-text で form-control と同じ --bs-border-color） */
.input-group > button.zuzu-file-pick-btn.input-group-text {
  cursor: pointer;
}

/* input-group 内ボタン: primary 青（検索・地図・患者検索など input 右端の操作） */
.input-group > .btn.zuzu-input-group-btn {
  color: #fff;
  background-color: var(--bs-primary);
  border-color: var(--bs-primary);
}
.input-group > .btn.zuzu-input-group-btn:hover,
.input-group > .btn.zuzu-input-group-btn:focus {
  color: #fff;
  background-color: var(--bs-link-hover-color, var(--bs-primary));
  border-color: var(--bs-link-hover-color, var(--bs-primary));
}
.input-group > .btn.zuzu-input-group-btn:focus-visible {
  color: #fff;
  background-color: var(--bs-link-hover-color, var(--bs-primary));
  border-color: var(--bs-link-hover-color, var(--bs-primary));
  box-shadow: 0 0 0 0.25rem var(--bs-focus-ring-color);
}

/* ファイル: ドラッグ＆ドロップ対象（.zuzu-file-drop 内の input-group に枠強調） */
.zuzu-file-drop .input-group {
  transition: box-shadow 0.15s ease-in-out;
}
.zuzu-file-drop.zuzu-file-drop-active .input-group {
  box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), 0.25);
}
.zuzu-file-drop .zuzu-file-label {
  cursor: pointer;
}

/* type=file: d-none 禁止（Firefox は非表示だと multipart 送信されない）。Bootstrap visually-hidden 相当 */
input[type="file"].zuzu-file-input-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
  opacity: 0;
}

/*
 * ラベル付き switch（form-control-sm 同型枠・横に状態文言・hidden で POST 値）
 * 用法（.ymir の field-switch-field + hidden と同趣旨）:
 *   <div class="zuzu-switch-field form-control form-control-sm"
 *        data-ok="あり" data-ng="なし" data-ok-value="1" data-ng-value="0">
 *     <div class="form-check form-switch mb-0">
 *       <input type="hidden" class="zuzu-switch-value" name="..." value="0">
 *       <input class="form-check-input" type="checkbox" role="switch" id="..." value="1">
 *       <span class="zuzu-switch-state-label" aria-live="polite"></span>
 *     </div>
 *   </div>
 * ラベル: data-ok / data-ng（または ymir 互換 data-on-label / data-off-label）
 * 値: data-ok-value / data-ng-value（省略時 1 / 0）。切替時に .zuzu-switch-value を zuzu.js が更新。
 */
/* 枠は form-control / -sm / -lg に任せる（padding・min-height は Bootstrap 準拠） */
.zuzu-switch-field {
  display: flex;
  align-items: center;
  padding: 0;
  background-color: var(--bs-body-bg);
}
.zuzu-switch-field.form-control {
  min-height: calc(1.5em + 0.75rem + calc(var(--bs-border-width) * 2));
  padding: 0.375rem 0.75rem;
}
.zuzu-switch-field.form-control-sm {
  min-height: calc(1.5em + 0.5rem + calc(var(--bs-border-width) * 2));
  padding: 0.25rem 0.5rem;
}
.zuzu-switch-field.form-control-lg {
  min-height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));
  padding: 0.5rem 1rem;
}
.zuzu-switch-field .form-check.form-switch {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  min-height: 1.5em;
  margin-bottom: 0;
  padding-left: 0;
}
.zuzu-switch-field .form-check-input {
  margin-top: 0;
  margin-left: 0;
  flex-shrink: 0;
  float: none;
}
.zuzu-switch-field .zuzu-switch-state-label {
  font-size: 1rem;
  line-height: 1.5;
  color: var(--bs-body-color);
  user-select: none;
}
.zuzu-switch-field.form-control-sm .form-check.form-switch {
  min-height: 1.5em;
}
.zuzu-switch-field.form-control-sm .zuzu-switch-state-label {
  font-size: 0.875rem;
  line-height: 1.5;
}
.zuzu-switch-field.form-control-lg .form-check.form-switch {
  min-height: 1.5em;
}
.zuzu-switch-field.form-control-lg .zuzu-switch-state-label {
  font-size: 1.25rem;
  line-height: 1.5;
}

/*
 * サイドナビ階層（Bootstrap collapse・nav-link 見た目は各アプリ側）
 */
.zuzu-nav-collapse-chevron {
  transition: transform 0.35s ease;
}
button.zuzu-nav-collapse-btn[aria-expanded="true"] .zuzu-nav-collapse-chevron {
  transform: rotate(90deg);
}

/* --- 標準ページシェル（zuzu-ui 既定・sample/page-shell.php）
 * ヘッダー/フッター: 薄いグレー（--bs-secondary-bg ≒ Bootstrap bg-body-secondary）
 * 本文: 白（--bs-body-bg ≒ Bootstrap bg-body）
 * body にはテーマクラスのみ（例: class="blue"）。全体を gray にする bg-body-tertiary は付けない。
 * コンテンツ（.zuzu-shell-main）: 指定がなければ親幅いっぱい（width 100%）。
 * 狭めたいときは main 直下に col-* を付けず、内側に .zuzu-content-narrow または .container を置く（zuzu-base/.cursor/rules/project.mdc）。
 */
.zuzu-shell {
  display: flex;
  flex-direction: column;
  width: 100%;
}
/* main 内デモ用ネスト shell（page-footer 等） */
.zuzu-shell-main .zuzu-shell {
  height: auto;
  max-height: none;
  overflow: visible;
  flex: none;
}
.zuzu-shell-header {
  background-color: var(--zuzu-shell-header-bg, var(--zuzu-shell-chrome-bg, var(--bs-secondary-bg)));
  flex-shrink: 0;
  min-height: var(--zuzu-shell-header-height);
}
/* flex 列先頭。sticky-top は付けない（付いていてもここで無効化） */
.zuzu-shell .zuzu-shell-header {
  position: relative;
  top: auto;
  z-index: 10;
  flex-shrink: 0;
}
.zuzu-shell .zuzu-shell-header.sticky-top {
  position: relative;
  top: auto;
}
/* window スクロール型（固定操作フッターなし）では sticky-top を有効化 */
.zuzu-shell:not(:has(> .zuzu-shell-footer-fixed)) > .zuzu-shell-header.sticky-top {
  position: sticky;
  top: 0;
}
.zuzu-shell-header.navbar {
  --bs-navbar-padding-y: 0;
  padding-top: 0;
  padding-bottom: 0;
  align-items: center;
  overflow: visible;
  min-height: var(--zuzu-shell-header-height);
  height: auto;
}
.zuzu-shell-header.bg-body-tertiary {
  background-color: var(--zuzu-shell-header-bg, var(--zuzu-shell-chrome-bg, var(--bs-secondary-bg))) !important;
}
.zuzu-shell-footer {
  background-color: var(--zuzu-shell-footer-bg, var(--zuzu-shell-chrome-bg, var(--bs-secondary-bg)));
  flex-shrink: 0;
  padding-bottom: var(--zuzu-safe-area-bottom);
}
/* 本文: 共通（幅・余白）。高さ／overflow は直下フッター種別で分岐（下記） */
.zuzu-shell-main {
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  background-color: var(--bs-body-bg);
  min-width: 0;
  flex-shrink: 0;
  padding-top: var(--zuzu-shell-main-padding-top);
  padding-left: calc(var(--bs-gutter-x, 1.5rem) * 0.5);
  padding-right: calc(var(--bs-gutter-x, 1.5rem) * 0.5);
  padding-bottom: var(--zuzu-main-padding-bottom) !important;
}
/* 固定操作フッターあり（正本 2026-07-08）:
 * シェルを画面高（100svh）に固定し、main が「残り高さ」を flex で埋めて内側だけスクロールする。
 * ヘッダー/フッターの実高（折り返し・ボーダー・note の有無）に依存しないため、二重スクロールが原理的に出ない。
 * calc による固定値引き算は廃止（実高ズレ＝二重化の原因だった）。
 * トップレベルのシェル（body 直下 / body>form 直下）だけを対象にし、sample の main 内ネスト shell には当てない。 */
body > .zuzu-shell:has(> .zuzu-shell-footer-fixed),
body > .zuzu-shell:has(> .zuzu-action-bar-fixed),
body > form > .zuzu-shell:has(> .zuzu-shell-footer-fixed),
body > form > .zuzu-shell:has(> .zuzu-action-bar-fixed) {
  height: 100svh;
  max-height: 100svh;
  overflow: hidden;
}
body > .zuzu-shell > .zuzu-shell-main:has(+ .zuzu-shell-footer-fixed),
body > .zuzu-shell > .zuzu-shell-main:has(+ .zuzu-action-bar-fixed),
body > form > .zuzu-shell > .zuzu-shell-main:has(+ .zuzu-shell-footer-fixed),
body > form > .zuzu-shell > .zuzu-shell-main:has(+ .zuzu-action-bar-fixed) {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  touch-action: pan-y;
  /* 旧 100px スペーサーは position:fixed フッター時代の名残。footer は flex 兄弟で content を隠さないため、
   * 通常余白のみとする（内容が収まる高さでは幻のスクロールバーを出さない）。 */
  padding-bottom: var(--zuzu-shell-main-padding-top) !important;
}
/* 固定操作フッターなし: window スクロール（著作権のみ・LP 等。二重スクロール防止） */
.zuzu-shell > .zuzu-shell-main:not(:has(+ .zuzu-shell-footer-fixed)) {
  height: auto;
  max-height: none;
  overflow: visible;
  flex: 1 1 auto;
}
/* ネストした demo 用 main（page-footer 内）は 100svh を当てない */
.zuzu-shell-main .zuzu-shell-main {
  height: auto;
  max-height: none;
  overflow: visible;
  padding-bottom: 0 !important;
}
/* main 直下の col-* だけ付けた幅制限は無効（各画面で引き算しない） */
.zuzu-shell-main > [class*="col-"] {
  width: 100% !important;
  max-width: 100% !important;
  flex: 0 0 auto !important;
}
/* 意図的に狭めるブロック（main の内側に置く） */
.zuzu-content-narrow {
  width: 100%;
  max-width: 36rem;
}

/*
 * Bootstrap table 列揃え（全 zuzu アプリ共通）
 * th は text-center で統一。td は Bootstrap 既定（左）または text-center / text-end / text-start を列ごとに付与。
 */
.table > :not(caption) > thead > tr > th.text-start,
.table > :not(caption) > tbody > tr > td.text-start {
  text-align: start !important;
}
.table > :not(caption) > thead > tr > th.text-center,
.table > :not(caption) > tbody > tr > td.text-center {
  text-align: center !important;
}
.table > :not(caption) > thead > tr > th.text-end,
.table > :not(caption) > tbody > tr > td.text-end {
  text-align: end !important;
}

/* シェル内 navbar・offcanvas 等 */
.zuzu-page-navbar .zuzu-header-title {
  font-size: 1.35rem;
  margin: 0;
  line-height: 1.25;
}

/*
 * 左ドロワー（Bootstrap offcanvas・背景は zuzu-color --zuzu-drawer-*）
 * 用法: offcanvas.offcanvas-start.zuzu-drawer-offcanvas
 *       内側に .zuzu-drawer-brand（任意）+ .zuzu-drawer-nav（nav nav-pills flex-column）
 * 各リンクに text-white を付けなくてよい（エンジンで白文字を既定にする）。
 */
.zuzu-drawer-offcanvas {
  --bs-offcanvas-width: min(280px, 85vw);
  --bs-offcanvas-bg: var(--zuzu-drawer-bg, #212529);
  --bs-offcanvas-color: var(--zuzu-drawer-color, #ffffff);
  --zuzu-drawer-link-color: var(--zuzu-drawer-color, #ffffff);
  --zuzu-drawer-nav-radius: 0.375rem;
}
.zuzu-drawer-offcanvas .zuzu-drawer-sidebar-panel {
  min-height: 100%;
  width: 100%;
}
.zuzu-drawer-offcanvas .zuzu-drawer-brand {
  min-height: 3.5rem;
  display: flex;
  align-items: center;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  flex-shrink: 0;
}
.zuzu-drawer-offcanvas .zuzu-drawer-brand a,
.zuzu-drawer-offcanvas .offcanvas-header a,
.zuzu-drawer-offcanvas .offcanvas-title {
  color: var(--zuzu-drawer-link-color);
}
.zuzu-drawer-offcanvas .zuzu-drawer-brand .zuzu-drawer-brand-title {
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.25;
}
.zuzu-drawer-offcanvas .zuzu-drawer-nav .nav-item {
  width: 100%;
}
.zuzu-drawer-offcanvas .zuzu-drawer-nav .collapse > .nav {
  width: 100%;
}
/* d-inline-flex 指定があってもパネル余白（p-3 等）内で左右いっぱい */
.zuzu-drawer-nav .nav-link {
  display: flex !important;
  align-items: center;
  width: 100%;
  box-sizing: border-box;
  gap: 0.5rem;
  border-radius: var(--zuzu-drawer-nav-radius, 0.375rem);
}
.zuzu-drawer-nav .nav-link i {
  width: 1.25em;
  text-align: center;
}
.zuzu-drawer-offcanvas .zuzu-drawer-nav .nav-link {
  color: var(--zuzu-drawer-link-color);
}
.zuzu-drawer-offcanvas .zuzu-drawer-nav .nav-link:hover,
.zuzu-drawer-offcanvas .zuzu-drawer-nav .nav-link:focus-visible {
  color: var(--zuzu-drawer-link-color);
  background-color: var(--zuzu-drawer-link-hover-bg);
}
.zuzu-drawer-offcanvas .zuzu-drawer-nav .nav-link.active,
.zuzu-drawer-offcanvas .zuzu-drawer-nav .nav-link.active:hover,
.zuzu-drawer-offcanvas .zuzu-drawer-nav .nav-link.active:focus-visible {
  color: var(--zuzu-drawer-active-fg, #ffffff);
  background-color: var(--zuzu-drawer-active-bg);
}
.zuzu-drawer-offcanvas .zuzu-nav-collapse-btn.nav-link {
  color: var(--zuzu-drawer-link-color);
}
.zuzu-drawer-offcanvas .zuzu-nav-collapse-btn.nav-link:hover,
.zuzu-drawer-offcanvas .zuzu-nav-collapse-btn.nav-link:focus-visible {
  color: var(--zuzu-drawer-link-color);
  background-color: var(--zuzu-drawer-link-hover-bg);
}
.zuzu-drawer-offcanvas .zuzu-drawer-nav .nav-item--logout .nav-link {
  color: var(--bs-danger);
  background: transparent;
}
.zuzu-drawer-offcanvas .zuzu-drawer-nav .nav-item--logout .nav-link:hover,
.zuzu-drawer-offcanvas .zuzu-drawer-nav .nav-item--logout .nav-link:focus-visible {
  color: var(--bs-danger);
  background-color: rgba(var(--bs-danger-rgb), 0.2);
}

/*
 * ドロワー付きシェル（sample / home）。横並びは drawer-body のみ。縦の鎖は maincol が引き継ぐ。
 * .zuzu-shell.zuzu-shell-drawer > .zuzu-shell-drawer-body > (.zuzu-shell-drawer-panel + .zuzu-shell-drawer-maincol)
 */
.zuzu-shell-drawer-body {
  display: flex;
  align-items: stretch;
  width: 100%;
}
.zuzu-shell-drawer-maincol {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
}
.zuzu-shell-drawer-maincol > .zuzu-shell-header,
.zuzu-shell-drawer-maincol > .zuzu-shell-footer,
.zuzu-shell-drawer-maincol > .zuzu-shell-footer-fixed,
.zuzu-shell-drawer-maincol > .zuzu-action-bar,
.zuzu-shell-drawer-maincol > .zuzu-action-bar-fixed {
  flex-shrink: 0;
  width: 100%;
}
@media (min-width: 992px) {
  .zuzu-shell.zuzu-shell-drawer .zuzu-shell-drawer-panel.offcanvas-lg {
    position: static;
    transform: none !important;
    visibility: visible !important;
    display: flex !important;
    flex-direction: column;
    flex-shrink: 0;
    width: var(--bs-offcanvas-width);
    height: auto;
    min-height: 100%;
    z-index: auto;
    border-right: 1px solid var(--bs-border-color-translucent, rgba(255, 255, 255, 0.15));
    background-color: var(--bs-offcanvas-bg) !important;
  }
  .zuzu-shell.zuzu-shell-drawer .zuzu-shell-drawer-panel.offcanvas-lg .offcanvas-body {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    min-height: 100%;
    background-color: var(--bs-offcanvas-bg) !important;
  }
}
@media (max-width: 991.98px) {
  .zuzu-shell.zuzu-shell-drawer .zuzu-shell-drawer-toggle {
    display: inline-block;
  }
}
.zuzu-drawer-offcanvas .zuzu-shell-drawer-theme-label {
  color: color-mix(in srgb, var(--zuzu-drawer-color, #fff) 65%, transparent);
}
.zuzu-drawer-offcanvas .zuzu-shell-drawer-theme .form-select {
  background-color: color-mix(in srgb, var(--zuzu-drawer-color, #fff) 10%, transparent);
  border-color: color-mix(in srgb, var(--zuzu-drawer-color, #fff) 25%, transparent);
  color: var(--zuzu-drawer-color, #fff);
}
.zuzu-drawer-offcanvas .zuzu-shell-drawer-theme .form-select:focus {
  border-color: color-mix(in srgb, var(--zuzu-drawer-color, #fff) 45%, transparent);
  box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--zuzu-drawer-color, #fff) 15%, transparent);
}

/* theme-color.php: 1 行 1 項目（右端まで） */
.zuzu-theme-color-form {
  width: 100%;
  max-width: 100%;
}
.zuzu-theme-color-row {
  display: grid;
  grid-template-columns: minmax(14rem, 2fr) 3.25rem repeat(3, minmax(3.25rem, 1fr)) minmax(5.5rem, 1.15fr);
  gap: 0.5rem 0.75rem;
  align-items: center;
  width: 100%;
  padding: 0.5rem 1rem;
  box-sizing: border-box;
}
.zuzu-theme-color-row-r input,
.zuzu-theme-color-row-g input,
.zuzu-theme-color-row-b input,
.zuzu-theme-color-row-a input {
  width: 100%;
}
.zuzu-theme-color-row-head {
  padding-top: 0.65rem;
  padding-bottom: 0.65rem;
}
.zuzu-theme-color-row-label {
  min-width: 0;
}
.zuzu-theme-color-row-title {
  display: block;
  font-size: 0.875rem;
  line-height: 1.35;
}
.zuzu-theme-color-row-code {
  display: block;
  font-size: 0.75rem;
  color: var(--bs-secondary-color);
}
.zuzu-theme-color-row-picker {
  justify-self: start;
}
.zuzu-theme-color-row-picker .form-control-color {
  width: 3rem;
  height: 2.25rem;
  padding: 0.15rem;
}
.zuzu-theme-color-row-r,
.zuzu-theme-color-row-g,
.zuzu-theme-color-row-b,
.zuzu-theme-color-row-a {
  min-width: 0;
}
.zuzu-theme-color-row-a .input-group-text {
  padding-left: 0.35rem;
  padding-right: 0.35rem;
}

/* 固定アクションバー（zuzu 標準。編集画面の戻る・保存等） */
:root {
  --zuzu-shell-header-height: 3rem;
  --zuzu-fixed-footer-extra: 1.25rem;
  --zuzu-action-bar-height: 3.2rem;
  --zuzu-safe-area-bottom: env(safe-area-inset-bottom, 0px);
  /* main 上余白（全画面共通骨格）。HTML に py-* は付けない。 */
  --zuzu-shell-main-padding-top: 1rem;
  /* main 下端余白の量（100px）。下の main ルールとセット。 */
  --zuzu-safari-main-spacer: 100px;
  --zuzu-main-padding-bottom: calc(var(--zuzu-safari-main-spacer) + var(--zuzu-safe-area-bottom));
  --zuzu-shell-footer-note-height: 1.125rem;
  --zuzu-action-bar-spacer: calc(var(--zuzu-action-bar-height) + var(--zuzu-fixed-footer-extra) + var(--zuzu-safe-area-bottom));
  --zuzu-shell-footer-fixed-with-note-spacer: calc(var(--zuzu-action-bar-height) + var(--zuzu-shell-footer-note-height) + var(--zuzu-fixed-footer-extra) + var(--zuzu-safe-area-bottom));
}
/* main 内の旧スペーサー div は padding-bottom と二重になるため非表示。 */
main > .zuzu-safari-bottom-spacer {
  display: none;
}
.zuzu-safari-bottom-spacer {
  /* 旧画面用の main 内スペーサー。新規は main の padding-bottom を使う。main 内では非表示（二重防止）。 */
  display: block;
  height: calc(var(--zuzu-safari-main-spacer) + var(--zuzu-safe-area-bottom));
  min-height: calc(var(--zuzu-safari-main-spacer) + var(--zuzu-safe-area-bottom));
  flex-shrink: 0;
  background-color: var(--bs-body-bg);
  pointer-events: none;
}
/* レガシー: zuzu-shell 直下の .zuzu-action-bar-fixed（段階的に footer 内へ移行） */
.zuzu-shell > .zuzu-action-bar-fixed {
  position: relative;
  bottom: auto;
  left: auto;
  right: auto;
  flex-shrink: 0;
  width: 100%;
}
/* フッター: main の下に置く（列の最後）。zuzu-shell-footer-fixed＝下端常時表示。position:fixed は使わない。 */
.zuzu-shell > .zuzu-shell-footer-fixed {
  position: relative;
  bottom: auto;
  left: auto;
  right: auto;
  flex-shrink: 0;
  width: 100%;
  z-index: 30;
  margin-top: 0;
  padding-bottom: var(--zuzu-safe-area-bottom);
}
.zuzu-shell-footer-fixed > .zuzu-action-bar {
  padding-bottom: 0;
  background-color: var(--zuzu-action-bar-bg, var(--bs-body-bg));
}
.zuzu-shell-footer-note {
  padding-top: 0.125rem;
  padding-bottom: 0;
  font-size: 0.6875rem;
  line-height: 1.15;
  background-color: var(--zuzu-shell-footer-bg, var(--zuzu-shell-chrome-bg, var(--bs-secondary-bg)));
}
.zuzu-action-bar.navbar {
  --bs-navbar-padding-y: 0;
  padding-top: 0;
}
.zuzu-action-bar {
  background-color: var(--zuzu-action-bar-bg, var(--bs-body-bg));
  min-height: var(--zuzu-action-bar-height);
  padding-bottom: var(--zuzu-safe-area-bottom);
  z-index: 30;
}
.zuzu-action-bar.bg-body-tertiary {
  background-color: var(--zuzu-action-bar-bg, var(--bs-tertiary-bg)) !important;
}
.zuzu-action-bar .container-fluid.d-flex {
  column-gap: 0;
}
.zuzu-action-bar .zuzu-action-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.05rem;
  min-width: 4rem;
  min-height: var(--zuzu-action-bar-height);
  padding: 0.15rem 0.5rem;
  margin: 0;
  border: 0;
  border-radius: 0;
  text-decoration: none;
  font-size: 0.6875rem;
  line-height: 1.15;
}
.zuzu-action-bar .zuzu-action-item i {
  font-size: 0.875rem;
  line-height: 1;
}
.zuzu-action-bar .zuzu-action-item-back {
  color: rgba(0, 0, 0, 0.45);
}
.zuzu-action-bar .zuzu-action-item-primary {
  color: var(--bs-primary);
  font-weight: 600;
}
.zuzu-action-bar .zuzu-action-item-primary.zuzu-action-item-success {
  color: var(--bs-success);
}
.zuzu-action-bar .zuzu-action-divider-start {
  border-left: 1px solid var(--bs-border-color);
}
.zuzu-action-bar .zuzu-action-divider-end {
  border-right: 1px solid var(--bs-border-color);
}

/* 操作フッター: スマホは既定サイズ、768px 以上で拡大 */
@media (min-width: 768px) {
  :root {
    --zuzu-action-bar-height: 4.5rem;
  }

  .zuzu-action-bar .zuzu-action-item {
    min-width: 5.5rem;
    padding: 0.35rem 0.85rem;
    font-size: 0.875rem;
    gap: 0.2rem;
  }

  .zuzu-action-bar .zuzu-action-item i {
    font-size: 1.25rem;
  }
}

/* snackbar（トースト・zuzu-core SetSnackbar / ShowSnackbar 用・ymir 同型） */
.snackbar {
  position: fixed;
  inset: 50% auto auto 50%;
  inline-size: min(36rem, 92vw);
  z-index: 2000;
  visibility: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  box-sizing: border-box;
  padding: 0.85rem 1.15rem;
  border-radius: var(--bs-border-radius, 0.375rem);
  border: 1px solid transparent;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
  cursor: pointer;
  text-align: center;
  font-size: 1.125rem;
  font-weight: 400;
  line-height: 1.45;
  transform: translate(-50%, calc(-50% + 0.75rem));
  opacity: 0;
  transition: transform 0.2s ease, opacity 0.2s ease, visibility 0.2s ease;
}
.snackbar.center,
.snackbar.top {
  inset: 50% auto auto 50%;
}
.snackbar:is(.active) {
  visibility: visible;
  transform: translate(-50%, -50%);
  opacity: 1;
}
/* save モード（SetSnackbar save → class secondary） */
.snackbar.secondary {
  color: #1b5e20;
  background-color: #e8f5e9;
  border-color: #c8e6c9;
}
.snackbar.error {
  color: #b71c1c;
  background-color: #ffebee;
  border-color: #ffcdd2;
}
.snackbar.tertiary {
  color: #fff;
  background-color: #5d5f61;
  border-color: transparent;
}
.snackbar.primary {
  color: #fff;
  background-color: #323232;
  border-color: transparent;
}
.snackbar i {
  flex-shrink: 0;
  font-size: 1.25rem;
  line-height: 1;
}

/* zuzu-date-picker（Bootstrap Modal + btn。zuzu-ui/js/zuzu-date-picker.js 正本） */
.zuzu-date-pick {
  display: inline-block;
  vertical-align: middle;
}

.zuzu-date-pick-trigger {
  color: inherit;
  line-height: inherit;
  text-align: center;
}

/* 日付セル: table 幅・btn サイズ（土日列色は Bootstrap bg-*-subtle） */
#zuzu-date-picker-modal .zuzu-date-picker-table {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
}

#zuzu-date-picker-modal .zuzu-date-picker-table th,
#zuzu-date-picker-modal .zuzu-date-picker-table td {
  border: 1px solid var(--bs-border-color, #dee2e6);
}

#zuzu-date-picker-modal .zuzu-date-picker-year,
#zuzu-date-picker-modal .zuzu-date-picker-month {
  width: auto;
  min-width: 5.5rem;
}

#zuzu-date-picker-modal .zuzu-date-picker-prev,
#zuzu-date-picker-modal .zuzu-date-picker-next {
  line-height: 1;
}

#zuzu-date-picker-modal .zuzu-date-picker-day {
  width: 2rem;
  height: 2rem;
  color: var(--bs-body-color, #212529);
  --bs-btn-padding-x: 0;
  --bs-btn-padding-y: 0;
  --bs-btn-line-height: 1;
  --bs-btn-font-size: 0.875rem;
  --bs-btn-hover-bg: transparent;
  --bs-btn-active-bg: transparent;
  --bs-btn-hover-color: var(--bs-body-color, #212529);
  --bs-btn-active-color: var(--bs-body-color, #212529);
}

#zuzu-date-picker-modal .zuzu-date-picker-day-empty {
  pointer-events: none;
}

/* zuzu-time-picker（Flatpickr 時刻のみ。読込順: flatpickr.min.css → zuzu.css 本節。zuzu-ui/js/zuzu-time-picker.js 正本） */
.zuzu-time-pick {
  display: inline-block;
  vertical-align: middle;
}

.flatpickr-calendar.open.zuzu-time-fp-calendar.noCalendar,
.flatpickr-calendar.zuzu-time-fp-calendar.noCalendar {
  width: auto;
  min-width: 0;
  max-width: calc(100vw - 1rem);
  font-size: 0.875rem;
  line-height: 1.5;
}

.flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-months,
.flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-innerContainer {
  display: none;
}

.zuzu-time-fp-bar {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.35rem;
  padding: 0.35rem 0.45rem;
  box-sizing: border-box;
  font-size: 0.875rem;
  line-height: 1.5;
}

.zuzu-time-fp-clear {
  flex: 0 0 auto;
  padding: 0.2rem 0.3rem;
  line-height: 1;
  text-decoration: none;
}

.zuzu-time-fp-clear i {
  font-size: 0.75rem;
}

.zuzu-time-fp-confirm {
  flex: 0 0 auto;
  padding: 0.2rem 0.3rem;
  line-height: 1;
  text-decoration: none;
}

.zuzu-time-fp-confirm i {
  font-size: 0.75rem;
}

.zuzu-time-fp-time-wrap {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
}

/* Flatpickr 標準の時刻スピナーは使わない（select 正本） */
.flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-time {
  display: none !important;
}

.zuzu-time-fp-time-wrap .zuzu-time-fp-hour,
.zuzu-time-fp-time-wrap .zuzu-time-fp-minute {
  width: auto;
  min-width: 3.25rem;
  flex: 0 0 auto;
}

.zuzu-time-fp-separator {
  flex: 0 0 auto;
  font-weight: 400;
  line-height: 1;
}

.flatpickr-calendar.zuzu-time-fp-calendar.hasTime.noCalendar .flatpickr-time {
  height: auto;
  max-height: none;
  line-height: 1.5;
  padding: 0;
  border: 0;
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: center;
  font-size: inherit;
}

.flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-time .numInputWrapper {
  height: auto;
  width: auto;
  min-width: 1.6rem;
  min-height: 1.75rem;
  padding: 0;
  float: none;
}

.flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-time .numInputWrapper span {
  display: none;
}

.flatpickr-calendar.zuzu-time-fp-calendar.hasTime.noCalendar .flatpickr-time.time24hr .numInputWrapper {
  width: auto;
  flex: 0 0 auto;
}

.flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-time input.numInput,
.flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-time input.flatpickr-hour,
.flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-time input.flatpickr-minute {
  font-size: inherit;
  font-weight: 400;
  line-height: inherit;
  min-height: 1.5em;
  padding: 0.25rem 0.15rem;
  -moz-appearance: textfield;
  appearance: textfield;
  overflow: hidden;
}

.flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-time input.numInput::-webkit-outer-spin-button,
.flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-time input.numInput::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-time .flatpickr-time-separator {
  font-size: inherit;
  font-weight: 400;
  line-height: inherit;
}

/* スマホ: ピッカーだけ大きく（PC は 0.875rem のまま） */
@media (max-width: 767.98px) {
  .flatpickr-calendar.open.zuzu-time-fp-calendar.noCalendar,
  .flatpickr-calendar.zuzu-time-fp-calendar.noCalendar {
    font-size: 1.25rem;
  }

  .zuzu-time-fp-bar {
    font-size: 1.25rem;
    gap: 0.5rem;
    padding: 0.5rem 0.65rem;
  }

  .zuzu-time-fp-clear {
    padding: 0.35rem 0.45rem;
  }

  .zuzu-time-fp-clear i {
    font-size: 1rem;
  }

  .zuzu-time-fp-confirm {
    padding: 0.35rem 0.45rem;
  }

  .zuzu-time-fp-confirm i {
    font-size: 1rem;
  }

  .flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-time .numInputWrapper {
    min-width: 2.25rem;
    min-height: 2.75rem;
  }

  .zuzu-time-fp-time-wrap .zuzu-time-fp-hour,
  .zuzu-time-fp-time-wrap .zuzu-time-fp-minute {
    min-width: 4rem;
    font-size: 1.25rem;
    min-height: 2.75rem;
  }

  .zuzu-time-fp-separator {
    font-size: 1.25rem;
  }

  .flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-time input.numInput,
  .flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-time input.flatpickr-hour,
  .flatpickr-calendar.zuzu-time-fp-calendar .flatpickr-time input.flatpickr-minute {
    min-height: 2.75rem;
    padding: 0.35rem 0.25rem;
  }
}
