:root {
	/* 外観設定がない画面の既定値。後続の共通設定と同じ階層で継承する。 */
	--elsa-button-default-bg: var(--elsa-border, #d2d2d2);
	--elsa-button-default-color: var(--elsa-text-muted, #667085);
	/*
		入力欄・ラベルタブの枠線色（Issue #3797/差し戻し）。**以前は
		`.block.elsaFieldRow`だけがこの変数を定義していた**ため、SKUカードの
		入力欄（`input.elsaText.elsaSkuValue`）のように`.elsaFieldRow`の外で
		`.elsaText`を使う画面は変数が届かず、各参照側の個別フォールバック
		（`#d2d2d2`など、Issue #3797より前の値）へ落ちて枠線色設定に追従
		しなかった。ここ（:root）へ定義を上げ、`--elsa-border-color`
		（外観設定「枠線色」、既定#d4d4d4）をどこからでも参照できるようにする。
	*/
	--elsa-field-control-border-color: var(--elsa-border-color, #d4d4d4);
	/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

		会話の隙間の正本はこの3行だけである（Issue #4016のオーナー決定）。

		会話の画面はエリアごとに隙間の値がばらばらだった（行6/10/6/14・
		会話欄18・吹き出しの中10/12・入力欄の三重の枠…）。値は**3つだけ**に
		し、**四辺とも同じ**にする。

		  外側の隙間 … 一覧の各行、参加者の並び、会話欄、入力欄の外側、
		                吹き出し同士の間隔
		  内側の隙間 … 吹き出しの中、入力欄の中
		  細かい隙間 … 並んだ印どうし、段どうし、文字と操作の間

		`core/css/elsa_chat.css`はこの3つだけを読み、直値を書かない。

		**利用者が選んだ値（`--elsa-…-spacing`）をここで受け止める。**
		`--elsa-field-control-border-color`と同じ形で、外観設定の変数を
		プログラム初期値のフォールバック付きで1回だけ読み、参照側は素の
		`var(--elsa-chat-gap-…)`だけを書く。外観設定の変数を参照側が直接
		読むと、設定が届かない画面ごとに別の既定が散る。

		**フォールバックの3つの数は`elsa_default_company_app_setting()`と
		同じでなければならない。** 一致は
		`tests/appearance_variable_contract_test.php`（既定値の照合）と
		`tests/chat_gap_contract_test.php`が固定する。

	┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
	--elsa-chat-gap-outer: var(--elsa-chat-outer-spacing, 10px);
	--elsa-chat-gap-inner: var(--elsa-chat-inner-spacing, 8px);
	--elsa-chat-gap-tight: var(--elsa-chat-tight-spacing, 6px);
	--elsa-tree-row-padding-inline: 6px;
	--elsa-tree-row-padding-block: 3px;
	/*
		貼り付くタブの並びの重なり順（Issue #5210）。本文の部品（FILE の入れ替えボタンなど z-index 1〜3）より上、
		本文から開く候補一覧（9 以上）・ボタンエリア（31）より下。段はここ 1 か所で決める。
	*/
	--elsa-z-sticky-tab-list: 4;
	--elsa-scrollbar-size: 8px;
	--elsa-scrollbar-thumb: rgba(0, 0, 0, .16);
	--elsa-scrollbar-thumb-active: rgba(0, 0, 0, .38);
	--elsa-scrollbar-track: transparent;
	/*
		文字・アイコン・印の上下中央（Issue #3852）。`core/js/elsa_ink_offset.js`が
		読み込み時に実フォントの字面の偏りを測って上書きする。JSが動く前・測れな
		かったときは0emのまま（無補正＝flexの箱中央のまま）に倒す。
	*/
	--elsa-ink-offset: 0em;
	/*
		候補の種類のバッジ（`.elsaSelectorKindBadge`。Issue #4484・オーナー指示2026-10-07）。
		バッジの決まりの「灰色の枠＝種類」の色はこの2行だけが持つ。形は「必須」
		「試用中」の枠と同じで、色だけが違う（警告色の枠＝注意とは意味が別）。
		外観設定の対象にしない（種類の見分けは会社ごとに変えない）。
	*/
	--elsa-selector-kind-badge-border-color: #8a919c;
	--elsa-selector-kind-badge-color: #555555;
	/*
		寸法。**文字の大きさは置き場所の文字の11/16**（既定の16pxで11px。表示設定で
		文字を大きくすれば一緒に伸びる）。**最小幅は最長の「権限グループ」（6字）＋
		左右のpadding**（バッジ自身の文字基準。枠の2pxは使う側で足す）で、全種類の
		幅をそろえて名前の頭を縦にそろえる。間隔もバッジ自身の文字基準。
	*/
	--elsa-selector-kind-badge-font-scale: .6875;
	--elsa-selector-kind-badge-min-width: 6.7em;
	--elsa-selector-kind-badge-gap: .6em;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	文字・アイコン・印の上下中央、共通CSSの1か所（Issue #3852）。

	**「箱の中央」と「字面の中央」は別物。** `display: flex; align-items: center;`
	は行の箱を中央へ置くだけで、フォントの字面（インク）はその箱の中でascent／
	descentの比だけ上下へ偏る（メイリオは下の余白が大きい）。この偏りの実測値
	（`--elsa-ink-offset`）を、文字を持つ要素へ`translateY`で1回だけ足して
	字面そのものを中央へ寄せる。実測とCSSカスタムプロパティの仕組みは
	`core/js/elsa_ink_offset.js`の冒頭コメントを正本とする。

	**使い方は`.elsaInkCenter`を1つ付けるだけ。** 部品側は種別（このクラス）を
	宣言するだけで、個別の`vertical-align`・上下`padding`の書き分け・
	`line-height`の調整をしない（画面ごとの個別調整は
	`tests/control_vertical_center_css_test.php`が禁止台帳で機械的に止める）。

	**`text-box-trim`が使えるブラウザはCSS側の正式な仕組みへ委ねる。**
	`--elsa-ink-offset`は0emのまま（JS側が検知して上書きしない）にし、
	`.elsaInkCenter`自身が`text-box-trim: trim-both`を宣言する。使えない
	ブラウザ（`@supports`が外れる環境。この原稿時点のLinux版Chromiumを含む）
	だけ`translateY`の実測補正を使う。どちらの経路でも結果は同じ位置になる
	——「箱の中心 = 字面の中心」。

	`display: inline-block`を添えるのは、`transform`がインライン要素の直接の
	子孫（テキストノードそのもの）には効かないため。中身がテキストだけの
	要素（`<span>`・`<b>`等）に付ける前提で、レイアウトの流れそのものは
	変えない（`inline-block`は依然として文字の流れの中に収まる）。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.elsaInkCenter {
	display: inline-block;
	transform: translateY(var(--elsa-ink-offset, 0em));
}

@supports (text-box-trim: trim-both) or (-webkit-text-box-trim: trim-both) {
	:root[data-elsa-text-box-trim] .elsaInkCenter {
		transform: none;
		text-box-trim: trim-both;
		text-box-edge: cap alphabetic;
		-webkit-text-box-trim: trim-both;
		-webkit-text-box-edge: cap alphabetic;
	}
}

/*
	アプリ内で送れる箱のスクロールバーはここだけが見た目を決める（Issue #3231）。
	`overflow: auto`を持つCHAT・LIST・右ペイン・候補一覧などを部品ごとに列挙すると、
	新しい送れる箱だけ太い既定表示へ戻る。全ての業務部品はclassを持つため、低詳細度の
	共通規則を先に置き、実際にoverflowする箱だけブラウザが描く形にする。

	色は標準の`scrollbar-color`だけが持つ。Chromiumで非標準thumbへ色を書くと標準色と
	その遷移を上書きするため、WebKit疑似要素は幅・透明な溝・角丸だけを担当する。
	モバイルはブラウザ既定のoverlay scrollbarを維持する。
*/
@media (min-width: 768px) {
	:where(html, body, [class]) {
		scrollbar-width: thin;
		scrollbar-color: var(--elsa-scrollbar-thumb) var(--elsa-scrollbar-track);
		transition: scrollbar-color .3s ease;
	}
	:where(html, body, [class])::-webkit-scrollbar {
		width: var(--elsa-scrollbar-size);
		height: var(--elsa-scrollbar-size);
	}
	:where(html, body, [class])::-webkit-scrollbar-track {
		background: var(--elsa-scrollbar-track);
	}
	:where(html, body, [class])::-webkit-scrollbar-thumb {
		border-radius: var(--elsa-scrollbar-size);
	}
}

@media (min-width: 768px) and (hover: hover) {
	:where(html, body, [class]):hover,
	:where(html, body, [class]):focus-within {
		scrollbar-color: var(--elsa-scrollbar-thumb-active) var(--elsa-scrollbar-track);
	}
}

* {
	box-sizing: border-box;
}

body {
	--elsa-block-action-height: calc(var(--elsa-button-font-size, 14px) * 2);
	/*
		**帯のボタンの図像と一覧の行の図像は同じ大きさ**（2026-09-03の利用者指示）。
		以前は帯の共通アイコンが`1em`（14px）、行の操作が`28px * 0.6`（16.8px）、
		行の種類アイコンが`1.1em`（15.4px）と3つばらばらだった。**操作面（28px）に
		対する比で1つに決める**ので、外観設定の文字サイズを変えても3つは揃ったまま
		である（比の値はIcon Playgroundの実測。Issue #2002）。
	*/
	--elsa-block-action-icon-size: calc(var(--elsa-block-action-height) * var(--elsa-block-action-icon-ratio, 0.60));
	/* #3609: assets have no intrinsic margin; inset paint, never the icon box. */
	--elsa-icon-padding: 1px;
	--elsa-icon-mask-size: calc(100% - 2 * var(--elsa-icon-padding)) calc(100% - 2 * var(--elsa-icon-padding));
	/*
		**帯のボタン同士の隙間は1つの値で決める**（2026-09-03の利用者指摘）。以前は
		行の隙間6px・まとまりの中4px・まとまりの境目20.8pxと3種類あり、同じ帯の中で
		ボタンの左右の空きが揃っていなかった。まとまりの境目は**この値の2倍＋区切り線**
		で作るので、「隙間の種類」は1つのままである。
	*/
	--elsa-block-action-gap: 6px;
	/*
		一覧のセルの中で、セルを埋めずに自分の枠を持つ部品（SWITCH）とマス目の線の間の余白
		（Issue #4561）。操作列のセルの余白（3px）と同じく、帯の隙間の半分。
	*/
	--elsa-list-cell-control-gap: calc(var(--elsa-block-action-gap) / 2);
	/*
		**タブ同士の隙間と、タブの並びの左端の余白は同じ1つの値**（2026-09-29のオーナー指摘）。
		以前は一番左のタブの左端がペインの境界線に接していた。`core/css/elsa_tab.css`の
		`.elsaTabList`が`gap`と`padding-inline-start`の両方でこの値を読む。
	*/
	--elsa-tab-gap: 2px;
	--elsa-list-search-max-width: 960px;
	/*
		Button artwork has one semantic source per icon. Every block consumes these
		tokens instead of owning a glyph, inline SVG, or block-local copy.
	*/
	--elsa-icon-apply: url("../php/blocks/icons/apply.svg");
	--elsa-icon-arrow-down: url("../php/blocks/icons/arrow-down.svg");
	--elsa-icon-arrow-left: url("../php/blocks/icons/arrow-left.svg");
	--elsa-icon-arrow-right: url("../php/blocks/icons/arrow-right.svg");
	--elsa-icon-arrow-up: url("../php/blocks/icons/arrow-up.svg");
	--elsa-icon-attention: url("../php/blocks/icons/attention.svg");
	--elsa-icon-ban: url("../php/blocks/icons/ban.svg");
	--elsa-icon-close: url("../php/blocks/icons/close.svg");
	--elsa-icon-confirm: url("../php/blocks/icons/confirm.svg");
	--elsa-icon-copy: url("../php/blocks/icons/copy.svg");
	--elsa-icon-correct: url("../php/blocks/icons/correct.svg");
	--elsa-icon-delete: url("../php/blocks/icons/delete.svg");
	--elsa-icon-document: url("../php/blocks/icons/document.svg");
	--elsa-icon-document-plus: url("../php/blocks/icons/document-plus.svg");
	--elsa-icon-download: url("../php/blocks/icons/download.svg");
	--elsa-icon-edit: url("../php/blocks/icons/edit.svg");
	--elsa-icon-enter: url("../php/blocks/icons/enter.svg");
	--elsa-icon-filter: url("../php/blocks/icons/filter.svg");
	--elsa-icon-folder: url("../php/blocks/icons/folder.svg");
	--elsa-icon-folder-plus: url("../php/blocks/icons/folder-plus.svg");
	--elsa-icon-group-plus: url("../php/blocks/icons/group-plus.svg");
	--elsa-icon-help: url("../php/blocks/icons/help.svg");
	--elsa-icon-list: url("../php/blocks/icons/list.svg");
	--elsa-icon-menu: url("../php/blocks/icons/menu.svg");
	--elsa-icon-more: url("../php/blocks/icons/more.svg");
	--elsa-icon-move: url("../php/blocks/icons/move.svg");
	--elsa-icon-notification: url("../php/blocks/icons/notification.svg");
	--elsa-icon-notification-off: url("../php/blocks/icons/notification-off.svg");
	--elsa-icon-paper-plane: url("../php/blocks/icons/paper-plane.svg");
	--elsa-icon-person-plus: url("../php/blocks/icons/person-plus.svg");
	--elsa-icon-plus: url("../php/blocks/icons/plus.svg");
	--elsa-icon-print: url("../php/blocks/icons/print.svg");
	--elsa-icon-resend: url("../php/blocks/icons/resend.svg");
	--elsa-icon-reset: url("../php/blocks/icons/reset.svg");
	--elsa-icon-revoke: url("../php/blocks/icons/revoke.svg");
	--elsa-icon-run: url("../php/blocks/icons/run.svg");
	--elsa-icon-save: url("../php/blocks/icons/save.svg");
	--elsa-icon-server: url("../php/blocks/icons/server.svg");
	--elsa-icon-settings: url("../php/blocks/icons/settings.svg");
	--elsa-icon-triangle-down: url("../php/blocks/icons/triangle-down.svg");
	--elsa-icon-triangle-up: url("../php/blocks/icons/triangle-up.svg");
	--elsa-icon-view: url("../php/blocks/icons/view.svg");
	--elsa-form-control-line-height: 2;
	--elsa-form-control-padding-block: 3px;
	--elsa-form-control-padding-inline: 8px;
	--elsa-form-control-border-width: 1px;
	--elsa-form-control-height: calc(2em + var(--elsa-form-control-padding-block) + var(--elsa-form-control-padding-block) + var(--elsa-form-control-border-width) + var(--elsa-form-control-border-width));
	/*
		2026-08-24〜25の間だけ、一覧の読み取り専用セルの列幅を`<input>`の`size`から
		写した較正値（`--elsa-text-cell-char-advance` / `--elsa-text-cell-char-slack`）で
		作っていた。**較正の下限がセルの上限を上回って隣の列へ重なった**ため撤去した
		（Issue #1918。経緯は`.elsaTextReadonly[data-list-field]`の注記）。読み取り専用の
		セルは実テキストなので、列幅は中身の実幅から決まる。較正値は要らない。
	*/
	/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

		**ボタンのホバー色はここで決めない**（2026-09-02の利用者指示。Issue #2689）

		それまでこの2行が「ホバーの地＝メインメニュー色、字＝その上に載る色」と
		決めていた。ホバー色が外観設定の項目になったので、値は`:root`から届く
		（`elsa_app_appearance_root_variables()`）。

		**ここへ書き戻さない。** この宣言は`body`に載るため、`:root`から届いた
		値を`body`の中の全要素に対して黙って覆い隠す。書き戻すと、外観設定で
		ホバー色を変えても**何も起きない**（値は届いているのに、より近い
		`body`の宣言が勝つ）。

		参照側は`var(--elsa-primary-color, #24333f)`の
		形で、値が届かない場面では従来どおりメインメニュー色へ倒れる。

	┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
	/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

		**危険色はアプリ全体で1つである**（Issue #2689 段階3）

		同じ「取り返しがつかない・失敗した」を示す色が `#b42318` `#c0392b`
		`#d92d20` の3値に割れていた。**外観設定の対象にはしない**——利用者が
		地色を変えても、危険であることの見え方は動かさない（押せないボタンの
		色を#2195で固定したのと同じ考え方である）。値はここ1か所が持つ。

		接続状態の赤（`--elsa-connection-state-error`）は別物である。あちらは
		「つながっていない」という状態の表示で、危険な操作の色ではない。

	┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
	--elsa-danger-color: #b42318;
	/*  危険色の上に載る文字。地色が固定なので、こちらも固定である。  */
	--elsa-danger-contrast: #ffffff;
	/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

		**印刷する文書の色は外観設定に従わない**（Issue #2689 段階3）

		納品書・請求書・見積書・注文請書・ピッキングリストは、画面ではなく
		**紙に出るもの**である。利用者が画面の文字色を薄い灰にしたときに、
		印刷した請求書まで薄い灰になっては困る。だから外観のトークンへは
		寄せず、**印刷用の定数としてここ1か所に集める。**

		集める理由は共通で、同じ「罫線」が`#444`と`#999`と`#222`に、同じ
		「見出しの帯」が`#f0f0f0`と`#eee`に割れていたためである。値が1か所に
		あれば、帳票の見た目を揃えたいときに1行で揃う。

	┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
	--elsa-document-paper: #ffffff;
	--elsa-document-ink: #222222;
	--elsa-document-ink-weak: #555555;
	--elsa-document-rule: #444444;
	--elsa-document-rule-weak: #999999;
	--elsa-document-band: #f0f0f0;
	--elsa-button-danger-hover-bg: var(--elsa-danger-color, #b42318);
	/*
		**「押せない（無効）」ボタンの見た目は、アプリ全体でこの2行だけが決める**
		（2026-08-28の利用者決定。Issue #2169の監査H5）。薄い灰の地に灰青の文字で、
		地と文字の明暗差は約2.6:1。利用者が候補4段階から選んだ値である。

		**画面ごとの上書きを置かないこと。** 2026-08-28まで無効の表現は2系統あった。

			(1) Amazon出荷指示の丸ボタン  白文字 on #d2d2d2 ＝ 1.51:1（V2の写し）
			(2) 共通ボタンの`opacity: 0.6`  地の色しだいで実効の明暗差が変わる

		どちらも「読めるか」を約束できない。**半透明は下に何が来るかで見え方が
		変わる**ため、地と文字を実色で決める方式へ寄せた。V2互換より読みやすさを
		優先する判断も同日の利用者承認による。

		**外観設定（システム標準→会社→本人）の対象にしない。** 会社や本人が
		ボタンの地色を変えても、「押せない」の見え方だけは全社共通で動かさない。
		`core/php/function/app_appearance.php`の変数表にこの2つを足さないこと。

		この2行が受け持つのは**ボタン（押して何かが起きる操作）**だけである。
		次の3つは別の意味なので、同じ色にしない。

			入力欄の無効   `--elsa-disabled-field-background-color`（外観設定で選べる）
			処理中         `.elsaFileBlockRotate:disabled`のように`cursor: wait`で待たせる状態
			選べない行     一覧の行の半透明（Issue #2169の監査H4。別課題）
	*/
	--elsa-button-disabled-bg: #eceef1;
	--elsa-button-disabled-color: #8a94a6;
	/* V2（elsa/css/reset.css）と同じ書体スタック。 */
	font-family: "メイリオ", meiryo, "ＭＳ Ｐゴシック", "MS PGothic", Verdana, Arial, "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", Osaka, sans-serif;
	color: var(--elsa-content-text-color, #333333);
	margin: 0;
	padding: 0 0 0 210px;
}

/*
	V2（elsa/css/reset.css）と同じく、フォーム部品へ本文の書体を継承させる。

	指定がないとブラウザ既定（Arial等）になり、同じフォーム上でTEXTと
	Selectorの書体が食い違う。V3では2026-08-05までこの状態だった。
	文字サイズは各ブロックの指定を尊重するため、ここでは書体だけを揃える。
*/

button,
input,
select,
textarea {
	font-family: inherit;
}

#elsaLayout {
	max-width: none;
	margin: 0;
	padding: 30px;
	color: var(--elsa-content-text-color, #333333);
	font-size: var(--elsa-form-font-size, 16px);
}

/*
	画面へ浮かせる操作（出荷指示の丸ボタンなど）の左右位置は、ウィンドウではなく
	**入力画面（左メニューを除いた領域）**を基準にする（2026-08-14の利用者指摘
	「丸ボタンですが左メニューも含めた左右中央になっています」）。

	左メニューの実幅をこの変数だけが持ち、開閉・レスポンシブで変わっても
	同じ式のまま追従する。`position: fixed`はウィンドウ基準なので、
	中央は `50% + 左メニュー幅 / 2` になる。**V2も同じ式だった**
	（`left: calc(50% - 70px + 110px)`。70pxはボタン群の半幅、110pxは
	左メニュー200pxの半分ぶんの寄せ）。
*/
:root { --elsa-content-left: 0px; }

body.elsaHasNavigation {
	--elsa-content-left: 210px;
	display: grid;
	grid-template-columns: 210px minmax(0, 1fr);
	/*
		2行目はバージョン刻印のフッター用。`auto`なので、フッターが無い
		ページでは高さ0のまま何も起きない。**`1fr auto`にすることで、
		本文が短いページでも余った高さを1行目が吸い、フッターのぶんだけ
		ページが100vhを超えてスクロールバーが出る、という事故を避ける。**
	*/
	grid-template-rows: 1fr auto;
	align-items: stretch;
	min-height: 100vh;
	min-height: 100dvh;
	padding-left: 0;
}

/*
	左メニューは2行ぶんを覆う。明示しないと自動配置で1行目だけに入り、
	自分の`min-height: 100vh`で行からはみ出す。
*/
body.elsaHasNavigation > #elsaNav {
	grid-row: 1 / -1;
	grid-column: 1;
}

body.elsaHasNavigation #elsaLayout {
	grid-row: 1;
	grid-column: 2;
	width: 100%;
	min-width: 0;
}

body.elsaHasNavigation > .elsaAppFooter {
	grid-row: 2;
	grid-column: 2;
}

/*
	メインカラム最下部のバージョン刻印（2026-08-15の利用者指示
	「利用者が気にならないようにしてください」）。

	**本文ではなく刻印なので、フォーム文字サイズには追従させない。**
	表示設定でフォームを24pxにしたときに一緒に大きくなると、目立たせない
	という目的に反する。色だけは共通の淡色トークンから取り、背景が変わっても
	読める側へ寄せる。左右のpaddingは`#elsaLayout`と同じ値にして、本文の
	左右端と刻印の端が揃うようにしてある。

	右寄せにするのは、視線の通り道である左端から外すためである。
*/
.elsaAppFooter {
	padding: 0 30px 12px;
	color: var(--elsa-text-muted, #667085);
	text-align: right;
}

/*
	著作権表記とバージョン刻印は**同じ見た目で、隙間なく2行**にする
	（2026-08-15の利用者指示）。どちらもブロックにして`margin: 0`を明示する。
	インラインのままだと行の箱と文字の箱がずれ、「密着している」ことを
	実寸で確かめられない。

	**寄せ方だけが違う。** 著作権はメインカラムの水平中央、バージョンは
	フッターの寄せ（PC幅は右、スマホ幅は左）をそのまま継ぐ。
*/
.elsaAppFooterCopyright,
.elsaAppFooterVersion {
	display: block;
	margin: 0;
	font-size: 11px;
	line-height: 1.4;
	opacity: 0.65;
}

.elsaAppFooterCopyright { text-align: center; }

.elsaPageTitleBlock { display: block; }
.elsaBreadcrumb { font-size: var(--elsa-breadcrumb-font-size, 32px); }
.elsaBreadcrumb > ol { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; margin: 20px 0 0; padding: 0; list-style: none; }
.elsaBreadcrumb li { display: inline-flex; align-items: baseline; min-width: 0; }
/*
	階層と階層のあいだの矢印。2026-08-29の利用者指示「右矢印が＞になっています。
	**共通アイコンのarrow-right.svgにできますか？**」。

	文字の`›`をやめ、共通アイコンの意味トークン（`--elsa-icon-arrow-right`）をmaskで
	敷く。**同じ意味の図像を文字とSVGで二重に持たない**（`docs/development-policy.md`
	「5. UI品質」）。大きさは`em`なので、見出しの文字サイズを変えても矢印が一緒に
	伸縮する。読み上げには要らない（道筋は前後の文字が示す）。
*/
.elsaBreadcrumb li + li::before {
	flex: 0 0 auto;
	align-self: center;
	width: .42em;
	height: .42em;
	margin-right: 6px;
	background: var(--elsa-border, #d2d2d2);
	content: "";
	-webkit-mask: var(--elsa-icon-arrow-right) var(--elsa-icon-arrow-right-mask-position, center) / var(--elsa-icon-arrow-right-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-arrow-right) var(--elsa-icon-arrow-right-mask-position, center) / var(--elsa-icon-arrow-right-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaBreadcrumbAncestor { color: var(--elsa-text-muted, #667085); }
.elsaBreadcrumbCurrent { max-width: 100%; flex-wrap: wrap; column-gap: .2em; }
.elsaBreadcrumb .elsaPageTitle { font-size: inherit; }
.elsaPageTitle { margin: 0; overflow-wrap: anywhere; }
.elsaDeveloperPageBadge { color: var(--elsa-button-danger-hover-bg, #b42318); font-weight: 700; white-space: nowrap; }

.elsaLineBlock {
	/*  見出しの罫は強調色に従う（旧い固定の青は外観設定に追随しなかった）。  */
	--elsa-line-color: var(--elsa-primary-color, #24333f);
	--elsa-line-width: 4px;
	--elsa-line-surface-color: var(--elsa-heading-background-color, #f5f7f9);
	--elsa-line-title-color: var(--elsa-heading-text-color, #333333);
	--elsa-line-title-size: var(--elsa-heading-text-size, 16px);
	--elsa-line-title-weight: 700;
	--elsa-line-padding-block: 8px;
	--elsa-line-padding-inline: 12px;
	display: block;
	box-sizing: border-box;
	width: 100%;
	min-width: 0;
	padding-top: calc(var(--elsa-line-top-addend, var(--elsa-block-spacing, 8px)) + var(--elsa-line-top-spacing, 8px));
	padding-bottom: var(--elsa-line-bottom-spacing, 0px);
}
.elsaLineTitle {
	min-width: 0;
	margin: 0;
	padding: var(--elsa-line-padding-block) var(--elsa-line-padding-inline);
	border-inline-start: var(--elsa-line-width) solid var(--elsa-line-color);
	background: var(--elsa-line-surface-color);
	color: var(--elsa-line-title-color);
	font-size: var(--elsa-line-title-size);
	font-weight: var(--elsa-line-title-weight);
	line-height: 1.5;
	overflow-wrap: anywhere;
}
.block.elsaLineRow { display: block; width: 100%; padding-top: 0; }
/*
	区画まるごと使えないときの見出しの「!」（Issue #5141）。見出しの罫と面を包み（`.elsaLineHead`）へ
	移し、見出しの文字と「!」を同じ1本の帯に並べる。「!」の升・図像・色は入力欄の「!」と同じ規則。
*/
.elsaLineBlock--alert .elsaLineHead {
	display: flex;
	align-items: center;
	min-width: 0;
	padding-inline-end: 6px;
	border-inline-start: var(--elsa-line-width) solid var(--elsa-line-color);
	background: var(--elsa-line-surface-color);
}
.elsaLineBlock--alert .elsaLineHead > .elsaLineTitle {
	flex: 1 1 auto;
	border-inline-start: 0;
	background: transparent;
}
/*  区画の見出しの「!」は、ボタン自身の種別（data-field-alert-kind="section"）で見た目を変える（外の祖先から装飾しない）。  */
.elsaFieldHeaderAction.elsaFieldAlertButton[data-field-alert-kind="section"] {
	border-left: 0;
	background: transparent;
}

/*
	折りたたみの見出し（Issue #4345、オーナー決定2026-10-03）。

	`option.collapsible.controls`を渡した呼び出しだけ、見出しの文字が開閉の
	ボタンになる（`core/php/blocks/line/line.php`）。**見出しの見た目は変えない**
	——面・罫・文字色・字の大きさは`.elsaLineTitle`が持ったままで、このボタンは
	背景も枠も持たず、font・colorを継承するだけの透明な当たり判定である。
	見出しを2つの部品（文字＋開閉ボタン）へ割らずに1つに保つため、開閉の印は
	`::after`のマスクで描く（DOMへ飾りの節点を足さない契約は
	`tests/line_block_test.php`が持つ）。矢印は左メニューの枝
	（`.elsaNavBranchToggle::after`）と同じ共通のarrow-rightを回して使い、
	専用の図像を増やさない。
*/
.elsaLineTitleToggle {
	display: flex;
	box-sizing: border-box;
	align-items: center;
	gap: 6px;
	width: 100%;
	min-width: 0;
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	font: inherit;
	text-align: start;
	cursor: pointer;
}
.elsaLineTitleToggle::after {
	box-sizing: border-box;
	flex: 0 0 auto;
	width: 1em;
	height: 1em;
	margin-left: auto;
	background: currentColor;
	content: "";
	-webkit-mask: var(--elsa-icon-arrow-right) var(--elsa-icon-arrow-right-mask-position, center) / var(--elsa-icon-arrow-right-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-arrow-right) var(--elsa-icon-arrow-right-mask-position, center) / var(--elsa-icon-arrow-right-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	transform: rotate(90deg);
	transition: transform 0.15s ease;
}
.elsaLineTitleToggle[aria-expanded="false"]::after { transform: rotate(0deg); }
@media (prefers-reduced-motion: reduce) {
	.elsaLineTitleToggle::after { transition: none; }
}

/*
	サポート › 使い方の区分の中身（Issue #4345）。開閉のために表を1枚だけ包む
	画面側のwrapperで、閉じた状態は`hidden`属性そのもの（画面側で表示・非表示の
	CSSを足さない）。

	**包むと、表が上の隙間を受け取れなくなる**（1014行目の`* + .elsaListContainer`は
	DOMの兄弟を見るため、包みの中で先頭の子になった表には先行の兄弟が無い）。
	表のルート（`.elsaListContainer`）を外の祖先セレクタから装飾するのは
	禁じられている（`tests/field_block_style_test.php`）ので、**包み自身**が
	同じ共通トークンで同じ大きさの上の隙間を持つ。
*/
.elsaGuideGroupBody { padding-top: var(--elsa-block-spacing, 8px); }

/*
	LINEが自分のコンテナ（タブパネル・ペイン・POPUP本文・フォームなど）の
	先頭要素であるときは、LINE自身の上部隙間を0にする。コンテナ自身の
	paddingと`--elsa-line-top-spacing`が二重に積み重なって不揃いな隙間に
	なるのを防ぐ（Issue #3702。fleetのタブパネルpadding16px + LINE既定
	25pxで観測）。**下側の隙間・線・見出し・背景は変えない。タブパネル
	自身のpaddingも別途の判断待ちのためここでは変えない。**

	LINEは経路によってDOM構造が2通りある。
	  1. フィールド行として描く経路（`core/php/function/field_draw.php`）は
	     `div.block.edit.elsaLineRow`でsectionを包む。sectionはその行の
	     唯一の子なので、section自身への`:first-child`は常に真になり
	     判定にならない。**判定すべきは行（.elsaLineRow）自身がコンテナの
	     先頭かどうか。**行は`field_draw.php`が全フィールド共通で描く
	     外部のラッパーであり、LINE専用ではない。そのため行を祖先にして
	     LINEのルート（`.elsaLineBlock`）を直接装飾する書き方は取らない
	     （`tests/field_block_style_test.php`「外部の祖先セレクタから
	     ブロックのルートを装飾しない」が禁じる。ブロックのルートを
	     動かしてよいのはブロック自身の規則だけである）。代わりに行は
	     自分自身（`.elsaLineRow:first-child`が主語）が持つトークン
	     `--elsa-line-top-spacing`を0へ上書きするだけにとどめ、実際の
	     `padding-top`はLINE自身の規則（上の`.elsaLineBlock`）がそのトークンを
	     読んで決める。カスタムプロパティは通常のCSSプロパティと違い祖先から
	     子孫へ継承されるため、行より内側の`.elsaLineBlock`だけへ値が届く。
	  2. `elsa_block_draw()`を直接呼ぶ経路（POPUP本文の区切りなど）は
	     包む要素を持たない。sectionが直接コンテナへ並ぶので、素の
	     `:first-child`がそのままコンテナの先頭かを表し、`.elsaLineBlock`
	     自身の規則としてそのまま`padding-top`を0にしてよい。
	2番目の規則が1番目の対象（行に包まれたsection）まで拾わないよう、
	親が`.elsaLineRow`でないことを`:not()`で明示する。

	`:first-child`は「コンテナの先頭**要素**」であって「先頭の`.block`」
	ではない。フォーム描画（`elsa_app_setting_use_inputs_html`・
	`company_appearance_editor.php`の`action`・`server_id`・`cmid`・
	`csrf_token`）は`.elsaAppSettingForm`の中でCSRF・modeの`<input type="hidden">`
	を`.block`より先に複数個並べて出す。この`<input>`群は不可視だが実在の
	要素なので、LINEが実質フォーム内で最初の行でも`:first-child`は真に
	ならず、隙間が残っていた（Issue #3702フォローアップ。fleetの
	テナント外観設定 `/fleet/?selection=tenant-action:*:*:appearance` の
	「共通カラー設定」で実機確認、`.elsaLineRow`が`.elsaAppSettingForm`の
	先頭要素ではなくpadding-top 25pxのまま）。`:nth-child(1 of .block)`
	（CSS Selectors Level 4、現行のChromium・Firefox・Safariで対応済み。
	本ファイルは`:has()`など同水準の機能を既に使っている）は「`.block`と
	一致する最初の子」を表すため、不可視な`<input type="hidden">`等の
	非`.block`要素に先行されても正しく先頭と判定する。`:first-child`規則は
	`:nth-child(of)`未対応の古いブラウザ向けの後方互換として残す
	（対応ブラウザではより限定的な`:nth-child(1 of .block)`が同じ宣言を
	上書きし、結果は変わらない）。

	**2026-09-26追記（#4097、実測して直した）**: 共通ALERT
	（`core/php/blocks/alert/alert.php`が描く`.elsaPageMessage.elsaAlertBlock`）
	の直後にLINEが来る画面（例: `/users/?mode=insert`の設定統合窓。
	ここではCONTROLLERが右のペインへ移り、LINEが`$params["fields"]`の
	先頭になる）で、ALERTとLINEの間の隙間が消えていた。原因は
	`:nth-child(1 of .block)`の絞り込み対象（`of`の後ろ）がALERTを
	含めておらず、ALERTのdiv自身に`.block`クラスが無いため数に入らない
	ことだった——ALERTが視覚的に直前にあっても、LINEは自分の兄弟の中で
	「`.block`に一致する最初の要素」のままで、コンテナの先頭と誤認して
	いた（Computed Styleで`padding-top: 0px`を確認）。

	**直しは「ALERTの直後」だけを隣接兄弟セレクタで名指しし、LINE自身の
	トークンを親から受け継ぐ値へ戻すだけ**（`inherit`。外観設定の値は`:root`に
	あるのでそれを受け継ぎ、設定が無ければ`padding-top: var(--elsa-line-top-spacing, 8px)`
	側のフォールバックへ落ちる——値を直書きしない。2026-10-05、Issue #4388で
	`initial`から改めた。`initial`は外観設定の値まで捨てて既定の8pxへ戻していた。LINE自身のpadding-topが
	上部隙間の唯一の持ち主、という#3489の決定はそのまま）。**詳細度は
	`.block`を重ねて合わせる**——`:nth-child(1 of S)`は疑似クラス分だけで
	なく`S`（ここでは`.block`）の詳細度も足すため、`.elsaLineRow:nth-child(1
	of .block)`は実は(0,3,0)で、素の`.elsaAlertBlock + .elsaLineRow`
	(0,2,0)では勝てない（実測でFAILし気づいた）。`.elsaAlertBlock +
	.block.elsaLineRow`まで揃えて(0,3,0)の同点にし、ファイルの後ろに
	置くことで勝たせる（既存の詳細度合わせと同じ作法）。`of`リストへ
	`.elsaAlertBlock`をカンマで足す案は`tests/field_block_style_test.php`の
	祖先セレクタ検査がカッコ内のカンマをセレクタ区切りと誤認し、
	「外部の祖先セレクタでブロックのルートを装飾している」と誤検知した
	ため採らない。ALERTが無い画面や、LINEが本当にコンテナの先頭である
	POPUP断片・見出し単体では、直前の兄弟がALERTではないためこの規則は
	発火せず、上部隙間は従来どおり0のままになる。

	**2026-09-27追記（オーナー決定、Issue #4113）**: 上の#3489の決定
	「見出しの上の距離は`--elsa-line-top-spacing`だけが決める」は、途中
	（コンテナの先頭ではない）LINEについて改めた。見出しの前後にある内容と
	同じ「欄同士の間隔」（`--elsa-block-spacing`）を挟まないのは不自然に
	詰まって見えるという実画面での指摘（外観設定）による。

	  * **コンテナの先頭のLINE**（上のIssue #3702・#4097の各規則が対象）
	    … 変わらず0。ペインやコンテナ自身のpaddingだけが隙間を持つ。
	  * **途中のLINE**（直前に実在のブロックがある） … 「ブロック同士の
	    間隔」＋「見出しの上部隙間」の**足し算**。以前は上部隙間だけだった。

	持ち主を1つに保つ設計自体は変えず、`.elsaLineBlock`が読む入力を
	2本（`--elsa-line-top-addend`・`--elsa-line-top-spacing`）に分けて
	`calc()`で足す。`--elsa-line-top-addend`は不指定なら
	`var(--elsa-block-spacing, 8px)`へ落ちる——**「途中」が既定**で、
	「先頭」の側だけがこの節の各規則で両トークンを0（または`initial`で
	フォールバックへ戻す）にする。先頭側の規則を1つ増やし忘れると
	「先頭にも足す」という退行になるため、0にする代入は必ずペアで書く
	（`tests/spacing_audit_browser_test.js`の変異2種がこの両方を検査する）。

	**単位無しの`0`は書かない。** `calc()`の足し算に混ぜるカスタム
	プロパティは、代入した字面がそのままトークンとして展開される。単位無しの
	`0`は`<number>`として展開され、`<length>`（`px`側の項）との加算は
	型不一致で`calc()`全体が無効になり、`padding-top`は（非継承プロパティの
	既定である）0へ落ちる——**結果だけ見ると偶然0pxで正しく見えるため、
	「先頭にも足す」変異が検知できなくなる**（実際に2026-09-27の実装中に
	この形で気づかず一度リグレッションを作った）。`0px`と書けば
	`<length>`として展開され、算術が正しく成立する。
*/
.elsaLineRow:first-child { --elsa-line-top-spacing: 0px; --elsa-line-top-addend: 0px; }
.elsaLineRow:nth-child(1 of .block) { --elsa-line-top-spacing: 0px; --elsa-line-top-addend: 0px; }
.elsaAlertBlock + .block.elsaLineRow { --elsa-line-top-spacing: inherit; --elsa-line-top-addend: inherit; }
/*
	**2026-10-05追記（Issue #4388）**: 画面が欄をまとめるために置く透明な包み
	（`[data-elsa-field-group]`、下の「種類で切り替わる欄の包み」と同じ目印）の
	先頭にLINEがあり、包みの手前に見えている内容があるとき、そのLINEは見た目の
	うえでは「途中のLINE」である。包みは器（padding）を持たないので、先頭の0へ
	落とすと直前の欄へ密着する（設定 › AI「使用するAI」の各AIの見出しで実測）。
	この場合だけ先頭扱いから外し、途中のLINEと同じ足し算（ブロック同士の間隔＋
	見出しの上部隙間）へ戻す。値は直書きせず、トークンを親から受け継ぐ値へ戻すか
	（行として描く経路）、先頭の0の規則から外す（裸の見出し）だけにする。
	左辺は欄の包みの規則（`[data-elsa-field-group] > .elsaFieldRow`）と同じで、
	見えない要素（`[hidden]`・空・隠し入力）を手前の内容と数えない。
*/
:where(:not(.elsaController):not(input[type="hidden"]):not([hidden]):not(script):not(template):not(:empty)) ~ [data-elsa-field-group] > .elsaLineRow:nth-child(1 of .block) { --elsa-line-top-spacing: inherit; --elsa-line-top-addend: inherit; }
.elsaLineBlock:first-child:not(.elsaLineRow > .elsaLineBlock):not(:where(:not(.elsaController):not(input[type="hidden"]):not([hidden]):not(script):not(template):not(:empty)) ~ [data-elsa-field-group] > .elsaLineBlock) {
	padding-top: 0;
}

.elsaHistoryTitle { margin: .83em 0; font-size: 1.5em; }
.elsaHistoryItems { display: grid; gap: 8px; }
.elsaHistoryItem { overflow: hidden; border: 1px solid var(--elsa-border, #d2d2d2); border-radius: 4px; background: var(--elsa-surface, #ffffff); }
.elsaHistorySummary { display: flex; flex-wrap: wrap; align-items: center; min-height: var(--elsa-form-control-height); padding: var(--elsa-form-control-padding-block) var(--elsa-form-control-padding-inline); gap: 4px 12px; cursor: pointer; line-height: var(--elsa-form-control-line-height); }
.elsaHistorySummary:hover, .elsaHistorySummary:focus-visible { background: var(--elsa-surface-sunken, #f5f7f9); }
.elsaHistoryTimestamp { font-variant-numeric: tabular-nums; }
.elsaHistoryEvent { font-weight: 600; }
.elsaHistoryActor, .elsaHistoryOverview { color: var(--elsa-text-muted, #667085); }
.elsaHistoryDetail { max-height: 420px; margin: 0; padding: 12px; overflow: auto; border-top: 1px solid var(--elsa-border, #d2d2d2); background: var(--elsa-surface-sunken, #f5f7f9); color: inherit; font: 0.875em/1.6 ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace; white-space: pre-wrap; overflow-wrap: anywhere; }
.elsaHistoryEmpty { margin: 0; padding: 12px; border: 1px solid var(--elsa-border, #d2d2d2); border-radius: 4px; background: var(--elsa-surface-sunken, #f5f7f9); }
.elsaCapacityBlock { width: 100%; }
.elsaCapacityGrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 320px)); justify-content: start; gap: var(--elsa-block-spacing, 8px); }
.elsaCapacityCard { position: relative; min-height: 132px; overflow: hidden; border: 1px solid var(--elsa-border, #d2d2d2); border-radius: 5px; background: var(--elsa-surface, #ffffff); }
.elsaCapacityCardFill { position: absolute; inset: 0 auto 0 0; display: block; height: 100%; background: var(--elsa-primary-color, #24333f); transition: width .2s ease; }
.elsaCapacityCardContent { position: relative; z-index: 1; display: grid; align-content: space-between; gap: 8px; min-height: 130px; padding: 10px; color: var(--elsa-content-text-color, #333333); text-shadow: 0 0 3px var(--elsa-surface, #ffffff), 0 0 3px var(--elsa-surface, #ffffff); }
.elsaCapacityCardTitle { margin: 0; font-size: 1em; }
.elsaCapacityCardValue { align-self: center; margin: 0; font-size: 1.1em; font-weight: 600; font-variant-numeric: tabular-nums; text-align: center; }
.elsaCapacityCardNote { align-self: end; margin: 0; color: var(--elsa-text-muted, #667085); font-size: .8em; line-height: 1.2; text-align: right; }
.elsaCapacityTrack { position: relative; width: 100%; height: 50px; overflow: hidden; border-radius: 4px; background: var(--elsa-button-default-bg, #d2d2d2); }
.elsaCapacityFill { position: absolute; inset: 0 auto 0 0; display: block; height: 100%; background: var(--elsa-primary-color, #24333f); transition: width .2s ease; }
.elsaCapacityContent { position: absolute; inset: 0; z-index: 1; color: var(--elsa-content-text-color, #333333); pointer-events: none; text-shadow: 0 0 3px var(--elsa-surface, #ffffff), 0 0 3px var(--elsa-surface, #ffffff); }
.elsaCapacityValue { position: absolute; inset: 4px 8px auto; margin: 0; font-size: inherit; font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1.35; text-align: center; }
.elsaCapacityNote { position: absolute; right: 6px; bottom: 3px; max-width: calc(100% - 12px); margin: 0; font-size: .8em; line-height: 1.2; text-align: right; }
.elsaCapacityUnavailable { margin: 0; padding: 12px; border: 1px solid var(--elsa-border, #d2d2d2); border-radius: 4px; background: var(--elsa-surface-sunken, #f5f7f9); }

/*
	STATUS CARD（Issue #3728 決定60）。「状態だけを表示するカード」で、
	CAPACITYのカード（`.elsaCapacityCard`）と同じ大きさ・同じ見た目の枠
	（min-height 132px、枠線、角丸、padding、内側のgrid gap）を共有する。
	進捗バー（`elsaCapacityCardFill`相当）は持たない——比率ではなく
	状態1語だからである。説明文は持たず、値と最終確認時刻の2段だけ。
	隙間（先行・後続ブロックとの間隔）は下の「ブロック間の隙間」節が
	CAPACITYと同じ規則でまとめて持つ。
*/
.elsaStatusCardBlock { width: 100%; }
.elsaStatusCard { position: relative; min-height: 132px; max-width: 320px; overflow: hidden; border: 1px solid var(--elsa-border, #d2d2d2); border-radius: 5px; background: var(--elsa-surface, #ffffff); }
.elsaStatusCardContent { display: grid; align-content: space-between; gap: 8px; min-height: 130px; padding: 10px; color: var(--elsa-content-text-color, #333333); }
.elsaStatusCardTitle { margin: 0; font-size: 1em; }
.elsaStatusCardValue { align-self: center; margin: 0; font-size: 1.1em; font-weight: 600; text-align: center; }
.elsaStatusCard.is-warning .elsaStatusCardValue { color: var(--elsa-semantic-caution-color, #dc6803); }
.elsaStatusCard.is-unavailable .elsaStatusCardValue { color: var(--elsa-text-muted, #667085); }
.elsaStatusCardDetail { align-self: end; margin: 0; color: var(--elsa-text-muted, #667085); font-size: .8em; line-height: 1.2; text-align: right; }

.elsaDashboardCardsBlock { width: 100%; min-width: 0; }
.elsaDashboardCardsGrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--elsa-block-spacing, 8px); align-items: stretch; }
.elsaDashboardCard { display: grid; grid-template-rows: auto minmax(0, 1fr); width: 100%; min-width: 0; height: 30em; overflow: hidden; border: 1px solid var(--elsa-border, #d2d2d2); border-radius: 5px; background: var(--elsa-surface, #ffffff); color: var(--elsa-content-text-color, #333333); }
.elsaDashboardCardHeader { display: flex; align-items: center; justify-content: space-between; gap: .75em; min-width: 0; min-height: 2.75em; padding: .625em; border-bottom: 1px solid var(--elsa-border, #d2d2d2); background: var(--elsa-button-default-bg, #d2d2d2); }
.elsaDashboardCardHeader h2 { min-width: 0; margin: 0; font-size: 1em; line-height: 1.35; overflow-wrap: anywhere; }
.elsaDashboardCardAction { flex: 0 0 auto; font-weight: 600; line-height: 1.35; }
.elsaDashboardCardAction:focus-visible { outline: 2px solid var(--elsa-primary-color, #24333f); outline-offset: 2px; }
.elsaDashboardCardBody { min-width: 0; min-height: 0; padding: .625em; overflow: auto; overflow-wrap: anywhere; }
.elsaDashboardCardBody > [data-block-type] { min-width: 0; }

/*
	`option["compact"]`の見た目。既定の`.elsaDashboardCard`は`height: 30em`固定で
	トップの大きな枠を想定しており、数字1行＋補足1行のKPIには高すぎる。高さを
	内容に任せ、横は4枚並ぶようにし、中身は縦に積む。

	**この4規則は2026-08-29まで`core/css/elsa_rental_billing_workspace.css`の中に
	しかなく、請求・入金の画面でしか読まれなかった。** ブロックのオプションの
	見た目を画面固有CSSが持つと、2つ目の画面が同じ`compact`を指定しても効かない
	（入居者ハブで実際にそうなった）。規則そのものは1つも増やさず、置き場だけを
	ブロックの側へ移してある（`docs/architecture.md`「外部の祖先セレクタから
	子ブロックを装飾しない」と同じ趣旨）。
*/
.elsaDashboardCardsBlock--compact .elsaDashboardCardsGrid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.elsaDashboardCardsBlock--compact .elsaDashboardCard { height: auto; }
.elsaDashboardCardsBlock--compact .elsaDashboardCardBody { display: flex; flex-direction: column; gap: 2px; align-items: flex-start; }

@media (max-width: 900px) {
	.elsaDashboardCardsBlock--compact .elsaDashboardCardsGrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
	.elsaDashboardCardsGrid { grid-template-columns: minmax(0, 1fr); }
}

/*
	CHARTブロック（Issue #3493）。375pxへの縮小は`viewBox`だけで行い、
	CSSは横幅いっぱいへ伸縮させるだけである（メディアクエリを持たない）。
	段の色はブロック側で`var(--...)`だけを塗るので、ここでは固定色を
	1つも書かない。凡例スウォッチだけは、ブロックが渡した`--...`を
	インラインstyleへそのまま乗せる（CSS側は正方形の形だけを持つ）。
*/
.elsaChartBlock { display: block; width: 100%; min-width: 0; margin: 0; }
.elsaChartBlock[hidden] { display: none; }
.elsaChartSvg { display: block; width: 100%; height: auto; }
.elsaChartBaseline { stroke: var(--elsa-border, #d2d2d2); stroke-width: 1; }
.elsaChartReferenceLine { stroke: var(--elsa-button-disabled-color); stroke-width: 1; stroke-dasharray: 4 3; }
.elsaChartReferenceLabel { font-size: 9px; fill: var(--elsa-button-disabled-color); }
.elsaChartAxisLabel { font-size: 9px; fill: var(--elsa-content-text-color, #333333); }
.elsaChartBarSegment:focus-visible { outline: 2px solid var(--elsa-primary-color, #24333f); outline-offset: 1px; }
.elsaChartLegend { display: flex; flex-wrap: wrap; gap: .75em; margin: .5em 0 0; padding: 0; list-style: none; }
.elsaChartLegendItem { display: inline-flex; align-items: center; gap: .4em; font-size: .9em; }
.elsaChartLegendSwatch { display: inline-block; width: .9em; height: .9em; border-radius: 2px; }

#elsaNav {
	display: flex;
	position: relative;
	width: 210px;
	min-height: 100vh;
	min-height: 100dvh;
	flex-direction: column;
	align-items: stretch;
	gap: 0;
	padding: 0;
	background: var(--elsa-primary-color, #24333f);
	color: var(--elsa-primary-contrast, #fff);
	font-size: var(--elsa-tree-font-size, 16px);
	overflow: visible;
	box-shadow: none;
}

.elsaNavBrand {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 210px;
	height: 210px;
	padding: 0;
	color: var(--elsa-primary-contrast, #fff);
	font-size: 1.1em;
	font-weight: 700;
	text-decoration: none;
	border-bottom: 1px solid var(--elsa-menu-border-color, #fff);
}

.elsaNavBrand img, .elsaNavBrand .elsaBrandWordmark { display: block; width: auto; height: auto; max-width: 210px; max-height: 210px; object-fit: contain; object-position: center; }
.elsaNavDesktopBrand { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; }
.elsaNavMobileBrand { display: none; }
.elsaMobileBrand { min-width: 0; align-items: center; justify-content: center; }
.elsaMobileBrandImage { display: block; object-fit: contain; }
.elsaBrandWordmark { color: inherit; }
.elsaMobileBrandText { display: block; max-width: 100%; overflow: hidden; color: var(--elsa-content-text-color, #333333); font-weight: 700; line-height: 1.2; text-align: center; text-overflow: ellipsis; white-space: nowrap; }
.elsaMobileBrand [hidden] { display: none !important; }

.elsaNavMenu { display: flex; flex: 0 0 auto; flex-direction: column; min-width: 0; }
.elsaNavMenu a, .elsaNavLogout { color: var(--elsa-primary-contrast, #fff); text-decoration: none; }
.elsaNavMenu a,
.elsaNavBranchToggle { display: flex; align-items: center; width: 210px; min-height: 45px; padding: 0 12px; border: 0; border-bottom: 1px solid var(--elsa-menu-border-color, #fff); background: var(--elsa-primary-color, #24333f); color: var(--elsa-primary-contrast, #fff); font: inherit; text-align: left; white-space: nowrap; cursor: pointer; }
.elsaNavMenu > .elsaNavLeaf { width: 210px; min-height: 45px; border: 0; border-bottom: 1px solid var(--elsa-menu-border-color, #fff); background: var(--elsa-primary-color, #24333f); }
.elsaNavMenu a:hover, .elsaNavMenu a:focus-visible,
.elsaNavBranchToggle:hover, .elsaNavBranchToggle:focus-visible { background: color-mix(in srgb, var(--elsa-primary-color, #24333f) 82%, var(--elsa-surface, #ffffff)); outline: none; }
.elsaNavBranchToggle { position: relative; }
.elsaNavBranchLabel { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/*
	Issue #4344 段③: 枝の行は「文字（.elsaNavBranchLabel のbutton）」と「＞（.elsaNavBranchCaret のbutton）」の
	2つの押し場所を持つ。見た目は従来の1枚のボタンのまま——文字のbutton（.elsaNavBranchText）は枠も地も
	持たず行いっぱいに伸び、行の折り返しの指定をそのまま継ぐ。＞のbuttonは描かれた＞（::after）の上へ
	透明に重なるだけで、何も描かない。
	**＞のbuttonは絵より上に置く（z-index: 1）。** 絵の`::after`は`transform`を持ち重なり順が上がるため、
	指定が無いと絵の16px四方のクリックを行（＝文字扱い、開くだけ）が受け、＞を押しても閉じない。
*/
.elsaNavBranchText { display: flex; flex: 1 1 auto; flex-wrap: inherit; align-content: inherit; align-items: center; align-self: stretch; row-gap: inherit; min-width: 0; padding: 0; border: 0; background: transparent; color: inherit; font: inherit; text-align: left; white-space: inherit; cursor: pointer; }
.elsaNavBranchCaret { position: absolute; z-index: 1; top: 0; right: 0; bottom: 0; width: calc(12px + 1.5em); padding: 0; border: 0; background: transparent; cursor: pointer; }
@media (min-width: 671px) {
	.elsaNavMenu .elsaNavBranch > .elsaNavBranchToggle:has(> button:focus-visible) { background: color-mix(in srgb, var(--elsa-primary-color, #24333f) 82%, var(--elsa-surface, #ffffff)); }
	.elsaNavBranchToggle > button:focus-visible { outline: none; }
}
.elsaNavBranchToggle::after { box-sizing: border-box; flex: 0 0 auto; width: 1em; height: 1em; margin-left: auto; border: 0; background: currentColor; content: ""; -webkit-mask: var(--elsa-icon-arrow-right) var(--elsa-icon-arrow-right-mask-position, center) / var(--elsa-icon-arrow-right-mask-size, var(--elsa-icon-mask-size)) no-repeat; mask: var(--elsa-icon-arrow-right) var(--elsa-icon-arrow-right-mask-position, center) / var(--elsa-icon-arrow-right-mask-size, var(--elsa-icon-mask-size)) no-repeat; transform: rotate(0deg); transition: transform 0.15s ease; }
.elsaNavBranch.is-open > .elsaNavBranchToggle::after { transform: rotate(90deg); }
.elsaNavChildren { max-height: 0; overflow: hidden; background: var(--elsa-primary-color, #24333f); transition: max-height 0.15s ease; }
.elsaNavChildren > .elsaNavLeaf { width: 210px; min-height: 45px; padding-left: 12px; border: 0; border-bottom: 1px solid var(--elsa-menu-border-color, #fff); background: var(--elsa-primary-color, #24333f); }
.elsaNavChildren > .elsaNavBranch > .elsaNavBranchToggle { width: 210px; padding-left: 12px; background: var(--elsa-primary-color, #24333f); }
.elsaNavChildren > .elsaNavLeaf:hover, .elsaNavChildren > .elsaNavLeaf:focus-visible,
.elsaNavChildren > .elsaNavBranch > .elsaNavBranchToggle:hover, .elsaNavChildren > .elsaNavBranch > .elsaNavBranchToggle:focus-visible { background: color-mix(in srgb, var(--elsa-primary-color, #24333f) 82%, var(--elsa-surface, #ffffff)); }
.elsaNavLeaf.elsaNavLevel3 { padding-left: 12px; background: var(--elsa-primary-color, #24333f); }
.elsaNavBranch.elsaNavLevel3 > .elsaNavBranchToggle { padding-left: 12px; background: var(--elsa-primary-color, #24333f); }
.elsaNavLeaf.elsaNavLevel3:hover, .elsaNavLeaf.elsaNavLevel3:focus-visible,
.elsaNavBranch.elsaNavLevel3 > .elsaNavBranchToggle:hover, .elsaNavBranch.elsaNavLevel3 > .elsaNavBranchToggle:focus-visible { background: color-mix(in srgb, var(--elsa-primary-color, #24333f) 82%, var(--elsa-surface, #ffffff)); }

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	左メニューの試用の札（Issue #4449・一号機裁定2026-10-06）

	札そのものの形と色は`.elsaTrialBadge`（下の方）が持つ。ここが足すのは
	**左メニューという置き場所の都合**だけで、2つある。

	1. **濃い地では塗りつぶす。** PCの左メニューの地はアプリ色（既定の濃紺
	   `#24333f`）なので、警告色の枠囲みのままだと文字のコントラストが
	   **1.97:1**しか無く読めなかった（2026-10-06に実測。契約テスト
	   `tests/feature_trial_badge_browser_test.js`が4.5:1以上を固定する）。
	   地を警告色そのもので塗り、文字はその色から導いた対の色
	   （`--elsa-semantic-danger-contrast`。`elsa_app_appearance_root_variables()`が
	   警告色の明るさから白か濃紺を選ぶ）にする。**新しい色を作らない。**
	   一号機の裁定の字面は「文字を濃い色にする」だが、この製品の警告色は
	   暗い赤（既定`#b42318`）なので濃い文字では4.5:1に届かない。**どちらを
	   載せるかを決めるのは既にある導出トークン1か所**で、利用者が明るい
	   警告色へ変えれば自動で濃い文字になる。色を固定で書くと、外観設定で
	   警告色を変えた会社だけが読めなくなる。

	2. **札が在っても機能の名前を切らない。** 行の幅は210px固定なので、
	   札を足した行では名前が…で省略され（表示設定24pxでは「タスク」が
	   「タ·」まで詰んだ）、長い名前は行からはみ出していた。**名前を優先し、
	   入り切らないときは行を高くする**（`flex-wrap`）。枝の▸だけは
	   2行目へ落とさず右端へ固定する。

	札を持つ行だけに効かせるため、描く側（`core/html/layout_nav.php`）が
	`.elsaNavHasBadge`を付ける。札の無い行のHTMLとCSSは1バイトも変わらない。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

.elsaNavMenu .elsaTrialBadge { border-color: var(--elsa-semantic-danger-color, #b42318); background: var(--elsa-semantic-danger-color, #b42318); color: var(--elsa-semantic-danger-contrast, #ffffff); }
/*
	Issue #4479: 未読の札は**メインカラーの塗りの丸**なので、地がメインカラーそのものの
	PCの左メニューでは地に溶けて見えなくなる。ここでだけ地と文字を入れ替える
	（同じ対のトークンを使い、新しい色は作らない）。スマホ幅の左メニューは明るい地
	なので、下の`@media`で元の向きへ戻す。
*/
.elsaNavMenu .elsaUnreadBadge { background: var(--elsa-primary-contrast, #ffffff); color: var(--elsa-primary-color, #24333f); }
.elsaNavMenu a.elsaNavHasBadge,
.elsaNavMenu .elsaNavBranchToggle.elsaNavHasBadge { flex-wrap: wrap; align-content: center; padding-top: .3em; padding-bottom: .3em; row-gap: .15em; white-space: normal; }
/*  名前の省略をやめる（名前が長い枝では折り返して全部見せる）。  */
.elsaNavHasBadge > .elsaNavBranchLabel, .elsaNavHasBadge > .elsaNavBranchText > .elsaNavBranchLabel { overflow: visible; text-overflow: clip; }
/*  ▸は行の右端・上下中央へ固定する。折り返した2行目へ送ると、開閉の記号が名前から離れて別の行の印に見える。  */
.elsaNavMenu .elsaNavBranchToggle.elsaNavHasBadge { padding-right: calc(12px + 1.5em); }
.elsaNavMenu .elsaNavBranchToggle.elsaNavHasBadge::after { position: absolute; top: 50%; right: 12px; margin-left: 0; transform: translateY(-50%); }
.elsaNavBranch.is-open > .elsaNavBranchToggle.elsaNavHasBadge::after { transform: translateY(-50%) rotate(90deg); }

.elsaNavUser { display: block; flex: 0 0 auto; min-width: 0; color: var(--elsa-primary-contrast, #fff); background: var(--elsa-primary-color, #24333f); }
.elsaNavAccountToggle { min-height: 64px; }
.elsaNavUserInfo { display: flex; flex: 1 1 auto; flex-direction: column; justify-content: center; min-width: 0; overflow: hidden; color: inherit; }
.elsaNavUserInfo > span { display: block; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.elsaNavCompanyName { font-size: 1.05em; font-weight: 700; }
.elsaNavUserName { margin-top: 2px; font-size: 0.85em; }
.elsaNavLogout { display: flex; align-items: center; width: 210px; min-height: 45px; padding: 0 12px; border-bottom: 1px solid var(--elsa-menu-border-color, #fff); background: var(--elsa-primary-color, #24333f); }
.elsaNavLogout:hover, .elsaNavLogout:focus-visible { background: color-mix(in srgb, var(--elsa-primary-color, #24333f) 82%, var(--elsa-surface, #ffffff)); outline: none; }
.elsaNavToggleButton { display: none; }
.elsaVisuallyHidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
/*
	**本文へ飛ぶリンク**（2026-09-04、Issue #2955 C5）。`<body>`の最初に在り、
	Tabの1回目で来る。ふだんは`.elsaVisuallyHidden`と同じ切り抜きで隠し、
	**焦点が当たったときだけ**左上へ実体として出す。

	`#elsaLayout`は本文の器なので、その左上に重ねて出す。色はアプリ色と
	その上に載る文字のトークンだけを読む——ここで実色を書かない。
*/
.elsaSkipLink { position: absolute; top: 0; left: 0; z-index: 1000; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; background: var(--elsa-primary-color, #24333f); color: var(--elsa-primary-contrast, #fff); text-decoration: none; }
.elsaSkipLink:focus-visible { width: auto; height: auto; padding: 8px 12px; margin: 8px; overflow: visible; clip: auto; border-radius: 4px; outline: 2px solid var(--elsa-primary-contrast, #fff); outline-offset: -4px; }
/*  行き先そのものは`tabindex="-1"`で受けるだけなので、輪郭は出さない。  */
#elsaLayout:focus { outline: none; }

@media (max-width: 670px) {
	/*  メニューが画面の外へ出るので、浮かせる操作の基準もウィンドウへ戻す。  */
	body, body.elsaHasNavigation { --elsa-content-left: 0px; --elsa-mobile-nav-header-height: 52px; --elsa-mobile-nav-logo-height: 39px; --elsa-mobile-nav-transition: 0.15s ease; display: block; padding-left: 0; }
	#elsaLayout { padding: calc(var(--elsa-mobile-nav-header-height) + 12px) 16px 16px; }
	/*
		刻印の左右も本文と同じ端へ揃える。**スマホ幅では左寄せにする。**
		右下にはメニューを開く丸ボタンが`position: fixed`で載っており、
		右寄せのままだと最下部まで送ったときに文字が隠れる。
	*/
	.elsaAppFooter { padding: 0 16px 16px; text-align: left; }
	#elsaNav { position: static; width: 0; height: 0; min-height: 0; padding: 0; overflow: visible; box-shadow: none; }
	.elsaNavBrand { position: fixed; z-index: 32; top: 0; right: 0; left: 0; display: flex; width: 100%; height: var(--elsa-mobile-nav-header-height); padding: 6px; border-bottom: 1px solid var(--elsa-border, #d2d2d2); border-radius: 0 0 22px 22px; background: var(--elsa-surface-sunken, #f5f7f9); box-shadow: 0 4px 12px rgba(36, 51, 63, 0.14); transition: border-radius var(--elsa-mobile-nav-transition); }
	.elsaNavBrand.is-mobile-menu-open { border-radius: 0; }
	.elsaNavDesktopBrand { display: none; }
	.elsaNavMobileBrand { display: flex; width: min(100%, 320px); height: var(--elsa-mobile-nav-logo-height); }
	.elsaNavMobileBrand .elsaMobileBrandImage { width: auto; height: var(--elsa-mobile-nav-logo-height); max-width: 100%; }
	.elsaNavMobileBrand .elsaBrandWordmark { color: var(--elsa-content-text-color, #333333); }
	.elsaNavMobileBrand .elsaMobileBrandText { font-size: clamp(17px, 5vw, 22px); }
	.elsaNavUser { display: block; width: 100%; background: transparent; }
	.elsaNavToggleButton { position: fixed; z-index: 33; right: 20px; bottom: 20px; left: auto; display: grid; place-items: center; width: 50px; height: 50px; padding: 0; border: 0; border-radius: 50%; background: var(--elsa-primary-color, #24333f); color: var(--elsa-primary-contrast, #fff); cursor: pointer; }
	.elsaNavToggleButton::before { display: block; width: 24px; height: 24px; background: currentColor; content: ""; -webkit-mask: var(--elsa-icon-menu) var(--elsa-icon-menu-mask-position, center) / var(--elsa-icon-menu-mask-size, var(--elsa-icon-mask-size)) no-repeat; mask: var(--elsa-icon-menu) var(--elsa-icon-menu-mask-position, center) / var(--elsa-icon-menu-mask-size, var(--elsa-icon-mask-size)) no-repeat; }
	.elsaNavToggleButton.is-mobile-menu-open::before { -webkit-mask: var(--elsa-icon-close) var(--elsa-icon-close-mask-position, center) / var(--elsa-icon-close-mask-size, var(--elsa-icon-mask-size)) no-repeat; mask: var(--elsa-icon-close) var(--elsa-icon-close-mask-position, center) / var(--elsa-icon-close-mask-size, var(--elsa-icon-mask-size)) no-repeat; }
	.elsaNavToggleButton > span { display: none; }
	.elsaNavMenu { position: fixed; z-index: 30; right: 0; bottom: -100%; left: 0; display: flex; width: 100%; height: calc(100dvh - var(--elsa-mobile-nav-header-height)); padding: 0 0 70px; overflow-x: hidden; overflow-y: auto; overscroll-behavior-y: contain; background: var(--elsa-surface-sunken, #f5f7f9); transition: bottom var(--elsa-mobile-nav-transition); }
	#elsaNav.is-mobile-menu-open .elsaNavMenu { bottom: 0; }
	.elsaNavMenu a, .elsaNavBranchToggle { width: 80%; margin: 0 auto; color: var(--elsa-text-muted, #667085); }
	/*
		`width`と`margin`をここでも書くのは、直前の`.elsaNavMenu a`（詳細度0,1,1）が
		PC用の`.elsaNavMenu > .elsaNavLeaf`（詳細度0,2,0）に負けるためである。
		第1階層の独立リーフが210pxのまま`margin: 0 auto`で
		中央へ寄り、他の行と左端が揃わなかった（2026-08-13の利用者指摘）。
		同じ詳細度で後から書くことで揃える。
	*/
	.elsaNavMenu > .elsaNavLeaf, .elsaNavMenu > .elsaNavBranch > .elsaNavBranchToggle { width: 80%; min-height: 65px; margin: 0 auto; border: 0; border-top: 1px solid var(--elsa-menu-border-color, #fff); background: transparent; }
	/*
		区切り線は「行の上側」だけが持つ。アカウント行が`border-bottom`を持つと
		直後の行の`border-top`と2本並び、幅が違えば二重線に見える
		（2026-08-13の利用者指摘「アカウント情報下の線が変になっています」）。
	*/
	.elsaNavMenu > .elsaNavUser > .elsaNavAccountToggle { min-height: 72px; border-top: 0; border-bottom: 0; background: transparent; }
	.elsaNavMenu > .elsaNavLogout { min-height: 65px; border: 0; border-top: 1px solid var(--elsa-menu-border-color, #fff); background: transparent; }
	.elsaNavMenu > :first-child > .elsaNavBranchToggle,
	.elsaNavMenu > :first-child.elsaNavLeaf { border-top: 0; }
	.elsaNavChildren { background: transparent; }
	.elsaNavChildren > .elsaNavLeaf, .elsaNavChildren > .elsaNavBranch > .elsaNavBranchToggle { width: 80%; min-height: 55px; padding-left: 28px; border: 0; background: transparent; }
	.elsaNavMenu a:hover, .elsaNavMenu a:focus-visible,
	.elsaNavBranchToggle:hover, .elsaNavBranchToggle:focus-visible { background: transparent; }
	/*
		**スマホ幅のメニューの地は白に近い面**（`--elsa-surface-sunken`）なので、
		試用の札は枠囲みへ戻す（Issue #4449・一号機裁定2026-10-06「白い地は
		今の枠囲みのまま」）。塗りつぶしのままにすると、明るい地の上に警告色の
		塊が載って、行の名前より札の方が強く見える。コントラストはどちらの
		見せ方でも4.5:1以上を契約テストが固定する。
	*/
	.elsaNavMenu .elsaTrialBadge { border-color: currentColor; background: transparent; color: var(--elsa-semantic-danger-color, #b42318); }
	/*  未読の札も明るい地では元の向き（地＝メインカラー）へ戻す（Issue #4479）。  */
	.elsaNavMenu .elsaUnreadBadge { background: var(--elsa-primary-color, #24333f); color: var(--elsa-primary-contrast, #ffffff); }
	.elsaNavLeaf.elsaNavLevel3, .elsaNavBranch.elsaNavLevel3 > .elsaNavBranchToggle { padding-left: 46px; }
	.elsaNavMenu .elsaNavLeaf[aria-current="page"] { border-radius: 4px; background: var(--elsa-selected-bg, #dceeff); color: var(--elsa-selected-color, #333333); font-weight: 700; }
	.elsaNavMenu .elsaNavLeaf.elsaNavLevel3[aria-current="page"] { background: var(--elsa-selected-bg, #dceeff); }
	.elsaNavMenu a:focus-visible, .elsaNavBranchToggle:focus-visible, .elsaNavBranchToggle:has(> button:focus-visible) { outline: 2px solid var(--elsa-primary-color, #24333f); outline-offset: -2px; }
}

@media (max-width: 480px) { #elsaLayout { padding: calc(var(--elsa-mobile-nav-header-height) + 8px) 8px 8px; } .elsaAppFooter { padding: 0 8px 8px; } }

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	ユーザー切替（見るだけ）の知らせ（Issue #4578 PR-B）

	ページの一番上、ヘッダーよりさらに上に**文書の流れの中で場所を取って**出す。
	重ねない（`position: fixed`にしない）。ヘッダー以下はその分だけ下へずれる。

	上端に固定している部品（スマホのヘッダー・メニュー、統合窓のヘッダー・木・窓の
	高さ、左メニューの最低の高さ）は、`body.elsaUserSwitchActive`のときだけ
	`--elsa-user-switch-band-height`（core/js/elsa_user_switch_band.js が実測して置く）
	の分だけ下げる・縮める。**画面ごとの分岐を書かず、ここ1か所で持つ。**

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.elsaUserSwitchBand { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 12px; box-sizing: border-box; width: 100%; min-width: 0; margin: 0; padding: 6px 16px; border-bottom: 2px solid var(--elsa-semantic-caution-color, #dc6803); background: var(--elsa-surface-sunken, #f5f7f9); color: var(--elsa-content-text-color, #333333); }
.elsaUserSwitchBandText { flex: 1 1 12em; min-width: 0; overflow-wrap: anywhere; font-weight: bold; }
.elsaUserSwitchBandForm { display: flex; flex: 0 0 auto; justify-content: flex-end; margin: 0 0 0 auto; }
body.elsaUserSwitchActive.elsaHasNavigation { grid-template-rows: auto 1fr auto; }
body.elsaUserSwitchActive.elsaHasNavigation > .elsaUserSwitchBand { grid-row: 1; grid-column: 1 / -1; }
body.elsaUserSwitchActive.elsaHasNavigation > #elsaNav { grid-row: 2 / -1; }
@media (min-width: 671px) {
	body.elsaUserSwitchActive.elsaHasNavigation > #elsaNav { min-height: calc(100vh - var(--elsa-user-switch-band-height, 0px)); min-height: calc(100dvh - var(--elsa-user-switch-band-height, 0px)); }
}
body.elsaUserSwitchActive.elsaHasNavigation #elsaLayout { grid-row: 2; }
body.elsaUserSwitchActive.elsaHasNavigation > .elsaAppFooter { grid-row: 3; }
body.elsaUserSwitchActive.elsaAppExplorerBody { grid-template-rows: auto minmax(0, 1fr) auto; }
body.elsaUserSwitchActive .elsaAppExplorer { --elsa-app-explorer-offset: var(--elsa-user-switch-band-height, 0px); }
@media (max-width: 670px) {
	/*  スマホのヘッダーは上端に固定なので、知らせも場所を取ったまま上端に留める（スクロールで知らせだけが流れて、ヘッダーの上に隙間が空くのを防ぐ）。  */
	body.elsaUserSwitchActive > .elsaUserSwitchBand { position: sticky; z-index: 32; top: 0; }
	body.elsaUserSwitchActive .elsaNavBrand { top: var(--elsa-user-switch-band-height, 0px); }
	body.elsaUserSwitchActive .elsaNavMenu { height: calc(100dvh - var(--elsa-mobile-nav-header-height) - var(--elsa-user-switch-band-height, 0px)); }
	body.elsaUserSwitchActive .elsaAppExplorerMobileHeader { top: var(--elsa-user-switch-band-height, 0px); }
	body.elsaUserSwitchActive .elsaPaneWindow.elsaAppExplorer.is-tree-open > .elsaAppExplorerNavPane { top: calc(var(--elsa-mobile-header-height) + var(--elsa-user-switch-band-height, 0px)); height: calc(100dvh - var(--elsa-mobile-header-height) - var(--elsa-user-switch-band-height, 0px)); }
	/*  統合窓は body の上余白でヘッダーの場所を空けている。知らせを最上部に置き、その下へ空ける。  */
	body.elsaUserSwitchActive.elsaAppExplorerBody { padding-top: 0; }
	body.elsaUserSwitchActive.elsaAppExplorerBody > .elsaUserSwitchBand { margin-bottom: var(--elsa-mobile-header-height); }
}

@media (prefers-reduced-motion: reduce) {
	.elsaNavBrand, .elsaNavToggleButton > span, .elsaNavMenu, .elsaNavChildren, .elsaNavBranchToggle::after { transition-duration: 0.01ms; }
}

body.elsaLoginPage {
	min-height: 100vh;
	min-height: 100dvh;
	padding-left: 0;
	background: var(--elsa-surface-sunken, #f5f7f9);
}

.elsaLoginPage #elsaLayout {
	min-height: 100vh;
	min-height: 100dvh;
	padding: 24px;
}

.elsaLoginShell {
	display: grid;
	min-height: calc(100vh - 48px);
	min-height: calc(100dvh - 48px);
	place-items: center;
}

.elsaLoginCard {
	width: min(100%, 560px);
	padding: 32px;
	border: 1px solid var(--elsa-border, #d2d2d2);
	border-radius: 8px;
	background: var(--elsa-surface, #ffffff);
	box-shadow: 0 8px 24px rgba(36, 51, 63, 0.10);
}

.elsaLoginBrand { display: flex; width: 100%; min-height: 64px; margin-bottom: 20px; padding: 0 12px; }
/*
	ロゴの大きさは画面固有の固定px・独自倍率を持たない（Issue #3481）。
	ヘッダー（`.elsaAppExplorerMobileHeaderBrand .elsaMobileBrandImage`、
	`core/css/elsa_app_explorer.css`）と同じ計算・同じ変数
	`--elsa-header-logo-scale`（外観設定「ロゴの大きさ（%）」、Issue #3418）を
	そのまま使う。ログイン前は会社・本人の上書きが無いので、ここへ届く値は
	必ずシステム標準（`core/html/layout_head.php`が`:root`へ配る値）である。
	基準の文字サイズ（`1em`）もヘッダーと同じ`#elsaLayout`の
	`--elsa-form-font-size`をそのまま継ぐ——ログイン画面も`#elsaLayout`の
	子孫（`.elsaLoginPage #elsaLayout`）なので、ここで新たに指定しない。
	外観設定のシステム標準を変えればログイン画面のロゴも追従する。
*/
.elsaLoginBrand .elsaMobileBrandImage { width: auto; height: calc(1em * var(--elsa-header-logo-scale, 1.2)); max-width: 100%; }
.elsaLoginBrand .elsaBrandWordmark { color: var(--elsa-content-text-color, #333333); }
.elsaLoginBrand .elsaMobileBrandText { font-size: calc(1em * var(--elsa-header-logo-scale, 1.2)); white-space: normal; overflow-wrap: anywhere; }

.elsaLoginCard h1 {
	margin: 0 0 20px;
	text-align: center;
}

.elsaLoginCard > .elsaAlertBlock {
	margin: 0 0 8px;
}

/*
	ログイン画面はパスキー認証（顔認証・パスキーでログイン）と、その後に
	続く別formの間に空のSTATUSブロックを挟む。STATUSは空のとき
	`display: none`になるため、隣接結合子（+）だけでは間に挟まった瞬間に
	隙間が消え、直前のCOMMANDボタンと後続formが密着して見える
	（2026-08-13利用者指摘）。#elsaLayout直下の登録ブロックが一般兄弟結合子
	（~）でこの問題を解決しているのと同じ考え方を、このカードのスコープに
	限って適用する。共通変数`--elsa-block-spacing`はそのまま使い、値は変えない。
	STATUSは`<span>`のためinlineのままでは`margin-top`が効かず、文字が入った
	ときだけ`display: block`にする（空のときは既存の`:empty{display:none}`が勝つ）。
*/
.elsaLoginCard > .elsaCommandBlock + .elsaStatusBlock:not(:empty) {
	display: block;
	margin-top: var(--elsa-block-spacing, 8px);
}
.elsaLoginCard > .elsaCommandBlock ~ .elsaLoginForm {
	margin-top: var(--elsa-block-spacing, 8px);
}

.button.elsaCommandBlock--wide {
	display: block;
	width: 100%;
	height: var(--elsa-block-action-height);
	min-height: var(--elsa-block-action-height);
	margin: 0;
}

@media (max-width: 640px) {
	.elsaLoginPage #elsaLayout { padding: 16px; }
	.elsaLoginShell { min-height: calc(100vh - 32px); min-height: calc(100dvh - 32px); }
	.elsaLoginCard { padding: 24px 16px; }
}

@media (max-width: 360px) {
	.elsaLoginPage #elsaLayout { padding: 8px; }
	.elsaLoginShell { min-height: calc(100vh - 16px); min-height: calc(100dvh - 16px); }
	.elsaLoginCard { padding: 20px 12px; }
}

.block {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	padding-top: 0;
}

.block + .block { padding-top: var(--elsa-block-spacing, 8px); }

/*
	`elsa_block_draw()`を画面から直接呼ぶ経路（field_draw.phpの行に包まれない
	裸の`.elsaListContainer`）は、以前は先行するのがLINEのときだけ隙間を
	持ち、ALERT・STATUS・別のLIST・CAPACITY・CONTROLLER・TABパネルの内容
	などが先行すると隙間が0のままだった（Issue #3707）。

	**先行要素の種類を問わない一般規則にする。** field_draw.php経由で行
	（`.block`）に包まれた経路は、行自身が上の`.block + .block`で隙間を
	持つため対象外のままでよい（`.elsaListContainer`は`.right`の中で
	先頭のまま残り、二重にしない）。`*`は直前の兄弟要素の種類を問わない
	汎用結合子で、コンテナの先頭要素（前の兄弟が無い）ならこの規則自体が
	発火しないため、追加のfirst-child規則は要らない（Issue #3702・PR
	#3704のLINE側first-child規則と対になる「先頭でなければ隙間を持つ」側
	の規則）。
*/
* + .elsaListContainer { margin-top: var(--elsa-block-spacing, 8px); }

/*
	意味を持たない配置コンテナで登録済みブロックを縦に並べる場合も、
	画面固有marginや空のspacerを作らず共通間隔だけを使う。
	直下のブロック自身のpaddingはgrid gapと二重にしない。
*/
.elsaBlockStack {
	display: grid;
	gap: var(--elsa-block-spacing, 8px);
	width: 100%;
}
.block.elsaBlockStackItem { padding-top: 0; }
.block.elsaBlockStackItem[hidden] { display: none; }

/*
	COMMAND owns no vertical gap; its preceding registered block supplies the configured spacing.

	**上（縦）の値をここで書かない**（Issue #3489 段階2・第3回）。以前は
	`margin: 0 8px 0 0`という一括指定で四辺すべてを決めており、上の0が
	下の共通規則（`:not(.elsaCommandBlock) + .elsaCommandBlock`、
	「ブロック同士の間隔」＝`--elsa-block-spacing`）を詳細度(0,3,0)対(0,2,0)で
	打ち消していた。その結果、Issue #3707でわざわざ「先行要素の種類を問わない
	一般規則」へ直したその規則は、既定のCOMMAND（`--wide`以外＝アプリの
	ほぼ全部）には一度も効いていなかった。2026-09-22の実測では、中央請求管理
	「容量の既定値」の保存ボタンとサーバー管理「お問い合わせAI設定」タブの
	保存ボタンが、直前のフォーム・入力欄へ隙間0pxで密着していた。

	横（`margin-right`）はボタンが横に並ぶときの間隔で、縦の隙間とは別の
	持ち主である。ここではそのまま残し、**縦だけを共通規則へ返す**。

	返し方は`--wide`が既にやっている形をそのまま使う。`.button.elsaCommandBlock--wide`
	（詳細度(0,2,0)）は共通規則と同じ詳細度で、**共通規則より前に**
	書いてあるため「兄弟が無ければ0・あれば共通間隔」が自然に決まる。既定の
	COMMANDにも同じ形の`.button.elsaCommandBlock { margin-top: 0; }`（(0,2,0)）を
	1行だけ置く。`.button`の`margin: 4px …`がCOMMANDのルートへ届かないことは
	これで変わらない（`tests/block_root_spacing_test.php`が`.button`を走査から
	外している根拠）。
*/
.button.elsaCommandBlock:not(.elsaCommandBlock--wide) { margin-right: 8px; margin-bottom: 0; margin-left: 0; }
.button.elsaCommandBlock { margin-top: 0; }
/* 帯では器の共通gapだけで間隔を作る。既定COMMANDの余白は変えない。 */
.button.elsaCommandBlock.elsaCommandBlock--band { margin: 0; }
.button.elsaCommandBlock--nowrap { white-space: nowrap; }
.button.elsaCommandBlock.elsaCommandBlock--checkboxAction {
	height: var(--elsa-block-action-height);
	min-height: var(--elsa-block-action-height);
	margin: 0 0 0 auto;
	align-self: center;
}
/*
	裸のCOMMAND（`elsa_block_draw()`直接呼び出し。CONTROLLERを介さない
	単独ボタン。item.php・login.php・manual_management.phpなどが多数
	使う）も、以前は先行するのがLINEか`.block`行のときだけ隙間を持って
	いた（Issue #3707の監査で発見。base.cssの`+ .elsa`規則を全数grepし、
	LISTと同じ狭い書き方が他に無いか確認した結果）。ALERT・STATUS・
	CAPACITY・LISTなど他のブロックが先行すると隙間が0のままだった。

	**COMMAND同士の隣接（帯の中の並び）は対象から外す。** 帯はボタン間の
	間隔を自分のgapだけで持ち、margin-topを足すと折り返し行がずれる
	（`:not(.elsaCommandBlock)`で先行がCOMMAND以外のときだけに絞る）。

	**ラベルタブ・トレイリング操作・CONTROLLERの中の裸COMMANDは対象外。**
	これらは行内の装飾であり、器のgapか自分のmarginで間隔を持つ。この
	規則（詳細度0,2,0）が先行要素の種類を問わず届いてしまわないよう、
	`.elsaFieldControlGroup--trailing > .elsaCommandBlock`（下、`margin: 0`）と
	`.left.elsaFieldHeader > .elsaCommandBlock`（下に`margin-top: 0`を
	追記）は既存の規則で保護する。

	**CONTROLLERの子は`.elsaController > .elsaCommandBlock`という外部の
	祖先セレクタでは保護しない。** ブロックのルート要素は自分の外の祖先
	セレクタから装飾しない契約（`tests/field_block_style_test.php`）がある
	ため、CONTROLLERが自分の子（`elsa_field_block_command()`経由の全ての
	COMMANDへ既に付与している`.elsaControllerButton`）へ**自分自身の
	クラスの組み合わせ**として書き戻す。
*/
:not(.elsaCommandBlock) + .elsaCommandBlock { margin-top: var(--elsa-block-spacing, 8px); }
.elsaCommandBlock.elsaControllerButton { margin-top: 0; }

/*
	ブロック間の隙間の正本は、ここから下の数行だけである。値は表示設定
	「ブロック同士の間隔」から`--elsa-block-spacing`として流れてくる。

	**ブロックは自分のルート要素へ縦マージンを書かない。** 書くと、利用者が
	設定を変えても動かない隙間が混じる。2026-08-14に利用者がシステム設定画面の
	DevToolsで`.elsaConnectionStatusBlock { margin: 8px 0 24px; }`を見つけて
	指摘した。`margin-top`は下の規則（id付きで詳細度が高い）に負けて死んで
	いたが、`margin-bottom: 24px`には対抗する規則が無く、下側だけが設定を
	無視して常に24px空いていた。同じ書き方がCAPACITY・履歴・カレンダー・
	予定詳細・CHAT・スペースにもあり、まとめて撤去した。
	検査は`tests/block_root_spacing_test.php`。例外は同ファイルへ理由付きで書く。

	ブロック自身が持つblock_spacingは先行する登録ブロックがある場合だけ有効。
	link/scriptなど非ブロック要素が先にあっても、配置領域の最初のブロックは0にする。

	**「最初のブロック」の判定は、画面が手で書いた`<form>`の中身まで見る**
	（Issue #3489 段階2・第3回）。左の`:not()`は兄弟だけを見るため、直前の
	内容が`<form>`に包まれていると——中に入力欄の行（`.block`）が何本あっても
	——「先行する登録ブロックが無い＝配置領域の最初のブロック」と誤判定し、
	この0が共通規則（「ブロック同士の間隔」）を詳細度(1,6,0)対(0,2,0)で
	打ち消していた。2026-09-22の実測では、中央請求管理「容量の既定値」の
	保存ボタンが、その上の4本の入力欄を抱えた`<form>`へ隙間0pxで密着して
	いた。`form`が内容であることは下の`… + form`へ共通間隔を配る規則
	で既に決めてあり、ここだけ数えていなかった。

	**中身のある`<form>`だけを数える。** CSRFの隠し欄だけを抱えた`<form>`の
	ように1pxも描かないものまで「先行する内容」に数えると、配置領域の本当の
	先頭のブロックが下へずれる。`:has()`で行（`.block`）か登録ブロック
	（`[data-block-type]`）を1つ以上持つ`<form>`に限る。
*/
#elsaLayout > [data-block-type]:not(.elsaController):not(.block ~ [data-block-type]):not([data-block-type] ~ [data-block-type]):not(form:has(.block, [data-block-type]) ~ [data-block-type]) { margin-top: 0; }

/* LIST自身は通常の配置領域外周へ余白を作らない。 */
.block.list { padding-top: 0; }

/* #elsaLayout直下では、登録ブロックと共通field rowの兄弟間だけへ設定値を適用する。 */
#elsaLayout > [data-block-type]:not(.elsaController) ~ [data-block-type]:not(.elsaController),
#elsaLayout > .block ~ [data-block-type]:not(.elsaController) { margin-top: var(--elsa-block-spacing, 8px); }
#elsaLayout > [data-block-type]:not(.elsaController) ~ .block,
#elsaLayout > .block ~ .block { padding-top: var(--elsa-block-spacing, 8px); }

/* CONTROLLER owns its vertical spacing; do not add block_spacing at either boundary. */
#elsaLayout > .elsaController + [data-block-type]:not(.elsaController) { margin-top: 0; }
#elsaLayout > .elsaController + .block { padding-top: 0; }

/*
	ALERTはTABや画面固有のフォームなど、#elsaLayout直下ではない配置領域にも置かれる。
	画面側のmarginではなく、隣接する登録済みブロックとの間だけ共通block spacingを与える。
	連続ALERTはelsaPageMessagesのgapが所有するため、この兄弟契約では二重にしない。
*/
#elsaLayout .block + .elsaAlertBlock,
#elsaLayout [data-block-type]:not(.elsaAlertBlock) + .elsaAlertBlock {
	margin-top: var(--elsa-block-spacing, 8px);
}
#elsaLayout .elsaAlertBlock + .block {
	padding-top: var(--elsa-block-spacing, 8px);
}
#elsaLayout .elsaAlertBlock + [data-block-type]:not(.elsaController):not(.elsaAlertBlock) {
	margin-top: var(--elsa-block-spacing, 8px);
}

/*
	ブロックの直前に何があっても（登録ブロックか、画面固有の無名wrapperか、
	種類を問わない）、直後のブロックとの隙間は共通間隔1つで持つ（Issue #3728
	決定60・決定65）。LIST（`* + .elsaListContainer`）やCOMMAND（`:not(.elsaCommandBlock)
	+ .elsaCommandBlock`）と同じ「先行要素の種類を問わない一般規則」の対象を、
	後続側（`.block`・`[data-block-type]`のブロックルート全般）へ広げたものである。

	2026-09-15、容量タブでCAPACITYの2枚カードと会社別内訳LISTが隙間なく接触
	している指摘（オーナー決定60）で最初に発覚し、`.elsaCapacityBlock + .block`
	のように先行要素の組み合わせを1つずつ列挙して直した。同じ日、テナント
	「AI利用設定」タブの自動保存フォームの包み（`elsa_fleet_tenant_panel_draw_ai_usage()`
	が出す`<div data-fleet-ai-autosave>`、クラスを持たない画面固有wrapper）と
	その直後のLIST行（`.block.list`）が同じ理由で接触した（決定65）。先行要素を
	CAPACITY・STATUS CARDだけに絞っていたため、それ以外のwrapperには効かなかった。
	**先行要素を列挙するたびに直すのをやめ、「CONTROLLER以外なら何でもよい」という
	一般規則1つへ吸収する。** fleetサーバーの各タブ・テナントの容量表示は
	`#elsaLayout`の直下ではなく統合窓（app_explorerウィンドウ）の何段か内側に
	描くため、`#elsaLayout > `直下限定の共通規則がそもそも届かない場所でもある。

	**`#elsaLayout`を経由する祖先セレクタは使わない**——CAPACITY自身のCSSが
	祖先に依存しないことを`tests/capacity_block_test.php`が固定している
	（`strpos($css, "#elsaLayout .elsaCapacity") === false`）ため、LIST・COMMANDと
	同じ完全に汎用なsibling規則にする。CONTROLLERだけは左辺の`:not(.elsaController)`
	で先行要素から除く。CONTROLLERは`--elsa-controller-spacing`という別の設定を
	自分で持ち、直後のブロックへ余白を要求しない契約（`#elsaLayout > .elsaController
	+ .block { padding-top: 0; }`ほか）を保つためで、隣接結合子（+）を使うぶん、
	COMMANDの一般化と同じくCONTROLLER以外が割り込む余地もない。

	**`.block`側だけ`.elsaBlockStackItem`も左辺から除く。** スタック内部の隣接
	（`.elsaBlockStack`のgridがgapを持つ行同士）は、`.block.elsaBlockStackItem
	{ padding-top: 0; }`がこの一般規則と同じ2クラスの詳細度でタイになり、後に
	書いた側が勝つ。除かずに書くと、スタック内部の隙間がgapとこの規則の二重に
	なる。CAPACITY・STATUS CARDがスタックの外から先頭アイテムの直前に来る場合は
	`.elsaBlockStackItem`ではないため対象のままで、この場合だけ隙間が要る
	（実機で確認済み）。`[data-block-type]`側は、`elsa_field_draw()`経由の行
	（`.elsaBlockStackItem`を含む）が`data-block-type`を出さないため対象化されず、
	除外を書く必要がない。

	**`.block.list`（`padding-top: 0`）より後に置く。** 同じ`.block`2クラスで
	詳細度がタイになるため、後に書いた側がタイで勝つ。先に置くと、先行要素の
	直後のLIST行へこの規則が一切効かなくなる（実機で確認済み）。

	2026-09-15、PR #3753（Issue #3728）のCIで2件再発した。**原因は同じ——
	自分の上部間隔を既に自分の専用契約で持つブロックまで、この一般規則が
	`[data-block-type]`だけを見て二重に効かせてしまうこと。** CONTROLLERを
	左辺で除いているのと同じ理由で、右辺（実際に margin-top を受け取る側）
	からも「専用契約を持つブロック」を除く。

	  - LOGIN画面の「または」区切り線（`.elsaLineBlock`）。上のLINEの節が
	    説明するとおり、自分の`padding-top: var(--elsa-line-top-spacing, 8px)`
	    だけで上部間隔を持つ設計で、先頭要素なら`:first-child`規則が0へ
	    落とす。この規則が margin-top を追加すると padding と二重になり、
	    箱どうしが密着する設計（`gap(passwordForm, line) === 0`）が崩れる
	    （`tests/login_card_spacing_browser_test.js`）。
	  - COMMAND（`.elsaCommandBlock`）。上の`:not(.elsaCommandBlock)
	    + .elsaCommandBlock`が先行要素の種類を問わずCOMMAND自身の上部間隔を
	    既に決めており、COMMAND同士の隣接は帯の中の並びとして意図的に0の
	    ままにする契約（813行目コメント）。COMMANDも`[data-block-type]`を
	    持つため、この一般規則（詳細度0,3,0）が`:not(.elsaCommandBlock)
	    + .elsaCommandBlock`（詳細度0,2,0）より勝ってCOMMAND同士の隙間を
	    8pxへ引き上げてしまい、CHATブロックの入力欄下段（＋・AI自動応対
	    トグル・送信2つが横一列に並ぶ`.elsaChatComposerActions`）で送信
	    ボタン2つ目だけ下がって段が崩れた
	    （`tests/support_request_accordion_browser_test.js`）。

	2026-09-15、Issue #3728のフォローアップでもう1件見つかった。左辺の
	`:not(...)`は「何かある」ことしか見ないため、**画面に何も描かない
	先行要素**（`elsa_app_setting_use_inputs_html()`が出す`<input type="hidden">`、
	描画結果が空文字列のときに残る空`<div hidden>`、`script`・`template`）も
	「先行する内容」と数え、実質先頭のブロックへ余白を足してしまっていた
	（`.elsaAppSettingForm`の隠しinput群の後に来るLINEで二重発生、
	`tests/line_first_child_gap_browser_test.js`）。左辺に同じ除外列を
	1つ追記し、描画されない要素を「先行する内容」から外す。

	**除外列は`:where()`で包み、詳細度を上げない。** `:not()`の中身は
	詳細度に加算されるため、除外を増やすたびに左辺が重くなり、外観設定の
	grid内リセット（`.block.elsaAppSettingFieldGridItem { padding-top: 0; }`
	など詳細度(0,2,0)）に勝ってgapとpaddingが二重になっていた
	（PR #3753のCIで発覚。`tests/app_appearance_grid_width_browser_test.js`）。
	`:where()`は中身を評価するが詳細度には0を返す。

	2026-09-15、PR #3753のCIで同じ理由からの逆方向の再発が1件見つかった。
	margin-top側（下の[data-block-type]規則）は右辺に生の`:not(.elsaController)`
	を持つため詳細度が(0,2,0)で保たれるが、padding-top側（この規則）は左辺を
	丸ごと`:where()`で包んだ結果、右辺が`.block`1クラスだけの(0,1,0)まで下がって
	いた。`.block.list`・`.block.elsaBlockStackItem`（ともに2クラスで(0,2,0)）
	より真に軽くなり、この規則を`.block.list`より後に置いても具体的な詳細度で
	負けるため、CAPACITY直後のLISTが再び隙間0に戻っていた（実測 capacityToList/
	listToList=0、`tests/fleet_usage_adapter_browser_test.js`）。右辺へ生の
	`:not(.elsaLineRow)`を1つ足して(0,2,0)へ戻す——LINEの行自身は
	`--elsa-line-top-spacing`経由で`.elsaLineBlock`が上部間隔を持つ設計
	（上のLINEの節）のため、`.elsaLineRow`自身へこの規則のpadding-topが
	二重に効かないよう除外する必要もあり、詳細度の復元と実害のない除外を
	1つで両立できる。これで`.block.list`・`.elsaBlockStackItem`（前）には
	タイで勝ち、grid内リセット（後）にはタイで負ける、という当初の設計どおりに戻る。

	2026-09-15、Issue #3728でもう1件見つかった。ラベルタブ（`.left.elsaFieldHeader`）の
	「?」ボタン（`field_help`ブロック、`.elsaFieldHeaderAction.elsaFieldHelpButton`）は
	`data-block-type="field_help"`を持つが`.elsaCommandBlock`ではないため、この一般規則の
	対象になり margin-top 15pxが付いていた。歯車（`.elsaSettingsButton`）は`<a>`で
	`data-block-type`を持たないため対象化されず無事だったが、ヘルプは同じ`p`の隣に並ぶ
	行内の飾りであるにもかかわらず包み（min-height 30px）が44pxまで伸びラベルの表示が
	崩れた（実測 margin-top=15px、包み高さ=43.8px）。1249行目の保護規則
	`.elsaFieldHeaderAction { margin-top: 0 }`は詳細度(0,1,0)でこの一般規則(0,2,0)に
	負けていた。右辺の除外列へ`:not(.elsaFieldHeaderAction)`を`:where()`の中に追記し、
	詳細度を変えずに対象から外す。

	2026-09-15、Issue #3753でもう1件見つかった。LISTの行の操作ボタン
	（`.elsaListActionGroup`内の`.elsaListAction`、`list_action`ブロック）は
	`data-block-type="list_action"`を持つため、同じ行に並ぶ2つ目以降のボタンが
	直前のボタンを「先行する内容」として拾われ、この一般規則の対象になり
	margin-top 15pxが付いていた。行の高さは43pxで固定（`elsaListActionGroup`は
	`gap: 3px`のinline-flex）のため、はみ出した2つ目のボタンが下の罫線に重なって
	崩れた（実測 margin-top=15px、行の高さ=43px超）。4507行目の保護規則
	`.elsaListAction { margin: 0 }`は詳細度(0,1,0)でこの一般規則(0,2,0)に負けていた。
	右辺の除外列へ`:not(.elsaListAction)`を`:where()`の中に追記し、詳細度を
	変えずに対象から外す。同じ1行のグループに並ぶ`.elsaListActionToggle`（畳んだ
	操作を開く「…」）は`data-block-type`を持たずこの規則の対象になったことはないが、
	将来同じグループへ`data-block-type`付きの部品が増えても崩れないよう、
	同じ除外列へ一緒に加えておく。

	2026-09-16、Issue #3802でもう1件見つかった。左ペインの木（`nav.elsaAppExplorerNavPane`
	直下、`elsa_field_draw(array("display" => "edit", ...))`が出す裸の`div.block.edit`）が、
	その直前に居る身元表示（`div.elsaAppExplorerIdentityPane`、PCでは中身が見えないが
	子要素を持つため`:empty`ではない）を「先行する内容」として拾われ、この一般規則の
	対象になりpadding-top 15pxが付いていた（実測 padding: 15px 0 0、外観設定「入力欄の
	間隔」の値）。左ペインの木は統合窓の多くの画面（電子帳簿保存・貿易関連文書保存・
	設定・取引先・fleetほか、`elsa_app_explorer_window()`を土台にする全画面）で同じ形の
	裸`.block.edit`を出すため、画面ごとの上書きではなく一般規則側に構造的な除外を1つ
	足す。右辺へ`:where(:not(.elsaAppExplorerNavPane > .block))`を追記し、詳細度を
	変えずに「`.elsaAppExplorerNavPane`の直下に居る`.block`」だけを対象から外す
	（`.elsaAppExplorerNavPane`の外の`.block`はこれまでどおり対象のまま）。
*/
:where(:not(.elsaController):not(.elsaBlockStackItem):not(input[type="hidden"]):not([hidden]):not(script):not(template):not(:empty)) + .block:not(.elsaLineRow):where(:not(.elsaAppExplorerNavPane > .block)) { padding-top: var(--elsa-block-spacing, 8px); }
:where(:not(.elsaController):not(input[type="hidden"]):not([hidden]):not(script):not(template):not(:empty)) + [data-block-type]:not(.elsaController):where(:not(.elsaLineBlock):not(.elsaCommandBlock):not(.elsaFieldHeaderAction):not(.elsaListAction):not(.elsaListActionToggle)) { margin-top: var(--elsa-block-spacing, 8px); }
/*
	2026-09-20、Issue #3799でもう1件見つかった。画面が`data-info-hint`（情報エリアへ
	短い理由を出す、Issue #3573）でブロックを包むと、その包みは`.block`でも
	`[data-block-type]`でもないため上の2規則の対象にならず、包みの中の
	ブロック自身も#elsaLayoutの直接の子ではなくなるので兄弟間隔が一切届かない
	（テナント概要タブのCAPACITY、`extensions/control_plane/fleet/php/
	tenant_panel.php`が実例。実測: 隙間0px）。**包みを`.elsaCapacityBlock`の
	ようなブロックのルート要素として扱う（ルート要素へ縦マージンを書く）のは
	禁じ手**（`tests/block_root_spacing_test.php`）なので、包み自身を対象に
	同じ一般規則をもう1つ足す。

	2026-09-20の実画面確認（PR #3956差し戻し）でもう1件見つかった。テナント
	概要タブのCAPACITY（サーバー容量）は`data-info-hint`だけでなく、その外側を
	`elsa_fleet_tenant_panel_open()`が出す`<section data-fleet-console>`
	（CSRF・endpoint等の送信用属性を持つ、Fleetコンソールの各タブで広く使う
	包み）でも包まれる。2つの包みが入れ子になると、内側（`data-info-hint`）は
	外側（`data-fleet-console`）の中で先頭の子になり「先行する兄弟が無い」ため
	上の`[data-info-hint]`規則が届かず、代わりに外側（`data-fleet-console`）
	自身が「LISTの直後」という兄弟関係を持つ。`data-fleet-console`もこの一般
	規則の対象外（`.block`でも`[data-block-type]`でもない）だったため、今度は
	外側の包みで同じ隙間ゼロが再発した（実測: 隙間0px）。他の画面では
	`data-fleet-console`が配置領域の先頭に来ることが多く、先頭ブロックは
	元々マージン0という別規則と一致していたため見つからずにいた。

	**画面ごとに1つずつ例外を足すのではなく、「中身を持たない透明な包み」という
	性質を一般規則の対象に含める。** `data-info-hint`・`data-fleet-console`を
	1つの`:where()`にまとめ、将来同じ型の包み（ブロックのルート要素になれない
	画面固有のwrapper）が増えても同じ規則が届く形にする。**包みが入れ子でも
	二重に計上されない**——兄弟関係を持つのは常にその時点で最も外側の包みだけで、
	内側の包みは（先行する兄弟が無いため）この規則の対象にならない。
*/
:where(:not(.elsaController):not(input[type="hidden"]):not([hidden]):not(script):not(template):not(:empty)) + :where([data-info-hint], [data-fleet-console]) { margin-top: var(--elsa-block-spacing, 8px); }
/*
	2026-09-20、Issue #3799 REOPEN（実画面確認NG、一号機指摘）。上の2つの
	直前修正（`data-info-hint`・`data-fleet-console`を一般規則の対象に含める
	対応）はPRの単体テストでは緑だったが、development実機ではテナント概要
	タブのCAPACITY 2本の隙間が依然30pxだった（狙いは15px＝`--elsa-block-spacing`
	の1倍）。テストの親要素が実画面の親（`.elsaTabPanel`）を再現していな
	かったために見逃していた。

	**原因は二重計上。** テナント概要タブの2本目のCAPACITY
	（`elsa_fleet_tenant_panel_draw_tenant_database_share()`が出す
	`[data-block-type="capacity"]`）は、1本目を包む
	`<section data-fleet-console>`の直後に来る`.elsaTabPanel`（`elsa_tab.css`
	97行目）の直接の子で、`.elsaTabPanel`自身が`display:grid; gap:
	var(--elsa-block-spacing)`を持っていたため、gapのrow-gapと、この
	一般規則が足すmargin-topが両方効いて合計30pxになっていた。

	2026-09-20、一号機裁定により方針転換。祖先（`.elsaTabPanel`）からブロックの
	ルート要素を0へ戻す専用規則（`tests/field_block_style_test.php`が固定する
	契約「外部の祖先セレクタからブロックのルートを装飾しない」に反する。許容
	祖先は`#elsaLayout`・`:root`・`html`・`body`のみ）を足す前回の対応
	（この一般規則群のあとに`.elsaTabPanel > .block`等の0戻し規則を3本追加）は
	その契約でCI赤になり撤回した。代わりに`.elsaTabPanel`自身から`gap`を外し
	（`core/css/elsa_tab.css`）、二重計上の片方（gap）を無くすことで隙間を
	この一般規則（margin-top/padding-top）だけに委ねる形にした。祖先側の
	0戻し規則は増やさない。
*/
/*
	2026-09-20、Issue #3799 REOPEN 続き（一号機裁定(a) 22:40 JST）。`.elsaTabPanel`の
	`gap`を0にした副作用の洗い出しで、16画面（`contents/item/item.php`×3、
	`contents/warehouse_setting/settings.php`×1、`contents/warehouse_stock/
	operation.php`×1・`history.php`×1・`receipts.php`×3・`transfers.php`×5、
	`extensions/control_plane/fleet/php/management_root.php`×2）が、TABブロックの
	子として`.elsaTabPanel`直下へ生の`<form>`（`.block`でも`[data-block-type]`
	でもない画面固有の送信フォーム）を直接echoしていることが分かった。これらは
	以前`.elsaTabPanel`の`gap`が唯一の隙間源だったため、gapを0にすると前の兄弟
	との隙間が0pxへ退行する。

	**画面ごとに包みを足すのではなく、一般規則の対象へ`form`を1つ加える。**
	`form`要素自身はブロックのルートではない（`elsa_block_draw()`が作るもので
	はなく、画面が手で書く送信フォームの入れ物）ため、`tests/field_block_style_test.php`
	が固定する「外部の祖先セレクタからブロックのルートを装飾しない」契約には
	当たらない——この規則が装飾するのは`.elsaTabPanel`の子である`form`自身で
	あり、`form`の中にあるブロックのルートへは触れない。左辺（先行する内容の
	条件）は上の`[data-info-hint]`/`[data-fleet-console]`規則と同じにする
	（`form`もこの2つと同様、`.block`ではないため`.elsaBlockStackItem`除外は
	不要）。
*/
:where(:not(.elsaController):not(input[type="hidden"]):not([hidden]):not(script):not(template):not(:empty)) + form { margin-top: var(--elsa-block-spacing, 8px); }
/*
	2026-09-21、Issue #3974。上の一般規則は兄弟関係（`.block + .block`など）
	だけを見るため、種類などで表示を切り替える欄を画面固有のDIVで包むと、
	その包みの中の先頭の`.elsaFieldRow`は自分の親の中では「先行する兄弟が
	無い」ことになり、間隔が付かず直前の行に密着する（かんたん APIの
	「接続してくる相手を登録」ポップアップで実測: 種類の直後、切り替わる
	欄の先頭——AIワーカーなら名前、仮想オフィス端末ならデバイス名——だけ
	padding-top 0）。

	**画面ごとにmarginを足すのではなく、この種の包みを共通の目印
	`[data-elsa-field-group]`で宣言する契約にし、その最初の`.elsaFieldRow`
	（`:nth-child(1 of .elsaFieldRow)`、478行目と同じ理由で`:first-child`
	より正確）へ一般規則と同じ間隔を1か所で与える。** 隣接（`+`）ではなく
	一般兄弟（`~`）を使うのは、種類で切り替わる複数の包みが常にDOM上へ
	並び、非表示側を`[hidden]`だけで隠す構造のため——非表示の包み
	（`:not([hidden])`から除外される）が直前に挟まっても、その手前の本当の
	先行内容（種類の行）まで届く。`+`のままだと、仮想オフィス端末を選んで
	AIワーカー側の包みが`hidden`になった状態でだけ、デバイス名の行が
	再び密着する（実際にオーナーが両方の種類で確認した）。
*/
:where(:not(.elsaController):not(input[type="hidden"]):not([hidden]):not(script):not(template):not(:empty)) ~ [data-elsa-field-group] > .elsaFieldRow:nth-child(1 of .elsaFieldRow) { padding-top: var(--elsa-block-spacing, 8px); }

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	見出し（LINE）の上の隙間の持ち主は1つだけ（Issue #3489 段階2・第2回）

	見出しの上の距離は、外観設定「見出し設定 › 上部隙間」
	（`--elsa-line-top-spacing`）だけが決める。LINEは415行目の自分の規則で
	その値を`padding-top`として持つ設計であり、**兄弟間隔（「ブロック同士の
	間隔」＝`--elsa-block-spacing`）はLINEの手前の境目には足さない。**

	上の一般規則（1094・1095行目）は既にこの契約を持っている
	（`:not(.elsaLineRow)`・`:not(.elsaLineBlock)`）。ところが、それより前に
	書かれた**古い個別規則が同じ除外を持っていなかった**ため、経路と置き場所に
	よって見出しの上だけ隙間が2通りになっていた（2026-09-21の実測）。

	  * `elsa_block_draw()`で直接描く裸の見出し（ポップアップの区切りなど）
	    … 8px（「上部隙間」だけ。狙いどおり）
	  * `elsa_field_draw()`の行として描く見出し（外観設定の9本の見出し、
	    受注・見積・納品の入力欄の区切りなど）
	    … 16px（842行目`.block + .block`のpadding-topが行自身へ乗り、
	    中のLINEが持つ8pxと足し算になる）
	  * `#elsaLayout`の直接の子として置いた見出し（請求の利用状況など）
	    … 16px（936〜939行目の`~`規則が同じことをする）

	利用者が「上部隙間」を40pxにしても、前者は40px・後者は48pxにしかならない
	——**同じ項目が同じ距離を決められない。**

	直しは「LINEの上の隙間はLINE自身の規則だけが持つ」を1か所で言い切る形に
	する。古い規則へ`:not()`を1つずつ足して回る形は取らない（足し忘れが
	今回の原因そのもので、規則が増えるたびに同じ抜けが起きる）。

	詳細度は、打ち消す相手（`#elsaLayout > .block ~ .block`＝(1,2,0)）に
	並ぶところまで上げ、**ファイルの後ろに置くことで**勝たせる。祖先に
	`#elsaLayout`を使うのは`tests/field_block_style_test.php`が許す唯一の形
	（ブロックのルートを外から装飾してよい祖先は`#elsaLayout`・`:root`・
	`html`・`body`だけ）。`#elsaLayout`の外（ポップアップの断片を単体で
	描く経路など）のために、同じ宣言を素の2クラスでも持つ。

	**下の隙間はここでは触らない。** 「下部隙間」（既定0）と「ブロック同士の
	間隔」（既定8）のどちらが見出しの下の距離を持つかは利用者の判断が要る
	ため、監査の台帳（`tests/spacing_audit_browser_test.js`の`line-bottom`）に
	残したままにする。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.block.elsaLineRow,
#elsaLayout .block.elsaLineRow { padding-top: 0; }
.elsaLineBlock[data-block-type],
#elsaLayout .elsaLineBlock[data-block-type] { margin-top: 0; }

.block .left {
	width: 200px;
	display: flex;
	flex-shrink: 0;
}

.block .left p {
	display: flex;
	flex: 1 1 auto;
	align-items: center;
	justify-content: flex-end;
	min-height: var(--elsa-form-control-height);
	margin: 0;
	padding: var(--elsa-form-control-padding-block) var(--elsa-form-control-padding-inline) var(--elsa-form-control-padding-block) 3px;
	font-size: 1em;
	line-height: var(--elsa-form-control-line-height);
	font-weight: bold;
	border: 1px solid var(--elsa-border, #d2d2d2);
	border-right: none;
	border-radius: 4px 0 0 4px;
	background: var(--elsa-surface-sunken, #f5f7f9);
}

.block .right {
	width: calc(100% - 200px);
	flex: 1 1 auto;
	flex-wrap: wrap;
	min-width: 0;
	min-height: var(--elsa-form-control-height);
	display: flex;
	align-items: center;
}

/*
	非一覧入力フィールドはラベルを上部タブとして本体へ接続する。
	elsa_field_draw()が付ける専用クラスへ限定し、LIST・LINE・配置用.blockへ波及させない。
*/
.block.elsaFieldRow {
	/*
		枠線色はラベル背景から独立したトークンにする（Issue #3556、
		2026-09-11のオーナー決定）。**以前はラベル背景色をそのまま
		使っていた**ため、ラベル背景を薄くすると入力欄の枠が消えて
		見えた。ラベルの枠（下の`.left p`・`.left.elsaFieldHeader`）も
		同じこの変数を見るので、ラベルと欄が一体に見える形は保たれる。

		Issue #3797で、この固定値`#d4d4d4`を外観設定の項目「枠線色」
		（`--elsa-border-color`）へ差し替えた。利用者が枠線色を変えると
		入力欄・ラベルタブの枠が一緒に動く。予備値は元の固定値のまま。

		**定義そのものは`:root`（base.cssの先頭）へ移した**（差し戻し。
		SKUカードなど`.elsaFieldRow`の外で`.elsaText`を使う画面に変数が
		届かず、枠線色の変更に追従しなかったため）。ここでは何も再定義せず、
		`:root`の値をそのまま継ぐ。
	*/
	--elsa-field-control-border-radius: 0 4px 4px 4px;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	align-items: stretch;
	width: 100%;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	名前+敬称の対の共通の器（Issue #3810）

	見積・受注・出荷納品・取引先情報の全ての対（取引先／担当者／納入先／
	納入先担当者）がここ1か所を通る。**追加のラッパー要素は置かない。**
	`elsa_field_draw()`が敬称側の`.left`／`.right`へ`elsaFieldPairHonorific`
	だけを足して、同じ`.block.elsaFieldRow`の直接の子として並べる
	（`.left`／`.right`が持つ枠線・ラベルタブ・disabled・歯車の見た目は、
	上のタブ無し用の規則がそのまま両方に効く）。ここで決めるのは
	**位置と幅だけ**である。

	名前は残りの幅、敬称は9em（全角6文字＋padding／borderの実測）まで。
	**375pxでも2列を保つ**（2026-09決定4）。敬称は幅を取らないため、
	640px以下でも縦に落とさない。

	**上端をそろえる。** Gridの既定`stretch`だと、背の低い側の箱が行の
	高さまで引き伸ばされる。名前・敬称はどちらも同じ構造（ラベルタブが
	上、入力欄が下）で高さが揃うのが普通だが、明示して黙ってずれる余地を
	無くす。
*/
.block.elsaFieldRow.elsaFieldRow--pair {
	grid-template-columns: minmax(0, 1fr) minmax(0, 9em);
	grid-template-rows: auto auto;
	align-items: start;
	column-gap: var(--elsa-block-spacing, 8px);
}
.block.elsaFieldRow.elsaFieldRow--pair > .left:not(.elsaFieldPairHonorific) { grid-column: 1; grid-row: 1; }
.block.elsaFieldRow.elsaFieldRow--pair > .right:not(.elsaFieldPairHonorific) { grid-column: 1; grid-row: 2; }
.block.elsaFieldRow.elsaFieldRow--pair > .left.elsaFieldPairHonorific { grid-column: 2; grid-row: 1; }
.block.elsaFieldRow.elsaFieldRow--pair > .right.elsaFieldPairHonorific { grid-column: 2; grid-row: 2; }

/* 必須より変更不可を優先し、行内の各FIELDブロックへ同じ面色を渡す。 */
.block.elsaFieldRow--required {
	--elsa-field-state-background: var(--elsa-required-field-background-color, #ffe6ee);
}

.block.elsaFieldRow--disabled {
	--elsa-field-state-background: var(--elsa-disabled-field-background-color, #e9ecef);
}

/*
	入力エラーの赤枠は`.elsaFieldRow`へ付けない。行を囲うと、ラベルのタブと
	入力欄の下に出るエラー文まで1つの枠の中に入ってしまう。
	赤枠の正しい位置はファイル末尾の`.has-error`の規則を参照。
*/

/*
	Issue #3556: タブと入力欄の間の枠線が消えていた。以前はここへ`z-index: 1`を、
	下の`.right`へ`margin-top: -1px`を置き、タブ側を1px重ねて入力欄の上枠線を
	隠す形にしていた（2026-08-10、`.right`自身がまだ別枠を描いていた頃の名残）。
	`.right`はもう自分の枠を持たず、中の入力ブロック（TEXT等）が
	`--elsa-field-control-border-color`で枠を描くだけなので、重ねる意味がなくなり、
	タブ下の0.8px（枠線）だけを隠す副作用になっていた。**重ねない**——タブは
	`border-bottom: 0`で開けたまま、入力欄の上枠線がその下を含めて全幅で通る形にする。
*/
.block.elsaFieldRow > .left {
	position: relative;
	display: block;
	width: max-content;
	max-width: 100%;
}

.block.elsaFieldRow > .left p,
.elsaFieldLabelCaption {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  min-height: 30px;
  padding: 0 10px;
	border: 1px solid var(--elsa-field-control-border-color, #d4d4d4);
	border-bottom: 0;
	border-radius: 5px 5px 0 0;
	background: var(--elsa-field-tab-background-color, #f0f0f0);
	color: var(--elsa-field-tab-text-color, #555);
	font-size: var(--elsa-field-tab-font-size, 14px);
	font-weight: normal;
  line-height: 1.2;
  overflow-wrap: anywhere;
}

/*
	必須バッジ。ラベルタブの中で「必須」を角丸の四角い枠で囲う。

	**括弧ではなく枠である**（2026-08-28の利用者指定）。四隅にRを付けた
	小さな長方形にし、ラベル文字より一回り小さくする。

	**寸法は全て`em`で書く。** 基準はラベルタブの文字サイズ
	（`--elsa-field-tab-font-size`）なので、表示設定で12〜24pxのどれを
	選んでもバッジと枠が一緒に伸縮する。**固定pxを書かないこと。**

	**色は警告色そのもの（Issue #3703、2026-09-14のオーナー決定）。**
	2026-09-11は「必須の印だけは拾えるように」注意色を45%混ぜた色を
	使っていたが、警告の三色（安全／注意／警告）のうち必須は警告色が
	正しいという指定に変わった。混色はやめ、`--elsa-semantic-danger-color`
	を直接使う。**バッジ専用の固定色は作らない**（一時期
	`--elsa-field-tab-required-color`を使ったが撤回済み。今回も同じ理由で
	復活させない）。既定値`#b42318`とラベルタブの既定背景`#f0f0f0`では
	5.77:1でAA（4.5:1）を満たす（`tests/field_required_badge_test.php`で
	実測して固定）。枠は引き続き`currentColor`＝同じ色にするので、色の
	指定はここ1か所だけで枠まで追従する。

	`padding-top`だけが`padding-bottom`より大きいのは**字面を枠の上下中央
	へ置くため**である（2026-08-28の利用者指摘）。書体の上端・下端
	（ascent 11 / descent 5）は非対称で、「必須」の字面（ink ascent 9 /
	descent 1）はさらに上寄りなので、余白を左右対称にすると字が1px上へ
	寄る（`development`の実測: 上2.68px・下4.68px）。ずれ量は
	`((ascent - descent) - (inkAscent - inkDescent)) / 2`で**文字サイズに
	比例する**ため、`.19em`＝そのずれの2倍を`padding-top`へ足すと、
	12〜24pxのどの設定でも中央に載る。**pxで書くと文字サイズを変えた
	ときに中央から外れる。**
	この値は書体の寸法から決まる。書体が変わったら
	`tests/field_required_badge_browser_test.js`の±1px検査が落ちるので、
	そのときは実測し直す。
*/
.elsaFieldRequiredBadge {
	flex: 0 0 auto;
	box-sizing: border-box;
	margin-left: .5em;
	padding: .19em .35em 0;
	border: 1px solid currentColor;
	border-radius: .25em;
	color: var(--elsa-semantic-danger-color, #b42318);
	font-size: .75em;
	font-weight: normal;
	line-height: 1.15;
	white-space: nowrap;
}

/*
	試用の札（Issue #4449・オーナー決定2026-10-06）。

	**形は入力欄の「必須」と同じ枠囲み、色は警告色の共通トークン**という指定
	なので、上の`.elsaFieldRequiredBadge`と**同じ寸法・同じ色変数**にする。
	**札専用の色を作らない**（`--elsa-semantic-danger-color`を直接使う。必須
	バッジが専用変数を撤回したのと同じ理由）。

	**寸法は全て`em`で書く。** 基準はこの札を置く行の文字サイズ（左メニューの
	行、アプリの木の行）なので、表示設定で12〜24pxのどれを選んでも札と枠が
	一緒に伸縮する。**固定pxを書かないこと。** `padding-top`だけが
	`padding-bottom`より大きいのは字面を枠の上下中央へ置くためで、理由と
	`.19em`の出どころは`.elsaFieldRequiredBadge`の注記が正本である。

	`display: inline-block`を足してあるのは、左メニューの葉が`<a>`の中の
	文字に続けてこの札を置くためである（`flex`の行では`flex: 0 0 auto`が効き、
	文字の流れの中では`inline-block`が効く）。**どちらの置き場所でも枠が
	潰れない**ようにする。

	`.elsaTreeItemBadge`は木の行での位置だけを決める（名前の…省略の犠牲に
	しない）。色と形はこのクラスが持つ。

	**ここが持つのは白〜明るい地の上の見せ方（枠囲み）である。** 濃い地
	（PCの左メニュー。地はアプリ色）では枠囲みのコントラストが1.97:1しか
	無く読めないため、`.elsaNavMenu .elsaTrialBadge`が地を警告色で塗って
	文字を導出の対の色へ替える（Issue #4449・一号機裁定2026-10-06）。
	その節は左メニューのCSSと一緒に上の方に在る——置き場所の都合は
	置き場所の節に置き、札の素の形はここ1か所に保つ。
*/
.elsaTrialBadge {
	display: inline-block;
	flex: 0 0 auto;
	box-sizing: border-box;
	margin-left: .5em;
	padding: .19em .35em 0;
	border: 1px solid currentColor;
	border-radius: .25em;
	color: var(--elsa-semantic-danger-color, #b42318);
	font-size: .75em;
	font-weight: normal;
	line-height: 1.15;
	vertical-align: baseline;
	white-space: nowrap;
}

/*
	「閲覧のみ」の札（Issue #4924）。形と色は上の`.elsaTrialBadge`がそのまま持ち、
	ここは置き場所（パンくずのすぐ後ろ）の都合だけを書く。札は理由を出す
	`data-info-hint`を持つので、「包み」の兄弟間隔（`[data-info-hint]`の一般規則）が
	上へ余白を足さないよう0に戻す——パンくずと同じ行に収める。
	形だけは長丸にする（一号機指示2026-10-16。`.elsaTrialBadge`自体は変えず、
	閲覧のみの札だけに効く。色は「注意」の札のまま）。
*/
.elsaViewOnlyBadge {
	margin-top: 0;
	border-radius: 999px;
	cursor: help;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	未読の札（Issue #4479・オーナーがプレビューで確認済み 2026-10-07）

	メニュー名の右横、試用の札の後ろに出す**塗りの丸**。寸法はオーナーの指定を
	そのまま書く（高さ16px・最小幅16px・左右4px・角丸8px・10.5px・太字・中央）。
	試用の札と違って`em`にしないのは、数字の丸は行の文字サイズに合わせて
	伸び縮みさせない指定だからである。

	色は**メインカラー**（地 `--elsa-primary-color`・文字 `--elsa-primary-contrast`）。
	外観設定でメインカラーを変えても、対の文字色は`elsa_app_appearance_root_variables()`
	がメインカラーの明るさから選ぶので読める。新しい色は作らない。

	**0件は出さない。** 札は`hidden`で描かれ（`elsa_unread_badge_html()`）、
	数を入れる`core/js/elsa_unread_badge.js`が1件以上のときだけ外す。
	`display`を書いた規則は`hidden`属性の既定（`display: none`）より強いので、
	下の`[hidden]`の1行で必ず消す——これが無いと0件の空の丸が見え、幅も取る。

	置き場所の位置（木の行で名前の…省略の犠牲にしない）は`.elsaTreeItemBadge`、
	濃い地（PCの左メニュー）での色の反転は`.elsaNavMenu .elsaUnreadBadge`が持つ。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.elsaUnreadBadge {
	display: inline-flex;
	flex: 0 0 auto;
	box-sizing: border-box;
	align-items: center;
	justify-content: center;
	height: 16px;
	min-width: 16px;
	margin-left: .5em;
	padding: 0 4px;
	border-radius: 8px;
	background: var(--elsa-primary-color, #24333f);
	color: var(--elsa-primary-contrast, #ffffff);
	font-size: 10.5px;
	font-weight: 700;
	line-height: 16px;
	text-align: center;
	white-space: nowrap;
}
.elsaUnreadBadge[hidden] { display: none; }

.elsaSettingsButton {
	--elsa-settings-button-size: var(--elsa-block-action-height);
	--elsa-settings-icon-size: 18px;
	display: inline-flex;
	box-sizing: border-box;
	align-items: center;
	justify-content: center;
	width: var(--elsa-settings-button-size);
	min-width: var(--elsa-settings-button-size);
	height: var(--elsa-settings-button-size);
	min-height: var(--elsa-settings-button-size);
}

/*
	歯車・ベルの図像。**寸法の変数には控えを持たせる**（2026-09-03）。
	`--elsa-settings-icon-size`を宣言するのは`.elsaSettingsButton`と
	ラベルタブの規則だけなので、それ以外の場所（右のペインの上部の
	ボタン行に置く共通の図像だけのボタンなど）へ同じ図像を置くと、
	`var()`が解決できず`width`／`height`が`auto`＝**幅0で消えていた。**
	控え（`1em`）は、他の共通図像（`.elsaCommon*Icon`）と同じ既定である。
	**変数を宣言している既存の場所では1pxも変わらない。**
*/
.elsaSettingsIcon {
	display: block;
	width: var(--elsa-settings-icon-size, 1em);
	height: var(--elsa-settings-icon-size, 1em);
	background: currentColor;
	-webkit-mask: var(--elsa-icon-settings) var(--elsa-icon-settings-mask-position, center) / var(--elsa-icon-settings-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-settings) var(--elsa-icon-settings-mask-position, center) / var(--elsa-icon-settings-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

.elsaNotificationIcon {
	display: block;
	width: var(--elsa-settings-icon-size, 1em);
	height: var(--elsa-settings-icon-size, 1em);
	background: currentColor;
	-webkit-mask: var(--elsa-icon-notification) var(--elsa-icon-notification-mask-position, center) / var(--elsa-icon-notification-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-notification) var(--elsa-icon-notification-mask-position, center) / var(--elsa-icon-notification-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

/*
	歯車・？などの操作を連れたラベルタブ。**タブの枠を描くのはこの包み**で、
	中の`p`は枠を持たない（下の規則で消す）。操作を枠の内側へ入れるために、
	枠の持ち主が`p`から包みへ1段上がる形である。

	**高さは枠なしのタブと1pxも違えない**（2026-08-30の利用者指示⑯）。
	枠の持ち主が変わると、高さの数え方も一緒に動いてしまう——

	  * 枠なし … `p`が`min-height: 30px`（border-box）を持ち、枠はその30pxの内側
	  * 包みあり … `p`の30pxはそのままで、包みの枠が**その外側**へ付く → 30.8px

	結果、歯車の付いた行だけがタブの下端で0.8px低くなっていた。**`min-height`を
	包みへ移す**ことで数え方を揃える。包みが30px（border-box）を名乗り、`p`は
	`min-height: 0`にして包みの内側いっぱい（29.2px）へ伸びる。枠なしのタブの
	中身も同じ29.2pxなので、上端・下端・高さの全てが一致する。

	**`p`側へ枠を戻す形では直せない。** 歯車は`p`と並んでこの包みの中に居るので、
	枠を`p`だけに付けるとタブの輪郭から歯車がはみ出す。
*/
.block.elsaFieldRow > .left.elsaFieldHeader,
.elsaFieldLabelTab {
	display: flex;
	align-items: stretch;
	box-sizing: border-box;
	min-height: 30px;
	width: max-content;
	max-width: 100%;
	border: 1px solid var(--elsa-field-control-border-color, #d4d4d4);
	border-bottom: 0;
	border-radius: 5px 5px 0 0;
	background: var(--elsa-field-tab-background-color, #f0f0f0);
	overflow: hidden;
}

.block.elsaFieldRow > .left.elsaFieldHeader p,
.elsaFieldLabelCaption {
	min-width: 0;
	/*  高さは包みが持つ（上の理由）。ここで30pxを名乗ると枠のぶんだけ高くなる。  */
	min-height: 0;
	border: 0;
	border-radius: 0;
}

/*
	ラベルタブの右へ付く操作は、歯車リンクでもCOMMANDブロックのボタンでも同じ見え方にする。
	見た目の正本をこの1か所に置き、片方だけ変わってタブの中で不揃いになるのを防ぐ。

	**`margin-top: 0`はIssue #3707の裸COMMAND一般規則からの保護。** ここは
	キャプション（`<p>`）やヘルプ・設定操作の隣に並ぶ行内の飾りであり、
	兄弟の種類に関わらず縦位置は揃ったままにする。

	**境界線はIssue #3797で`currentColor`から入力欄と同じ枠線色トークンへ
	変えた。** 以前は自分の文字色をそのまま境界に流用していたため、
	ラベルタブの文字色を変えると境界の太さの印象まで一緒に動いていた。
	枠として意味を持つ線は、入力欄・ラベルの枠と同じ変数を見る。
*/
.elsaFieldHeaderAction,
.block.elsaFieldRow > .left.elsaFieldHeader > .elsaCommandBlock {
	flex: 0 0 var(--elsa-settings-button-size);
	margin-top: 0;
	border: 0;
	border-left: 1px solid var(--elsa-field-control-border-color, #d4d4d4);
	border-radius: 0;
	background: var(--elsa-settings-button-background, var(--elsa-field-tab-background-color, #f0f0f0));
	color: var(--elsa-settings-button-color, var(--elsa-field-tab-text-color, #555));
	text-decoration: none;
}

.elsaFieldHeaderAction:focus-visible,
.block.elsaFieldRow > .left.elsaFieldHeader > .elsaCommandBlock:focus-visible {
	outline: 2px solid var(--elsa-primary-color, #24333f);
	outline-offset: -3px;
}

/*
	ラベルタブの中の操作も、押せないときはアプリ共通の無効色にする
	（2026-08-28。以前は`opacity: .55`で、タブの背景色は利用者が選べるため
	実効の明暗差を約束できなかった）。歯車は`<a>`なので`:disabled`を持てず、
	`is-disabled`と`aria-disabled="true"`の両方が付く。COMMANDは`<button>`だが、
	1つ上の規則（0,4,0）が背景を決めているので同じ詳しさで並べる。
*/
.elsaFieldHeaderAction.is-disabled,
.block.elsaFieldRow > .left.elsaFieldHeader > .elsaCommandBlock:disabled,
.block.elsaFieldRow > .left.elsaFieldHeader > .elsaCommandBlock[aria-disabled="true"] {
	background: var(--elsa-button-disabled-bg);
	color: var(--elsa-button-disabled-color);
	opacity: 1;
	cursor: not-allowed;
}

/*
	ラベルタブのヘルプ・歯車・ベル・COMMANDは、**図像をラベルタブの文字サイズと
	同じ大きさ**にする（2026-08-17の利用者指示）。表示設定で「入力欄のラベル」の
	文字サイズを変えると、キャプションの文字と一緒に図像も追従する。

	**固定pxにしないこと。** 固定にすると文字サイズを変えたときにタブの中だけ揃わなくなる。

	操作面（クリック領域）はラベル文字サイズの2倍、図像は1emとする。
	操作面と図像を同じ文字サイズへ連動させ、設定値を変えても中央配置を保つ。
*/
.elsaFieldHeaderAction.elsaSettingsButton,
.elsaFieldHeaderAction.elsaFieldHelpButton,
.elsaFieldHeaderAction.elsaFieldAlertButton,
.block.elsaFieldRow > .left.elsaFieldHeader > .elsaCommandBlock {
	--elsa-field-tab-icon-size: 1em;
	--elsa-settings-icon-size: var(--elsa-field-tab-icon-size);
	--elsa-settings-button-size: calc(var(--elsa-field-tab-font-size, 14px) * 2);
	font-size: var(--elsa-field-tab-font-size, 14px);
	height: var(--elsa-settings-button-size);
	min-height: var(--elsa-settings-button-size);
}

/*
	図像の種類ごとの既定値より、ラベルタブの1つの寸法を必ず優先する。
	新しいラベルタブ操作を追加するときも、この並びへ実際のアイコンクラスを加える。
*/
.elsaFieldHeaderAction > .elsaSettingsIcon,
.elsaFieldHeaderAction > .elsaNotificationIcon,
.elsaFieldHeaderAction > .elsaCommonHelpIcon,
.elsaFieldHeaderAction > .elsaCommonAttentionIcon,
.block.elsaFieldRow > .left.elsaFieldHeader > .elsaCommandBlock > .elsaCommonResetIcon {
	width: var(--elsa-field-tab-icon-size);
	height: var(--elsa-field-tab-icon-size);
}

/*
	help.svgは図形の下側に点があるため、枠の数学的な中央だけでは文字より低く見える。
	ラベル文字サイズに比例して図像だけをわずかに上げ、歯車など他の操作の位置は変えない。
*/
.elsaFieldHeaderAction > .elsaCommonHelpIcon {
	transform: translateY(-0.0625em);
}

.elsaFieldHelpButton,
.elsaFieldAlertButton {
	display: inline-flex;
	box-sizing: border-box;
	align-items: center;
	justify-content: center;
	width: var(--elsa-settings-button-size);
	min-width: var(--elsa-settings-button-size);
	padding: 0;
	font-family: inherit;
	font-weight: inherit;
	line-height: 1;
	cursor: pointer;
}

/*
	ラベルタブの「!」（Issue #5141・オーナー決定2026-10-18）。升・図像の寸法は上の
	「?」・歯車と同じ規則が持ち、ここは色だけ。**色は外観設定の警告色のトークン**
	（`--elsa-semantic-danger-color`、`elsa_app_appearance_css_variables()`の`danger_color`）
	で、固定色を書かない。外観設定で警告色を変えると「!」も一緒に変わる。
	ホバーは他の操作と同じ規則（`@media (hover: hover)`の中）が地と字を入れ替える。
*/
.elsaFieldHeaderAction.elsaFieldAlertButton {
	color: var(--elsa-semantic-danger-color, #b42318);
}

/* .buttonと.elsaCommandBlockが持つ余白・最小幅・角丸を、タブの中では打ち消す。 */
.block.elsaFieldRow > .left.elsaFieldHeader > .elsaCommandBlock {
	display: inline-flex;
	box-sizing: border-box;
	align-items: center;
	justify-content: center;
	width: var(--elsa-settings-button-size);
	min-width: var(--elsa-settings-button-size);
	height: var(--elsa-settings-button-size);
	min-height: var(--elsa-settings-button-size);
	margin: 0;
	padding: 0;
	font-family: inherit;
	font-weight: inherit;
	line-height: 1;
	cursor: pointer;
}

@media (hover: hover) {
	.elsaFieldHeaderAction:not(.is-disabled):hover,
	.block.elsaFieldRow > .left.elsaFieldHeader > .elsaCommandBlock:not(:disabled):not(:where([aria-disabled="true"])):hover {
		background: var(--elsa-primary-color, #24333f);
		color: var(--elsa-primary-contrast, #fff);
	}
}

/*
	リセットは共通のcanonical reset.svgをmaskで着色する。
	図像の寸法は既定で`1em`＝そのボタンの文字サイズ。ラベルタブでは上の規則が
	`--elsa-settings-icon-size: 1em`とタブの文字サイズを与えるため、ラベルの文字と
	同じ大きさになり、表示設定の文字サイズ変更へそのまま追従する（2026-08-14の利用者指示）。
	**固定pxを書かないこと。** 書くと文字サイズを変えたときに追従しなくなる。
*/
.elsaCommonResetIcon {
	display: block;
	width: var(--elsa-settings-icon-size, 1em);
	height: var(--elsa-settings-icon-size, 1em);
	background: currentColor;
	-webkit-mask: var(--elsa-icon-reset) var(--elsa-icon-reset-mask-position, center) / var(--elsa-icon-reset-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-reset) var(--elsa-icon-reset-mask-position, center) / var(--elsa-icon-reset-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	flex: 0 0 auto;
}

/*
	上矢印。文書保存の「1つ上へ」が使う（2026-08-29の利用者指示「『1つ上へ』
	ボタンは文字でなくSVG共通アイコンの上矢印で」）。図形は共通の`arrow-up.svg`で、
	寸法と色はRESETの印と同じ流儀（`currentColor`のmask）にそろえる。
*/
.elsaCommonArrowUpIcon {
	display: block;
	width: var(--elsa-settings-icon-size, 1em);
	height: var(--elsa-settings-icon-size, 1em);
	background: currentColor;
	-webkit-mask: var(--elsa-icon-arrow-up) var(--elsa-icon-arrow-up-mask-position, center) / var(--elsa-icon-arrow-up-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-arrow-up) var(--elsa-icon-arrow-up-mask-position, center) / var(--elsa-icon-arrow-up-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	flex: 0 0 auto;
}

/*
	左右の矢印（2026-09-03）。図像だけのボタンの中身として、上矢印と同じ流儀で
	共通の`arrow-left.svg`／`arrow-right.svg`をmaskで着色する。カレンダーの月送り
	（右のペインの上部のボタン行）が最初の利用者である。**画面ごとに同じmask規則を
	書き直さない**——それをやっていた結果、同じ矢印の寸法と色の決め方が
	`elsa_calendar.css`・`elsa_chat.css`・`elsa_communication_space.css`で
	それぞれ別に育っていた。
*/
.elsaCommonArrowLeftIcon,
.elsaCommonArrowRightIcon {
	display: block;
	width: var(--elsa-settings-icon-size, 1em);
	height: var(--elsa-settings-icon-size, 1em);
	background: currentColor;
	flex: 0 0 auto;
}

.elsaCommonArrowLeftIcon {
	-webkit-mask: var(--elsa-icon-arrow-left) var(--elsa-icon-arrow-left-mask-position, center) / var(--elsa-icon-arrow-left-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-arrow-left) var(--elsa-icon-arrow-left-mask-position, center) / var(--elsa-icon-arrow-left-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

.elsaCommonArrowRightIcon {
	-webkit-mask: var(--elsa-icon-arrow-right) var(--elsa-icon-arrow-right-mask-position, center) / var(--elsa-icon-arrow-right-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-arrow-right) var(--elsa-icon-arrow-right-mask-position, center) / var(--elsa-icon-arrow-right-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

/*
	指で引いて運んでいる間（`core/js/elsa_touch_drag.js`）。**文字を選ばせず、
	画面も送らない。** 指の下の景色が動くと落とし場所を狙えない。
*/
.is-elsaTouchDragging,
.is-elsaTouchDragging * {
	user-select: none !important;
	-webkit-user-select: none !important;
}

.is-elsaTouchDragging { touch-action: none; }

/*
	運べるものは指でも掴める。**長押しの間に画面が送られない**ようにしておかないと、
	掴んだつもりの指で一覧だけが動く。
*/
[draggable="true"] { touch-action: pan-y; }

/*
	ダウンロード。文書保存の帯のダウンロードが使う（2026-08-29の利用者指示）。
	図形はLIST行のダウンロードと同じ共通の`download.svg`である。
*/
.elsaCommonDownloadIcon {
	display: block;
	width: var(--elsa-settings-icon-size, 1em);
	height: var(--elsa-settings-icon-size, 1em);
	background: currentColor;
	-webkit-mask: var(--elsa-icon-download) var(--elsa-icon-download-mask-position, center) / var(--elsa-icon-download-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-download) var(--elsa-icon-download-mask-position, center) / var(--elsa-icon-download-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	flex: 0 0 auto;
}

/*
	文書に＋。文書保存の「新しい文書」が使う（2026-08-29の利用者指示）。
	＋の位置と線の太さはfolder-plusとそろえてある。
*/
.elsaCommonDocumentPlusIcon {
	display: block;
	width: var(--elsa-settings-icon-size, 1em);
	height: var(--elsa-settings-icon-size, 1em);
	background: currentColor;
	-webkit-mask: var(--elsa-icon-document-plus) var(--elsa-icon-document-plus-mask-position, center) / var(--elsa-icon-document-plus-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-document-plus) var(--elsa-icon-document-plus-mask-position, center) / var(--elsa-icon-document-plus-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	flex: 0 0 auto;
}

/*
	フォルダに＋。文書保存の「新しいフォルダ」が使う（2026-08-29の利用者指示）。
*/
.elsaCommonFolderPlusIcon {
	display: block;
	width: var(--elsa-settings-icon-size, 1em);
	height: var(--elsa-settings-icon-size, 1em);
	background: currentColor;
	-webkit-mask: var(--elsa-icon-folder-plus) var(--elsa-icon-folder-plus-mask-position, center) / var(--elsa-icon-folder-plus-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-folder-plus) var(--elsa-icon-folder-plus-mask-position, center) / var(--elsa-icon-folder-plus-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	flex: 0 0 auto;
}

/*
	文書・帳票。Amazon Vendor Centralの出荷作業「帳票を発行」が使う（Issue #3483）。
	図形はLIST行の「規程とマニュアル」と同じ共通の`document.svg`である。
*/
.elsaCommonDocumentIcon {
	display: block;
	width: var(--elsa-settings-icon-size, 1em);
	height: var(--elsa-settings-icon-size, 1em);
	background: currentColor;
	-webkit-mask: var(--elsa-icon-document) var(--elsa-icon-document-mask-position, center) / var(--elsa-icon-document-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-document) var(--elsa-icon-document-mask-position, center) / var(--elsa-icon-document-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	flex: 0 0 auto;
}

/*
	上矢印＋受け皿（取込・アップロード）。Amazon Vendor Centralの出荷作業
	「出荷後CSVの取込」が使う（Issue #3483）。図形はLIST行の「適用」と同じ
	共通の`apply.svg`である。
*/
.elsaCommonApplyIcon {
	display: block;
	width: var(--elsa-settings-icon-size, 1em);
	height: var(--elsa-settings-icon-size, 1em);
	background: currentColor;
	-webkit-mask: var(--elsa-icon-apply) var(--elsa-icon-apply-mask-position, center) / var(--elsa-icon-apply-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-apply) var(--elsa-icon-apply-mask-position, center) / var(--elsa-icon-apply-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	flex: 0 0 auto;
}

/*
	サーバー（拠点）。総合コストの帯「サーバー管理」が使う（Issue #3493の配信後QA）。
	図像はサーバー管理（Fleet）に対応する新規の共通`server.svg`である。
*/
.elsaCommonServerIcon {
	display: block;
	width: var(--elsa-settings-icon-size, 1em);
	height: var(--elsa-settings-icon-size, 1em);
	background: currentColor;
	-webkit-mask: var(--elsa-icon-server) var(--elsa-icon-server-mask-position, center) / var(--elsa-icon-server-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-server) var(--elsa-icon-server-mask-position, center) / var(--elsa-icon-server-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	flex: 0 0 auto;
}

/*
	紙飛行機（送る）。文書保存のボタンエリアの「回覧に回す」が使う（Issue #4486）。
	図像は既存の共通`paper-plane.svg`で、サーバーと同じ描き方にする。
*/
.elsaCommonPaperPlaneIcon {
	display: block;
	width: var(--elsa-settings-icon-size, 1em);
	height: var(--elsa-settings-icon-size, 1em);
	background: currentColor;
	-webkit-mask: var(--elsa-icon-paper-plane) var(--elsa-icon-paper-plane-mask-position, center) / var(--elsa-icon-paper-plane-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-paper-plane) var(--elsa-icon-paper-plane-mask-position, center) / var(--elsa-icon-paper-plane-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	flex: 0 0 auto;
}

/*
	図像だけのCOMMANDは**共通の操作部品の当たり面**（28px四方）を持つ。文字が
	無いぶん押す場所が小さくなるので、寸法を共通トークンから受け取る。
*/
.elsaCommandBlock--iconOnly {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	width: var(--elsa-block-action-height);
	min-width: var(--elsa-block-action-height);
	height: var(--elsa-block-action-height);
	min-height: var(--elsa-block-action-height);
	padding: 0;
}

/*
	**左右の余白を打ち消すのは`.button`より後でなければ効かない**（2026-09-03）。
	すぐ上の`padding: 0`は`.button`（このファイルのずっと下で`padding: 0 15px`を
	名乗る）と同じ詳しさなので、後に書かれている`.button`が勝っていた。
	`box-sizing: border-box`の要素は、指定した幅より左右の余白の合計が大きいと
	**余白の合計が実効の幅になる**ため、28px角のつもりの図像ボタンが実際には
	30px幅で描かれていた（文書保存・電子帳簿などの上部のボタン行の全部）。
	クラスを2つ並べて詳しさを上げ、宣言どおり28px角にする。
*/
.button.elsaCommandBlock--iconOnly { padding: 0; }

/*
	図像の余白を確かめる共通の診断表示。mask自身へ背景を塗ると余白まで切り抜かれるため、
	操作面の背景レイヤーを図像の箱だけに限定する。面・図像の寸法と描き方は変えない。
	注意色の半透明では無効色やテーマ色に近づくため、実効currentColorの明度から
	無彩色の明度95/10を選ぶ。境界50でも3:1以上の余裕を持ち、hover・無効時も
	CSSだけで追従する。currentColorの既定は共通ボタン側を正本とする。
*/
.button.elsaCommandBlock.elsaCommandBlock--iconOnly.elsaCommonIconBackground {
	background-image: linear-gradient(lab(from currentColor calc(95 - round(up, l - 50, 100) * 0.85) 0 0 / 1), lab(from currentColor calc(95 - round(up, l - 50, 100) * 0.85) 0 0 / 1));
	background-size: var(--elsa-block-action-icon-size) var(--elsa-block-action-icon-size);
	background-position: center;
	background-repeat: no-repeat;
}

/*
	**図像だけの共通ボタンの図像は、帯・一覧の図像と同じ大きさ**にする（2026-09-03に
	入った`--elsa-block-action-icon-size`＝操作面28pxに対する比）。

	同じ決定は同じ日に共通の一覧ツールバー（`.elsaExplorerListToolbarAction`、
	`core/css/elsa_app_explorer.css`）へ入っているが、**あちらは一覧の道具だけを
	名指ししている。** 帯へ載るのは一覧の道具だけではない（カレンダーの月送り・
	通知・追加・設定が同じ日に載った）ので、ここでは**「図像だけの共通ボタン」という
	条件で同じ値を配る。** 一覧の道具は両方に当たるが、値が同じなので見た目は
	1pxも変わらない。

	**名前を持つボタンは対象外**——文字の隣に並ぶ図像は文字の大きさに従うほうが
	揃って見える（あちらと同じ判断）。
*/
.elsaCommandBlock--iconOnly > .elsaCommonArrowUpIcon,
.elsaCommandBlock--iconOnly > .elsaCommonArrowLeftIcon,
.elsaCommandBlock--iconOnly > .elsaCommonArrowRightIcon,
.elsaCommandBlock--iconOnly > .elsaCommonPlusIcon,
.elsaCommandBlock--iconOnly > .elsaCommonFolderPlusIcon,
.elsaCommandBlock--iconOnly > .elsaCommonDocumentPlusIcon,
.elsaCommandBlock--iconOnly > .elsaCommonDownloadIcon,
.elsaCommandBlock--iconOnly > .elsaCommonDeleteIcon,
.elsaCommandBlock--iconOnly > .elsaCommonResetIcon,
.elsaCommandBlock--iconOnly > .elsaCommonSaveIcon,
.elsaCommandBlock--iconOnly > .elsaCommonDocumentIcon,
.elsaCommandBlock--iconOnly > .elsaCommonApplyIcon,
.elsaCommandBlock--iconOnly > .elsaCommonServerIcon,
.elsaCommandBlock--iconOnly > .elsaCommonPaperPlaneIcon,
.elsaCommandBlock--iconOnly > .elsaCommonRevokeIcon,
.elsaCommandBlock--iconOnly > .elsaCommonBanIcon,
.elsaCommandBlock--iconOnly > .elsaCommonRunIcon,
.elsaCommandBlock--iconOnly > .elsaCommonCloseIcon,
.elsaCommandBlock--iconOnly > .elsaCommonConfirmIcon,
.elsaCommandBlock--iconOnly > .elsaCommonCopyIcon,
/*  Issue #4350: 通知の「後で知らせる」（通知なしの図像）。「消す」は上の閉じる図像をそのまま使う。  */
.elsaCommandBlock--iconOnly > .elsaCommonNotificationOffIcon,
.elsaCommandBlock--iconOnly > .elsaCommonPrintIcon,
.elsaCommandBlock--iconOnly > .elsaSettingsIcon,
.elsaCommandBlock--iconOnly > .elsaListColumnFilterIcon,
.elsaCommandBlock--iconOnly > .elsaNotificationIcon {
	width: var(--elsa-block-action-icon-size);
	height: var(--elsa-block-action-icon-size);
}

/* 文字と並ぶときだけ字間を空ける。寸法は上の1.2emがそのまま効く。 */
.elsaCommandBlock--icon:not(.elsaCommandBlock--iconOnly) {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
}

.block.elsaFieldRow > .right {
	display: flex;
	width: 100%;
	min-width: 0;
	min-height: var(--elsa-form-control-height);
	/*
		Issue #3852 段階2c。`.block .right`（共通既定）が持つ`align-items: center`に
		頼らず、この行自身にも明示する——STATUSブロック等がここへ縦積みされる箱の
		中央寄せは、より詳しいこのセレクタが1件でも上書きしたら消える。
	*/
	align-items: center;
	/*
		ここはFIELDブロックを置くための器で、入力面ではない。必須・変更不可の面色は
		`--elsa-field-state-background`を読む各ブロック自身が描く。器まで塗ると、
		SELECTORの候補状態文のように入力欄より下へ伸びる子があると、空いた部分が
		入力枠からはみ出した帯に見える（2026-09-07、Issue #3277）。
	*/
	background: transparent;
}

.elsaFieldControlGroup { display: flex; align-items: stretch; width: 100%; min-width: 0; }
.elsaFieldControl { display: flex; flex: 1 1 auto; min-width: 0; }
.elsaFieldControl > input,
.elsaFieldControl > select,
.elsaFieldControl > textarea { width: 100%; }
/*
	欄の単位（例: リマインダーの「日前」）。placeholderだけに頼ると、既定値が
	入っている間は説明が隠れて意味が伝わらない（Issue #3480・利用者指摘）。
	`<input>`の隣へ常時表示の文字として置き、入力の状態に関わらず出続ける。
*/
.elsaFieldControl:has(.elsaTextUnit) > input { flex: 1 1 auto; width: auto; min-width: 0; }
.elsaTextUnit { flex: 0 0 auto; align-self: center; margin-left: .5em; white-space: nowrap; }
/*
	見積の読込（Issue #3812。オーナー決定）。検索欄とボタンを1組として
	横並びにする器に`--trailing`修飾を持たせ、その内側のCOMMANDだけへ
	隙間とボタン寸法の例外を当てる。無印の`.elsaFieldControlGroup`
	（複数選択の選択済み行、core/js/elsa_selector.js 79行）はこの規則の
	対象外のまま変わらない——あちらの削除ボタンは`.elsaCommandBlock`を
	持たないため、そもそも影響しない。

	**ボタンの高さは検索欄と同じ（`--elsa-form-control-height`）——
	ボタン寸法規則（28px、docs/architecture.md「操作アイコン・操作面」の節）の
	例外としてオーナーが個別に認めた1件である（docs/architecture.md「通常の
	アクションボタン」の節に追記）。角丸は結合を表す片側フラットをやめ、
	通常の丸みへ戻す。

	**`--elsa-field-control-border-radius`は使わない。** このトークンは
	`.block.elsaFieldRow`が`0 4px 4px 4px`（ラベルタブに接する左上だけ
	角を落とす値）で定義しており、CSS変数は継承するため、この器の中で
	同名を使うとボタンも左上が角張る。ボタンはラベルに接しない独立した
	部品なので、`.button`の既定`border-radius: 4px`をそのまま使う
	（打ち消す指定を書かない）。

	**`font-size`を検索欄と同じ`--elsa-form-font-size`へ合わせる。**
	`--elsa-form-control-height`は`em`基準の式（`calc(2em + ...)`）なので、
	`var()`は使う場所の文字サイズで再計算される。`.button`の既定文字サイズ
	（`--elsa-button-font-size`、14px）のまま高さだけ入力欄の値へ合わせると、
	同じ変数でも入力欄（16px基準・40px）とボタン（14px基準・36px）で
	計算結果が食い違う（2026-09-19、実機Playwright実測で発覚）。
*/
.elsaFieldControlGroup--trailing { column-gap: var(--elsa-block-spacing, 8px); }
.elsaFieldControlGroup--trailing > .elsaCommandBlock {
	flex: 0 0 auto;
	min-width: 72px;
	margin: 0;
	font-size: var(--elsa-form-font-size, 16px);
	height: var(--elsa-form-control-height);
	min-height: var(--elsa-form-control-height);
}
/*
	**縦の隙間はこの器が持たない**（Issue #3489 段階2・第2回。Issue #3799で
	`.elsaTabPanel`から`gap`を外したのと同じ直し）。以前は`gap`が縦横とも
	`--elsa-block-spacing`を持ち、その二重計上を避けるために直下の`.block`の
	`padding-top`を0へ戻していた。ところが見出し（LINE）は自分の規則で
	`--elsa-line-top-spacing`を`padding-top`として持つため、その0戻しの
	対象外で、**器のrow-gapと見出しの上部隙間が足し算になっていた**
	（外観設定の9本の見出しで実測16px。同じ見出しをポップアップで描くと8px）。

	`row-gap`を0にして、縦の隙間の出どころを共通の一般規則
	（`:where(…) + .block` の`padding-top`）へ一本化する。直下の子はどれも
	`grid-column: 1 / -1`（下の行）で1行に1つなので、横方向の`column-gap`だけ
	残せば見た目は変わらない。
*/
.elsaAppSettingForm {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	column-gap: var(--elsa-block-spacing, 8px);
	row-gap: 0;
	width: 100%;
}
.elsaAppSettingForm[hidden] { display: none; }
/*
	リセットボタンは「押しても何も変わらない項目」でhiddenになる。
	**ブラウザ既定の`[hidden]{display:none}`だけでは消えない。** ラベルタブの
	中のCOMMANDブロックも図像付きのCOMMANDブロックも、上でdisplayを明示して
	いるため詳細度で勝ってしまう。
	一括リセットは行ごと消す。ボタンだけ消すと、gridの1行ぶんの隙間が残る。
*/
.elsaAppSettingForm .block.elsaFieldRow > .left.elsaFieldHeader > .elsaCommandBlock[hidden],
.elsaAppSettingForm > .elsaAppSettingResetAll > .right > .elsaCommandBlock[hidden] { display: none; }
.elsaAppSettingForm > .elsaAppSettingResetAll:has(> .right > .elsaCommandBlock[hidden]) { display: none; }
.elsaController [data-app-setting-reset-all][hidden] { display: none; }
/*
	直下の`.block`の`padding-top`を0へ戻す規則は、上の`row-gap: 0`と一緒に
	撤去した（Issue #3489 段階2・第2回）。器が縦の隙間を持たなくなったので、
	戻す相手がもう無い——残すと、この器の中だけ縦の隙間が消える。
*/
.elsaAppSettingForm > .elsaFieldRow { grid-column: 1 / -1; }
.elsaAppSettingForm > .elsaLineRow,
.elsaAppSettingForm > .elsaAppSettingResetAll,
.elsaAppSettingForm > .elsaAppSettingAdoptCurrent { grid-column: 1 / -1; }
.elsaAppSettingForm > .elsaFieldRow--span-2 { grid-column: span 2; }
.elsaAppSettingForm > .elsaFieldRow--span-3 { grid-column: span 3; }
.elsaAppSettingForm > .elsaFieldRow--span-6 { grid-column: span 6; }

/*
	取引先名+敬称は共通の対（`.block.elsaFieldRow--pair`）が横並びを組むため、
	`.elsaCustomerEditor`自身はもう2列を持たない（Issue #3810。以前の
	`.elsaCustomerNameField`／`.elsaCustomerHonorificField`と、運送設定タブの
	中だけ列を組み直していた`.elsaTabPanel[data-elsa-tab-panel="customer"]`の
	上書きは、対を共通化したことで両方不要になった）。
*/
.elsaCustomerEditor {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--elsa-block-spacing, 8px);
	width: 100%;
}
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	**行の間隔はGridの`gap`だけが作る**（2026-08-30。⑯）

	`.elsaCustomerEditor`はGridなので、行と行のあいだは`gap`が空ける。ところが
	共通の縦積みの規則（`.block + .block { padding-top: … }`）もここへ効いており、
	詳細度で負けた行だけが余分に押し下げられる。**全ての行を同じ名札
	（`elsaCustomerFullField`）へ揃えることで、詳細度の食い違いを起こさない。**

	**入れ物の側から`.elsaCustomerEditor > .block`と書いてはいけない。** それは
	外の祖先からブロックのルートを装飾することであり、共通の規則に反する
	（`docs/architecture.md`・`tests/field_block_style_test.php`が落とす）。
	2026-08-30、いちどその形で書いて検査に捕まった。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.block.elsaCustomerFullField { grid-column: 1 / -1; padding-top: 0; }
@media (max-width: 640px) {
	.elsaAppSettingForm { grid-template-columns: minmax(0, 1fr); }
	.elsaAppSettingForm > .elsaFieldRow--span-2,
	.elsaAppSettingForm > .elsaFieldRow--span-3,
	.elsaAppSettingForm > .elsaFieldRow--span-6 { grid-column: 1; }
	.elsaFieldControlGroup--trailing > .elsaCommandBlock { min-width: 80px; }
}

.block.elsaEditListSpacing + .block.elsaEditListSpacing {
	margin-top: var(--elsa-block-spacing, 8px);
}

@media (max-width: 670px) {
	.block.elsaFieldRow {
		--elsa-field-control-border-radius: 0 0 4px 4px;
		max-width: 100%;
	}

	.block.elsaFieldRow > .left,
	.block.elsaFieldRow > .left p {
		box-sizing: border-box;
		width: 100%;
		max-width: 100%;
	}

	/*
		Issue #4571: 歯車・？を連れた見出しも、ほかの見出しと同じく幅いっぱいの帯に
		する。上の`.block.elsaFieldRow > .left`（詳細度(0,3,0)）の`width: 100%`は、
		包みの`width: max-content`（`.block.elsaFieldRow > .left.elsaFieldHeader`、
		(0,4,0)）に負けていたため、狭い画面で「?」付きの見出しだけが短いタブの
		まま残り、「?」が見出しと別の箱に見えていた。ここで同じ詳細度で幅を戻す。
	*/
	.block.elsaFieldRow > .left.elsaFieldHeader {
		display: flex;
		width: 100%;
	}

	.block.elsaFieldRow > .left.elsaFieldHeader p {
		width: auto;
		flex: 1 1 auto;
	}

	.block.elsaFieldRow--file {
		width: min(100%, var(--elsa-field-row-width, 200px));
	}
}

/* TEXTの外観は配置先ではなく、ブロック自身のクラスだけで決定する。 */

.elsaText {
	width: 100%;
	min-height: var(--elsa-form-control-height);
	padding: var(--elsa-form-control-padding-block) var(--elsa-form-control-padding-inline);
	border: var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius: var(--elsa-field-control-border-radius, 4px);
	color: inherit;
	font-size: 1em;
	line-height: var(--elsa-form-control-line-height);
	background: var(--elsa-field-state-background, #fff);
}

/* 高さの固定は単一行だけに適用し、textareaのrowsを妨げない。 */

input.elsaText {
	height: var(--elsa-form-control-height);
}

/* 帯の入力欄も、配置先ではなくTEXT自身が共通の操作高さへそろえる。 */
.elsaText--band {
	min-height: var(--elsa-pane-window-band-control-height);
	font-size: var(--elsa-band-font-size, 16px);
}

input.elsaText--band,
.elsaText--band.elsaTextReadonly {
	height: var(--elsa-pane-window-band-control-height);
}

textarea.elsaText {
	resize: vertical;
}

/*
	Issue #4635（2026-10-10、オーナー報告、iPhone）: 入力中の欄に付く枠線の
	上の辺がラベルの段に隠れていた。枠線は入力欄の外側に描かれ、すぐ上の
	ラベルの段（`.block.elsaFieldRow > .left`、`position: relative`）は
	位置指定の無い入力欄のoutlineより手前に塗られるためである。
	**枠線を入力欄の内側へ描く。** 色・太さ・線種はブラウザ既定のまま変えず、
	位置だけを2px内へ寄せる（一覧の検索欄`.elsaListSearchBox`と同じ値）。
	内側なら、ラベルの重なりにも、祖先の`overflow: hidden`にも左右されない。

	画面ごと・ブロックごとに書き足さない。ラベルの付く入力欄はここ1か所で受ける
	（1行・複数行・数値・日付などのTEXT、選択と候補入力の`.elsaSelectorSuggestInput`、
	FIELDの器へ直接置かれた`input`／`select`）。TREEの引き金は自前の線を持つので、
	その規則の側で同じ値にしてある。
	`tests/field_focus_ring_visible_browser_test.js`が375px・1280pxで実測する。
*/
.elsaText:focus-visible,
.elsaFieldControl > input:focus-visible,
.elsaFieldControl > select:focus-visible,
.elsaSelectorSuggestInput:focus-visible {
	outline-offset: -2px;
}

/*
	読み取り専用のTEXTは実テキスト要素（`<output>`）で描く。**入力欄と外観を1pxも
	変えない。** 寸法・余白・枠・背景・行高は上の`.elsaText`をそのまま使い、ここでは
	`<input>`のブラウザ既定のうちテキスト要素に無いものだけを補う。

	- `display: block`。`<input>`と同じ`inline-block`にすると、あふれを隠した
	  インラインブロックのベースラインが下マージン端へ移り、LISTのセルで行が
	  1行あたり6px高くなる。`block`なら行boxが生まれず、行高は入力欄と同じになる。
	  1行の`<input>`はベースラインが自分の中にあるため、通常のブロック容器でも
	  `block`と同じ高さになる（実測で確認済み）。
	- `white-space: pre`。`<input>`は折り返さず、連続する空白もそのまま見せる。
	- `overflow: hidden`。`<input>`は入りきらない値を枠で切る。
	- `text-align: start`。`<input>`はブラウザ既定でこの値を持ち、寄せを指定した
	  容器の中でも変わらない。テキスト要素は継承するため明示して同じにする。
*/

.elsaTextReadonly {
	display: block;
	height: var(--elsa-form-control-height);
	white-space: pre;
	overflow: hidden;
	text-align: start;
}

/*
	数字の欄の寄せの正本はここ1か所（2026-10-17のオーナー決定、Issue #5088）。

	- **表（一覧・明細）の数字の列は右寄せ**＋桁が縦にそろう字形（2026-08-28の
	  利用者決定、Issue #2169）。上下の行で桁を見比べるためである。
	- **欄が1つずつ縦に並ぶフォーム・カードの数字の欄（価格・数量・在庫など）は
	  左寄せ。** 見比べる相手が上下に無く、見出しの直後（左端）から読み始めるため、
	  右へ寄せると視線が欄の幅だけ横へ飛ぶ。左はTEXTの既定（`<input>`の
	  `text-align: start`と上の`.elsaTextReadonly`）のままにし、ここでは足さない。

	「表の中かどうか」は**下の`data-align="number"`の有無だけで決まる。** この印を
	付けるのは表のセルとして描くTEXTだけで（LISTの数値列のセル＝`list.php`が
	`option.align`を渡す。判定は`core/php/function/list_column_align.php`。明細の表の
	数量・単価など＝`sales_document_lines`が`option.table_cell`と一緒に渡す）、
	フォーム・カードに描くTEXTには付かない（TEXTが`text.php`で閉じる）。画面のCSSで数字の欄を右へ寄せない
	（以前の`elsa_sku.css`の`input.elsaText.elsaSkuValue`の右寄せは消した）。
	`tests/all_screens_render_crawl_browser_test.js`が全画面のcomputed styleで固定する。

	**印はTEXT自身が持つ。** 一覧の数値セルは`<td>`側でも右へ寄せているが、
	`<input>`はブラウザ既定の`text-align: start`を持ち、容器の寄せを継承しない。
	置き場所（LISTのセル）から`.elsaText`を装飾すると`docs/architecture.md`
	「外部の祖先セレクタから子ブロックを装飾しない」に反するため、LISTは
	`option.align`でこの属性を渡すだけにし、寄せの実体はここが持つ。

	詳細度は`.elsaTextReadonly`（`text-align: start`）と`input.elsaText`より
	高いので、読み取り専用でも入力欄でも同じ寄せになる。

	**枠は付けない**（2026-08-28の利用者決定「一覧内の編集欄への枠付与は不採用」）。
	ここで変えるのは寄せと数字の字形だけである。
*/
.elsaText[data-align="number"] {
	text-align: right;
	font-variant-numeric: tabular-nums;
}

/*
	複数行（textarea）の読み取り専用。高さは`rows`と同じ「行数 × 行高」で決め、
	折り返しと縦の伸縮もtextareaへ合わせる。

	`inline-block`にするのは、`<textarea>`のベースラインが下マージン端にあり、
	通常のブロック容器では行boxの下に文字の下ぶんの隙間が付くためである。
	`block`にするとその隙間が消え、容器が7px縮む。
*/

.elsaTextReadonly--multiline {
	display: inline-block;
	height: calc(var(--elsa-text-readonly-rows, 2) * var(--elsa-form-control-line-height) * 1em + var(--elsa-form-control-padding-block) + var(--elsa-form-control-padding-block) + var(--elsa-form-control-border-width) + var(--elsa-form-control-border-width));
	white-space: pre-wrap;
	overflow-wrap: break-word;
	overflow: auto;
	resize: vertical;
}

/*
	単一行の読み取り専用TEXTのopt-in折り返し（`option.wrap`、Issue #4393）。
	SHA-256のような64文字の固定長の値は、既定の「枠で切る」ままだと375pxの画面幅
	で読めなくなる。**一覧のセルの既存規則（`.elsaTextReadonly[data-list-field="true"]`）
	と同じ3つの値にそろえる**——折り返しの見え方を場所ごとに作り分けない。

	高さは`auto`にして行数ぶん伸ばす。1行に収まる値の高さは`.elsaText`の
	`min-height`が入力欄と同じに保つ（上のセルの規則と同じ理由）。
*/
.elsaTextReadonly--wrap {
	height: auto;
	white-space: pre-wrap;
	overflow-wrap: anywhere;
}

.elsaSelectorSuggest {
	position: relative;
	width: 100%;
}

.elsaSelectorSuggestInput {
	width: 100%;
}

/*
	選択モードの可視部品はbutton（Issue #4051）。**新しい色・枠は作らない。**
	UA既定のbutton装飾（枠・地色・中央寄せ）だけを消し、直後の共通規則
	（`.elsaSelectorField, .elsaSelectorSuggestInput`）が入力欄と同じ寸法・枠・
	フォントを両方へ当てる。
*/
.elsaSelectorSuggestButton {
	appearance: none;
	-webkit-appearance: none;
	overflow: hidden;
	text-align: start;
	text-overflow: ellipsis;
	white-space: nowrap;
	cursor: pointer;
}

/*
	**無効なSELECTORの文字色は、無効なTEXTと同じにする（どちらも地のまま）。**
	2026-10-06に一度`--elsa-button-disabled-color`を当てたが、LISTの外にある
	無効なSELECTOR（編集フォームなど）だけが灰色になり、隣の無効なTEXTは地の色の
	ままで、**同じ意味の欄が2つの見た目になった**（一号機の判断 2026-10-06。
	「同じ意味は同じ見た目」）。灰色にそろえるなら、無効なTEXTも同じ共通トークンへ
	一緒に寄せる変更が要る——片方だけ灰色にしない。

	押せない理由は`title`（可視部品にも乗る。`core/php/blocks/selector/selector.php`）
	がマウスオーバーに出す。
*/
.elsaSelectorSuggestButton:disabled {
	cursor: default;
}

.elsaSelectorField,
.elsaSelectorSuggestInput {
	width: 100%;
	height: var(--elsa-form-control-height);
	min-height: var(--elsa-form-control-height);
	padding: var(--elsa-form-control-padding-block) var(--elsa-form-control-padding-inline);
	border: var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius: var(--elsa-field-control-border-radius, 4px);
	color: inherit;
	font: inherit;
	line-height: var(--elsa-form-control-line-height);
	background: var(--elsa-field-state-background, #fff);
}

.elsaSelectorField[multiple] {
	height: auto;
	min-height: calc(var(--elsa-form-control-height) + var(--elsa-form-control-height) + var(--elsa-form-control-height));
}

.elsaSelectorSuggestSelections {
	display: grid;
	gap: 0;
	width: 100%;
	margin: 0;
}

/*
	複数SUGGESTは、選択済み項目を1件ずつ全幅の読み取り専用TEXTで積み上げ、
	末尾の追加入力を常に独立した全幅行として描画する。削除は各TEXT右端の
	共通close操作へ統一し、画面別のchip/TEXT分岐を持たない。
	保存値・選択順・changeイベントは表示方法から独立した従来契約を維持する。
*/
.elsaSelectorSuggest[data-multiple="true"] {
	display: block;
	min-height: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: transparent;
}

.elsaSelectorSuggest[data-multiple="true"] .elsaSelectorSuggestTextRow {
	margin: 0;
}

.elsaSelectorSuggest[data-multiple="true"] .elsaSelectorSuggestTextRow + .elsaSelectorSuggestTextRow {
	margin-top: calc(-1 * var(--elsa-form-control-border-width));
}

.elsaSelectorSuggest[data-multiple="true"] .elsaFieldControl {
	position: relative;
}

.elsaSelectorSuggest[data-multiple="true"] .elsaSelectorSuggestSelectionText {
	width: 100%;
	padding-right: calc(var(--elsa-block-action-height) + 10px);
	border-radius: 0;
}

.elsaSelectorSuggest[data-multiple="true"] .elsaSelectorSuggestTextRow:first-child .elsaSelectorSuggestSelectionText {
	border-radius: 0 4px 0 0;
}

.elsaSelectorSuggest[data-multiple="true"] .elsaSelectorSuggestInput {
	width: 100%;
	height: var(--elsa-form-control-height);
	min-height: var(--elsa-form-control-height);
	margin-top: calc(-1 * var(--elsa-form-control-border-width));
	padding: var(--elsa-form-control-padding-block) var(--elsa-form-control-padding-inline);
	border: var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius: 0 0 4px 4px;
	/*
		固定値の白を書いていたため、複数SUGGESTだけ必須のピンク面色
		（`--elsa-field-state-background`、行の`elsaFieldRow--required`が立てる）
		を受け取れなかった（2026-09-02、Issue #2169後続）。単一SUGGEST・TEXT等の
		共通FIELDと同じ変数へ揃える。
	*/
	background: var(--elsa-field-state-background, var(--elsa-surface, #ffffff));
}

.elsaSelectorSuggest[data-multiple="true"] .elsaSelectorSuggestSelections:empty + .elsaSelectorSuggestInput {
	margin-top: 0;
	border-radius: var(--elsa-field-control-border-radius, 4px);
}

@media (max-width: 670px) {
	.elsaSelectorSuggest[data-multiple="true"] .elsaSelectorSuggestTextRow:first-child .elsaSelectorSuggestSelectionText {
		border-radius: 0;
	}
}

.elsaSelectorSuggestTextRemove {
	position: absolute;
	top: 50%;
	right: 5px;
	transform: translateY(-50%);
	cursor: pointer;
}

.elsaSelectorSuggestTextRemove > .elsaCommonCloseIcon {
	width: 1.15em;
	height: 1.15em;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	開いた候補一覧は入力欄と一体に見せる（Issue #3848、2026-09-18のオーナー決定）

	- 一覧は入力欄と**同じ枠線**を使い、1本ぶん食い込ませて重ねる。以前の
	  `top: calc(100% + 2px)`は2pxの隙間を作り、しかも入力欄の下枠と一覧の
	  上枠で線が二重に見えていた。
	- 角の丸みは**外形の4角だけ**に残す。下へ開くときは入力欄の下2角と一覧の上2角を
	  0にし、一覧の下2角へ入力欄と同じ丸みを置く。**丸みの値は`border-radius`の
	  一括指定を入力欄と同じ変数から受け取り、角の側だけを`0`で消す**ので、
	  会社別に丸みを変えても一覧が勝手にずれない（値を書き写さない）。
	- 上へ開くときは上下を入れ替えるだけで、同じ規則がそのまま成り立つ。開く向きは
	  `core/js/elsa_selector.js`が実寸で決め、枠の`data-open-direction`で伝える。

	**吹き出しを最前面に（Issue #4051）。** 表のセル・統合窓・ポップアップの
	どれの中でも、置き場所の`overflow`で切られてはいけない。要素はDOM上そのまま
	（フォームとの関連を保つ）で、開いている間だけ`position: fixed`にする。
	`top`／`left`／`bottom`／`width`は固定値を持たず、`core/js/elsa_selector.js`の
	`positionList()`が開くたび・スクロールのたび・リサイズのたびに入力欄／buttonの
	実寸（`getBoundingClientRect`）から画面座標で計算し、インラインstyleで置く
	（375pxでも画面内に収まるよう、右端では左へ寄せる。同ファイルを参照）。
	**祖先にtransform／filterがあると`position: fixed`は効かなくなる**ため、
	LIST・統合窓・ポップアップの器がこれらを持たないことを
	`tests/selector_placement_contract_test.php`で固定する。

	**z-indexは60。** LISTの通常セル（z-index無し）より上、実在するポップアップ層
	（`.elsaAppExplorerPaneToggle`のz-index33超のツリー全画面オーバーレイ120等）
	より下——LISTの見出し漏斗パネル（`.elsaListColumnFilterPanel`、`core/css/
	base.css`）と同じ役目・同じ値に揃える。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

.elsaSelectorSuggestList {
	position: fixed;
	z-index: 60;
	max-height: 15rem;
	overflow-y: auto;
	border: var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius: var(--elsa-field-control-border-radius, 4px);
	border-top-left-radius: 0;
	border-top-right-radius: 0;
	background: var(--elsa-surface, #ffffff);
	/*
		オーナー決定（2026-09-19）: 他の入力欄と重なって境目が分かりにくいため、
		外周に影を付ける。値はスマホ幅ヘッダー（`.elsaAppExplorerMobileHeader`、
		core/css/elsa_app_explorer.css）と同じ`0 4px 12px rgba(36, 51, 63, 0.14)`
		（トークン化されていないため、既存の書き方に合わせてそのまま複製）。
		入力欄と一体に見せる1pxの重なり・角丸の規則はそのまま変えない。
	*/
	box-shadow: 0 4px 12px rgba(36, 51, 63, 0.14);
}

/*
	Issue #4093 (3): 一覧は開いている間`<body>`直下へ移るため、もう
	`.elsaSelectorSuggest`のDOM上の子孫ではない。向きの印
	（`data-open-direction`）は`wrapper`だけでなく`list`自身にも付ける
	（`core/js/elsa_selector.js`の`positionList()`）ので、ここは祖先経由
	ではなく一覧自身の属性で拾う。
*/
.elsaSelectorSuggestList[data-open-direction="up"] {
	border-radius: var(--elsa-field-control-border-radius, 4px);
	border-bottom-left-radius: 0;
	border-bottom-right-radius: 0;
	/*  上へ開くときは影も上へ（下方向のy成分を反転しただけ）。  */
	box-shadow: 0 -4px 12px rgba(36, 51, 63, 0.14);
}

/*
	開いている間の入力欄。**閉じているときの形は`[data-open-direction]`が
	付かない既定の規則1本**で決まるので、ここは開いた側の2角を消すだけにする。
	`:empty + input`（選択済みが1件も無い複数SUGGEST）は一括指定で4角を
	書き戻すため、同じ組み合わせを明示して打ち勝つ。
*/
.elsaSelectorSuggest[data-open-direction="down"] .elsaSelectorSuggestInput,
.elsaSelectorSuggest[data-open-direction="down"][data-multiple="true"] .elsaSelectorSuggestSelections:empty + .elsaSelectorSuggestInput {
	border-bottom-right-radius: 0;
	border-bottom-left-radius: 0;
}

.elsaSelectorSuggest[data-open-direction="up"] .elsaSelectorSuggestInput,
.elsaSelectorSuggest[data-open-direction="up"][data-multiple="true"] .elsaSelectorSuggestSelections:empty + .elsaSelectorSuggestInput {
	border-top-right-radius: 0;
	border-top-left-radius: 0;
}

/*
	上へ開く複数SUGGESTでは、外形の上辺は積み上がった選択済みの1行目である。
	一覧はその上に付くので、1行目の上2角も0にする。
*/
.elsaSelectorSuggest[data-open-direction="up"][data-multiple="true"] .elsaSelectorSuggestTextRow:first-child .elsaSelectorSuggestSelectionText {
	border-top-right-radius: 0;
	border-top-left-radius: 0;
}

/*
	Issue #3848再オープン（2026-09-19）: 入力欄は`position: static`のまま、
	選択済みの札（上、`margin-top: -1px`）・候補一覧（下、`margin-top: -1px`）と
	1px重ねて一体に見せているため、フォーカス時のoutlineが上下とも重なった側の
	下に隠れていた。`.elsaListInlineRow .elsaField:focus-visible`と同じ手法で、
	フォーカス中だけ入力欄を最前面へ出す。

	**Issue #4051で候補一覧が`position: fixed`・`z-index: 60`になった後も、
	この値だけは候補一覧より大きく保つ。** 一覧はもう入力欄と同じ祖先の
	重なりの文脈に縛られず（`position: fixed`は実質ルート直下で比較される）、
	フォーカスで入力欄側を持ち上げても一覧の`z-index: 60`未満では一覧の下に
	沈んだままになる（`tests/selector_list_shape_browser_test.js`の実測で
	検出、2026-09-24）。61（一覧の60より大きい最小値）にする。
*/
.elsaSelectorSuggestInput:focus-visible {
	position: relative;
	z-index: 61;
}

/*
	候補の行の高さは入力欄と同じ（`--elsa-form-control-height`）。**paddingで
	高さを作らない**——文字サイズを変えたときに入力欄と行がずれるためである。
	上下中央はflexが担い、字面の微差は内側の`.elsaInkCenter`が持つ
	（`tests/control_vertical_center_*`の契約）。
*/
.elsaSelectorSuggestOption {
	display: flex;
	align-items: center;
	width: 100%;
	height: var(--elsa-form-control-height);
	min-height: var(--elsa-form-control-height);
	padding: 0 var(--elsa-form-control-padding-inline);
	border: none;
	border-bottom: var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
	background: var(--elsa-surface, #ffffff);
	color: inherit;
	font: inherit;
	text-align: left;
	cursor: pointer;
}

/*  最後の行の下線と一覧の下枠が重なって太く見えないようにする。  */
.elsaSelectorSuggestOption:last-child {
	border-bottom: 0;
}

.elsaSelectorSuggestOption:hover,
.elsaSelectorSuggestOption:focus {
	background: var(--elsa-hover-bg, #eaf4ff);
}

/*
	候補の種類のバッジ（Issue #3480の`kind_label`。#4484・オーナー指示2026-10-07で
	左端・灰色の枠へ）。候補の行と複数選択の札の両方へ`core/js/elsa_selector.js`の
	`kindBadge()`1か所が描く。

	**形は`.elsaFieldRequiredBadge`・`.elsaTrialBadge`と同じ枠囲み**（padding・角丸・
	行の高さ・上下中央の`.19em`。出どころは`.elsaFieldRequiredBadge`の注記が正本）で、
	色だけを`:root`の種類の2トークンにする。新しい形を作らない。
	**最小幅は全種類で同じ**（`--elsa-selector-kind-badge-min-width`＋枠2px）にして
	文字を中央に置き、名前の頭を縦にそろえる。
*/
.elsaSelectorKindBadge {
	display: inline-block;
	flex: 0 0 auto;
	box-sizing: border-box;
	min-width: calc(var(--elsa-selector-kind-badge-min-width) + 2px);
	margin-right: var(--elsa-selector-kind-badge-gap);
	padding: .19em .35em 0;
	border: 1px solid var(--elsa-selector-kind-badge-border-color);
	border-radius: .25em;
	color: var(--elsa-selector-kind-badge-color);
	font-size: calc(var(--elsa-selector-kind-badge-font-scale) * 1em);
	font-weight: normal;
	line-height: 1.15;
	text-align: center;
	white-space: nowrap;
}

/*
	他社の人の会社名の札（Issue #4483 PR-2）。名前の右に置き、形は上の種類の
	バッジのまま、色だけをチャットの参加者のバッジの「他社・AI」
	（`.elsaChatHeaderBadge--ai`。薄いメインカラー）と同じ式にする。
*/
.elsaSelectorPeerBadge {
	min-width: 0;
	margin-right: 0;
	margin-left: var(--elsa-selector-kind-badge-gap);
	border-color: color-mix(in srgb, var(--elsa-primary-color, #24333f) 40%, var(--elsa-surface, #ffffff));
	background: color-mix(in srgb, var(--elsa-primary-color, #24333f) 12%, var(--elsa-surface, #ffffff));
	color: inherit;
}

/*
	複数選択の札（読み取り専用のinput）はバッジを中に持てないので、札の枠の
	左端へ重ねて置き、名前の頭をバッジ＋間隔の分だけ右へずらす。ずらす量は
	バッジと同じトークンから計算する（バッジの文字基準の値に倍率を掛けて
	札の文字基準へ直す）ので、候補の行と札とで名前の頭の位置がそろう。
	`data-kind`はバッジを描いた札にだけ付く（`kind_label`の無い札は今のまま）。
*/
.elsaSelectorSuggest .elsaFieldControl[data-kind="true"] > .elsaSelectorKindBadge {
	position: absolute;
	top: 50%;
	left: calc(var(--elsa-form-control-padding-inline) + var(--elsa-form-control-border-width));
	transform: translateY(-50%);
	pointer-events: none;
}

.elsaSelectorSuggest .elsaFieldControl[data-kind="true"] > .elsaSelectorSuggestSelectionText {
	padding-left: calc(var(--elsa-form-control-padding-inline) + var(--elsa-selector-kind-badge-font-scale) * (var(--elsa-selector-kind-badge-min-width) + var(--elsa-selector-kind-badge-gap)) + 2px);
}

.elsaSelectorSuggestMore {
	display: block;
	width: 100%;
	height: var(--elsa-block-action-height);
	min-height: var(--elsa-block-action-height);
	padding: 0 8px;
	border: none;
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	font: inherit;
	cursor: pointer;
}

.elsaSelectorSuggestMore:focus-visible {
	outline: 2px solid var(--elsa-primary-color, #24333f);
	outline-offset: 2px;
}

@media (hover: hover) {
	.elsaSelectorSuggestMore:hover {
		background: var(--elsa-primary-color, #24333f);
		color: var(--elsa-primary-contrast, #fff);
	}
}

.elsaSelectorSuggestStatus {
	/*
		remote SELECTORはaria-live用の空要素を常設する。空でも高さを予約すると、
		入力欄の下に存在しない状態文の帯が残るため、文がある時だけレイアウトへ戻す。
	*/
	display: none;
	min-height: 0;
	margin: 0;
	color: var(--elsa-text-muted, #667085);
	font-size: .875em;
}

.elsaSelectorSuggestStatus:not(:empty) {
	display: block;
	min-height: 1.4em;
	margin-top: 4px;
}

.elsaSelectorSuggestStatus[data-state="error"] {
	color: var(--elsa-danger-color, #b42318);
}

/*
	TREEは選択結果を1行の入力欄として見せ、開いたときだけ階層を展開する。
	文字・高さ・余白はTEXT/SELECTORと同じ表示設定変数を使い、固定pxの
	文字サイズを持たない。入れ子のgroupが1段分の字幅だけ字下げする。
*/
.elsaTree {
	position: relative;
	width: 100%;
	min-width: 0;
	font: inherit;
}

.elsaTreeTrigger {
	display: flex;
	box-sizing: border-box;
	align-items: center;
	justify-content: space-between;
	gap: .75em;
	width: 100%;
	height: var(--elsa-form-control-height);
	min-height: var(--elsa-form-control-height);
	padding: var(--elsa-form-control-padding-block) var(--elsa-form-control-padding-inline);
	border: var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius: var(--elsa-field-control-border-radius, 4px);
	/*
		固定値の白を書いていたため、ドロップダウン表示のTREEは必須でも
		ピンクの面色（`--elsa-field-state-background`）にならなかった
		（2026-09-02、Issue #2169後続）。TEXT/SELECTOR/SUGGESTと同じ変数へ揃える。
	*/
	background: var(--elsa-field-state-background, var(--elsa-surface, #ffffff));
	color: inherit;
	font: inherit;
	line-height: var(--elsa-form-control-line-height);
	text-align: left;
	cursor: pointer;
}

.elsaTreeTrigger:disabled {
	background: var(--elsa-field-disabled-bg, #eee);
	color: var(--elsa-field-disabled-color, #666);
	cursor: default;
}

.elsaTreeTriggerLabel {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.elsaTreeTriggerArrow,
.elsaTreeToggle {
	flex: 0 0 auto;
	width: .9em;
	height: .9em;
	background: currentColor;
	-webkit-mask: var(--elsa-icon-arrow-right) var(--elsa-icon-arrow-right-mask-position, center) / var(--elsa-icon-arrow-right-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-arrow-right) var(--elsa-icon-arrow-right-mask-position, center) / var(--elsa-icon-arrow-right-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

.elsaTreeTrigger[aria-expanded="true"] .elsaTreeTriggerArrow,
.elsaTreeItem[aria-expanded="true"] > .elsaTreeItemRow > .elsaTreeToggle,
.elsaCommonExpandedArrowRightIcon {
	transform: rotate(90deg);
}

.elsaTreeToggle--empty {
	visibility: hidden;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	開閉の矢印は**マウスが乗っているあいだだけ**出す

	2026-08-30の利用者指示（Windowsエクスプローラー準拠、画面の写しつき）。
	**行ごとではなく、ツリー全体で一度に現れる**のがエクスプローラーの作法で、
	1行ずつ点いたり消えたりすると、目で追っている行が動いていないのに景色だけが
	ちらつく。

	**消えるのは`opacity`だけである。** 場所は取ったままなので、現れても消えても
	行の中の文字は1pxも動かない。`aria-expanded`はここと無関係に付いたままで、
	読み上げと操作は見た目に左右されない。

	**指で触る端末では出しっぱなしにする。** `hover`を持たない環境では乗せる操作が
	無く、隠れたままだと開ける手がかりが画面から消える。判定は`@media (hover: hover)`
	＝「乗せられる入力装置がある」ときだけ隠す、という向きで書く（隠す側を例外に
	すると、判定が効かない環境で矢印が消えたままになる）。

	キーボードだけで操作している人にも出す（`:focus-within`）。乗せる操作が無くても、
	いま開けるかどうかが見えている必要がある。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

@media (hover: hover) {
	/*
		**器はツリー全体**（`.elsaTree`）である。行（`.elsaTreeItemRow`）に掛けると
		1行ずつ現れる形になり、エクスプローラーの見え方から外れる。
	*/
	/*
		**消えるときほどゆっくり、そしてもっとふわっと**（2026-08-31の利用者指示で
		4回調整。150ms一律→250ms／400ms→800ms／1000ms→カーブを分離→
		**表示も1000msへ揃える**）。
		`ease-in-out`は後半が漸近的で、消える動き（1→0）の後半は透明度0.1台＝
		ほぼ見えない時間が長く、体感の変化が前半へ圧縮されていた（利用者
		「どうみても1000msもかかってない」）。実測（100ms刻み）でも、消える
		動きが不透明度0.5を割るまでの時間は`ease-in-out`で約480ms（全体の
		半分未満）だった。

		**消えるとき（1→0）はease-in系**（`cubic-bezier(0.55, 0, 0.8, 0.4)`。
		最初は濃いまま粘り、最後にすっと消える）へ、**出るとき（0→1）は
		ease-out系**（`ease-out`。すぐ見え始めて滑らかに定着）へ分けた。
		乗せた瞬間は用があって乗せているので早めに出し切り、外したときは
		名残を残して最後まで見える時間を延ばす。同じ実測で、消える動きが
		不透明度0.5を割るまでの時間は約480ms→約780msへ伸びた（目標の500ms
		以上を達成）。

		**表示・非表示とも700msへ揃える**（2026-08-31の利用者の再調整指示。
		表示800ms／非表示1000ms→両方1000msへ揃えた直後に、「表示をもう少し
		速く、非表示は表示と同じ速度に」との指示で両方700msへ）。カーブ
		（出る=ease-out系・消える=ease-in系）は変えない。時間だけを揃え、
		乗せたときも外したときも同じ長さのふわっとになる。

		乗せた瞬間は用があって乗せているので早めに出し（表示）、外したときは
		名残を残してゆっくり消す（非表示）。ツリーの端から端へマウスが横切るだけで
		パッパッと点滅するのを防ぐ狙いもある。**利用者からの再調整が続く見込みのため、
		時間とカーブを`.elsaTree`の変数4つへ集約した。** 次に変えるときはこの4行の
		値だけを書き換えればよい（下の2つのルールへ数値やカーブを書き足さない）。
	*/
	.elsaTree {
		--elsa-tree-toggle-fade-in: 700ms;
		--elsa-tree-toggle-fade-out: 700ms;
		--elsa-tree-toggle-fade-in-curve: ease-out;
		--elsa-tree-toggle-fade-out-curve: cubic-bezier(0.55, 0, 0.8, 0.4);
	}

	.elsaTree .elsaTreeToggle {
		opacity: 0;
		transition: opacity var(--elsa-tree-toggle-fade-out) var(--elsa-tree-toggle-fade-out-curve);
	}

	.elsaTree:hover .elsaTreeToggle,
	.elsaTree:focus-within .elsaTreeToggle {
		opacity: 1;
		transition-duration: var(--elsa-tree-toggle-fade-in);
		transition-timing-function: var(--elsa-tree-toggle-fade-in-curve);
	}
}

/*
	**動きを減らす設定でも止めない**（2026-08-31の利用者＝製品責任者の明示指示）。
	以前はここに`@media (hover: hover) and (prefers-reduced-motion: reduce) {
	.elsaTree .elsaTreeToggle { transition: none; } }`を置いていたが、利用者の
	実機は`prefers-reduced-motion: reduce`を返す環境で、この分岐がフェードを
	常時無効化していた（「＞マークのふわっとが効いていない」の実体）。

	**対象は不透明度だけの変化で、位置・大きさ・視差は動かさない。** 動きを
	減らす配慮が対象とする「動き」（移動・回転・視差・自動再生等、酔いや注意の
	急な引っ張りを起こす種類）には当たらないと利用者が判断した。同じ理由で
	`core/css/elsa_app_explorer.css`のスクロールバー色フェードも同じ分岐を
	持たない（2026-08-31）。
*/

.elsaTreePanel {
	position: absolute;
	z-index: 20;
	top: calc(100% + 2px);
	left: 0;
	box-sizing: border-box;
	width: 100%;
	max-width: 100%;
	max-height: min(24em, 55vh);
	overflow: auto;
	overscroll-behavior: contain;
	border: var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius: var(--elsa-field-control-border-radius, 4px);
	background: var(--elsa-surface, #ffffff);
	box-shadow: 0 .35em 1em rgba(0, 0, 0, .14);
}

.elsaTreeList {
	/*
		字下げ1段の幅。帯を左へ戻す量もこれで決まるので、値は1か所だけに置く。

		**半文字**である（2026-08-30の利用者指示。1.25em＝17.5pxから0.5em＝7pxへ）。
		2026-09-03の利用者指摘により、親子関係を読み取りやすくするため、字下げを
		1段あたり1文字分へ戻す。深い階層でも名前は1行のまま省略表示され、全文は
		既存のtitleで確認できるため、階層の判別を優先する。

		**行の左右の余白もツリーの中だけ詰める**（8px→6px）。共通の入力欄の余白
		（`--elsa-form-control-padding-inline`）はそのままにして、ここで名前を
		付け替える。**帯を左へ戻す計算も同じ変数を読む**ので、詰めても帯の左端は
		ペインの端に揃ったままである。
	*/
	/* Inherit the appearance setting; consumers retain the 1em fallback. */
	min-width: 0;
	padding: var(--elsa-form-control-padding-block);
}

.elsaTreeGroup {
	min-width: 0;
	padding-inline-start: var(--elsa-tree-indent, 1em);
}

/*
	**枝同士の隙間は外観設定の項目である**（2026-09-02の利用者決定。Issue #2689 段階3）。
	既定は0で、今までどおり行が隣り合う。0より大きくすると、木の行のあいだが
	空いて1行ずつ読みやすくなる。

	行そのものの高さ（`--elsa-form-control-height`）は触らない——指で押せる
	大きさを変えずに、行と行のあいだだけを空ける。
*/
.elsaTreeList,
.elsaTreeGroup {
	display: grid;
	row-gap: var(--elsa-tree-row-spacing, 0px);
	align-content: start;
}

/*
	**閉じた枝は見えない。** 上の`display: grid`はブラウザ既定の
	`[hidden] { display: none }`より強い（作者の規則が既定に勝つ）ため、これが
	無いと閉じた枝（`hidden`）まで描かれ、ログイン直後に木が全部開いて見える
	うえ▷で閉じられない（2026-09-02の実障害。PR #2703の副作用）。
*/
.elsaTreeGroup[hidden] {
	display: none;
}

/*
	遅延読み込みの枝を開いた直後の行（Issue #3712より前は「読み込み中…」の
	文字だったが、いまは共通の回転マーク`.elsaLoadingSpinner`だけを持つ）。
	**押せる行ではない**ので、ホバーの帯も⋮も持たず、字下げだけを行の文字の
	開始位置へ合わせる。子が届いた時点で消える（届かなかったときも消え、
	枝は未読込へ戻って開き直せる）。0.2秒未満で終わる読み込みでは、この行
	そのものを作らない（`core/js/elsa_tree.js`）。
*/
.elsaTreeLoading {
	padding: 2px 0 2px var(--elsa-form-control-padding-inline);
	color: var(--elsa-text-muted, #667085);
	font-size: .85em;
}

.elsaTreeItem {
	min-width: 0;
	outline: none;
}

.elsaTreeItemRow {
	display: flex;
	align-items: center;
	/*
		開閉矢印と名前のあいだ。**半分に詰めた**（2026-08-30の利用者指示。
		.55em＝7.7pxから.28em＝3.9pxへ）。理由は⑤⑥と同じ「表示できるエリアを
		少しでも大きくしたい」で、Windowsのエクスプローラーの詰まり具合に寄せてある。
		**行の高さ（36px）は触らない**ので、指で押せる大きさは変わらない。
	*/
	gap: .28em;
	min-width: 0;
	min-height: var(--elsa-form-control-height);
	padding: var(--elsa-tree-row-padding-block, 3px) var(--elsa-tree-row-padding-inline, var(--elsa-form-control-padding-inline));
	/*
		行の帯（ホバーと選択の面）は**階層の深さに関わらず端から端まで**にする
		（2026-08-29の利用者指摘「ツリーの上位と下位で幅が異なります。下位でも
		最上位の幅で帯を表示してください」）。Windowsエクスプローラーの行の
		ハイライトと同じ作法である。

		字下げを作っているのは`.elsaTreeGroup`の`padding-inline-start`なので、
		**帯だけをその分だけ左へ戻し、同じ量を内側の余白へ足す。** こうすると
		文字の開始位置は今までどおり1段ずつ下がり、帯の左端だけが最上位と揃う。
		右端は元から全階層で同じなので触らない。
	*/
	margin-inline-start: calc(-1 * var(--elsa-tree-band-inset, 0em));
	padding-inline-start: calc(var(--elsa-tree-row-padding-inline, var(--elsa-form-control-padding-inline)) + var(--elsa-tree-band-inset, 0em));
	border-radius: var(--elsa-field-control-border-radius, 4px);
	line-height: var(--elsa-form-control-line-height);
	cursor: pointer;
}

/*
	戻す量は自分が何段目かで決まる。`aria-level`は描く側（`tree.php`）もJS
	（`treeBuildItem`）も必ず付けるので、これを段数の正本として読む。

	**深さ12まで用意する。** 業務で最も深い文書フォルダでも10階層で、それより深い
	ツリーでは帯が字下げの位置から始まる（崩れはしない）。
*/
.elsaTreeItem[aria-level="2"] > .elsaTreeItemRow { --elsa-tree-band-inset: calc(var(--elsa-tree-indent, 1em) * 1); }
.elsaTreeItem[aria-level="3"] > .elsaTreeItemRow { --elsa-tree-band-inset: calc(var(--elsa-tree-indent, 1em) * 2); }
.elsaTreeItem[aria-level="4"] > .elsaTreeItemRow { --elsa-tree-band-inset: calc(var(--elsa-tree-indent, 1em) * 3); }
.elsaTreeItem[aria-level="5"] > .elsaTreeItemRow { --elsa-tree-band-inset: calc(var(--elsa-tree-indent, 1em) * 4); }
.elsaTreeItem[aria-level="6"] > .elsaTreeItemRow { --elsa-tree-band-inset: calc(var(--elsa-tree-indent, 1em) * 5); }
.elsaTreeItem[aria-level="7"] > .elsaTreeItemRow { --elsa-tree-band-inset: calc(var(--elsa-tree-indent, 1em) * 6); }
.elsaTreeItem[aria-level="8"] > .elsaTreeItemRow { --elsa-tree-band-inset: calc(var(--elsa-tree-indent, 1em) * 7); }
.elsaTreeItem[aria-level="9"] > .elsaTreeItemRow { --elsa-tree-band-inset: calc(var(--elsa-tree-indent, 1em) * 8); }
.elsaTreeItem[aria-level="10"] > .elsaTreeItemRow { --elsa-tree-band-inset: calc(var(--elsa-tree-indent, 1em) * 9); }
.elsaTreeItem[aria-level="11"] > .elsaTreeItemRow { --elsa-tree-band-inset: calc(var(--elsa-tree-indent, 1em) * 10); }
.elsaTreeItem[aria-level="12"] > .elsaTreeItemRow { --elsa-tree-band-inset: calc(var(--elsa-tree-indent, 1em) * 11); }

/*
	名前は**折り返さず、入りきらない分を…で省略する**（2026-08-29の利用者指摘
	「狭い幅でツリーの文字が縦並びになり読めない」）。エクスプローラーの作法である。

	修正前は`overflow-wrap: anywhere`だったので、左のペインが下限まで縮むと
	「101号室」が1文字ずつ折り返して縦書きになり、階層そのものが読めなくなった。
	**折り返しを許すと、狭いほど行が高くなって画面から溢れる。** 省略なら行の
	高さは変わらない。

	全文は`title`（マウスオーバー）で読める。**縮むのは名前だけ**で、行末の状態
	（`.elsaTreeItemMeta`）は`flex: 0 0 auto`で右端に残る。省略の犠牲にすると
	「いま使えるか」が狭い画面でだけ消える。
*/
.elsaTreeItemLabel {
	flex: 0 1 auto;
	min-width: 0;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

/*
	行の右端の短い状態（提供中・有効など）。**1件ずつ開かずに読めること**が役目なので、
	名前より弱く、しかし読める濃さにする。名前が長い行では名前を先に詰める。
*/
.elsaTreeItemMeta {
	flex: 0 0 auto;
	margin-left: auto;
	font-size: .8em;
	color: var(--elsa-text-muted, #667085);
	white-space: nowrap;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	名前と、その右横の札のまとまり（Issue #4449・一号機裁定2026-10-06）。

	**札が名前の幅を奪わないようにするための1枚である。** 札を行の直下へ
	並べていたときは、行の幅が決まっている（左ペインは280px、スマホ幅の行は
	画面幅の80%）ため、札のぶんだけ名前が…で省略された——**札が無ければ
	収まる名前**が表示設定24pxで最大26行、16pxで最大6行切れていた（2026-10-06の
	実測）。まとまりへ入れると、名前の幅を決めるのはまとまりの幅になり、
	**札の有無で名前の省略の起き方が1行も変わらない。**

	`flex-wrap: wrap`が決めるのは「札をどこへ置くか」だけである。

	 * 名前の右の余りに札が入る → 同じ行の名前のすぐ右横（従来の見え方）
	 * 入らない → **名前を切らずに**札を名前の下へ回す（行が1段高くなる）

	**名前そのものは折り返さない**（`.elsaTreeItemLabel`の`white-space: nowrap`。
	2026-08-29の利用者指摘「狭い幅でツリーの文字が縦並びになり読めない」）。
	名前だけで入り切らない行は、札が在っても無くても同じように…で省略する。
	折り返す対象は**まとまりの中の並び**（名前という1つの箱と札という1つの箱）で、
	名前の中の文字ではない。

	`row-gap`を`.1em`に留めるのは、2段になった行でも1行ぶんの高さの増え方が
	名前と札の隙間ぶんだけで済むようにするためである。札の左の`.35em`は
	`.elsaTreeItemBadge`が持つので、ここでは列の隙間を作らない。

	**伸び縮みは既定のまま**（`flex: 0 1 auto`）なので書かない。統合窓の左ペインで
	▸を右端へ押し出すために伸ばす必要があるのはこの幅だけなので、その1行は
	`core/css/elsa_app_explorer.css`の`@media`の中に在る。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.elsaTreeItemName {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	/*
		**名前より狭くなれること。** これが無いと、まとまりの最小幅が名前の
		全長（`white-space: nowrap`の`min-content`）になり、名前は…で省略される
		代わりに**行からはみ出す**。
	*/
	min-width: 0;
	row-gap: .1em;
}

/*
	名前のすぐ右横の札（Issue #4449。「試用中」「試用期間切れ」）。

	**行末の状態（`.elsaTreeItemMeta`）とは置き場所が違う。** あちらは
	`margin-left: auto`で右端へ寄るが、札は名前に付く印なので寄せない。
	**省略の犠牲にしない**（`flex: 0 0 auto`）——名前が長い行では名前を先に
	詰め、札は残す。狭い画面でだけ契約の状態が消えてはいけない。

	形と色（枠囲み・警告色の共通トークン）は`.elsaTrialBadge`が持ち、ここでは
	位置だけを決める。左の`.35em`は、同じ行に居るときは名前との間隔になり、
	名前の下へ回ったときは名前の左端からの字下げになる——**どちらでも札が
	名前より左へ出ない。**
*/
.elsaTreeItemBadge {
	flex: 0 0 auto;
	margin-left: .35em;
}

/*
	⋮も右端へ寄る（`margin-left: auto`）ので、状態が並ぶ行では**寄せるのは
	状態だけ**にする。両方が寄せると名前と状態のあいだが開き、別の列に見える。
*/
/*
	補足の重み（`meta_tone`）。**色は補助でしかない。** 意味は補足の文字そのもの
	（「■ 滞納 ¥73,000」）が持ち、先頭の形で色抜きでも読み分けられる。
	色だけに頼らせないため、滞納は太さも一緒に変える。
*/
.elsaTreeItemMeta.is-unpaid { --elsa-tree-state-text: color-mix(in srgb, var(--elsa-semantic-caution-color) 10%, var(--elsa-content-text-color, #333)); color: var(--elsa-tree-state-text, #8a5a00); }
.elsaTreeItemMeta.is-overdue { --elsa-tree-state-text: color-mix(in srgb, var(--elsa-semantic-danger-color) 10%, var(--elsa-content-text-color, #333)); color: var(--elsa-tree-state-text, var(--elsa-button-danger-hover-bg, #b42318)); font-weight: 700; }

.elsaTreeItemMeta ~ .elsaTreeItemMenu { margin-left: .35em; }

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	**「選択中」の見せ方はアプリ全体で1つである**（2026-09-02の利用者決定。Issue #2689。
	2026-09-27の利用者決定で左端の縦線は廃止——ごちゃごちゃ感が出るため）。

	  地   = 行の選択色（外観設定の項目）
	  文字 = 太字

	以前は左端にメインカラーの縦線4px（`box-shadow: inset`）も引いていたが、
	選択は背景色と太字だけで示す。行の高さも文字の開始位置も動かさない
	という前提（影は場所を取らない）は変わらないが、線自体を無くした。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.elsaTreeItem[aria-selected="true"] > .elsaTreeItemRow {
	background: var(--elsa-selected-bg, #dceeff);
	color: var(--elsa-selected-color);
	font-weight: 700;
}

/*
	**葉を持たない行き先の現在地**（TREEの`location`、Issue #4333）。開閉だけの節は
	選択の値にできないので`aria-current="location"`で示し、選択と同じ見え方にする。
*/
.elsaTreeItem[aria-current="location"] > .elsaTreeItemRow {
	background: var(--elsa-selected-bg, #dceeff);
	color: var(--elsa-selected-color);
	font-weight: 700;
}

.elsaTreeItem[aria-disabled="true"] > .elsaTreeItemRow {
	color: var(--elsa-field-disabled-color, #777);
	cursor: not-allowed;
}

.elsaTreeTrigger:focus-visible,
.elsaTreeItem:focus-visible > .elsaTreeItemRow {
	outline: 2px solid var(--elsa-primary-color, #24333f);
	outline-offset: 1px;
}

/*  Issue #4635: 引き金はラベルのすぐ下に置かれる入力欄なので、線を内側へ描く（理由は`.elsaText:focus-visible`の注記）。  */
.elsaTreeTrigger:focus-visible {
	outline-offset: -2px;
}

@media (hover: hover) {
	.elsaTreeItem:not([aria-disabled="true"]) > .elsaTreeItemRow:hover {
		background: var(--elsa-hover-bg, #eaf4ff);
	}
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	TREEの編集（2026-08-28の利用者決定）

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

/*
	据え置き表示。ドロップダウンの浮きだけを戻し、枠・角丸・地色・字送りは
	TREEのものをそのまま使う。**別の見た目のツリーを増やさない。**

	**入れ物は位置の基準であり続ける。** ここを`static`にすると、右クリックで
	出す操作の一覧（`.elsaTreeMenu`）の基準が画面全体へ移り、押した場所ではなく
	ページの左上へ出る（2026-08-28に中央サーバーの実画面で発生）。浮きを戻すのは
	パネルの側だけでよい。
*/
.elsaTree--inline { position: relative; }

/*
	据え置き（inline）のTREEは**自分では送らない。** 高さの上限を切ってあるので
	中身が全部出ており、送るのはこれを入れた側（窓のペイン・画面の本文）である。

	**それでも`overflow: auto`のままにすると、送る操作がここで止まる。** 上限が
	無いぶん自分は動けないのに、浮くパネルのための`overscroll-behavior: contain`が
	親への持ち上がりまで断つため、**ツリーの行の上でホイールを回しても何も起きない。**
	効くのはペインのスクロールバーの真上だけになる（2026-08-30に利用者が中央サーバーの
	実画面で発見。同じ画面での実測でも、行の上の実ホイールがペインを0pxしか
	動かさず、この2行を足すと同じ操作で379px動いた）。

	**狭い画面で自分が送る画面は、そちらで名指しし直す**（物件情報・請求入金・
	契約・入居者ハブの`@media`が`max-height`と`overflow: auto`を戻す）。上限を
	持つときは本当に送れるので、`contain`で親を止めるのがそのまま正しい。
*/
.elsaTreePanel--inline {
	position: static;
	max-height: none;
	overflow: visible;
	overscroll-behavior: auto;
	box-shadow: none;
}

/*
	TREEと選択詳細を並べる共通配置。階層と詳細を持つ画面は同じ左右→上下の
	規則を使い、ブロック間隔は利用者設定の正本から受け取る。
*/
.elsaTreeDetailLayout {
	display: grid;
	grid-template-columns: minmax(min(100%, 18em), 0.36fr) minmax(0, 1fr);
	gap: var(--elsa-block-spacing, 8px);
	align-items: start;
	min-width: 0;
}

.elsaTreeDetailPane {
	min-width: 0;
}

@media (max-width: 760px) {
	.elsaTreeDetailLayout { grid-template-columns: minmax(0, 1fr); }
}

/*
	行の⋮。狭い画面には右クリックが無いので、**同じ操作をここから出す**。
	図像はLISTの行操作と同じ（`--elsa-icon-more`）。ハンバーガー≡は並び替えの
	つかみ手と読み違えるため使わない（2026-08-28の利用者決定）。

	当たり面は共通の28px契約に揃える。PCでは当たったときと焦点があるときだけ
	濃くし、ふだんは薄く置いて階層の文字を邪魔しない。
*/
.elsaTreeItemMenu {
	flex: 0 0 auto;
	box-sizing: border-box;
	display: grid;
	place-items: center;
	width: var(--elsa-block-action-height);
	min-width: var(--elsa-block-action-height);
	height: var(--elsa-block-action-height);
	min-height: var(--elsa-block-action-height);
	margin-left: auto;
	padding: 0;
	border: 0;
	border-radius: 4px;
	background: transparent;
	color: inherit;
	font: inherit;
	line-height: 1;
	cursor: pointer;
}

.elsaTreeItemMenuIcon {
	display: block;
	width: var(--elsa-block-action-icon-size);
	height: var(--elsa-block-action-icon-size);
	background: currentColor;
	-webkit-mask: var(--elsa-icon-more) var(--elsa-icon-more-mask-position, center) / var(--elsa-icon-more-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-more) var(--elsa-icon-more-mask-position, center) / var(--elsa-icon-more-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

.elsaTreeItemMenu:focus-visible {
	outline: 2px solid var(--elsa-primary-color, #24333f);
	outline-offset: 1px;
}

@media (hover: hover) {
	.elsaTreeItemMenu { opacity: .35; }
	.elsaTreeItemRow:hover > .elsaTreeItemMenu,
	.elsaTreeItemMenu:focus-visible,
	.elsaTreeItemMenu[aria-expanded="true"] { opacity: 1; }
	.elsaTreeItemMenu:hover { color: var(--elsa-primary-color, #24333f); }
}

/*
	右クリック／⋮で出す操作の一覧。押した場所へ出すのでツリーの内側に置き、
	座標はJSが入れる（ツリーの左上からの相対）。
*/
/*
	操作の一覧は**画面に対して置く**（`fixed`）。2026-08-30の利用者報告「左ペイン内の
	⋮メニューを開くとペイン外が表示されません」。

	窓は角を丸く切るために`overflow: clip`を持ち、左のペインは階層が長いときのために
	`overflow: auto`を持つ。`absolute`のままだと、その2つがメニューを切り、項目の
	頭文字（新・名・削）しか見えなかった。**`fixed`はどちらの切り取りも越える**
	（実測で確認）ので、窓の角の切り取りをやめずに全体を出せる。

	座標は`elsa_tree.js`が画面の座標で入れ、右端・下端に当たるときは内側へ寄せる
	（下端では上向きに開く）。
*/
.elsaTreeMenu {
	position: fixed;
	z-index: 30;
	min-width: 10em;
	padding: 4px;
	border: var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius: var(--elsa-field-control-border-radius, 4px);
	background: var(--elsa-surface, #ffffff);
	box-shadow: 0 .35em 1em rgba(0, 0, 0, .18);
}

.elsaTreeMenuItem {
	display: block;
	box-sizing: border-box;
	width: 100%;
	min-height: var(--elsa-form-control-height);
	padding: var(--elsa-form-control-padding-block) var(--elsa-form-control-padding-inline);
	border: 0;
	border-radius: var(--elsa-field-control-border-radius, 4px);
	background: transparent;
	color: inherit;
	font: inherit;
	line-height: var(--elsa-form-control-line-height);
	text-align: left;
	white-space: nowrap;
	cursor: pointer;
}

.elsaTreeMenuItem--danger { color: var(--elsa-button-danger-hover-bg, #b42318); }

.elsaTreeMenuItem:focus-visible {
	outline: 2px solid var(--elsa-primary-color, #24333f);
	outline-offset: -2px;
}

@media (hover: hover) {
	.elsaTreeMenuItem:hover { background: var(--elsa-hover-bg, #eaf4ff); }
}

/*
	その場の名前入力。行の高さを変えないよう、共通の入力欄と同じ字送りで
	行の中へ収める。**列が動くと、名前を変えた瞬間に階層が跳ねて見える。**
*/
.elsaTreeRenameInput {
	box-sizing: border-box;
	flex: 1 1 auto;
	min-width: 0;
	height: calc(var(--elsa-form-control-height) - 2px);
	padding: 0 var(--elsa-form-control-padding-inline);
	border: var(--elsa-form-control-border-width) solid var(--elsa-primary-color, #24333f);
	border-radius: var(--elsa-field-control-border-radius, 4px);
	background: var(--elsa-surface, #ffffff);
	color: inherit;
	font: inherit;
	line-height: var(--elsa-form-control-line-height);
}

/*
	疑似削除済みの項目。**見えるが生きていない**ことが一目で分かるよう、
	一覧の削除済み行と同じ薄い見せ方に揃える。
*/
.elsaTreeItem[data-tree-deleted="true"] > .elsaTreeItemRow {
	background: var(--elsa-surface-sunken, #f5f7f9);
	color: var(--elsa-field-disabled-color, #777);
}

/*
	引き出し中の見せ方。**「中へ入れる」と「前後へ挟む」を別の形で示す。**
	同じ塗りにすると、離した後で初めてどちらだったか分かることになる。
*/
.elsaTreeItem.is-dragging > .elsaTreeItemRow { opacity: .45; }

.elsaTreeItemRow[data-tree-drop="inside"] {
	outline: 2px solid var(--elsa-primary-color, #24333f);
	outline-offset: -2px;
	background: var(--elsa-hover-bg, #eaf4ff);
}

/*
	「前後へ挟む」の線は行のborder-radiusを継がない独立要素で描く。
	行自体（`.elsaTreeItemRow`）は角丸を持つため、以前のようにその
	box-shadowで線を表現すると、線の両端が角丸に沿って曲がり、
	「]」を90度回転させたような形に見えてしまう（2026-09-03の利用者指摘）。
	疑似要素は`border-radius: 0`の直線の帯とし、行の角丸の影響を受けない。
	太さは3px（見づらいという指摘を受けて2pxから拡大、2026-09-03）。
*/
.elsaTreeItemRow[data-tree-drop="before"],
.elsaTreeItemRow[data-tree-drop="after"] {
	position: relative;
}

.elsaTreeItemRow[data-tree-drop="before"]::after,
.elsaTreeItemRow[data-tree-drop="after"]::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	height: 3px;
	border-radius: 0;
	background: var(--elsa-primary-color, #24333f);
	pointer-events: none;
}

.elsaTreeItemRow[data-tree-drop="before"]::after { top: 0; }

.elsaTreeItemRow[data-tree-drop="after"]::after { bottom: 0; }

.elsaFieldStatic {
	display: flex;
	align-items: center;
	width: 100%;
	min-height: var(--elsa-form-control-height);
	padding: var(--elsa-form-control-padding-block) var(--elsa-form-control-padding-inline);
	border: 1px solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius: var(--elsa-field-control-border-radius, 4px);
	color: inherit;
	line-height: var(--elsa-form-control-line-height);
	background: var(--elsa-field-state-background, #fff);
}

.button {
	display: inline-flex;
	box-sizing: border-box;
	align-items: center;
	justify-content: center;
	height: var(--elsa-block-action-height);
	min-height: var(--elsa-block-action-height);
	padding: 0 15px;
	margin: 4px 8px 4px 0;
	border: none;
	border-radius: 4px;
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	text-decoration: none;
	font-family: inherit;
	font-size: var(--elsa-button-font-size, 14px);
	line-height: 1;
	vertical-align: middle;
	cursor: pointer;
}

.button[hidden] {
	display: none !important;
}

.button:focus-visible {
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	outline: 2px solid var(--elsa-primary-color, #24333f);
	outline-offset: 2px;
}

/*
	無効の見た目の正本。地・文字は`--elsa-button-disabled-*`（bodyの定義）だけを
	参照し、**ここで実色を書かない。** `opacity`は使わない（理由は変数の注記）。
	`aria-disabled="true"`も同じ見た目にする。`<a>`は`:disabled`を持てず、
	リンクをボタンに見せている箇所（ラベルタブの歯車など）はこの属性で示すためである。
*/
.button:disabled,
.button[aria-disabled="true"],
.button:disabled:hover,
.button:disabled:focus,
.button[aria-disabled="true"]:hover,
.button[aria-disabled="true"]:focus {
	background: var(--elsa-button-disabled-bg);
	color: var(--elsa-button-disabled-color);
	opacity: 1;
	cursor: default;
}

/*
	**危険なボタンは押す前から見分けが付く**（2026-09-04、Issue #2955 C6）。

	2026-09-04まで、この規則は`.button`と同じ2行だった。差が出るのは下の
	`@media (hover: hover)`の中だけで、**`hover: none`の端末では危険ボタンが
	普通のボタンと最後まで同じ見た目のままだった。** 削除確認ダイアログを
	実測すると「キャンセル」も「削除」も文字`rgb(102,112,133)`／地`rgb(210,210,210)`で
	同一だった（Issue #2169の横断監査 C6）。指で操作する端末には、押す前に
	見分ける手掛かりが1つも無かったということである。

	静止状態を危険色で塗る。色は`--elsa-danger-color`と`--elsa-danger-contrast`
	だけを読む——**アプリ全体で1つの危険色で、外観設定の対象にしない**と
	決めた組である（Issue #2689 段階3）。だから地色の設定を変えても、
	この対比（#b42318 の上に #ffffff で 6.5:1）は動かない。**ここで実色を
	書かない。**

	`.button-danger`は付いている場所が3つしかない（共通Alertの破壊的な実行
	ボタン・CONTROLLERの削除・外部API接続情報の消去）。どれも取り返しの
	つかない操作なので、静止状態から赤で名乗ってよい。
*/
.button-danger {
	background: var(--elsa-danger-color);
	color: var(--elsa-danger-contrast, #fff);
}

/*
	キーボードのフォーカスでも危険色を保つ。`.button:focus-visible`は地と文字を
	既定色へ戻すため、これが無いとフォーカスした瞬間だけ普通のボタンに見える。
*/
.button-danger:focus-visible {
	background: var(--elsa-danger-color);
	color: var(--elsa-danger-contrast, #fff);
}

.button-danger:disabled:hover,
.button-danger:disabled:focus {
	background: var(--elsa-button-disabled-bg);
	color: var(--elsa-button-disabled-color);
}

.elsaCommonPlusIcon {
	display: inline-block;
	width: 1em;
	height: 1em;
	background: currentColor;
	-webkit-mask: var(--elsa-icon-plus) var(--elsa-icon-plus-mask-position, center) / var(--elsa-icon-plus-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-plus) var(--elsa-icon-plus-mask-position, center) / var(--elsa-icon-plus-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	vertical-align: -0.125em;
	flex: 0 0 auto;
}

.elsaCommonPersonPlusIcon,
.elsaCommonGroupPlusIcon {
	display: inline-block;
	width: 1em;
	height: 1em;
	background: currentColor;
	vertical-align: -0.125em;
	flex: 0 0 auto;
}
.elsaCommonPersonPlusIcon {
	-webkit-mask: var(--elsa-icon-person-plus) var(--elsa-icon-person-plus-mask-position, center) / var(--elsa-icon-person-plus-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-person-plus) var(--elsa-icon-person-plus-mask-position, center) / var(--elsa-icon-person-plus-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaCommonGroupPlusIcon {
	-webkit-mask: var(--elsa-icon-group-plus) var(--elsa-icon-group-plus-mask-position, center) / var(--elsa-icon-group-plus-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-group-plus) var(--elsa-icon-group-plus-mask-position, center) / var(--elsa-icon-group-plus-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

.elsaCommonCloseIcon,
.elsaCommonConfirmIcon,
.elsaCommonDeleteIcon,
.elsaCommonSaveIcon,
.elsaCommonHelpIcon,
.elsaCommonAttentionIcon {
	display: block;
	width: 1em;
	height: 1em;
	background: currentColor;
	flex: 0 0 auto;
}
.elsaCommonCloseIcon {
	-webkit-mask: var(--elsa-icon-close) var(--elsa-icon-close-mask-position, center) / var(--elsa-icon-close-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-close) var(--elsa-icon-close-mask-position, center) / var(--elsa-icon-close-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaCommonConfirmIcon {
	-webkit-mask: var(--elsa-icon-confirm) var(--elsa-icon-confirm-mask-position, center) / var(--elsa-icon-confirm-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-confirm) var(--elsa-icon-confirm-mask-position, center) / var(--elsa-icon-confirm-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaCommonDeleteIcon {
	-webkit-mask: var(--elsa-icon-delete) var(--elsa-icon-delete-mask-position, center) / var(--elsa-icon-delete-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-delete) var(--elsa-icon-delete-mask-position, center) / var(--elsa-icon-delete-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaCommonSaveIcon {
	-webkit-mask: var(--elsa-icon-save) var(--elsa-icon-save-mask-position, center) / var(--elsa-icon-save-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-save) var(--elsa-icon-save-mask-position, center) / var(--elsa-icon-save-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaCommonAttentionIcon {
	-webkit-mask: var(--elsa-icon-attention) var(--elsa-icon-attention-mask-position, center) / var(--elsa-icon-attention-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-attention) var(--elsa-icon-attention-mask-position, center) / var(--elsa-icon-attention-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaCommonHelpIcon {
	-webkit-mask: var(--elsa-icon-help) var(--elsa-icon-help-mask-position, center) / var(--elsa-icon-help-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-help) var(--elsa-icon-help-mask-position, center) / var(--elsa-icon-help-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	ポップアップの帯の図像（Issue #3750 第1回。2026-09-15の利用者決定）

	共通ポップアップの帯へ載るボタンは、画面の帯と同じ28pxのアイコンボタンで
	ある（外形は`.elsaCommandBlock--iconOnly`、図像はここ）。**同じ意味の図像を
	新しく描かず、既存の意味トークンを使う**——失効は`revoke`、停止は`ban`、
	再開は`run`、複製は`copy`である。**失効・停止を`delete`（ゴミ箱）で
	見せない**（`docs/development-policy.md`「5. UI品質」）。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.elsaCommonRevokeIcon,
.elsaCommonBanIcon,
.elsaCommonRunIcon,
.elsaCommonCopyIcon,
.elsaCommonNotificationOffIcon,
.elsaCommonPrintIcon {
	display: block;
	width: 1em;
	height: 1em;
	background: currentColor;
	flex: 0 0 auto;
}
/*
	通知の「後で知らせる」（Issue #4350）。既存の意味トークン
	`--elsa-icon-notification-off`（しばらく鳴らさない）をそのまま通すだけで、
	新しいSVGは増やさない。
*/
.elsaCommonNotificationOffIcon {
	-webkit-mask: var(--elsa-icon-notification-off) var(--elsa-icon-notification-off-mask-position, center) / var(--elsa-icon-notification-off-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-notification-off) var(--elsa-icon-notification-off-mask-position, center) / var(--elsa-icon-notification-off-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaCommonRevokeIcon {
	-webkit-mask: var(--elsa-icon-revoke) var(--elsa-icon-revoke-mask-position, center) / var(--elsa-icon-revoke-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-revoke) var(--elsa-icon-revoke-mask-position, center) / var(--elsa-icon-revoke-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaCommonBanIcon {
	-webkit-mask: var(--elsa-icon-ban) var(--elsa-icon-ban-mask-position, center) / var(--elsa-icon-ban-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-ban) var(--elsa-icon-ban-mask-position, center) / var(--elsa-icon-ban-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaCommonRunIcon {
	-webkit-mask: var(--elsa-icon-run) var(--elsa-icon-run-mask-position, center) / var(--elsa-icon-run-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-run) var(--elsa-icon-run-mask-position, center) / var(--elsa-icon-run-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaCommonCopyIcon {
	-webkit-mask: var(--elsa-icon-copy) var(--elsa-icon-copy-mask-position, center) / var(--elsa-icon-copy-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-copy) var(--elsa-icon-copy-mask-position, center) / var(--elsa-icon-copy-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaCommonPrintIcon {
	-webkit-mask: var(--elsa-icon-print) var(--elsa-icon-print-mask-position, center) / var(--elsa-icon-print-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-print) var(--elsa-icon-print-mask-position, center) / var(--elsa-icon-print-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

/*
	リマインダーの印（Issue #3480）。**共通LISTの機能として実装し、宣言した一覧
	だけに出す**（今はタスク一覧だけ。2026-09-10の利用者決定）。旧「対応が必要」の
	丸いベル（`.elsaListRowProjection`の`::before`、Issue #2767）と旧「!」の丸印
	（`.elsaReminderMarker`のcircle+文字）はどちらもこの1種類へ統合し、それ以外の
	意味では使わない。

	**印は4状態とも同じ図像（ベル／斜線付きベル）で、色だけが状態を伝える**——
	鈴は設定した行だけに出し、色は文字色が既定。警告色になるのは「期限が過ぎた」ときだけ（近い＝文字色。Issue #4348）。
	現時点で通知の「閉じた・後で」の記録は無いため、過ぎていて設定が有効＝警告色とする。
	新しい色を持ち込まない。あり・近い・過ぎたはPHP資産共通notification.svg、
	なしはnotification-off.svgをmaskで使う。

	**セルの中身は差し替えない**（一覧の各列は共通の読み取り専用TEXTで描く契約。
	画面固有の描き方へ替えると長文の折り返しと最小行高の保証が一緒に失われる
	——実ブラウザ検査で実測）。そこで印は**行の先頭セルへ重ねる**。宣言した行
	（`data-reminder-present`を持つ行）だけに空きを作り、宣言していない一覧の
	HTMLは1バイトも変わらない。
*/
[data-reminder-state="danger"] {
	--elsa-reminder-color: var(--elsa-semantic-danger-color, #b42318);
}
.elsaReminderMarker {
	display: inline-flex;
	flex: 0 0 1.1em;
	width: 1.1em;
	height: 1.1em;
	background: currentColor;
	-webkit-mask: var(--elsa-icon-notification) var(--elsa-icon-notification-mask-position, center) / var(--elsa-icon-notification-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-notification) var(--elsa-icon-notification-mask-position, center) / var(--elsa-icon-notification-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
[data-reminder-state="danger"] .elsaReminderMarker {
	color: var(--elsa-reminder-color);
}
[data-reminder-present="0"] .elsaReminderMarker {
	-webkit-mask: var(--elsa-icon-notification-off) var(--elsa-icon-notification-off-mask-position, center) / var(--elsa-icon-notification-off-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-notification-off) var(--elsa-icon-notification-off-mask-position, center) / var(--elsa-icon-notification-off-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	opacity: .5;
}
.elsaReminderMarkerLink,
.elsaReminderMarkerStatic {
	display: inline-flex;
	position: absolute;
	left: .35em;
	top: .7em;
	color: inherit;
}
.elsaReminderMarkerStatic { cursor: default; }
.elsaList tr[data-reminder-present] > td:first-child {
	position: relative;
	padding-left: 1.6em;
}
/* 行の背景・日付の文字色は期限の状態で変えない。鈴の印の色だけが状態を伝える（Issue #4348）。 */

@media (hover: hover) {
	/*
		理由つきの押せないボタン（`aria-disabled="true"`）もホバーで押せそうに見せない（Issue #4525）。
		除外は`:where()`で包み、詳しさを足さない。`:not([aria-disabled])`のままだと詳しさが1段上がり、
		図像のボタンの地色・maskの規則まで上書きして矢印が消えた。この形はファイル内の他の除外も同じ。
	*/
	.button:not(:disabled):not(:where([aria-disabled="true"])):hover {
		background: var(--elsa-primary-color, #24333f);
		color: var(--elsa-primary-contrast, #fff);
	}

	/*
		静止状態も危険色になったので（上の`.button-danger`）、ホバーは
		**地色ではなく縁で**返事をする。色を増やさず、外寸も動かさない
		（`box-shadow`の内側描画で、`.button`は`border: none`のままである）。
	*/
	.button-danger:not(:disabled):not(:where([aria-disabled="true"])):hover {
		background: var(--elsa-button-danger-hover-bg);
		color: var(--elsa-danger-contrast, #fff);
		box-shadow: inset 0 0 0 2px var(--elsa-danger-contrast, #fff);
	}
}

.elsaController {
	display: flex;
	width: 100%;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 8px;
	margin: var(--elsa-controller-spacing, 16px) 0;
	padding: 0;
}

/*
	統合窓（Issue #2169）の右の帯へ収めた版（`option.variant => "band"`）。
	**本文の上下にボタンの塊を残さない**という2026-08-30の利用者決定により、
	これまで本文の上下に置いていた操作は右のペインの帯1か所へ集まる。帯は
	折り返さず、入りきらない道具は共通の畳み（`elsa_pane_window_overflow.js`）が
	「…」へ移すので、ここが外すのは**全幅・折り返し・上下の隙間**だけである。
*/
.elsaController--band {
	width: auto;
	margin: 0;
	flex-wrap: nowrap;
	justify-content: flex-end;
	/*
		**ボタン同士の隙間は窓のトークン**（2026-09-06の利用者指摘「上下左右の隙間が
		画面によって異なる」）。既定の`.elsaController`は8pxで、行の他の道具（6px）と
		食い違っていた。**外の祖先から塗らない**ためにここ（ブロック自身のmodifier）で
		読む（`tests/field_block_style_test.php`）。
	*/
	gap: var(--elsa-pane-window-band-gap, var(--elsa-block-action-gap, 6px));
}

.elsaControllerButton {
	height: var(--elsa-block-action-height);
	min-height: var(--elsa-block-action-height);
	padding: 0 15px;
	margin: 0;
	border-radius: 5px;
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	font-size: 14px;
	line-height: 2;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	アイコンだけのボタン（2026-08-30の利用者指示。⑲）

	統合窓の帯へ入る「新規登録」は**＋のアイコンだけ**にする。帯は横1行で、道具が
	増えるほど文字のぶんだけ先に「…」へ畳まれるため、名前を出さないほうが多くの
	道具が画面に残る。**28×28の正方形**で、指でも押せる大きさを保つ。

	**姿を決めるのはここ1か所**である（出す・出さないの判定は
	`core/php/blocks/controller/button/insert/insert.php`）。LIST型の統合窓画面は
	帯を名乗るだけでこのボタンになり、画面ごとにアイコンボタンを組み立てない。

	**読み上げ名と浮き出しヒントはHTML側が必ず持つ**（`aria-label`／`title`）。
	CSSで文字を消しているのではなく、初めから文字を出していないので、押す前に
	何が起きるかは名前とヒントが伝える（文書エクスプローラーのフォルダ＋・
	ファイル＋と同じ規則）。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.elsaControllerButton--icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	width: 28px;
	min-width: 28px;
	height: 28px;
	min-height: 28px;
	padding: 0;
	flex: 0 0 auto;
}

/*
	正方形の中では、アイコンの縦のずらし（文字の並びに合わせる分）が要らない。
	大きさは**一覧の行の図像と同じ共通トークン**である（2026-09-03の利用者指示）。

	**戻る（左矢印。Issue #4098で上矢印から変更）と削除（ゴミ箱）も同じ大きさで並ぶ**（2026-09-06の利用者指示。
	差し込み文書生成の編集画面 Ver.`8f72957c`。「戻るは文書保存の『ひとつ上へ』と
	同じアイコンボタン、削除はゴミ箱のアイコンボタン」）。保存の図像は
	共通COMMANDのiconOnly寸法規則を使う（Issue #3361）。
*/
.elsaControllerButton--icon > .elsaCommonPlusIcon,
.elsaControllerButton--icon > .elsaCommonPersonPlusIcon,
.elsaControllerButton--icon > .elsaCommonGroupPlusIcon,
.elsaControllerButton--icon > .elsaCommonArrowUpIcon,
.elsaControllerButton--icon > .elsaCommonArrowLeftIcon,
.elsaControllerButton--icon > .elsaCommonDeleteIcon {
	width: var(--elsa-block-action-icon-size);
	height: var(--elsa-block-action-icon-size);
	vertical-align: 0;
}


/*
	Issue #3852 段階2c。`min-height`が字面の行より高いため、箱の中で字面を
	上下中央へ寄せる仕組み（flex＋align-items:center）を自身が持つ。**画面ごとの
	paddingでは調整しない。** 字面そのものの微差は内側の`.elsaInkCenter`が持つ。
*/
.elsaStatusBlock {
	display: flex;
	align-items: center;
	justify-content: center;
	/*  折り返した2行目以降も中央に置く（flexのjustify-contentは1つの箱しか寄せない）。  */
	text-align: center;
	color: var(--elsa-text-muted, #667085);
	flex: 0 0 100%;
	min-height: 1.4em;
}
.elsaStatusBlock:empty { display: none; }
.elsaFieldRow:has(> .right > .elsaStatusBlock:only-child:empty) { display: none; }
/*
	**中身が状態表示だけのボタンエリアは、何も出ていない間は場所を取らない**
	（Issue #3821）。

	保存ボタンを持たない自動保存の画面は、ボタンエリアを「保存しました」を
	出す置き場としてだけ置いている。状態表示が空のとき、`.elsaStatusBlock:empty`
	（1つ上の規則）で中身は消えるが、包み（`.elsaController`）は
	`margin: var(--elsa-controller-spacing, 16px) 0`をそのまま持つため、
	**上下16pxずつ、合わせて32pxの空白**が残っていた。2026-09-19に
	`/settings/ai/`をローカルで描画して実測した（ボタンエリアの置き場から
	「月の予算（円）」の欄まで32px、包みの高さは0px）。同じ形は
	`/application-setting/`など、状態表示だけのボタンエリアを置く設定画面に
	共通である。

	**画面ごとに消さず、包みの側で1つの規則にする。** 1つ上の
	`.elsaFieldRow:has(...)`と同じ考え方で、`:has()`は状態が入った瞬間に
	外れるので、「保存しました」は今までどおり同じ場所へ出る。
	ボタンやリンクを1つでも持つボタンエリアは`:only-child`が外れるため
	対象にならない。

	**消したぶんの隙間は、ボタンエリアを置かない画面と同じ8pxへ戻す。**
	ボタンエリアの直後の行は、上の「CONTROLLER owns its vertical spacing」の
	規則と`:not(.elsaController)`の除外で隙間を0にしている。これは包みが自分で
	16pxを持つからであり、**包みごと消えたあとは根拠が無い。** 戻さないと
	見出しと最初の欄が隙間0で接する（2026-09-19の実測: 直後の欄の
	`padding-top`が0px、ボタンエリアを置かない同じ画面は8px）。
	詳細度は、`#elsaLayout`直下の規則（id付き）と統合窓の中の一般規則の
	両方へ勝つように同じ形を2つ並べる。
*/
.elsaController:has(> .elsaStatusBlock:only-child:empty) { display: none; }
#elsaLayout > .elsaController:has(> .elsaStatusBlock:only-child:empty) + [data-block-type]:not(.elsaController),
.elsaController:has(> .elsaStatusBlock:only-child:empty) + [data-block-type]:not(.elsaController):where(:not(.elsaLineBlock):not(.elsaCommandBlock):not(.elsaFieldHeaderAction):not(.elsaListAction):not(.elsaListActionToggle)) { margin-top: var(--elsa-block-spacing, 8px); }
#elsaLayout > .elsaController:has(> .elsaStatusBlock:only-child:empty) + .block,
.elsaController:has(> .elsaStatusBlock:only-child:empty) + .block:not(.elsaLineRow) { padding-top: var(--elsa-block-spacing, 8px); }

.elsaStatusBlock[data-state="success"] { --elsa-status-state-text: color-mix(in srgb, var(--elsa-semantic-safe-color) 10%, var(--elsa-content-text-color, #333)); color: var(--elsa-status-state-text, #067647); }
.elsaStatusBlock[data-state="error"] { --elsa-status-state-text: color-mix(in srgb, var(--elsa-semantic-danger-color) 10%, var(--elsa-content-text-color, #333)); color: var(--elsa-status-state-text, var(--elsa-danger-color, #b42318)); }

.elsaAlertDialog,
.elsaConfirmationBlock {
	background: transparent;
	border: 0;
	max-width: min(520px, calc(100vw - 32px));
	padding: 0;
	width: 100%;
}

.elsaAlertDialog::backdrop,
.elsaConfirmationBlock::backdrop { background: rgba(17, 24, 39, .55); }
.elsaAlertDialogPanel,
.elsaConfirmationPanel { background: var(--elsa-surface, #ffffff); border-radius: 8px; box-shadow: 0 16px 48px rgba(0, 0, 0, .28); display: grid; gap: 16px; max-height: calc(100vh - 32px); overflow: auto; padding: 24px; }
.elsaAlertDialogTitle,
.elsaConfirmationTitle { font-size: 1.25em; margin: 0; }
/*
	確認ダイアログの本文は改行を保つ。**送る文面をそのまま見せて確かめる**用途
	（お問い合わせの「この内容でAIへ依頼」など）があり、複数行の指示が1行へ
	潰れると何を送るのか読めない。`textContent`で入れるため`pre-wrap`にする。
*/
.elsaAlertDialogMessage,
.elsaConfirmationMessage { margin: 0; overflow-wrap: anywhere; white-space: pre-wrap; }
.elsaAlertDialogField,
.elsaConfirmationField { display: grid; gap: 6px; }
.elsaAlertDialogActions,
.elsaConfirmationActions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
.elsaAlertDialogValidation { color: var(--elsa-danger-color, #b42318); font-size: .875em; }

.elsaListContainer {
	width: 100%;
	min-width: 0;
	max-width: 100%;
	color: var(--elsa-content-text-color, #333333);
	font-size: var(--elsa-form-font-size, 16px);
}

.elsaListContainer--form { margin-top: var(--elsa-block-spacing, 8px); }
.block.edit > .right > .elsaListContainer--form,
.block.insert > .right > .elsaListContainer--form { margin-top: 0; }

.elsaListTools {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	align-items: end;
	gap: 8px;
	margin: 0;
}

/*
	**「削除済を表示」は帯の左のボタン群の末尾**（2026-09-03の利用者決定）。
	母集団の切り替えは検索条件ではないので、検索枠の中に居ると「検索の一部」に
	見えるうえ、キーワードの入力可能幅を文字数ぶん奪っていた。

	統合窓（`is-search-in-band`）では共通クライアントがこの器を左のボタン行の
	末尾へ運ぶ（`core/js/elsa_list.js`）。**運ぶ前・運べないときの置き場が
	ここ**で、道具の行を持たない一覧では検索枠の左に独立して立つ。
*/
.elsaListDeletedToggleSlot {
	grid-column: 1 / -1;
	display: flex;
	align-items: center;
	justify-content: flex-start;
	min-width: 0;
}

.elsaListTools .elsaListSearch {
	display: block;
	grid-column: 1 / -1;
	justify-self: center;
	width: 100%;
	max-width: var(--elsa-list-search-max-width);
	min-width: 0;
}

/*
	キーワードだけ、日付・数値・選択・複合条件のいずれでも同じ幅契約を使う。
	利用可能幅までは100%、広い画面では共通トークンで頭打ちにして中央へ置く。
	検索解除とヘルプをLIST本体の最右端まで離さず、画面固有CSSも不要にする。
*/

/*
	一体型の検索枠（2026-08-15の利用者の指示「検索ボックスですがバラバラにせず、
	V2のように一体型にしてください」）。

	V2（`elsa/php/draw/block/list/search/style.css`）は、枠内の段それぞれに
	`border`を与え、最初の段だけ上を丸め、最後の段だけ下を丸め、2段目以降の
	`border-top`を消して1つの枠に見せていた。V3は**箱が内側の枠線を1つだけ持ち**、
	段の間だけ区切り線を引く。内側のbox-shadowにすることでTEXTと同じ高さへ枠線分を
	加算せず、段の数が増えても線が二重にならない。
*/
.elsaListSearchBox {
	overflow: hidden;
	min-width: 0;
	border: 0;
	border-radius: var(--elsa-field-control-border-radius, 4px);
	background: var(--elsa-surface, #ffffff);
	color: inherit;
	box-shadow: inset 0 0 0 var(--elsa-form-control-border-width) var(--elsa-field-control-border-color, #d2d2d2);
}

.elsaListSearchRow {
	position: relative;
	display: flex;
	align-items: center;
	min-width: 0;
}

/*  Issue #3797: 検索行の区切りも一覧の線として「枠線色」を使う。  */
.elsaListSearchRow + .elsaListSearchRow { box-shadow: inset 0 1px 0 var(--elsa-border-color, #d4d4d4); }

/*
	枠の中の入力は自分の枠線を持たない。枠線は`.elsaListSearchBox`が1つだけ持つ。

	セレクタへ`.elsaListTools`を重ねているのは、下にある
	`.elsaListTools input[type="..."]`（枠線1px）と同じ詳細度では**記述順で負ける**
	ため。順序に頼らず、枠の中であることを条件に勝たせる。
*/
.elsaListTools .elsaListSearchBox input[type="search"],
.elsaListTools .elsaListSearchBox input[type="text"],
.elsaListTools .elsaListSearchBox input[type="date"],
.elsaListTools .elsaListSearchBox select {
	border: 0;
	border-radius: 0;
	background-color: transparent;
}

.elsaListSearchBox input:focus-visible,
.elsaListSearchBox select:focus-visible { outline-offset: -2px; }

.elsaListSearchRow--keyword > input[type="search"] { flex: 1 1 auto; }

.elsaListSearchRow--clear { justify-content: flex-end; padding: 4px 5px; }

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	検索欄の幅（2026-09-03の利用者決定）

	**「×」「？」が両方出ても文字が十分に入る幅を必ず確保する。** 以前は右端の
	操作を`2em`の真円2つで浮かせ、入力の右余白を`4em + 10px`空けていたため、
	統合窓の帯（入力欄の幅が`14em`・狭い画面で`7em`）では**打てる幅が66px、
	狭いPC幅では約24px**しか残っていなかった。

	新しい契約は2つだけである。

	  1. 操作は`--elsa-list-search-action-size`（当たり判定20px）の**枠なしの
	     小さな図像**で、右余白はその2つぶん＋間隔だけを空ける
	  2. 入力欄は`min-width`で**最小の打てる幅**を確保し、帯の空きに応じて広がる

	`14em`から右余白（50px）と左余白を引くと、打てる幅は10emを下回らない。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.elsaListSearch {
	--elsa-list-search-action-size: calc(1em * 1.43);
	--elsa-list-search-action-icon: 12px;
	--elsa-list-search-action-gap: 2px;
	--elsa-list-search-min-width: 14em;
}
.elsaListTools .elsaListSearch input[type="search"] {
	/*
		**下限は容器を超えない。** 375pxで文字サイズを上げると`14em`が画面幅を
		超えるため、そのまま下限にするとページ全体が横スクロールする（2026-09-03の
		実測）。容器いっぱいまでは`14em`を確保し、それより狭いときは容器へ合わせる。
	*/
	min-width: min(var(--elsa-list-search-min-width), 100%);
	padding-right: calc(var(--elsa-list-search-action-size) * 2 + var(--elsa-list-search-action-gap) + 8px);
}
.elsaListSearch input[type="search"]::-webkit-search-cancel-button { appearance: none; }
.elsaListSearchControls {
	position: absolute;
	top: 50%;
	right: 4px;
	display: flex;
	align-items: center;
	gap: var(--elsa-list-search-action-gap);
	transform: translateY(-50%);
}
.elsaListTools .elsaListSearchClearOnly { grid-column: span 1; }

/*
	**基本形は真円の押しボタンのまま残す。** この定義は共通SELECTORの候補欄の
	「×」（`.elsaSelectorSuggestTextRemove`。`core/js/elsa_selector.js`が
	`elsaListFilterClear`を付けて作る）が共有しており、ここを触ると一覧と関係
	ない画面の見た目が変わる。`2em`は文字サイズ14pxのとき28pxである。
*/
.elsaListFilterClear,
.elsaListSearchHelpButton {
	--elsa-list-search-action-size: 2em;
	flex: 0 0 var(--elsa-list-search-action-size);
	display: inline-grid;
	place-items: center;
	box-sizing: border-box;
	width: var(--elsa-list-search-action-size);
	min-width: var(--elsa-list-search-action-size);
	height: var(--elsa-list-search-action-size);
	min-height: var(--elsa-list-search-action-size);
	padding: 0;
	border: 1px solid var(--elsa-border, #d2d2d2);
	border-radius: 50%;
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	font-size: 1em;
	line-height: 1;
	text-decoration: none;
}
.elsaListFilterClear[hidden],
.elsaListSearchError[hidden] { display: none; }
.elsaListFilterClear { background: var(--elsa-button-default-bg, #d2d2d2); color: var(--elsa-button-default-color, #667085); }
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	**検索欄の中の「×」「？」は、入力欄の中の小さな図像である**（2026-09-03の
	利用者決定）

	以前は`2em`の真円に枠と地色を持つ「ボタン風」で、帯の中の押しボタンと見分けが
	付かず、検索枠の見た目を壊していた。当たり判定は20px角（指で押せる下限）まで
	落とし、**枠と地色は持たない。** hoverのときだけ薄く敷く。

	大きさを`em`ではなく`px`で持つのは、入力欄の高さ自体が
	`--elsa-block-action-height`（28px固定）へ揃ったためである。片方だけ文字
	サイズへ追従させると、文字を大きくしたときに図像が欄からはみ出す。

	**上書きは検索枠の中だけに効かせる**（`.elsaListSearch`の子孫）。素の
	`.elsaListFilterClear`は共通SELECTORが共有しているので触らない。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.elsaListSearch .elsaListFilterClear,
.elsaListSearch .elsaListSearchHelpButton {
	--elsa-list-search-action-size: calc(1em * 1.43);
	border: 0;
	border-radius: 4px;
	background: transparent;
	color: var(--elsa-text-muted, #667085);
	cursor: pointer;
}
.elsaListSearch .elsaListFilterClear > .elsaCommonCloseIcon,
.elsaListSearch .elsaListSearchHelpButton > .elsaCommonHelpIcon {
	width: var(--elsa-list-search-action-icon, 12px);
	height: var(--elsa-list-search-action-icon, 12px);
}
@media (hover: hover) {
	.elsaListSearch .elsaListFilterClear:hover,
	.elsaListSearch .elsaListSearchHelpButton:hover {
		border-color: transparent;
		background: var(--elsa-hover-bg, #eaf4ff);
		color: var(--elsa-content-text-color, #333333);
	}
}

/*
	物件情報の2ペイン（Issue #2169）は共通LISTを持たないので、同じ切り替えを
	ツリーの見出しへ置く。**あちらは文字の押しボタンのまま**（見出しの中に1つだけ
	立つので、図像だけでは何の切り替えか読めない）。リンクなので下線だけ外す。
*/
.elsaPropertyTreeDeletedToggle {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	box-sizing: border-box;
	height: var(--elsa-block-action-height, 28px);
	min-height: var(--elsa-block-action-height, 28px);
	padding: 0 .7em;
	border: 1px solid var(--elsa-border, #d2d2d2);
	border-radius: 1em;
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	font: inherit;
	/*  外形（ボタン文字サイズ×2）の基準の文字サイズを自分で持つ（Issue #4935 の決まり2。本文の16pxを継がない）。  */
	font-size: var(--elsa-button-font-size, 14px);
	line-height: 1.2;
	white-space: nowrap;
	cursor: pointer;
	text-decoration: none;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	**削除済みの切り替えは、帯の他の文字ボタンと同じ姿にする**（2026-09-03の利用者指示）

	2026-09-03に置き場が帯の左のボタン群の末尾へ移った結果、**丸いピル型の文字ボタン
	だけが四角いボタンの列に混ざり、同じ行の中で1つだけ作りが違う**状態になっていた
	（利用者が電子帳簿保存の実画面で発見。実測: 角丸14px・枠0.8pxに対し、隣は角丸
	4px・枠なし）。

	揃える相手は**同じ帯の文字ボタン**（「並べ替え」「表示」＝
	`.elsaExplorerListToolbarMenuToggle`）である。高さ・角丸・枠・地色・内側余白を
	そちらへ合わせる。押している間の見た目（`aria-pressed="true"`で色が変わる）は
	従来のまま変えない。

	**図像は持たせていない。** 「削除済みを表示」を表す共通アイコンが無く、素の
	ゴミ箱は2026-08-28に利用者が「行の削除ボタンと混同する」として却下している
	（同じ帯に素のゴミ箱の「削除」が並ぶ画面がある）。図像を足すなら共通の図像を
	1つ新設する判断が要るので、ここでは文字のままにしてある。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.elsaListDeletedToggle {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	box-sizing: border-box;
	height: var(--elsa-block-action-height, 28px);
	min-height: var(--elsa-block-action-height, 28px);
	padding-inline: .65em .5em;
	border: 0;
	border-radius: 4px;
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	font: inherit;
	/*  外形（ボタン文字サイズ×2）の基準の文字サイズを自分で持つ（Issue #4935 の決まり2。本文の16pxを継がない）。  */
	font-size: var(--elsa-button-font-size, 14px);
	line-height: 1.2;
	white-space: nowrap;
	cursor: pointer;
	text-decoration: none;
}
/*
	**表示中だけ色を付ける**（利用者指定）。図像だけでは今どちらなのかが
	`aria-pressed`にしか出ないため、目で見ても分かるようにする。
*/
.elsaListDeletedToggle[aria-pressed="true"],
.elsaPropertyTreeDeletedToggle[aria-pressed="true"] {
	border-color: var(--elsa-primary-color, #24333f);
	background: var(--elsa-primary-color, #24333f);
	color: var(--elsa-primary-contrast, #fff);
}
/*
	検索ボックスの隣に並ぶ「×」と「？」は、同じ図像の大きさで揃える
	（2026-08-18の利用者指示）。**別々の倍率を持たせない。** 以前は「？」だけ
	1.4emで、隣の1.15emより明らかに大きかった。倍率を共有しておけば、外観
	設定で文字サイズを変えても揃ったままになる。

	**大きさは`1em`。** 1.15emは28pxの円に対して図像が勝ちすぎており、利用者が
	実画面で1emを確認して決めた（2026-08-19）。**共通SELECTORが共有している
	基本形の値である**（一覧の検索枠の中だけは上の12pxが勝つ）。
*/
.elsaListFilterClear > .elsaCommonCloseIcon,
.elsaListSearchHelpButton > .elsaCommonHelpIcon { width: 1em; height: 1em; }
.elsaListFilterClear:focus-visible,
.elsaListSearchHelpButton:focus-visible,
.elsaListDeletedToggle:focus-visible,
.elsaPropertyTreeDeletedToggle:focus-visible { outline: 2px solid var(--elsa-primary-color, #24333f); outline-offset: 2px; }
@media (hover: hover) {
	.elsaListFilterClear:hover,
	.elsaListSearchHelpButton:hover,
	.elsaListDeletedToggle:hover,
	.elsaPropertyTreeDeletedToggle:hover { border-color: var(--elsa-primary-color, #24333f); background: var(--elsa-primary-color, #24333f); color: var(--elsa-primary-contrast, #fff); }
}
.elsaListSearchError { margin: 6px 0 0; color: var(--elsa-danger-color, #b42318); font-size: .9em; }
/*
	**一覧の道具の入力欄は帯のボタンと同じ高さ**（2026-09-03の利用者決定）。
	既定の`--elsa-form-control-height`（文字サイズに応じて36〜44px）のままだと、
	統合窓を使っていない画面で検索欄だけが帯のボタンより明らかに高くなる。
	共通の`--elsa-block-action-height`（28px）へ揃え、**画面ごとの上書きを不要に
	する。**
*/
.elsaListTools input[type="search"],
.elsaListTools input[type="text"],
.elsaListTools input[type="date"] {
	width: 100%;
	height: var(--elsa-block-action-height, 28px);
	min-height: var(--elsa-block-action-height, 28px);
	padding: 0 var(--elsa-form-control-padding-inline);
	border: var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius: var(--elsa-field-control-border-radius, 4px);
	color: inherit;
	font: inherit;
	line-height: var(--elsa-form-control-line-height);
	background-color: var(--elsa-surface, #ffffff);
}

.elsaListTools select {
	width: 100%;
	height: var(--elsa-form-control-height);
	min-height: var(--elsa-form-control-height);
	padding: var(--elsa-form-control-padding-block) 28px var(--elsa-form-control-padding-block) var(--elsa-form-control-padding-inline);
	border: var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius: var(--elsa-field-control-border-radius, 4px);
	color: inherit;
	font: inherit;
	line-height: var(--elsa-form-control-line-height);
	background-color: var(--elsa-surface, #ffffff);
}

.elsaListSort {
	display: flex;
	align-items: center;
	color: inherit;
	text-decoration: none;
}

.elsaListSortIcon { display: inline-block; width: .85em; height: .85em; margin-left: .2em; background: currentColor; }
.elsaListSortIcon--asc { -webkit-mask: var(--elsa-icon-arrow-up) var(--elsa-icon-arrow-up-mask-position, center) / var(--elsa-icon-arrow-up-mask-size, var(--elsa-icon-mask-size)) no-repeat; mask: var(--elsa-icon-arrow-up) var(--elsa-icon-arrow-up-mask-position, center) / var(--elsa-icon-arrow-up-mask-size, var(--elsa-icon-mask-size)) no-repeat; }
.elsaListSortIcon--desc { -webkit-mask: var(--elsa-icon-arrow-down) var(--elsa-icon-arrow-down-mask-position, center) / var(--elsa-icon-arrow-down-mask-size, var(--elsa-icon-mask-size)) no-repeat; mask: var(--elsa-icon-arrow-down) var(--elsa-icon-arrow-down-mask-position, center) / var(--elsa-icon-arrow-down-mask-size, var(--elsa-icon-mask-size)) no-repeat; }

.elsaListSort:hover,
.elsaListSort:focus-visible { text-decoration: underline; }

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	列フィルタ（見出しの漏斗。Issue #2169の設計コメント4件が正本）

	図形は共通`filter.svg`の外部`<use>`だけを参照する。線画と塗りの2画像へ
	分けず、**ここにSVGのパスも文字記号も置かない**（`docs/development-policy.md`）。

	パネルは開いている間だけ`<body>`直下の層へ移る（`core/js/elsa_list.js`）。
	表の箱は`contain: paint`で内側を切り落とすため、見出しに置いたままでは
	**行の少ない一覧でパネルの下半分が消える。** 位置は開くときにJSが決めるので、
	ここでは寸法と見た目だけを持つ。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

/*
	漏斗を持つ見出しの中身。**並べ替えのリンクは`display: flex`**なので、
	そのまま漏斗を横へ置くと次の行へ落ちて見出しが2段になる。
*/
.elsaListHeadingInner {
	display: flex;
	align-items: center;
	gap: .1em;
	min-width: 0;
}

.elsaListHeadingInner > .elsaListSort { min-width: 0; }

.elsaList th.elsaListCellNumber > .elsaListHeadingInner { justify-content: flex-end; }

.elsaListColumnFilterControl {
	display: inline-flex;
	vertical-align: middle;
}

.elsaListColumnFilter {
	display: grid;
	place-items: center;
	width: 1.7em;
	height: 1.7em;
	margin-left: .15em;
	padding: 0;
	border: 0;
	border-radius: 3px;
	background: none;
	color: inherit;
	cursor: pointer;
	opacity: .55;
	transition: opacity .12s ease, background-color .12s ease;
}

.elsaListColumnFilter:hover,
.elsaListColumnFilter:focus-visible { opacity: 1; }

/*
	**効いている列は消さない。** 絞り込んだ本人が後から見ても、どの列で絞ったかが
	見出しだけで分かるようにする（外し方が分からない絞り込みを作らない）。

	**印はアイコンの色だけで示し、背景は敷かない**（2026-09-06の利用者指示）。
	以前は不透明度を上げて背景をグレーにしていたが、色をメインカラー
	（`--elsa-primary-color`）へ変えるだけにし、周囲の四角い塗りは無くす。
*/
.elsaListColumnFilter[data-list-column-filter-active="true"] {
	opacity: 1;
	background: none;
	color: var(--elsa-primary-color, #24333f);
}

.elsaListColumnFilterIcon {
	display: block;
	--elsa-filter-icon-size: .95em;
	width: var(--elsa-filter-icon-size);
	height: var(--elsa-filter-icon-size);
	/* Clamp opposing sides proportionally when their sum exceeds this fixed box. */
	padding-top: min(var(--elsa-icon-filter-pad-top, var(--elsa-icon-padding)), calc(var(--elsa-filter-icon-size) * var(--elsa-icon-filter-pad-top-ratio, .5)));
	padding-right: min(var(--elsa-icon-filter-pad-right, var(--elsa-icon-padding)), calc(var(--elsa-filter-icon-size) * var(--elsa-icon-filter-pad-right-ratio, .5)));
	padding-bottom: min(var(--elsa-icon-filter-pad-bottom, var(--elsa-icon-padding)), calc(var(--elsa-filter-icon-size) * var(--elsa-icon-filter-pad-bottom-ratio, .5)));
	padding-left: min(var(--elsa-icon-filter-pad-left, var(--elsa-icon-padding)), calc(var(--elsa-filter-icon-size) * var(--elsa-icon-filter-pad-left-ratio, .5)));
	fill: none;
	stroke: currentColor;
}
.elsaCommandBlock--iconOnly > .elsaListColumnFilterIcon { --elsa-filter-icon-size: var(--elsa-block-action-icon-size); }

.elsaListColumnFilter[data-list-column-filter-active="true"] .elsaListColumnFilterIcon,
.elsaListColumnFilterIcon[data-list-column-filter-active="true"] { fill: currentColor; }

/*
	パネルの置き場所（表の外）。閉じているパネルは`hidden`なので何も見えないが、
	**器自体が行間を作らない**ように高さを持たせない。
*/
.elsaListColumnFilterPanels {
	display: contents;
}

.elsaListColumnFilterPanel {
	position: fixed;
	z-index: 60;
	box-sizing: border-box;
	width: min(280px, calc(100vw - 24px));
	max-height: min(320px, calc(100vh - 24px));
	overflow-y: auto;
	padding: 8px;
	border: 1px solid var(--elsa-border, #d2d2d2);
	border-radius: 4px;
	background: var(--elsa-surface, #ffffff);
	box-shadow: 0 6px 18px rgba(0, 0, 0, .18);
	font-size: var(--elsa-form-font-size, 16px);
	font-weight: normal;
	text-align: left;
	white-space: normal;
}

.elsaListColumnFilterPanel[hidden] { display: none; }

/*
	開くときの動きは**位置が動く**ため、`prefers-reduced-motion`では止める。
	透明度のフェードは残す（2026-08の確定方針）。
*/
@media (prefers-reduced-motion: no-preference) {
	.elsaListColumnFilterPanel { animation: elsaListColumnFilterOpen .12s ease-out; }
}

@keyframes elsaListColumnFilterOpen {
	from { opacity: 0; transform: translateY(-4px); }
	to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
	.elsaListColumnFilterPanel { animation: elsaListColumnFilterFade .12s ease-out; }
}

@keyframes elsaListColumnFilterFade {
	from { opacity: 0; }
	to { opacity: 1; }
}

.elsaListColumnFilterTitle {
	margin: 0;
	font-weight: bold;
}

.elsaListColumnFilterChoices {
	margin: 0;
	padding: 0;
	list-style: none;
}

.elsaListColumnFilterChoice {
	display: flex;
	align-items: center;
	gap: 6px;
	box-sizing: border-box;
	width: 100%;
	/*  指で押せる高さ（スマホ幅でも1件ずつ確実に押せる）。  */
	min-height: 32px;
	padding: 2px 4px;
	border-radius: 3px;
	cursor: pointer;
}

.elsaListColumnFilterChoice:hover,
.elsaListColumnFilterChoice:focus-within { background-color: var(--elsa-hover-bg, #eaf4ff); }

.elsaListColumnFilterChoiceLabel {
	flex: 1 1 auto;
	min-width: 0;
	overflow-wrap: anywhere;
}

.elsaListColumnFilterChoiceCount {
	flex: 0 0 auto;
	color: var(--elsa-text-muted, #667085);
	font-variant-numeric: tabular-nums;
}

/*
	範囲の2種（日付・数値）は**同じ形**で置く。呼び名だけが「開始・終了」と
	「下限・上限」で違い、並びも入力の幅もそろえる——同じ一覧の中で列ごとに
	パネルの形が変わると、どの列を触っているのか目で追う手数が増える。
*/
.elsaListColumnFilterDates,
.elsaListColumnFilterNumbers {
	display: grid;
	gap: 6px;
}

.elsaListColumnFilterDate,
.elsaListColumnFilterNumber {
	display: grid;
	grid-template-columns: 3em 1fr;
	align-items: center;
	gap: 6px;
}

.elsaListColumnFilterDate > input[type="date"],
.elsaListColumnFilterNumber > input[type="number"] { min-width: 0; }

.elsaListColumnFilterEmpty {
	margin: 6px 0 0;
	color: var(--elsa-text-muted, #667085);
	font-size: .85em;
}

.elsaListColumnFilterHead {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--elsa-block-spacing, 8px);
	margin-bottom: var(--elsa-block-spacing, 8px);
}

.elsaListScroll {
	box-sizing: border-box;
	width: 100%;
	max-width: 100%;
	overflow-x: auto;
	contain: inline-size paint;
	margin: 0;
	border: 1px solid var(--elsa-border, #d2d2d2);
	border-radius: 4px;
}

/*
	`option.scroll_body`を宣言した一覧だけ、**箱が自分で縦にも送る**
	（2026-08-30、Issue #2169の統合窓）。検索枠を右の帯へ出すにはペインの箱を
	`display: contents`で透かす必要があり、**透かした箱はもう送れない**ためである。

	追加読み込みの見張りも箱の中に居るので（`core/php/blocks/list/list.php`）、
	下まで送ったときだけ次を読む。端まで送ってもページごと動かない。
*/
.elsaListScroll--body {
	min-height: 0;
	overflow: auto;
	overscroll-behavior: contain;
}

.elsaListTools + .elsaListScroll,
.elsaListReorderStatus:has(.elsaStatusBlock:not(:empty)) + .elsaListScroll {
	margin-top: var(--elsa-block-spacing, 8px);
}

/*
	表の幅は中身の自然な幅にする（2026-08-15の利用者の指示）。

	`width: 100%`だけだと、列の合計が容器より広い一覧で**全列がmin-content幅まで
	潰れる**。入力で描く列は`size`があるので潰れないが、素のテキストの列は
	`overflow-wrap: anywhere`と相まって極端に細くなり、商品名のような列が数文字ずつ
	折り返す。以前は`min-width: 10em`がこれを隠していた（375pxの実測で商品名の列が
	64pxまで潰れた）。

	`width: max-content`で各列が中身どおりの幅を取り、`min-width: 100%`で中身が
	少ないときは容器いっぱいへ広げる（右端がぎざぎざにならない）。はみ出した分は
	`.elsaListScroll`の中だけを横スクロールする。1列が長すぎて表を食い尽くさない
	ようにする上限は、セルの`max-width`と入力の`size`が持つ。
*/
.elsaList {
	width: max-content;
	min-width: 100%;
	border-spacing: 0;
}

/*
	列幅は内容に追従する（2026-08-15の利用者の指示「LISTブロックですがセルの内容に
	セル幅が追従するようにしてください」）。

	以前は全データ列へ`min-width: 10em`を敷いていた（2026-08-06。画面ごとに
	「全列を圧縮する一覧」と「折り返して横スクロールする一覧」が混在していたのを
	揃えるため）。**揃える目的は達したが、内容が2文字の列も10em取るため、
	項目の多い一覧が不必要に横へ伸びていた。** 最小幅を撤去し、代わりに

	- 見出しの`white-space: nowrap`が「項目名は必ず1行で読める」下限を持つ
	- セルがreadonly入力で描かれる列は、入力の`size`が中身の表示幅を持つ
	  （`core/php/blocks/text/text.php`。`size`が無いと入力の固有幅は既定の
	  20文字で頭打ちになり、内容に追従しない）

	の2つで幅を決める。長い内容は上限で頭打ちにして折り返す（入力の列は`size`の
	上限、素のテキストの列は`overflow-wrap`）ため、1列が表を食い尽くさない。
	画面幅を超えた分は従来どおり`.elsaListScroll`の中だけを横スクロールする。
*/
.elsaList th,
.elsaList td {
	min-width: 2.5em;
	/*  Issue #3797: 見出し・セルの線は外観設定の「枠線色」を使う（自動計算の--elsa-borderから移した）。  */
	border-right: 1px solid var(--elsa-border-color, #d4d4d4);
	border-bottom: 1px solid var(--elsa-border-color, #d4d4d4);
	text-align: left;
	vertical-align: middle;
	line-height: 1.4;
}

/*
	見出し行の地色は外観設定「右ペイン › ラベル背景色」（`field_tab_background_color`
	→`--elsa-field-tab-background-color`）を読む（2026-09-16のオーナー決定・
	Issue #3798）。それまではベース色（`--elsa-surface-sunken`）を直に読んでおり、
	ラベルタブの色を変えても一覧の見出し行には反映されなかった。
*/
.elsaList th {
	padding: 7px 8px;
	background: var(--elsa-field-tab-background-color, #f0f0f0);
	font-weight: 700;
	white-space: nowrap;
}

/*
	素のテキストの列の上限。ここを超える中身は列を広げずに折り返す。表が
	`width: max-content`で伸びるようになったため、上限が無いと長い1列が
	表全体を押し広げる。入力で描く列の同じ役目は`size`の上限が持つ。
*/
.elsaList td {
	max-width: 24em;
	padding: 4px 8px;
	overflow-wrap: anywhere;
}

/* LIST列が明示した長文だけを1行に保ち、完全値はセルのtitleで読めるようにする。 */
.elsaList td.elsaListCellNowrap {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	overflow-wrap: normal;
}

.elsaList td.elsaListCellField { padding: 0; }

/*
	数値の列は右揃え＋桁が縦にそろう字形（2026-08-28の利用者決定、Issue #2169）。

	**見出しも本文と同じ側へ寄せる**（会計帳票の一般作法）。数字だけ右で見出しが
	左に残ると、どの見出しがどの列かを目で追う手数が増える。

	`font-variant-numeric: tabular-nums`は、数字1文字ぶんの幅を全て同じにする
	字形へ切り替える。既定のプロポーショナル字形では「1」が細く「0」が太いため、
	右端を揃えても桁の位置は縦にそろわない。

	**どの列が数値かはCSSでは決まらない。** 判定は
	`core/php/function/list_column_align.php`の1か所が持ち、LISTブロックが
	`<th>`と`<td>`へこのクラスを付ける。CSSはその印を塗るだけにする。

	**寄せは「表（`.elsaList`）の中かどうか」だけで決まる**（Issue #5088、2026-10-17の
	オーナー決定）。表は一覧と明細の両方で、明細の表（`sales_document_lines`）も
	金額・原価・粗利・合計のセル（`<td>`でも中の`<div>`でも）へ同じ印を付ける。
	ブロックや画面のCSSで数字を右へ寄せない。表の外では印を付けても効かない。

	セルの中の入力欄・読み取り専用表示は、この`text-align`では動かない
	（`<input>`はブラウザ既定の`text-align: start`を持ち、容器の寄せを継承
	しない）。**そこはTEXTブロック自身の`[data-align="number"]`が受け持つ**
	（上の`.elsaText[data-align="number"]`）。セルの祖先セレクタから子ブロックを
	装飾しない、という`docs/architecture.md`の規則を守るためである。
*/
.elsaList .elsaListCellNumber {
	text-align: right;
	font-variant-numeric: tabular-nums;
}

/*
	並べ替えできる見出しの中身は`.elsaListSort`がflexで並べるため、
	`text-align`では動かない。三角の印を文字の右に付けたまま、まとまりごと
	右端へ寄せる。
*/
.elsaList th.elsaListCellNumber > .elsaListSort { justify-content: flex-end; }

/*
	操作列は一覧の右端へ貼り付ける（2026-08-28の利用者決定）。

	項目の多い一覧では、編集・プレビュー・削除が最後の列にあるため、
	**右端まで横スクロールしないと押せなかった。** `position: sticky`で
	`.elsaListScroll`の内側の右端へ留めると、どこまでスクロールしていても
	操作へ手が届く。表が容器に収まっている一覧では貼り付く先が本来の位置と
	同じなので、見た目は何も変わらない。
*/
.elsaList th.elsaListActionHeading,
.elsaList td.elsaListCellAction {
	position: sticky;
	right: 0;
	z-index: 2;
	width: 1%;
	min-width: 2em;
	padding: 3px;
	text-align: center;
}

.elsaListActionGroup {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 3px;
	flex-wrap: nowrap;
	white-space: nowrap;
	vertical-align: middle;
	line-height: 1;
}

.elsaList th:last-child,
.elsaList td:last-child { border-right: none; }

/*
	差し戻し: 区分行（`.elsaListSection`）が一覧の最終行のとき、この規則の詳細度
	（class 2 / type 3）が`.elsaListSectionCell`の下線（class 2 / type 1）に
	勝ってしまい、区分行の下線だけが消えていた（合成DOMで確認）。区分行は
	この規則の対象から外し、区分行自身の下線をそのまま出す。
*/
.elsaList tbody tr:last-child:not(.elsaListSection) td { border-bottom: none; }

/*
	**行の地色は行が変数として1つだけ持つ。**

	左右へ貼り付けたセルの下は、他の列がそのまま通り抜ける。地が透けていると
	重なった文字が読めてしまうため、貼り付くセルは不透明でなければならない。
	地色を`td`ごとに直接書く作りのままだと、偶数行・hover・選択・選択不可・
	削除済み・インライン追加の状態ぶんだけ「不透明にする書き足し」が要り、
	状態が1つ増えるたびに書き忘れが**その状態の行でだけ文字が重なる**不具合になる。
	行が変数を持ち、全ての`td`がそれを塗る形にすれば、状態が増えても
	貼り付くセルの地は自動的に揃う。

	既定は右ペインの背景色（外観設定の`--elsa-surface`）に従う。
*/
.elsaList tbody tr { --elsa-list-row-bg: var(--elsa-surface, #ffffff); }
.elsaList tbody tr:nth-child(even) { --elsa-list-row-bg: var(--elsa-surface-sunken, #f5f7f9); }
/*
	行のホバーはTREEと同じ1つの項目である（2026-09-02の利用者決定）。
	一覧だけ別の水色（#f2f7fa）を持っていたのを寄せた。
*/
.elsaList tbody tr:hover { --elsa-list-row-bg: var(--elsa-hover-bg, #eaf4ff); }
.elsaList tbody td { background: var(--elsa-list-row-bg); }

/*
	まとまりの見出し（`option.section_column`。2026-08-30・Issue #2169 統合順3番）。

	社内マニュアルの目次のように、行の上へ「章・分類」を1本立てる。**行ではなく
	区切りに見える**ようにするため、地色は行の縞から外し、上に線を1本置く。
	最初の見出しには上の線を出さない（表の頭のすぐ下で線が二重になる）。

	`:hover`の色を継がせない。見出しは押せないので、指せる行に見えてはいけない。
*/
.elsaList tbody tr.elsaListSection,
.elsaList tbody tr.elsaListSection:nth-child(even),
.elsaList tbody tr.elsaListSection:hover { --elsa-list-row-bg: var(--elsa-surface, #ffffff); }

.elsaList tbody .elsaListSectionCell {
	background: var(--elsa-list-row-bg);
	/*  Issue #3797: 区分行の線も一覧の他の線と同じ「枠線色」を使う。  */
	border-top: 2px solid var(--elsa-border-color, #d4d4d4);
	border-bottom: 1px solid var(--elsa-border-color, #d4d4d4);
	padding: .55em .7em .35em;
	text-align: left;
	font-weight: 700;
	font-size: .95em;
	color: var(--elsa-primary-color, #24333f);
}

.elsaList tbody tr.elsaListSection:first-child .elsaListSectionCell { border-top: none; }

/*
	貼り付いた列の縁の影は、**その下を実際に列が通っているときだけ**出す。

	表が容器に収まっていて何も隠れていないのに影が出ると、押せない縦線が
	1本増えたようにしか見えない。「今どちら側に続きがあるか」は横スクロールの
	位置でしか分からないため、判定は`core/js/elsa_list.js`が行い、ここは
	付いたクラスに応じて影を描くだけにする。
*/
.elsaListScroll--pinnedRight .elsaList th.elsaListActionHeading,
.elsaListScroll--pinnedRight .elsaList td.elsaListCellAction {
	box-shadow: -6px 0 6px -6px rgba(0, 0, 0, .35);
}

.elsaListScroll--pinnedLeft .elsaList th.elsaListSelectionColumn,
.elsaListScroll--pinnedLeft .elsaList td.elsaListSelectionColumn {
	box-shadow: 6px 0 6px -6px rgba(0, 0, 0, .35);
}

/*
	行選択（LISTのoption["row_select"]）。SHIFTクリックの範囲選択で
	表の文字列が反転しないよう、行の文字列選択を止める。CHECKBOXや
	操作リンクは通常どおり押せる。
*/
.elsaListContainer--rowSelect .elsaList tbody tr {
	cursor: pointer;
	-webkit-user-select: none;
	user-select: none;
}

/*
	行そのものを選択操作にする一覧では、内部状態を保持するCHECKBOX列を
	画面から除く。選択状態は行の背景色、キーボード操作はフォーカスした行の
	Spaceキーで伝える。
*/
.elsaList .elsaListSelectionControl { display: none; }

/*
	チェック列を見せる行選択の一覧は、その列を**左端へ貼り付ける**
	（2026-08-28の利用者決定「左右両固定・中央スクロール」）。

	どこまで横へスクロールしても「どの行を選んでいるか」と「選ぶ手段」が
	画面から出ていかない。列が先頭にあるときだけ貼り付ける判定はLISTブロックが
	行い（`elsaListSelectionColumn`）、`left: 0`が正しい位置になることを保証する。
	行そのものを選択操作にする一覧（`row_select_control = row`）はこの列を
	隠しているため、対象にしない。
*/
.elsaListContainer--rowSelect[data-list-row-selection-control="checkbox"] .elsaList th.elsaListSelectionColumn,
.elsaListContainer--rowSelect[data-list-row-selection-control="checkbox"] .elsaList td.elsaListSelectionColumn {
	position: sticky;
	left: 0;
	z-index: 2;
}

.elsaListContainer--rowSelect[data-list-row-selection-control="row"] .elsaList tbody tr:focus-visible {
	outline: 2px solid var(--elsa-primary-color, #24333f);
	outline-offset: -2px;
}

/*
	読み取り専用の欄はクリックを受け取らない。一覧の列の多くはreadonlyの
	入力で描かれるため、そのままだと行の大半が「押しても選ばれない」帯になる。
*/
.elsaListContainer--rowSelect .elsaList tbody td input[readonly],
.elsaListContainer--rowSelect .elsaList tbody td input[disabled],
.elsaListContainer--rowSelect .elsaList tbody td textarea[readonly],
.elsaListContainer--rowSelect .elsaList tbody td textarea[disabled] {
	pointer-events: none;
}

.elsaListContainer--rowSelect .elsaList tbody tr.elsaListRowSelected {
	--elsa-list-row-bg: var(--elsa-selected-bg, #dceeff);
}

.elsaListContainer--rowSelect .elsaList tbody tr.elsaListRowSelected td {
	color: var(--elsa-selected-color);
}

.elsaListContainer--rowSelect .elsaList tbody tr.elsaListRowSelected > .elsaListSelectionControl + td {
	box-shadow: inset 4px 0 0 var(--elsa-primary-color, #24333f);
}

/*
	選択できない行（取消済みの出荷単位など）。**見えるが操作できない**ことが
	一目で分かるよう薄く見せ、クリックのカーソルも出さない。
*/
.elsaListContainer--rowSelect .elsaList tbody tr.elsaListRowUnselectable {
	cursor: default;
	opacity: 0.55;
}

.elsaListContainer--rowSelect .elsaList tbody tr.elsaListRowUnselectable {
	--elsa-list-row-bg: var(--elsa-surface-sunken, #f5f7f9);
}

/*
	画面へ浮く丸い操作ボタン（V2の出荷指示と同じ形）。

	利用者の指摘（2026-08-14）:「出荷指示画面の右や下にある操作ボタンが
	再現できていません（丸いボタン）」。前日に「右端固定は狭い端末で一覧へ
	重なるため形を変えた」と判断したが、**不採用**となった。V2はこの作りで
	実運用されており、一覧へ重なることも含めてV2どおりにする。

	V2の実装（`contents/html/amazon/amazon_ship_instruct/style.css`）:
	- `.amazon_ship_fix_button` … `position: fixed; display:flex; gap:20px; z-index:9`
	- `.right` … `height:100%; top:0; right:30px; flex-direction:column`（縦の中央へ並ぶ）
	- `.bottom` … `left:calc(50% - 70px + 110px); bottom:30px`（下部の中央やや右）
	- 子は一律 `width:60px; height:60px; border-radius:30px`
	- 日付は `:hover` で `width:200px` へ広がり、隠れている `input[type=date]` が出る

	中身は登録済みブロック（Command・Status・TEXT）のままで、この要素は
	**位置だけを決める容器**である（`docs/development-policy.md`「3. ブロック優先」の
	「意味や表示を持たない配置コンテナ」）。
*/
.elsaFixedActionColumn,
.elsaFixedActionBar {
	--elsa-fixed-action-size: 60px;
	--elsa-fixed-action-radius: calc(var(--elsa-fixed-action-size) / 2);
	--elsa-fixed-action-expanded-width: 228px;
	position: fixed;
	z-index: 9;
	display: flex;
	gap: 20px;
	margin-top: 0 !important;
}

/*
	右端の縦列。V2と同じく画面の高さいっぱいを占め、中身を縦の中央へ寄せる。
	`width: 0`にしているのもV2どおりで、透明な柱が一覧のクリックを奪わないようにする。
	ボタン自身は`pointer-events`を戻す。
*/
.elsaFixedActionColumn {
	top: 0;
	right: 30px;
	width: 0;
	height: 100%;
	flex-direction: column;
	justify-content: center;
	align-items: flex-end;
	pointer-events: none;
}

.elsaFixedActionColumn > * { margin: 0 !important; pointer-events: auto; }

/*
	下部の確定・取消。**入力画面（左メニューを除いた領域）の中央**へ置く。
	V2も左メニュー200pxの半分だけ右へ寄せていた（`calc(50% - 70px + 110px)`）。
*/
.elsaFixedActionBar {
	left: calc(50% + var(--elsa-content-left, 0px) / 2);
	/*
		**下に何か居るぶんだけ持ち上げる**（2026-08-31・Issue #2169 統合順5番 段階4）。
		V2は画面の下端から30pxで、下には何も無かった。統合窓では最下段に情報表示の帯が
		在るので、そのぶん持ち上げないと**確定・取消のボタンが帯に重なる。**
		既定は0なので、窓の外（従来の画面）の位置は1pxも変わらない。
	*/
	bottom: calc(30px + var(--elsa-fixed-action-bottom-inset, 0px));
	transform: translateX(-50%);
	justify-content: center;
	align-items: center;
}

/*
	丸ボタンの共通の見た目。**色はV2の実装をそのまま写す**
	（2026-08-14の利用者指摘「各ボタンの色も異なっています」）。

	V2は丸ごとに違う色を持っていたのではなく、**状態で色が変わる**。
	根拠は`elsa/html/center/center.css`の`.button`と`elsa/css/default.css`の変数。

		通常   文字 #555   地 #d2d2d2   (--center_button_default_font / _bg)
		hover  文字 #fff   地 #028dff   (--center_button_hover_font / _bg)

	**無効の色だけはV2を写さない。** V2は文字だけ白（1.51:1）にしていたが、
	2026-08-28の利用者決定でアプリ共通の無効色（`--elsa-button-disabled-*`）へ
	統一した。詳しくは下の`.elsaFixedActionColumn > .button:disabled`の注記。

	丸の地色は`.amazon_ship_fix_button > *`が全ての子へ`#d2d2d2`を敷いていた
	（選択件数の`<p>`と日付の`<div>`も同じ地色になる）。
	**影は付けない。** V2に無く、付けると別物に見える。
*/
.elsaFixedActionColumn > *:not(.elsaFixedActionCarriers),
.elsaFixedActionBar > * {
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	flex: 0 0 auto;
	box-sizing: border-box;
	width: var(--elsa-fixed-action-size);
	height: var(--elsa-fixed-action-size);
	min-width: var(--elsa-fixed-action-size);
	min-height: var(--elsa-fixed-action-size);
	padding: 0;
	border: 0;
	border-radius: var(--elsa-fixed-action-radius);
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	font-size: 1.1em;
	font-weight: bold;
	line-height: 1.2;
	text-align: center;
	/*  「N件\n確定」のように改行を含む文言をそのまま2行で出す（V2の<br>と同じ）。  */
	white-space: pre-line;
	overflow: hidden;
}

/*  V2の`.button:not(.off):not(:disabled):hover` と `:focus`。  */
.elsaFixedActionColumn > .button:not(:disabled):not(:where([aria-disabled="true"])):hover,
.elsaFixedActionColumn > .button:not(:disabled):not(:where([aria-disabled="true"])):focus,
.elsaFixedActionBar > .button:not(:disabled):not(:where([aria-disabled="true"])):hover,
.elsaFixedActionBar > .button:not(:disabled):not(:where([aria-disabled="true"])):focus,
.elsaFixedActionCarriers > .button:not(:disabled):not(:where([aria-disabled="true"])):hover,
.elsaFixedActionCarriers > .button:not(:disabled):not(:where([aria-disabled="true"])):focus {
	background: var(--elsa-fix-button-hover-bg, #028dff);
	color: var(--elsa-fix-button-hover-color, #fff);
}

/*
	**無効の色だけはV2互換の例外**（2026-08-28の利用者決定。Issue #2169の監査H5）。

	V2の`.button:disabled`は地色#d2d2d2のまま文字だけ白にしていた。写すと
	明暗差は1.51:1で、押せないのか文字が消えたのか読み取れない。位置・寸法・
	通常色・hover色はV2のまま写し、**無効のときの地と文字だけ**アプリ共通の
	`--elsa-button-disabled-*`へ寄せる。

	このセレクタが残っているのは色を上書きするためではなく、上の
	`.elsaFixedActionColumn > *:not(...)`（0,3,0）が`.button:disabled`（0,2,0）より
	詳しく、譲らせるには同じ詳しさが要るためである。**実色をここへ書かないこと。**
*/
.elsaFixedActionColumn > .button[aria-disabled="true"],
.elsaFixedActionBar > .button[aria-disabled="true"],
.elsaFixedActionCarriers > .button[aria-disabled="true"],
.elsaFixedActionColumn > .button:disabled,
.elsaFixedActionBar > .button:disabled,
.elsaFixedActionCarriers > .button:disabled {
	background: var(--elsa-button-disabled-bg);
	color: var(--elsa-button-disabled-color);
	opacity: 1;
	cursor: default;
}

/*  選択件数のバブル。V2は数字だけを大きく出していた。  */
.elsaFixedActionColumn > .elsaStatusBlock {
	font-size: 1.8em;
	font-weight: bold;
}

/*
	日付の丸。月と日を2行で出し、hover・focusで横へ広がって日付入力が現れる。
	**V2はhoverだけだった。** タッチ端末とキーボードでも開けるよう、
	`:focus-within`と「押したら開く」（JS）を足してある。
*/
.elsaFixedActionDate {
	position: relative;
	gap: var(--elsa-block-spacing, 8px);
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	overflow: hidden;
	transition: width 0.3s ease;
}

.elsaFixedActionDate:hover,
.elsaFixedActionDate:focus-within {
	width: var(--elsa-fixed-action-expanded-width);
	flex-direction: row;
	justify-content: flex-start;
	align-items: center;
	padding: 6px 10px;
}

/*
	丸の中の日付が断られたとき（Issue #5057）は、丸そのものに赤枠を出す。畳んだ丸では
	日付の入力欄が隠れているので、入力欄の赤枠だけでは利用者にどの丸か見えない。
*/
.elsaFixedActionDate:has(.elsaField[aria-invalid="true"]) {
	box-shadow: 0 0 0 2px var(--elsa-danger-color, #b42318);
}

.elsaFixedActionDate .elsaStatusBlock {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 calc(var(--elsa-fixed-action-size) - 12px);
	box-sizing: border-box;
	width: calc(var(--elsa-fixed-action-size) - 12px);
	height: calc(var(--elsa-fixed-action-size) - 12px);
	min-height: 0;
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	font-size: 1.15em;
	font-weight: bold;
	line-height: 1.2;
	white-space: pre-line;
	text-align: center;
	overflow: hidden;
}

/*
	入力欄と項目名は普段は見えない。広がったときはFIELDブロックの項目名を
	入力欄の上へ出し、どちらの日付を操作しているか分かるようにする。
*/
.elsaFixedActionDate .elsaFieldRow { display: none; }
.elsaFixedActionDate .elsaFieldRow > .left { display: none !important; }

.elsaFixedActionDate:hover .elsaFieldRow,
.elsaFixedActionDate:focus-within .elsaFieldRow {
	display: grid;
	position: absolute;
	top: 6px;
	right: 10px;
	box-sizing: border-box;
	width: calc(100% - var(--elsa-fixed-action-size) - 16px);
	min-width: 0;
	height: calc(100% - 12px);
	margin: 0 !important;
	padding: 0;
	grid-template-rows: 14px minmax(0, 1fr);
	row-gap: 2px;
}

.elsaFixedActionDate:hover .elsaFieldRow > .left,
.elsaFixedActionDate:focus-within .elsaFieldRow > .left {
	display: flex !important;
	align-items: center;
	justify-content: flex-start;
	box-sizing: border-box;
	width: 100%;
	min-width: 0;
	min-height: 0;
	height: 14px;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--elsa-button-default-color, #667085);
	font-size: 0.7rem;
	font-weight: normal;
	line-height: 14px;
	text-align: left;
	white-space: nowrap;
}

.elsaFixedActionDate:hover .elsaFieldRow > .left > p,
.elsaFixedActionDate:focus-within .elsaFieldRow > .left > p {
	width: 100%;
	margin: 0;
	overflow: hidden;
	text-overflow: ellipsis;
}

.elsaFixedActionDate .elsaFieldRow > .right {
	display: block;
	position: static;
	box-sizing: border-box;
	width: 100%;
	min-width: 0;
	min-height: 0;
	height: 100%;
	margin: 0;
}

.elsaFixedActionDate .elsaText {
	display: block;
	box-sizing: border-box;
	width: 100%;
	max-width: 100%;
	min-width: 0;
	height: 100%;
	/*
		共通`.elsaText`の`min-height: var(--elsa-form-control-height)`（約35px）を
		打ち消す。V2の丸を60pxへ揃えた際、この床が`height: 100%`より優先され
		（`min-height`は`height`より常に勝つ）、日付入力が丸の下端から6px未満まで
		はみ出した（2026-09-01）。ここは丸の中の専用の小さな入力で、共通FIELDの
		既定の高さに従う必要が無い。
	*/
	min-height: 0;
	padding: 2px 6px;
	border: var(--elsa-form-control-border-width, 1px) solid var(--elsa-field-control-border-color, #d2d2d2);
	background: var(--elsa-surface, #ffffff);
	font-size: 0.85rem;
}

/*
	運送業者の丸ボタンは社数が増えるとこの列だけが伸びる。画面の高さを超えたら
	ここだけを縦スクロールさせ、下の指示解除が画面外へ出ないようにする。
*/
.elsaFixedActionCarriers {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 20px;
	flex: 0 1 auto;
	max-height: 50vh;
	overflow-y: auto;
	pointer-events: auto;
	padding: 0;
	scrollbar-width: none;
}

.elsaFixedActionCarriers::-webkit-scrollbar { width: 0; height: 0; }

.elsaFixedActionCarriers > .button {
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	flex: 0 0 auto;
	box-sizing: border-box;
	width: var(--elsa-fixed-action-size);
	height: var(--elsa-fixed-action-size);
	min-width: var(--elsa-fixed-action-size);
	min-height: var(--elsa-fixed-action-size);
	margin: 0 !important;
	padding: 0;
	border: 0;
	border-radius: var(--elsa-fixed-action-radius);
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	font-size: 0.95em;
	font-weight: bold;
	line-height: 1.2;
	text-align: center;
	white-space: pre-line;
	overflow-wrap: anywhere;
	overflow: hidden;
}


/*
	狭い画面。V2は横幅の想定が机上のPCだけだったため、そのままでは一覧を覆う。
	**位置と形はV2のまま**で、余白と直径だけを詰める。
*/
@media (max-width: 767px) {
	.elsaFixedActionColumn,
	.elsaFixedActionBar {
		--elsa-fixed-action-size: 56px;
		--elsa-fixed-action-expanded-width: 216px;
	}
	.elsaFixedActionColumn { right: 8px; gap: 10px; }
	.elsaFixedActionBar { bottom: 12px; gap: 10px; }
	.elsaFixedActionColumn > *:not(.elsaFixedActionCarriers),
	.elsaFixedActionBar > *,
	.elsaFixedActionCarriers > .button {
		font-size: 0.85em;
	}
	.elsaFixedActionCarriers { gap: 10px; max-height: 45vh; }
	.elsaFixedActionColumn > .elsaStatusBlock { font-size: 1.4em; }
}

/*
	V2の`fix_menu`ブロック（画面右端の▲▼と見出しジャンプ）。

	V2は`elsa/php/field/_block/fix_menu/`が本文の見出し（LINEブロック）を読み、
	`▲`（先頭へ）＋見出し＋`▼`（末尾へ）の縦並びを`<body>`へ足していた。
	普段は右端から2文字分だけ覗き、hoverで全部出る（`opacity: 0.5` → `1`）。
	`#elsaLayout`の外に置くため、ブロック優先の対象外（ナビゲーション）。
*/
.elsaFixMenu {
	position: fixed;
	top: 50%;
	transform: translateY(-50%);
	z-index: 10;
	display: flex;
	flex-direction: column;
	gap: 5px;
	margin: 0;
	padding: 0;
	list-style: none;
	opacity: 0.5;
	transition: right 0.3s ease-out, opacity 0.3s ease-out;
}

.elsaFixMenu:hover,
.elsaFixMenu:focus-within {
	right: 0 !important;
	opacity: 1;
}

.elsaFixMenu button {
	display: block;
	width: 100%;
	min-width: 80px;
	padding: 5px;
	border: 0;
	border-radius: 5px 0 0 5px;
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: inherit;
	font-size: 1.1em;
	text-align: center;
	cursor: pointer;
}

.elsaFixMenu button:hover,
.elsaFixMenu button:focus-visible { background: var(--elsa-primary-color, #24333f); color: var(--elsa-primary-contrast, #fff); }

.elsaFixMenuIcon { display: block; width: 1em; height: 1em; margin: auto; background: currentColor; }
.elsaFixMenuIcon--up { -webkit-mask: var(--elsa-icon-arrow-up) var(--elsa-icon-arrow-up-mask-position, center) / var(--elsa-icon-arrow-up-mask-size, var(--elsa-icon-mask-size)) no-repeat; mask: var(--elsa-icon-arrow-up) var(--elsa-icon-arrow-up-mask-position, center) / var(--elsa-icon-arrow-up-mask-size, var(--elsa-icon-mask-size)) no-repeat; }
.elsaFixMenuIcon--down { -webkit-mask: var(--elsa-icon-arrow-down) var(--elsa-icon-arrow-down-mask-position, center) / var(--elsa-icon-arrow-down-mask-size, var(--elsa-icon-mask-size)) no-repeat; mask: var(--elsa-icon-arrow-down) var(--elsa-icon-arrow-down-mask-position, center) / var(--elsa-icon-arrow-down-mask-size, var(--elsa-icon-mask-size)) no-repeat; }

@media (max-width: 767px) {
	/*  狭い画面では覗かせる幅が一覧を圧迫するため、見出しジャンプは出さない。  */
	.elsaFixMenu { display: none; }
}


/*
	箱編集画面（V3独自。V2に対応する画面は無い）の操作のまとまり。
	丸ボタンにはせず、通常の並びのままで見た目だけを揃える。
	運送業者が増えたときにここだけを縦スクロールさせる点は共通。
*/
.elsaBoxEditorActions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin-top: var(--elsa-block-spacing, 8px);
}

.elsaBoxEditorActions > * { margin-top: 0; }

.elsaBoxEditorActions .elsaFieldRow { flex: 0 1 auto; margin-top: 0; }

.elsaBoxEditorCarriers {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	flex: 1 1 100%;
	max-height: calc((var(--elsa-block-action-height, 28px) + 8px) * 3);
	overflow-y: auto;
}

/*
	一覧のセルの入力。**`min-width`を持たせない。** 8emの下限を敷いていた頃は、
	中身が2文字の列も8em取り、列幅が内容に追従しなかった（2026-08-15の指示）。
	列の下限は見出しの実幅が持ち、列の実幅は入力の`size`（中身の表示幅）が決める。
*/
.elsaText[data-list-field="true"],
.elsaSelectorField[data-list-field="true"],
.elsaSelectorSuggestInput--list {
	width: 100%;
	min-width: 0;
	min-height: calc(2em + var(--elsa-form-control-padding-block) + var(--elsa-form-control-padding-block));
	height: calc(2em + var(--elsa-form-control-padding-block) + var(--elsa-form-control-padding-block));
	padding: var(--elsa-form-control-padding-block) var(--elsa-form-control-padding-inline);
	border: 0;
	border-radius: 0;
	line-height: var(--elsa-form-control-line-height);
	background: transparent;
}

/*
	LISTの罫線はセルだけが持つ。子FIELDにも通常画面用の枠が残ると、1pxの線が
	重なって太く見える。属性を付ける各ブロックの実装だけに依存せず、LISTセル直下の
	登録FIELDを共通の安全網で枠なしにする。
*/
.elsaList td.elsaListCellField > .elsaField {
	border: 0;
	border-radius: 0;
	background: transparent;
}

/*
	同じ安全網を、直下の子ではなく**セルの中の入力部品**（SELECTORの入力欄・
	選択button・トレイリングcommandを伴うTEXT／NUMBERの`.elsaFieldControl`内
	input）へも広げる（Issue #4051）。SELECTORはラッパー`.elsaSelectorSuggest`
	を挟むため直下では拾えない。「枠は置き場所が持つ」——フォーム内のSELECTOR
	（このセレクタに当たらない）は従来どおり枠1本のまま、LISTのセル内だけ0にする
	（`docs/list-block.md`「セル全面」の規則）。

	CHECKBOXの組（`.elsaCheckboxGroup`）も同じ（Issue #4561）。組は幅100%で
	セルを埋めるため、自分の枠がマス目の線のすぐ内側へもう1本の線として出ていた
	（予定の通知設定の「通知方法」）。フォーム内の組はこのセレクタに当たらず枠1本の
	まま。フォーカスの印は選択肢の四角（`:focus-visible + span`のoutline）が持ち、
	エラーの赤は下の共通の赤枠規則が組自身に付けるので、枠を消しても両方とも残る。
*/
.elsaList td.elsaListCellField .elsaCheckboxGroup,
.elsaList td.elsaListCellField .elsaSelectorSuggestInput,
.elsaList td.elsaListCellField .elsaSelectorSuggestButton,
.elsaList td.elsaListCellField .elsaFieldControl > input[type="text"],
.elsaList td.elsaListCellField .elsaFieldControl > input[type="number"] {
	border: 0;
	border-radius: 0;
	background: transparent;
}

.elsaText[data-list-field="true"]:disabled,
.elsaSelectorField[data-list-field="true"]:disabled,
.elsaSelectorSuggestInput--list:disabled {
	color: inherit;
	opacity: 1;
}

/*
	読み取り専用のセルは、**素のテキストの列と同じ決まり方をする。** 列幅は中身の
	実幅に追従し、上限（`.elsaList td`の`max-width`）に達したらそこで折り返す。

	2026-08-24から読み取り専用は実テキスト要素（`<output>`）で描くため、セルは
	`<input>`と違って中身の実幅を自分で持っている。**列幅を決める根拠が2つある
	状態にしない。** 実際、`<input>`の`size`を`--elsa-text-cell-char-*`で写した
	`min-width`を持たせていたところ、その下限（40文字＝25.75em）が上のセルの上限
	（24em）を上回り、**読み取り専用のセルだけがセルの外へ28pxはみ出して隣の列の
	文字へ重なった**（Issue #1918。/amazon-vendor-central/centers/の「Amazon住所」と
	「取得元」で発生）。下限が上限を超えられる作りである限り、較正値を直しても
	同じことが起きる。

	折り返しは`<input>`の既定（1行・あふれは切る）と異なるが、**一覧のセルでは
	切るより折り返す方が要件である**（Issue #1918要件2「列の上限幅で折り返し、
	全文を読めること」）。住所のように上限を超える値は、切ると画面から読み取れない。
	折り返しの規則（`overflow-wrap: anywhere`）は素のテキストの列と揃える。

	高さは`auto`にして行数ぶん伸ばす。1行に収まる値の高さは`.elsaText`の
	`min-height`が入力欄と同じに保つ。
*/

.elsaTextReadonly[data-list-field="true"] {
	height: auto;
	white-space: pre-wrap;
	overflow-wrap: anywhere;
}

.elsaListNav {
	margin: 12px 0;
	display: flex;
	align-items: center;
	gap: 8px;
}

.elsaListAction {
	--elsa-list-action-size: var(--elsa-block-action-height);
	display: inline-flex;
	box-sizing: border-box;
	align-items: center;
	justify-content: center;
	width: var(--elsa-list-action-size);
	min-width: var(--elsa-list-action-size);
	max-width: var(--elsa-list-action-size);
	height: var(--elsa-list-action-size);
	min-height: var(--elsa-list-action-size);
	max-height: var(--elsa-list-action-size);
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 4px;
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	font: inherit;
	line-height: 1;
	text-decoration: none;
	vertical-align: middle;
	cursor: pointer;
}

.elsaListAction:focus-visible {
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	outline: 2px solid var(--elsa-primary-color, #24333f);
	outline-offset: 2px;
}

@media (hover: hover) {
	.elsaListAction:hover {
		background: var(--elsa-primary-color, #24333f);
		color: var(--elsa-primary-contrast, #fff);
	}

	.elsaListAction--delete:hover {
		background: var(--elsa-button-danger-hover-bg);
		color: var(--elsa-danger-contrast, #fff);
	}

	/*
		**押せない操作は、ホバーしても押せそうに見せない**（2026-09-06、Issue #2078）。
	*/
	.elsaListAction:disabled:hover,
	.elsaListAction--delete:disabled:hover,
	.elsaListAction[aria-disabled="true"]:hover,
	.elsaListAction--delete[aria-disabled="true"]:hover {
		background: var(--elsa-button-default-bg, #d2d2d2);
		color: var(--elsa-button-default-color, #667085);
	}
}

/*
	押せない行操作（共通の削除ロックが理由を持つ行）。**枠と大きさは変えない**
	——並んだ操作の位置がずれると、押せる操作まで探し直すことになる。理由は
	`title`と読み上げ名が持つので、色の薄さだけで伝えようとしない。
*/
.elsaListAction:disabled,
.elsaListAction[aria-disabled="true"] {
	opacity: 0.4;
	cursor: not-allowed;
}

.elsaListActionIcon {
	display: block;
	/*
		28pxの共通操作面に対するIcon Playground実寸（Issue #2002）。**帯のボタンの
		図像と行の種類アイコンも同じ値を読む**（2026-09-03の利用者指示）ので、値は
		共通トークンが持つ。
	*/
	width: var(--elsa-block-action-icon-size);
	height: var(--elsa-block-action-icon-size);
	background: currentColor;
	-webkit-mask: var(--elsa-list-action-icon) var(--elsa-list-action-mask-position, center) / var(--elsa-list-action-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-list-action-icon) var(--elsa-list-action-mask-position, center) / var(--elsa-list-action-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

.elsaListAction--view { --elsa-list-action-icon: var(--elsa-icon-view); }
.elsaListAction--edit { --elsa-list-action-icon: var(--elsa-icon-edit); }
.elsaListAction--download { --elsa-list-action-icon: var(--elsa-icon-download); }
/* 別の場所へ移す行操作（Icon Playgroundの登録名「移動」）。 */
.elsaListAction--move { --elsa-list-action-icon: var(--elsa-icon-move); }
.elsaListAction--run { --elsa-list-action-icon: var(--elsa-icon-run); }
.elsaListAction--correct { --elsa-list-action-icon: var(--elsa-icon-correct); }
.elsaListAction--apply { --elsa-list-action-icon: var(--elsa-icon-apply); }
.elsaListAction--delete { --elsa-list-action-icon: var(--elsa-icon-delete); }
/* 復元はIcon Playgroundの登録名「訂正」の共通maskを使う（Issue #2002）。 */
.elsaListAction--restore { --elsa-list-action-icon: var(--elsa-icon-correct); }
.elsaListAction--resend { --elsa-list-action-icon: var(--elsa-icon-resend); }
.elsaListAction--revoke { --elsa-list-action-icon: var(--elsa-icon-revoke); }
/*
	上の1行ずつの規則は契約テスト（LIST delete actions use the shared delete
	meaning token 等）が文字列で完全一致照合するため、Icon Playgroundの余白
	設定（Issue #3609）はここへ混ぜず、別の規則としてper-iconのmask-size/
	position変数だけを足す。行を触るたびに契約が壊れるのを避ける。
*/
.elsaListAction--view { --elsa-list-action-mask-size: var(--elsa-icon-view-mask-size, var(--elsa-icon-mask-size)); --elsa-list-action-mask-position: var(--elsa-icon-view-mask-position, center); }
.elsaListAction--edit { --elsa-list-action-mask-size: var(--elsa-icon-edit-mask-size, var(--elsa-icon-mask-size)); --elsa-list-action-mask-position: var(--elsa-icon-edit-mask-position, center); }
.elsaListAction--download { --elsa-list-action-mask-size: var(--elsa-icon-download-mask-size, var(--elsa-icon-mask-size)); --elsa-list-action-mask-position: var(--elsa-icon-download-mask-position, center); }
.elsaListAction--move { --elsa-list-action-mask-size: var(--elsa-icon-move-mask-size, var(--elsa-icon-mask-size)); --elsa-list-action-mask-position: var(--elsa-icon-move-mask-position, center); }
.elsaListAction--run { --elsa-list-action-mask-size: var(--elsa-icon-run-mask-size, var(--elsa-icon-mask-size)); --elsa-list-action-mask-position: var(--elsa-icon-run-mask-position, center); }
.elsaListAction--correct { --elsa-list-action-mask-size: var(--elsa-icon-correct-mask-size, var(--elsa-icon-mask-size)); --elsa-list-action-mask-position: var(--elsa-icon-correct-mask-position, center); }
.elsaListAction--apply { --elsa-list-action-mask-size: var(--elsa-icon-apply-mask-size, var(--elsa-icon-mask-size)); --elsa-list-action-mask-position: var(--elsa-icon-apply-mask-position, center); }
.elsaListAction--delete { --elsa-list-action-mask-size: var(--elsa-icon-delete-mask-size, var(--elsa-icon-mask-size)); --elsa-list-action-mask-position: var(--elsa-icon-delete-mask-position, center); }
.elsaListAction--restore { --elsa-list-action-mask-size: var(--elsa-icon-correct-mask-size, var(--elsa-icon-mask-size)); --elsa-list-action-mask-position: var(--elsa-icon-correct-mask-position, center); }
.elsaListAction--resend { --elsa-list-action-mask-size: var(--elsa-icon-resend-mask-size, var(--elsa-icon-mask-size)); --elsa-list-action-mask-position: var(--elsa-icon-resend-mask-position, center); }
.elsaListAction--revoke { --elsa-list-action-mask-size: var(--elsa-icon-revoke-mask-size, var(--elsa-icon-mask-size)); --elsa-list-action-mask-position: var(--elsa-icon-revoke-mask-position, center); }
/*
	tests/icon_playground_test.php（Issue #3609のPR1で追加）はdelete・restoreの
	2つだけ、意味トークンとmask-size/positionをまとめた1行の文字列を固定して
	いる。上のsplit済みの規則と両立させるため、その2つだけ重ねて出す
	（同じvar()なので値の食い違いは無い）。
*/
.elsaListAction--delete { --elsa-list-action-icon: var(--elsa-icon-delete); --elsa-list-action-mask-size: var(--elsa-icon-delete-mask-size, var(--elsa-icon-mask-size)); --elsa-list-action-mask-position: var(--elsa-icon-delete-mask-position, center); }
.elsaListAction--restore { --elsa-list-action-icon: var(--elsa-icon-correct); --elsa-list-action-mask-size: var(--elsa-icon-correct-mask-size, var(--elsa-icon-mask-size)); --elsa-list-action-mask-position: var(--elsa-icon-correct-mask-position, center); }

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	スマホ幅の行操作（2026-08-28の利用者決定）

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

/*
	狭い画面では、右端へ貼り付けた操作列が3つ4つ並ぶと一覧の中身を覆う。
	操作が2つ以上ある行は**右端の1つのボタンへ畳み**、押したときだけ
	行の高さの中を左へ滑らせて出す。

	**図像は縦三点（⋮）で、ハンバーガー（≡）は使わない。**
	≡は並び替えのつかみ手と読み違えやすく、
	一覧の行では「押すと開く」と「つかんで動かす」が同じ行に隣り合うためである
	（2026-08-28の利用者決定。この理由ごと決定である）。十字のつかみ手そのものは
	Issue #4355で廃止し、掴む面は上下ボタンの入れ物（`.elsaSortControl`）へ移った
	が、同じ行に「つかんで動かす」が並ぶことは変わらないのでこの決定は続く。

	**操作が1つだけの行は畳まない。** 1つのために1回押させるとクリック数が増える。
	畳むかどうかはLISTブロックが行ごとに数えて決める（`elsaListCellAction--collapsible`）。
*/
.elsaListActionToggle {
	--elsa-list-action-size: var(--elsa-block-action-height);
	display: none;
	box-sizing: border-box;
	align-items: center;
	justify-content: center;
	width: var(--elsa-list-action-size);
	min-width: var(--elsa-list-action-size);
	max-width: var(--elsa-list-action-size);
	height: var(--elsa-list-action-size);
	min-height: var(--elsa-list-action-size);
	max-height: var(--elsa-list-action-size);
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 4px;
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	font: inherit;
	line-height: 1;
	vertical-align: middle;
	cursor: pointer;
}

.elsaListActionToggleIcon {
	display: block;
	width: var(--elsa-block-action-icon-size);
	height: var(--elsa-block-action-icon-size);
	background: currentColor;
	-webkit-mask: var(--elsa-icon-more) var(--elsa-icon-more-mask-position, center) / var(--elsa-icon-more-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-more) var(--elsa-icon-more-mask-position, center) / var(--elsa-icon-more-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

.elsaListActionToggle:focus-visible {
	outline: 2px solid var(--elsa-primary-color, #24333f);
	outline-offset: 2px;
}

@media (hover: hover) {
	.elsaListActionToggle:hover {
		background: var(--elsa-primary-color, #24333f);
		color: var(--elsa-primary-contrast, #fff);
	}
}

@media (max-width: 767px) {
	.elsaListCellAction--collapsible > .elsaListActionToggle { display: inline-flex; }

	/*
		操作の群れは**操作セルそのものが左へ伸びた面**として描く
		（2026-08-28の利用者フィードバック）。

		初版はボタンの大きさに合わせた白い座布団を、角丸と浮きの影で行の上へ
		乗せていた。利用者の指摘は「左にスライドする際、ボタンに白背景があり、
		白背景のサイズがボタン合わせなので違和感がある。**ボタンが配置されている
		セルが左に伸びるようにしてはどうか**」である。

		そこで次の形にする。

		- `right: 100%`・`top: 0`・`bottom: 0`でセルの左隣へ**隙間なく**接し、
		  高さもセルと同じにする。角丸も浮きの影も持たない。
		- 地色はセルと同じ行の変数（`--elsa-list-row-bg`）を使う。
		  **セルと展開部の境目が無い、ひと続きの面になる。**
		- 境界は**左端の1本だけ**。行の内容との境目をここで示す。
		- 開閉は`clip-path`で右から左へ面が伸びる。`opacity`のフェードや
		  平行移動は「セルが伸びる」動きには見えないため使わない。
	*/
	.elsaListCellAction--collapsible > .elsaListActionGroup {
		position: absolute;
		top: 0;
		right: 100%;
		bottom: 0;
		z-index: 1;
		box-sizing: border-box;
		display: flex;
		margin: 0;
		padding: 0 3px;
		border-left: 1px solid rgba(0, 0, 0, .18);
		border-radius: 0;
		background: var(--elsa-list-row-bg);
		box-shadow: none;
		visibility: hidden;
		clip-path: inset(0 0 0 100%);
		transition: clip-path .2s ease, visibility 0s linear .2s;
	}

	.elsaListCellAction--collapsible.is-open > .elsaListActionGroup {
		visibility: visible;
		clip-path: inset(0 0 0 0);
		transition: clip-path .2s ease, visibility 0s;
	}

	/*
		伸びた面の上のボタンは**素で並べる**。個別の背景（座布団）を戻すと、
		「白背景のサイズがボタン合わせ」と指摘された形へそのまま戻る。
		28px角の当たり面と図像の中央寄せは共通規則のまま変えない。
		フォーカス時も地を塗らず、輪郭だけで示す。

		**印はボタン自身が持つ**（`data-list-action-collapsed`。LISTブロックが
		畳む行の操作へ付ける）。祖先のセルから子孫のボタンを塗る書き方は、
		ブロックのルートを外から装飾することになり`docs/architecture.md`の規則に
		反する（`tests/field_block_style_test.php`が落とす）。
	*/
	.elsaListAction[data-list-action-collapsed="true"],
	.elsaListAction[data-list-action-collapsed="true"]:focus-visible {
		background: transparent;
	}

	/*
		押した⋮も、開いているあいだは面の上の素の図像にする。四角い座布団を
		面の途中へ残すと、ひと続きの面が2つに割れて見える。
		「今開いているのはこれ」は色で示す。
	*/
	.elsaListCellAction--collapsible.is-open > .elsaListActionToggle {
		background: transparent;
		color: var(--elsa-primary-color, #24333f);
	}

	/*
		開いているあいだは、貼り付いた列の左縁の影を消す。**面の途中に影の筋が
		入ると、伸びたセルが2枚に割れて見える。** 行の内容との境界は、
		伸びた面の左端の1本が受け持つ。
	*/
	.elsaListScroll--pinnedRight .elsaList td.elsaListCellAction.is-open {
		box-shadow: none;
	}
}

/*
	狭い画面でもポインターがある環境（幅を狭めたPC等）では、当たっていることを
	返す必要がある。座布団を戻さず**図像の色だけ**で返す。削除は危険の色のまま。
*/
@media (max-width: 767px) and (hover: hover) {
	.elsaListAction[data-list-action-collapsed="true"]:hover {
		background: transparent;
		color: var(--elsa-primary-color, #24333f);
	}

	.elsaListAction--delete[data-list-action-collapsed="true"]:hover {
		background: transparent;
		color: var(--elsa-button-danger-hover-bg);
	}
}

@media (prefers-reduced-motion: reduce) {
	.elsaListCellAction--collapsible > .elsaListActionGroup { transition: none; }
}

/*
	削除済みの行（Issue #1811 段6）。「削除済みも表示」を入れた一覧だけに出る。
	**見えるが生きていない**ことが一目で分かるよう、選択できない行と同じ
	薄い見せ方に揃える。
*/
.elsaListContainer .elsaList tbody tr.elsaListRowDeleted {
	--elsa-list-row-bg: var(--elsa-surface-sunken, #f5f7f9);
}

.elsaList tbody tr.elsaListRowDeleted td {
	color: var(--elsa-text-muted, #667085);
}

/*
	運べる行（LISTの`option.row_drag`）。**掴めることは掴む前に分かる必要がある。**
	運んでいる間は薄くして、どれを持っているかを面で示す（TREEの行と同じ見せ方）。
	指の環境では引く操作を求めないので、当たり判定の形は変えない。
*/
.elsaList tbody tr[data-row-drag-type] { cursor: grab; }

.elsaList tbody tr[data-row-drag-type].is-dragging { opacity: .45; }

/* 共通LISTのopt-inインライン追加。寸法は既存セル/FIELD規則をそのまま使う。 */
.elsaList tbody tr.elsaListInlineRow--draft { --elsa-list-row-bg: color-mix(in srgb, var(--elsa-primary-color, #24333f) 3%, var(--elsa-surface, #ffffff)); }
.elsaListInlineRow--saving { opacity: .7; }
.elsaList tbody tr.elsaListInlineRow--error { --elsa-list-error-background: color-mix(in srgb, var(--elsa-semantic-danger-color) 2%, var(--elsa-surface, #fff)); --elsa-list-row-bg: var(--elsa-list-error-background, #fff8f7); }
.elsaListInlineRow .elsaField:focus-visible { position: relative; z-index: 1; }

.elsaColorControl {
	gap: 10px;
	padding: 0 8px;
	border: 1px solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius: var(--elsa-field-control-border-radius, 0 4px 4px 0);
	background: var(--elsa-field-state-background, #fff);
}

.elsaColorControl input[type="color"] {
	-webkit-appearance: none;
	appearance: none;
	display: block;
	flex: 0 0 40px;
	width: 40px;
	min-width: 40px;
	height: 30px;
	min-height: 30px;
	padding: 0;
	border: 1px solid var(--elsa-border, #d2d2d2);
	border-radius: 4px;
	background: transparent;
	cursor: pointer;
	overflow: hidden;
}

.elsaColorControl input[type="color"]::-webkit-color-swatch-wrapper {
	padding: 0;
}

.elsaColorControl input[type="color"]::-webkit-color-swatch,
.elsaColorControl input[type="color"]::-moz-color-swatch {
	border: 0;
	border-radius: 0;
}

.elsaColorControl output {
	font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	FILEプレビュー上のオーバーレイ操作（2026-08-28に例外を廃止）

	共通の28pxへ統一する（利用者指示「あまりにも小さい」）。2026-08-16の
	28px統一では、ここだけ20pxの別契約として検査の外へ置いていた。

	**操作面も図像も、トークン1つずつを全ボタンが共有する。** メニュー・
	追加・プレビュー・ダウンロード・回転・削除のどれも28px角の操作面に
	16px角の図像（四方6pxの内側余白）で、ボタンごとの例外を作らない。
	以前は同じ帯の中でメニューと削除が20px、回転が14px、他が12pxと
	3種類の大きさが並んでいた。**将来ボタンが増えても、この2つの
	トークンだけを参照させる。**

	**図像は四方同じ余白で置く＝上下左右の中央になる。** ボタンごとの
	marginやtop/leftの微調整で中央へ寄せない。ずれの検出は
	tests/common_action_dimensions_test.php（規則の側）と
	tests/file_browser_test.js（実ブラウザの実測）が行う。

	図像はすべて`viewBox="0 0 24 24"`の共通SVGをmaskで敷いたベクターなので、
	28pxへ広げても拡大でにじまない。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

.elsaFileBlock,
.elsaCommonFileRotateIcon {
	/* FILEと帯で、同じ回転図形の正方形比率を共有する。 */
	--elsa-file-action-icon-square: calc(70.7% - 1.414 * var(--elsa-icon-padding));
	/*
		Icon Playgroundの左右/上下が非対称な余白設定（Issue #3609）では、
		正方形の大きさ（--elsa-file-action-icon-square、共通の内側余白で
		45度でもはみ出さない契約、common_action_dimensions_test.php）は
		変えない。軸ごとの余白差はmask-positionの中心のずれ（offset-x/y）
		だけで表す。
	*/
	--elsa-file-action-icon-offset-x: calc((var(--elsa-icon-file-rotate-pad-left, var(--elsa-icon-padding)) - var(--elsa-icon-file-rotate-pad-right, var(--elsa-icon-padding))) / 2);
	--elsa-file-action-icon-offset-y: calc((var(--elsa-icon-file-rotate-pad-top, var(--elsa-icon-padding)) - var(--elsa-icon-file-rotate-pad-bottom, var(--elsa-icon-padding))) / 2);
}
.elsaFileBlock {
	--elsa-file-action-size: var(--elsa-block-action-height);
	--elsa-file-action-icon-inset: calc((var(--elsa-file-action-size) - var(--elsa-block-action-icon-size)) / 2);
	/*
		線画ではなく面で描く図像（回転の正方形）の一辺。
		**70.7%＝1/√2、回転時の対角線が枠と一致する利用者指定値
		（2026-08-28）。** 根拠と実測値は下の回転の節に書く。
	*/
	--elsa-file-icon-stroke: 3px;
	--elsa-file-button-default-bg: var(--elsa-button-default-bg, #d2d2d2);
	--elsa-file-button-hover-bg: var(--elsa-primary-color, #24333f);
	--elsa-file-button-icon: var(--elsa-button-default-color, #667085);
	display: flex;
	align-items: flex-start;
	flex-wrap: wrap;
	gap: 8px;
	width: 100%;
	padding: 0;
}

.elsaFileBlockPreviewSurface {
	position: relative;
	z-index: 1;
	display: flex;
	flex: 1 1 auto;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	min-width: 0;
	min-height: 0;
	background-color: var(--elsa-surface, #ffffff);
}

.elsaFileBlockPreview {
	display: block;
	width: 100%;
	height: 100%;
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
}

.elsaFileBlockDocumentPreview { border: 0; }

.elsaFileBlock.has-preview .elsaFileBlockPreviewSurface {
	position: absolute;
	inset: 0;
}

.elsaFileBlockPreviewSurface.is-transitioning {
	opacity: 0;
	transition: opacity 0.15s ease;
}

.elsaFileBlockPreviewSurface.is-transitioning.is-visible { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
	.elsaFileBlockPreviewSurface.is-transitioning { transition-duration: 0.01ms; }
}

.elsaFileBlock.has-preview .elsaFileBlockDropZone { padding: 0; }

.elsaFileBlockTextPreview {
	box-sizing: border-box;
	padding: 8px;
	resize: none;
	border: 0;
	background: var(--elsa-surface, #ffffff);
	color: var(--elsa-content-text-color, #333333);
	font: 0.85em/1.4 ui-monospace, SFMono-Regular, Consolas, monospace;
}

/*
	種別アイコンと「見えるファイル名」の2段。ドロップ直後の先行サムネイルと
	保存済みの種別表示で同じ内側部品を使い、保存の前後で見た目を変えない。
	内側の寸法をemに頼らないよう、この部品が自分でfont-sizeを決める。
*/

.elsaFileBlockTypePreview,
.elsaFileBlockPlaceholder {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 8px;
	box-sizing: border-box;
	max-width: 100%;
	max-height: 100%;
	padding: 8px;
	overflow: hidden;
	color: var(--elsa-text-muted, #667085);
	font-size: 13px;
}

.elsaFileBlockTypePreviewIcon {
	display: grid;
	place-items: center;
	flex: 0 0 auto;
	box-sizing: border-box;
	width: 96px;
	max-width: 100%;
	aspect-ratio: 4 / 5;
	border: 2px solid currentColor;
	border-radius: 6px;
	background: var(--elsa-surface, #ffffff);
	font-weight: 700;
	letter-spacing: 0.08em;
}

.elsaFileBlockTypePreviewName {
	display: -webkit-box;
	max-width: 100%;
	overflow: hidden;
	color: inherit;
	font-weight: 400;
	letter-spacing: normal;
	line-height: 1.3;
	text-align: center;
	overflow-wrap: anywhere;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
}

.elsaFileBlockTypePreview.is-pdf,
.elsaFileBlockPlaceholder.is-pdf { color: #c73b32; }

.elsaFileBlockTypePreview.is-office,
.elsaFileBlockPlaceholder.is-office { color: #2e659d; }

/*
	先行サムネイルは本体プレビューへ重ね、本体の読み込みが終わったら
	取り除く。背景を塗るのは、下でPDFのembedが白紙のまま待つ間に
	透けて二重に見えないようにするため。
*/

.elsaFileBlockPlaceholder {
	position: absolute;
	z-index: 1;
	inset: 0;
	width: 100%;
	height: 100%;
	background: var(--elsa-surface, #ffffff);
}

.elsaFileBlock [data-file-rotate][hidden] { display: none !important; }

.elsaListInfinite {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: 10px;
	min-height: 1px;
	padding: 0;
}

.elsaListInfinite[hidden] { display: none; }
.elsaListInfinite:has(> .button:not([hidden])),
.elsaListInfinite:has(> [data-list-status]:not(:empty)) { padding: var(--elsa-block-spacing, 8px) 0 0; }

.elsaListInfinite [data-list-load-next][hidden] { display: none; }

/*
	一覧の「もっと読む」とページ送りは、押しても場所が変わらないよう色を動かさない。
	**無効のときは共通の無効色へ譲る**（2026-08-28。以前はここが`:disabled`まで
	通常色で塗り、上の`.button:disabled`より詳しいセレクタなので勝っていた）。
*/
.elsaListNav > .button:not(:disabled),
.elsaListNav > .button:not(:disabled):hover,
.elsaListNav > .button:not(:disabled):focus,
.elsaListInfinite > .button:not(:disabled),
.elsaListInfinite > .button:not(:disabled):hover,
.elsaListInfinite > .button:not(:disabled):focus {
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
}

.elsaListNav > .button:focus-visible,
.elsaListInfinite > .button:focus-visible {
	outline: 2px solid var(--elsa-primary-color, #24333f);
	outline-offset: 2px;
}

@media (hover: hover) {
	.elsaListNav > .button:hover,
	.elsaListInfinite > .button:hover {
		background: var(--elsa-primary-color, #24333f);
		color: var(--elsa-primary-contrast, #fff);
	}
}

.elsaListInfinite [data-list-status] { color: var(--elsa-text-muted, #667085); }

.elsaFileBlockReplace {
	display: none;
	position: absolute;
	z-index: 2;
	inset: 0;
	cursor: default;
}

.elsaFileBlock.has-file .elsaFileBlockReplace { display: block; }

.elsaFileBlockInput {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
}

.elsaFileBlockDropZone {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 1 var(--elsa-file-drop-width, 200px);
	width: var(--elsa-file-drop-width, 200px);
	max-width: 100%;
	min-height: var(--elsa-file-drop-min-height, var(--elsa-file-drop-height, 200px));
	height: var(--elsa-file-drop-height, 200px);
	aspect-ratio: var(--elsa-file-drop-aspect-ratio, auto);
	padding: 8px;
	border: 1px solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius: var(--elsa-field-control-border-radius, 0 4px 4px 0);
	background: var(--elsa-field-state-background, #fff);
	color: var(--elsa-text-muted, #667085);
	text-align: center;
	overflow: hidden;
}

.elsaFileBlockPrompt { position: relative; z-index: 1; }
.elsaFileBlock.has-file .elsaFileBlockPrompt { display: none; }
.elsaFileBlockFileName { position: relative; z-index: 1; max-width: 100%; overflow-wrap: anywhere; }

/*
	操作の帯（V2の`.elsaFileButtons`と同じ組み方）。半透明の白を敷くのは、
	濃い書類や暗い画像の上へ重なったときにボタンを読めるようにするため
	（2026-08-28の利用者指摘「半透明の白背景が無いように見える」）。V2は
	`rgba(255,255,255,0.7)`だったが、操作面が28pxになって帯の面積が増えた
	ぶん透けが目立つため0.85まで上げ、明るい画像の上でも帯の輪郭が分かる
	よう髪の毛一本の縁を足す。ボタン個別の円ではなく群をまとめる帯なのは
	V2に合わせている。

	**縦に積みきれないときは列を折り返す。** compact-square（140px角）では
	28px×5個が入らず、`overflow: hidden`のドロップ枠に切り落とされて押せなく
	なる。`wrap-reverse`で2列目を左へ伸ばし、枠の外へ出さない。

	折り返しの境目は`max-height`が決める。枠の内側（padding box）に対して
	上に5px、下に3px残す`calc(100% - 8px)`とすると、既定の200px枠では
	最大の6操作（28×6＋間隔3×5＋内側3×2＝189px）が1列に収まり、
	140px枠では4操作で折り返る。10px引くと200px枠が1pxだけ足りず、
	6操作目が不要に2列目へ落ちる。
*/

.elsaFileBlockActions {
	position: absolute;
	z-index: 3;
	top: 5px;
	right: 5px;
	display: flex;
	flex-flow: column wrap-reverse;
	align-items: stretch;
	align-content: flex-start;
	gap: 3px;
	box-sizing: border-box;
	max-height: calc(100% - 8px);
	font-size: 10px;
	padding: 3px;
	border-radius: 5px;
	background: rgba(255, 255, 255, 0.85);
	box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
	transform: none;
}

.elsaFileBlock:not(.has-file) .elsaFileBlockActions { display: none; }

/*
	メニューは常に見えている1つだけなので、表示（grid）と重なり順だけを
	自分で持つ。**操作面（大きさ・丸い座布団・地の色）と図像（位置・色）は
	下の共通規則から取る。** 2026-08-28まではここで
	`background: transparent`・`border-radius: 0`と、図像の色に
	`--elsa-file-button-default-bg`（＝ボタンの地の色）を使っており、
	**外形は28pxなのに座布団が無く図像も薄いため、1つだけ小さく見えていた**
	（利用者指摘）。
*/

.elsaFileBlockMenu {
	z-index: 2;
	display: grid;
	place-items: center;
	outline: none;
}

.elsaFileBlockMenu span {
	display: none;
	/* Legacy spans stay in the markup so older cached JavaScript remains harmless. */
}

.elsaFileBlock--compactWide {
	--elsa-file-drop-width: 100%;
	--elsa-file-drop-height: 96px;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	compact-square（商品画像・SKU画像）

	商品画像は正方形にする。各モールへ登録する商品画像が正方形のため、
	登録時と同じ見え方で確認できる。一辺は呼び出し側が
	--elsa-file-square-size で指定でき、既定は140px。

	**幅と高さの両方をこのバリアントが決める（2026-08-28に修正）。**
	以前は幅だけ`100%`にしていたため、置き場所の幅がそのまま一辺になり、
	SKUカードの中（140px幅の枠）では140×140、商品編集画面の素の`<form>`の
	中ではPC 1251×140・スマホ 341×140と、**同じ`variant => "compact-square"`が
	置き場所で別の寸法になっていた。** 「登録済みブロックの寸法は
	ブロック自身が決め、外の祖先に決めさせない」という
	docs/architecture.md「ブロックCSSと操作ボタンの共通契約」に反する。
	一辺を自分で持てば、どこへ置いても正方形になる。

	枠より狭い場所では`.elsaFileBlockDropZone`の`max-width: 100%`が縮める。
	正方形が保てない幅ではみ出すよりは、収まる方を採る。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

.elsaFileBlock--compactSquare {
	--elsa-file-drop-width: var(--elsa-file-square-size, 140px);
	--elsa-file-drop-height: var(--elsa-file-square-size, 140px);
}

/* 表セルではセルの罫線を唯一の外周にし、FILEを幅・高さとも一杯にする。 */

.elsaFileBlock--tableCell,
.elsaFileBlock--tableCell .elsaFileBlockDropZone {
	width: 100%;
	height: 100%;
	min-height: 100%;
	max-width: none;
	box-sizing: border-box;
}

.elsaFileBlock--tableCell .elsaFileBlockDropZone {
	flex: 1 1 100%;
	padding: 0;
	border: 0;
	border-radius: 0;
}

/*
	**表のセルでは行の高さいっぱいの正方形**（Issue #4818、オーナー指摘2026-10-14）。
	表のセルの高さは中身から決まるので、CSSだけでは「セルの高さ＝自分の幅」を作れない。
	core/js/elsa_file.jsの`elsaFileBlockFitTableCells()`がセルの中身の高さを
	`--elsa-file-cell-size`へ書き、ここがその値で幅と高さを決める。上下の負の余白で
	**行の高さへは寄与しない**（寄与すると行が縮めなくなり、値が自分を追いかける）。
	値が無い間（JSの前）は4emの正方形で、負の余白も0のまま。
	狭い枠では「ファイルをドロップ」の字が「＋」と重なるので、字は読み上げ用だけにする
	（枠そのものの`aria-label`も同じ名前を持つ）。
	枠（DropZone）の既定の`flex: 0 1 200px`は、200pxより高い行で横を200pxに止めるので、
	表のセルでは上の規則が`flex: 1 1 100%`にして正方形いっぱいへ広げる。
*/
.elsaFileBlock--tableCell {
	width: var(--elsa-file-cell-size, 4em);
	height: var(--elsa-file-cell-size, 4em);
	min-height: 0;
	margin-top: calc(var(--elsa-file-cell-size, 0px) / -2);
	margin-bottom: calc(var(--elsa-file-cell-size, 0px) / -2);
	margin-left: auto;
	margin-right: auto;
}

.elsaFileBlock--tableCell .elsaFileBlockPrompt { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

.elsaFileBlockMenu:focus-visible {
	outline: 2px solid var(--elsa-primary-color, #24333f);
	outline-offset: 2px;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	オーバーレイ操作の「操作面」（2026-08-28に全ボタン共通へ）

	メニューを含む全ボタンが、ここから大きさ・丸い座布団・地の色を取る。
	**1つでも自前の面を持つと、外形が28pxでも見た目だけが揃わない。**
	実際メニューだけが`transparent`・`border-radius: 0`で、同寸の検査を
	通り抜けたまま「小さく見える」状態が残っていた。

	`display`はここに置かない。メニューは常に見えていて、他は
	帯を開いたときだけ現れるという違いがあるためである。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

.elsaFileBlockMenu,
.elsaFileBlockPicker,
.elsaFileBlockAdd,
.elsaFileBlockPreviewAction,
.elsaFileBlockDownloadAction,
.elsaFileBlockRotate,
.elsaFileBlockDelete {
	position: relative;
	width: var(--elsa-file-action-size);
	min-width: var(--elsa-file-action-size);
	height: var(--elsa-file-action-size);
	min-height: var(--elsa-file-action-size);
	padding: 0;
	margin: 0;
	box-sizing: border-box;
	border: 0;
	border-radius: 50%;
	background: var(--elsa-file-button-default-bg);
	cursor: pointer;
	transform: none;
}

.elsaFileBlockPicker,
.elsaFileBlockAdd,
.elsaFileBlockPreviewAction,
.elsaFileBlockDownloadAction,
.elsaFileBlockRotate,
.elsaFileBlockDelete {
	display: none;
}

/*
	図像も全ボタン共通。位置（四方同じ余白＝上下左右の中央）と色をここで
	決め、**各ボタンは自分のmaskだけを足す。** 色に地の色トークンを使うと、
	薄い図像が1つだけ紛れ込む（メニューが実際にそうだった）。
*/

.elsaFileBlockMenu::before,
.elsaFileBlockPicker::before,
.elsaFileBlockAdd::before,
.elsaFileBlockPreviewAction::before,
.elsaFileBlockDownloadAction::before,
.elsaFileBlockRotate::before,
.elsaFileBlockDelete::before {
	position: absolute;
	inset: var(--elsa-file-action-icon-inset);
	background: var(--elsa-file-button-icon);
	content: "";
}

.elsaFileBlockMenu::before {
	-webkit-mask: var(--elsa-icon-menu) var(--elsa-icon-menu-mask-position, center) / var(--elsa-icon-menu-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-menu) var(--elsa-icon-menu-mask-position, center) / var(--elsa-icon-menu-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

.elsaFileBlockActions:hover .elsaFileBlockAction,
.elsaFileBlockActions.is-open .elsaFileBlockAction { display: grid; place-items: center; }
.elsaFileBlockActions .elsaFileBlockAction {
	z-index: 1;
	flex: 0 0 var(--elsa-file-action-size);
}
.elsaFileBlockActions .elsaFileBlockAction::before,
.elsaFileBlockActions .elsaFileBlockAction::after,
.elsaFileBlockActions .elsaFileBlockAction svg {
	pointer-events: none;
}
.elsaFileBlockAdd:not(.elsaFileBlockAddAction) {
	display: grid;
	place-items: center;
	position: absolute;
	z-index: 2;
	top: 8px;
	right: 8px;
	margin: 0;
}
.elsaFileBlock.has-file .elsaFileBlockAdd:not(.elsaFileBlockAddAction) { display: none; }
.elsaFileBlockPicker:focus,
.elsaFileBlockAdd:focus,
.elsaFileBlockPreviewAction:focus,
.elsaFileBlockDownloadAction:focus,
.elsaFileBlockRotate:focus,
.elsaFileBlockDelete:focus {
	background: var(--elsa-file-button-default-bg);
}

@media (hover: hover) {
	/*
		ホバーで変わるのは**操作面**である。メニューだけが`:hover::before`
		（図像の色）を変えていたのは、座布団を持っていなかったための
		取り繕いで、2026-08-28に他と同じ主語へそろえた。
	*/
	.elsaFileBlockMenu:hover,
	.elsaFileBlockPicker:hover,
	.elsaFileBlockAdd:hover,
	.elsaFileBlockPreviewAction:hover,
	.elsaFileBlockDownloadAction:hover,
	.elsaFileBlockRotate:hover {
		--elsa-file-button-icon: var(--elsa-primary-contrast, #fff);
		background: var(--elsa-file-button-hover-bg);
	}

	.elsaFileBlockDelete:hover {
		--elsa-file-button-icon: var(--elsa-primary-contrast, #fff);
		background: var(--elsa-button-danger-hover-bg);
	}
}

/* 各ボタンが足すのは自分のmaskだけ。位置・色・大きさは上の共通規則が持つ。 */

.elsaFileBlockPicker::before,
.elsaFileBlockAdd::before {
	-webkit-mask: var(--elsa-icon-plus) var(--elsa-icon-plus-mask-position, center) / var(--elsa-icon-plus-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-plus) var(--elsa-icon-plus-mask-position, center) / var(--elsa-icon-plus-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

.elsaFileBlockPicker::after,
.elsaFileBlockAdd::after { content: none; }

.elsaFileBlockPreviewAction::before {
	-webkit-mask: var(--elsa-icon-view) var(--elsa-icon-view-mask-position, center) / var(--elsa-icon-view-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-view) var(--elsa-icon-view-mask-position, center) / var(--elsa-icon-view-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}

.elsaFileBlockDownloadAction::before {
	-webkit-mask: var(--elsa-icon-download) var(--elsa-icon-download-mask-position, center) / var(--elsa-icon-download-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-download) var(--elsa-icon-download-mask-position, center) / var(--elsa-icon-download-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaFileBlockDownloadAction::after { content: none; }

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	右へ90度回転（V2挙動の再現。2026-08-28の利用者指示）

	**図像は正方形である。** V2は`.elsaFileRotate::before`を操作面の半分
	（2emの操作面に1emの塗りつぶし）の四角として描き、ホバー中は
	`animation: rotate 1s infinite`で90度回してみせていた。正方形は90度
	回すと元と同じ形になるため、繰り返しの折り返しが見えず「転がり続ける」
	ように読める。

	2026-08-17の`操作アイコンを意味別の単一資産へ統合`（PR #1578、
	commit 477027af）が、この四角を円弧矢印の`rotate.svg` maskへ置き換えて
	いた。矢印は90度回すと元と違う向きになるため、折り返しのたびに図像が
	跳ね、V2の転がりが失われていた。四角へ戻し、`rotate.svg`は参照が
	無くなった（実体の削除は配信の安全装置に従って削除だけのPRで行う。
	`docs/deployment.md`「安全装置」）。

	**見た目の大きさを線画とそろえる**（2026-08-28の利用者指摘2件）。

	最初は16pxの箱をそのまま塗りつぶしていて「1つだけ大きい」と言われ、
	次に箱の半分（8px角）へ縮めたら「すごく小さい」と言われた。
	**基準は箱の大きさでも塗る面積でもなく、実際に描かれる図形の差し渡し
	である。**

	以下は2026-08-28時点の比較根拠。#3609ではSVGの余白を正規化し、
	回転図像も共通余白を除いた内側の枠に対して70.7%を適用する。
	他の5つは当時`viewBox="0 0 24 24"`のSVGを`mask ... contain`で敷いた線画で、
	**16pxの箱の中で実際に描かれる幅はパスの座標から11.0〜12.8px**
	（close 11.0 / view 11.7 / download 12.0 / menu 12.7 / plus 12.8）。
	箱いっぱいの16pxではないため、正方形を16pxにすると1つだけ大きく、
	8pxにすると1つだけ小さく見える。

	**一辺は図像枠の70.7%（＝1/√2）とする。70.7%＝1/√2、回転時の対角線が
	枠と一致する利用者指定値（2026-08-28）。** 16pxの枠なら一辺は約11.3px。

	この比率は**回転しても枠からはみ出さない最大の正方形**である。正方形は
	45度のときに差し渡しが√2倍になるため、一辺 × √2 ＝ 枠の一辺、すなわち
	11.3 × 1.414 ＝ 16.0px となり、**回転の最中に角が枠いっぱいへ届きながら、
	決して枠の外へは出ない。** 他の線画（実測 11.0〜12.8px）とも同じ帯に
	収まるため、静止時の差し渡しも並びの中で浮かない。

	16pxのままだと45度で22.6pxとなり、28pxの座布団の縁にほとんど触れていた。

	切り出しは他のボタンと同じ`mask`で行う。SVGを1枚増やさないのは、
	正方形はCSSの矩形そのもので描けて、90度回しても寸分違わず同じ形に
	なるためである（資産にすると`viewBox`の余白ぶんだけ形がずれる）。

	**動きは図像だけへ掛ける。** 操作面（円）を回しても見た目は変わらず、
	フォーカス枠まで回ってしまう。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/

.elsaFileBlockRotate { display: none; }
.elsaFileBlockRotate::before,
.elsaCommonFileRotateIcon {
	-webkit-mask: linear-gradient(#000, #000) calc(50% + var(--elsa-file-action-icon-offset-x)) calc(50% + var(--elsa-file-action-icon-offset-y)) / max(0px, var(--elsa-file-action-icon-square)) max(0px, var(--elsa-file-action-icon-square)) no-repeat;
	mask: linear-gradient(#000, #000) calc(50% + var(--elsa-file-action-icon-offset-x)) calc(50% + var(--elsa-file-action-icon-offset-y)) / max(0px, var(--elsa-file-action-icon-square)) max(0px, var(--elsa-file-action-icon-square)) no-repeat;
	transform-origin: calc(50% + var(--elsa-file-action-icon-offset-x)) calc(50% + var(--elsa-file-action-icon-offset-y));
}
/*
	**動きを減らす設定でも止めない**（2026-08-28の利用者指摘
	「マウスオーバーで回転しない」）。このPCのChromiumは
	`prefers-reduced-motion: reduce`を返すため、抑止を置いていた間は
	利用者の画面で一度も転がらなかった。**対象は16pxの図像1つ、利用者が
	自分でホバーしたときだけで、画面の位置も大きさも変えない。** V2にも
	抑止は無く、この図像の意味（右へ90度回す）は動きでしか伝わらないため、
	意図して例外にする。
*/
@media (hover: hover) {
	.elsaFileBlockRotate:hover::before,
	.button:hover > .elsaCommonFileRotateIcon {
		animation: elsa-file-block-v2-rotate 1s infinite;
	}
}
/*
	0.3秒で90度回し、残りは次の一拍まで止まる（V2が`transition: transform
	0.3s linear`で意図していた間合い）。90度で正方形は元の形へ戻るので、
	0%へ巻き戻る瞬間は見えない。
*/
@keyframes elsa-file-block-v2-rotate {
	0% {
		transform: rotate(0deg);
	}
	30% {
		transform: rotate(90deg);
	}
	100% {
		transform: rotate(90deg);
	}
}
/*
	回転中は`disabled`を付けて二度押しを止める。**これは「押せない」ではなく
	「処理中」**なので、共通の無効色（`--elsa-button-disabled-*`）へ寄せない。
	`cursor: wait`が待たせている意味を持ち、終われば自分で戻る。
*/
.elsaFileBlockRotate:disabled { cursor: wait; opacity: .65; }
.elsaFileBlockRotate:disabled::before,
.button:disabled > .elsaCommonFileRotateIcon { animation: none; }
/*
	削除の図像はLIST行と同じ承認済みA案（共通delete.svg）にする
	（2026-09-01の利用者決定、Issue #2609）。close.svgは検索条件解除、
	ダイアログ終了、未送信添付の取消など、削除ではない×だけが使う。
*/

.elsaFileBlockDelete::before {
	-webkit-mask: var(--elsa-icon-delete) var(--elsa-icon-delete-mask-position, center) / var(--elsa-icon-delete-mask-size, var(--elsa-icon-mask-size)) no-repeat;
	mask: var(--elsa-icon-delete) var(--elsa-icon-delete-mask-position, center) / var(--elsa-icon-delete-mask-size, var(--elsa-icon-mask-size)) no-repeat;
}
.elsaFileBlockDelete::after { content: none; }

.elsaFileBlock.is-dragover .elsaFileBlockDropZone {
	border-color: var(--elsa-primary-color, #24333f);
	background: var(--elsa-hover-bg, #eaf4ff);
	color: var(--elsa-primary-color, #24333f);
}

.elsaImportBlock {
	display: grid;
	gap: 12px;
	width: 100%;
}

.elsaImportBlockDropZone {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	min-height: 180px;
	padding: 24px;
	border: 2px dashed var(--elsa-border, #d2d2d2);
	border-radius: 8px;
	background: var(--elsa-surface-sunken, #f5f7f9);
	cursor: pointer;
}

.elsaImportBlockLarge .elsaImportBlockDropZone {
	min-height: clamp(280px, 42vh, 440px);
	padding: 40px;
	font-size: 1.15em;
}

.elsaImportBlock.is-dragover .elsaImportBlockDropZone {
	border-color: var(--elsa-primary-color, #24333f);
	background: var(--elsa-hover-bg, #eaf4ff);
}

.elsaImportBlockPrompt { font-weight: 600; }
.elsaImportBlockLimit { margin-top: 6px; color: var(--elsa-text-muted, #667085); font-size: 0.85em; }
.elsaImportBlockQueue { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.elsaImportBlockQueue li { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 10px; border: 1px solid var(--elsa-border, #d2d2d2); border-radius: 4px; }
.elsaImportBlockQueue li.is-complete { --elsa-import-state-background: color-mix(in srgb, var(--elsa-semantic-safe-color) 2%, var(--elsa-surface, #fff)); border-color: var(--elsa-semantic-safe-color, #53a653); background: var(--elsa-import-state-background, #f0fff0); }
.elsaImportBlockQueue li.is-error { --elsa-import-state-background: color-mix(in srgb, var(--elsa-semantic-danger-color) 4%, var(--elsa-surface, #fff)); border-color: var(--elsa-semantic-danger-color, var(--elsa-danger-color, #b42318)); background: var(--elsa-import-state-background, #fff1f0); }
.elsaImportBlockFileName { overflow-wrap: anywhere; }
.elsaImportBlockStatus { flex: 0 0 auto; }
.elsaImportBlockResult { flex: 0 0 auto; }
.elsaImportBlockStart { justify-self: center; }

.elsaImportPlayground { max-width: 960px; }
.elsaImportPlaygroundActions { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0; }
.elsaImportPlaygroundActions button { min-height: var(--elsa-form-control-height); }

.elsaCheckLabel {
	display: flex;
	align-items: center;
	width: 100%;
	min-height: var(--elsa-form-control-height);
	padding: var(--elsa-form-control-padding-block) var(--elsa-form-control-padding-inline);
	border: 1px solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius: var(--elsa-field-control-border-radius, 0 4px 4px 0);
	gap: 8px;
	line-height: var(--elsa-form-control-line-height);
	background: var(--elsa-field-state-background, #fff);
}

.elsaError { color: var(--elsa-danger-color, #b42318); }

@media (max-width: 640px) {

	.block .left,
	.block .right {
		width: 100%;
		flex-basis: 100%;
	}

	.block .left p {
		padding: var(--elsa-form-control-padding-block) var(--elsa-form-control-padding-inline);
		justify-content: flex-start;
		border-right: 1px solid var(--elsa-border, #d2d2d2);
		border-bottom: none;
		border-radius: 4px 4px 0 0;
	}

	.elsaFieldStatic {
		border-radius: 0 0 4px 4px;
	}

	.elsaColorControl,
	.elsaFileBlockDropZone,
	.elsaCheckLabel {
		border-radius: 0 0 4px 4px;
	}

	.elsaColorControl {
		padding-left: 0;
	}

}
.elsaCheckboxLabel{
	display:inline-flex;
	align-items:center;
	gap:8px;
	min-height:var(--elsa-form-control-height);
	padding-inline:8px;
	border-radius:5px;
	line-height:var(--elsa-form-control-line-height);
	cursor:pointer;
}
.elsaCheckboxLabel:hover{
	background:var(--elsa-primary-color, #24333f);
	color:var(--elsa-primary-contrast, #fff);
}
.elsaCheckboxLabel > input[type="checkbox"]{
	position:absolute;
	opacity:0;
	pointer-events:none;
}
.elsaCheckboxLabel > input[type="checkbox"] + span{
	box-sizing:border-box;
	display:inline-block;
	position:relative;
	width:24px;
	height:24px;
	flex:0 0 24px;
	border:2px solid var(--elsa-border, #d2d2d2);
	border-radius:5px;
	background:var(--elsa-field-state-background, #fff);
}
.elsaCheckboxLabel > input[type="checkbox"]:checked + span:after{
	content:"";
	position:absolute;
	left:4px;
	top:5px;
	width:11px;
	height:6px;
	border-left:3px solid var(--elsa-primary-color, #24333f);
	border-bottom:3px solid var(--elsa-primary-color, #24333f);
	transform:rotate(-50deg);
}
.elsaCheckboxLabel > input[type="checkbox"]:focus-visible + span{
	outline:2px solid var(--elsa-primary-color, #24333f);
	outline-offset:2px;
}
.elsaCheckboxLabel > input[type="checkbox"]:disabled + span{
	background:var(--elsa-disabled-field-background-color, #e9ecef);
}
.elsaCheckboxLabel.elsaCheckboxLabelDisabled{
	cursor:default;
}
.elsaCheckboxLabel.elsaCheckboxLabelDisabled:hover{
	background:transparent;
	color:inherit;
}
.elsaCheckboxOption{
	display:inline-flex;
	align-items:center;
	flex-wrap:wrap;
	gap:4px 8px;
	min-width:0;
}
.elsaCheckboxOptionNote{
	display:inline-flex;
	align-items:center;
	flex-wrap:wrap;
	gap:4px 8px;
	min-width:0;
}
.elsaCheckboxOptionNote--error{
	color:var(--elsa-button-danger-hover-bg, #b42318);
	font-weight:700;
}
.elsaCheckboxOptionNote a{
	color:var(--elsa-primary-color, #24333f);
	text-decoration:underline;
	text-underline-offset:2px;
}
/*
	CHECKBOXの要約表示（`render_mode: "summary"`）。選択中の表示名だけを描く
	読み取り専用の見せ方で、一覧のセルで使う。

	**`margin:0`と余白の指定を省かない。** `<p>`のブラウザ既定marginは`1em 0`で、
	要約を置くセルは`.elsaList td.elsaListCellField`が`padding:0`にしている
	（入力ブロックが自分の枠を持つため）。どちらも指定しないと、要約の行だけが
	上下へ1emずれて他の列と基準線が合わない。素のテキストの列と同じに見せるため、
	`.elsaList td`と同じ`4px 8px`を要約自身が持つ。
*/
.elsaCheckboxSummary{
	margin:0;
	padding:4px 8px;
	overflow-wrap:anywhere;
}
.elsaCheckboxGroup{
	display:flex;
	flex-wrap:wrap;
	gap:4px 16px;
	box-sizing:border-box;
	width:100%;
	min-height:var(--elsa-form-control-height);
	border:var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius:var(--elsa-field-control-border-radius, 4px);
	background:var(--elsa-field-state-background, #fff);
	overflow:hidden;
}
/*
	LISTのセルに居るCHECKBOX（ブロック自身が`data-list-field`を名乗る）は、狭い画面で
	選択肢を縦に積む（Issue #4142 PR-B 差し戻し②）。一覧の表は中身どおりの幅
	（`width:max-content`）で描くので、横に並んだ選択肢は折り返されず、列を足すと
	375px幅の枠（予定のポップアップ等）から押し出される。縦に積めば列の幅は
	最も長い選択肢1つぶんになる。
*/
@media (max-width: 640px){
	.elsaCheckboxGroup[data-list-field="true"]{
		flex-direction:column;
		flex-wrap:nowrap;
		gap:4px;
	}
}
.elsaSwitchGroup{
	display:flex;
	flex-wrap:wrap;
	/* A one-CSS-pixel gap rasterizes as alternating 1/2 device pixels at DPR 1.25. */
	gap:0;
	/*
		**隠したラジオの居場所をこの枠の中に閉じる**（2026-08-31にdevelopmentの実画面で実測）。

		`.elsaSwitchChoice`は`position:absolute`で見えなくしている。位置の基準になる
		祖先が1つも無いと、基準は**ページ全体**になる。ふだんは透明で誰も気づかないが、
		**統合窓では違う。** 窓は画面の高さちょうどで立ち、送るのはペインの内側だけ、
		というのが決めごとである（`core/css/elsa_app_explorer.css`）。ペインが内側で
		送られて中身が画面より下まで伸びると、この隠しラジオだけがペインの外——
		ページの座標——に居座り、**ページ全体が縦に動くようになる。**

		実測: Amazonの利用要件の編集（PC幅1280×800）でページが383px動き、
		Amazon API接続設定（375px幅）で101px動いた。`position:relative`を1行足すと
		どちらも0pxになり、ペインの内側の送りと切り替えの見た目（80×34px）は変わらない。

		`overflow:hidden`は既にこの枠が持っているので、基準さえここへ寄せれば
		隠しラジオはこの枠の中で切り取られる。
	*/
	position:relative;
	box-sizing:border-box;
	width:max-content;
	max-width:100%;
	min-height:var(--elsa-form-control-height);
	padding:0;
	border:var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius:var(--elsa-field-control-border-radius, 4px);
	background:var(--elsa-field-control-border-color, #d2d2d2);
	overflow:hidden;
}
.elsaSwitchChoice{
	position:absolute;
	opacity:0;
	pointer-events:none;
}
.elsaSwitchChoice + label{
	position:relative;
	display:inline-flex;
	align-items:center;
	justify-content:center;
	flex:1 0 auto;
	min-width:80px;
	min-height:calc(var(--elsa-form-control-height) - (2 * var(--elsa-form-control-border-width)));
	padding:var(--elsa-form-control-padding-block) 12px;
	border:0;
	border-radius:0;
	background:var(--elsa-field-state-background, #fff);
	text-align:center;
	line-height:var(--elsa-form-control-line-height);
	white-space:nowrap;
	word-break:keep-all;
	cursor:pointer;
}
.elsaSwitchChoice + label:not(:first-of-type){
	/* Borders snap to the same physical-pixel width as the group's outer border. */
	border-inline-start:var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
}
.elsaSwitchChoice + label:last-of-type{border-radius:0;}
@media (max-width:960px){
	.elsaSwitchGroup{width:100%;}
	.elsaSwitchChoice + label{
		flex-basis:33.333333%;
		min-width:33.333333%;
	}
	.elsaSwitchChoice + label:nth-of-type(3n + 1){border-inline-start:0;}
	.elsaSwitchChoice + label:nth-of-type(n + 4){border-block-start:var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);}
}
@media (max-width:640px){
	.elsaSwitchChoice + label{
		flex-basis:50%;
		min-width:50%;
	}
	.elsaSwitchChoice + label:nth-of-type(even){border-inline-start:var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);}
	.elsaSwitchChoice + label:nth-of-type(odd){border-inline-start:0;}
	.elsaSwitchChoice + label:nth-of-type(n + 3){border-block-start:var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);}
}
/* LIST cells use the compact common-button height without changing normal field SWITCHes. */
.elsaList .elsaSwitchGroup{
	flex-wrap:nowrap;
	width:max-content;
	height:28px;
	min-height:28px;
	border-radius:4px;
}
/*
	一覧のセルの中のSWITCHは、マス目の線から決まった余白だけ離す（Issue #4561、
	オーナー指摘 2026-10-09 設定 › AI の機能ごとの許可）。SWITCHはセルを埋めずに
	自分の枠を持つ部品なので、セルの`padding:0`のままだと枠がマス目の線に接して
	見えた。余白は**SWITCH自身の外側**が持つ（開発方針「LISTセル内では親セルの
	paddingで隙間を作らない」）。値は操作列のセルの余白と同じ帯の隙間の半分
	（`--elsa-list-cell-control-gap`）。選択肢型・色見本・トグルのどれにも効く。
*/
.elsaList td.elsaListCellField .elsaSwitchGroup{
	margin:var(--elsa-list-cell-control-gap);
}
.elsaList .elsaSwitchChoice + label{
	height:calc(28px - (2 * var(--elsa-form-control-border-width)));
	min-height:calc(28px - (2 * var(--elsa-form-control-border-width)));
	padding-top:0;
	padding-bottom:0;
	border-block-start:0;
}
.elsaList .elsaSwitchChoice + label:not(:first-of-type){
	border-inline-start:var(--elsa-form-control-border-width) solid var(--elsa-field-control-border-color, #d2d2d2);
}
.elsaSwitchChoice:checked + label{
	z-index:1;
	background:var(--elsa-primary-color, #24333f);
	color:var(--elsa-primary-contrast, #fff);
}
.elsaSwitchChoice:focus-visible + label{
	outline:2px solid var(--elsa-primary-color, #24333f);
	outline-offset:-3px;
}
/*
	**SWITCHは入力欄であってボタンではない。** 地は`--elsa-field-state-background`
	（無効な行では外観設定の`--elsa-disabled-field-background-color`）から来て、
	選択中の1つはアプリ色で塗られる。共通の無効色（`--elsa-button-disabled-*`）で
	上書きすると**どれが選ばれているのかが消える**ため、意図してここには寄せない
	（2026-08-28の統一の対象外。境界はbodyの変数の注記が持つ）。
*/
.elsaSwitchChoice:disabled + label{
	cursor:default;
	opacity:.6;
}
/*
	SWITCHのopt-in色見本（`design => "swatch"`、Issue #4351 予定の色）。
	選択肢は28px角の色見本で、色は`elsa_field_block_switch()`が各見本へ渡す
	`--elsa-switch-swatch`だけから取る。選んだ見本には地の文の色の輪を付ける。
	幅が狭くても見本は折り返して並ぶだけで、既定の選択肢型の段組み（33%・50%）は使わない。
*/
.elsaSwitchGroup.elsaSwitchGroup--swatch{
	gap:6px;
	width:auto;
	min-height:0;
	padding:3px;
	border:0;
	background:transparent;
	overflow:visible;
}
.elsaSwitchGroup.elsaSwitchGroup--swatch .elsaSwitchChoice + label.elsaSwitchSwatch{
	flex:0 0 auto;
	box-sizing:border-box;
	width:28px;
	min-width:28px;
	height:28px;
	min-height:28px;
	padding:0;
	border:1px solid var(--elsa-field-control-border-color, #d2d2d2);
	border-radius:4px;
	background:var(--elsa-switch-swatch);
}
.elsaSwitchGroup.elsaSwitchGroup--swatch .elsaSwitchChoice:checked + label.elsaSwitchSwatch{
	outline:2px solid var(--elsa-content-text-color, #333333);
	outline-offset:2px;
}
.elsaSwitchGroup.elsaSwitchGroup--swatch .elsaSwitchChoice:focus-visible + label.elsaSwitchSwatch{
	outline:2px solid var(--elsa-primary-color, #24333f);
	outline-offset:2px;
}
/*
	SWITCHのopt-inトグル。既定の選択肢型へは一切作用させない。
	44×24pxの中を20pxのつまみが移動し、色は会社別の共通tokenだけから取る。
*/
.elsaSwitchGroup--toggle{
	position:relative;
	display:inline-block;
	flex:none;
	box-sizing:border-box;
	width:44px;
	min-width:44px;
	max-width:44px;
	height:24px;
	min-height:24px;
	padding:0;
	border:0;
	border-radius:999px;
	background:transparent;
	overflow:visible;
}
.elsaSwitchGroup--toggle .elsaSwitchToggleInput{
	position:absolute;
	z-index:2;
	inset:0;
	width:100%;
	height:100%;
	margin:0;
	opacity:0;
	pointer-events:auto;
	cursor:pointer;
}
.elsaSwitchGroup--toggle .elsaSwitchToggleInput + .elsaSwitchToggleTrack{
	position:absolute;
	inset:0;
	display:block;
	box-sizing:border-box;
	min-width:0;
	min-height:0;
	padding:2px;
	border:0;
	border-radius:999px;
	background:var(--elsa-border, #d2d2d2);
	cursor:pointer;
}
.elsaSwitchToggleThumb{
	display:block;
	width:20px;
	height:20px;
	border-radius:50%;
	background:var(--elsa-surface, #ffffff);
	box-shadow:0 1px 2px color-mix(in srgb, var(--elsa-content-text-color, #333333) 22%, transparent);
	transition:transform .15s ease;
}
.elsaSwitchGroup--toggle .elsaSwitchToggleInput:checked + .elsaSwitchToggleTrack{
	background:var(--elsa-primary-color, #24333f);
	color:inherit;
}
.elsaSwitchGroup--toggle .elsaSwitchToggleInput:checked + .elsaSwitchToggleTrack .elsaSwitchToggleThumb{
	transform:translateX(20px);
}
.elsaSwitchGroup--toggle .elsaSwitchToggleInput:focus-visible + .elsaSwitchToggleTrack{
	outline:2px solid var(--elsa-primary-color, #24333f);
	outline-offset:2px;
}
.elsaSwitchGroup--toggle .elsaSwitchToggleInput:disabled{
	cursor:not-allowed;
}
.elsaSwitchGroup--toggle .elsaSwitchToggleInput:disabled + .elsaSwitchToggleTrack{
	background:var(--elsa-disabled-field-background-color, #e9ecef);
	cursor:not-allowed;
	opacity:.58;
}
@media (prefers-reduced-motion:reduce){
	.elsaSwitchToggleThumb{transition:none;}
}
.elsaPageMessages:empty { display: none; }
.elsaPageMessages { display: grid; gap: var(--elsa-block-spacing, 8px); margin: 0; }
.elsaFeedbackOverlay { position: fixed; top: 12px; left: 50%; z-index: 1400; width: min(720px, calc(100vw - 32px)); max-height: calc(100vh - 24px); overflow-y: auto; transform: translateX(-50%); pointer-events: none; }
.elsaFeedbackOverlayItem { box-sizing: border-box; width: 100%; min-width: 0; box-shadow: 0 10px 28px rgba(20, 36, 48, .2); pointer-events: auto; animation: elsaFeedbackEnter 180ms ease-out both; }
.elsaFeedbackOverlayItem.is-leaving { animation: elsaFeedbackLeave 220ms ease-in both; }
@keyframes elsaFeedbackEnter { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } }
@keyframes elsaFeedbackLeave { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(-8px); } }
/* Thin state surfaces use tinted body text, not the contrast of a solid semantic fill.
   A missing semantic token invalidates the local derivation so each consumer keeps its legacy fallback. */
.elsaPageMessage { --elsa-page-message-state-background: color-mix(in srgb, var(--elsa-semantic-danger-color) 6%, var(--elsa-surface, #fff)); --elsa-page-message-state-border: color-mix(in srgb, var(--elsa-semantic-danger-color) 38%, var(--elsa-surface, #fff)); --elsa-page-message-state-text: color-mix(in srgb, var(--elsa-semantic-danger-color) 10%, var(--elsa-content-text-color, #333)); align-items: flex-start; background: var(--elsa-page-message-state-background, #fff1f0); border: 1px solid var(--elsa-page-message-state-border, #f2a8a2); border-left: 4px solid var(--elsa-semantic-danger-color, var(--elsa-danger-color, #b42318)); border-radius: 6px; color: var(--elsa-page-message-state-text, #7a271a); display: flex; gap: 12px; justify-content: space-between; padding: 12px 14px; }
.elsaPageMessage[hidden] { display: none; }
.elsaPageMessage.is-success { --elsa-page-message-state-background: color-mix(in srgb, var(--elsa-semantic-safe-color) 5%, var(--elsa-surface, #fff)); --elsa-page-message-state-border: color-mix(in srgb, var(--elsa-semantic-safe-color) 47%, var(--elsa-surface, #fff)); --elsa-page-message-state-text: color-mix(in srgb, var(--elsa-semantic-safe-color) 10%, var(--elsa-content-text-color, #333)); background: var(--elsa-page-message-state-background, #ecfdf3); border-color: var(--elsa-page-message-state-border, #75d89a); border-left-color: var(--elsa-semantic-safe-color, #067647); color: var(--elsa-page-message-state-text, #05603a); }
.elsaPageMessage.is-info { background: #eff8ff; border-color: #84caff; border-left-color: #1570ef; color: #1849a9; }
.elsaPageMessage.is-warning { --elsa-page-message-state-background: color-mix(in srgb, var(--elsa-semantic-caution-color) 7%, var(--elsa-surface, #fff)); --elsa-page-message-state-border: color-mix(in srgb, var(--elsa-semantic-caution-color) 61%, var(--elsa-surface, #fff)); --elsa-page-message-state-text: color-mix(in srgb, var(--elsa-semantic-caution-color) 10%, var(--elsa-content-text-color, #333)); background: var(--elsa-page-message-state-background, #fffaeb); border-color: var(--elsa-page-message-state-border, #fec84b); border-left-color: var(--elsa-semantic-caution-color, #dc6803); color: var(--elsa-page-message-state-text, #7a2e0e); }
.elsaPageMessage > :first-child { flex: 1 1 16rem; min-width: 0; }
.elsaPageMessageAction { flex: 0 0 auto; margin: 0; white-space: nowrap; }
.elsaPageMessageClose { appearance: none; flex: 0 0 var(--elsa-block-action-height); display: grid; place-items: center; width: var(--elsa-block-action-height); min-width: var(--elsa-block-action-height); height: var(--elsa-block-action-height); min-height: var(--elsa-block-action-height); padding: 0; border: 0; border-radius: 50%; background: transparent; color: currentColor; cursor: pointer; }
.elsaPageMessageClose::before { width: 1em; height: 1em; background: currentColor; content: ""; -webkit-mask: var(--elsa-icon-close) var(--elsa-icon-close-mask-position, center) / var(--elsa-icon-close-mask-size, var(--elsa-icon-mask-size)) no-repeat; mask: var(--elsa-icon-close) var(--elsa-icon-close-mask-position, center) / var(--elsa-icon-close-mask-size, var(--elsa-icon-mask-size)) no-repeat; }
.elsaPageMessageClose:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
@media (hover: hover) { .elsaPageMessageClose:hover { background: rgba(0, 0, 0, .08); } }
@media (prefers-reduced-motion: reduce) { .elsaFeedbackOverlayItem, .elsaFeedbackOverlayItem.is-leaving { animation: none; } }
@media (max-width: 640px) { .elsaFeedbackOverlay { top: 8px; width: calc(100vw - 24px); max-height: calc(100vh - 16px); } .elsaFeedbackOverlayItem { flex-wrap: wrap; } .elsaPageMessageAction { flex: 1 1 auto; order: 2; } .elsaPageMessageClose { order: 3; } }
.elsaAlertBlock[data-alert-placement] { margin: 0; }
.elsaAlertDialog[data-alert-placement="modal"] { margin: auto; }
.elsaSettingsRoundtripOpen { overflow: hidden; }
/*
	Settings roundtrips render inside a dialog iframe. The server omits the
	navigation shell for this context, and these overrides also keep a stale
	navigation class from reserving the normal left navigation column.
*/
body.elsaContextLayout,
body.elsaContextLayout.elsaHasNavigation { --elsa-content-left: 0px; display: block; min-width: 0; margin: 0; padding: 0; overflow-x: hidden; background: var(--elsa-surface, #ffffff); }
body.elsaContextLayout #elsaNav { display: none; }
body.elsaContextLayout #elsaLayout { box-sizing: border-box; grid-row: auto; grid-column: auto; width: 100%; min-width: 0; min-height: 0; margin: 0; padding: var(--elsa-block-spacing, 8px); overflow: visible; }
body.elsaContextLayout .elsaPageTitleBlock { display: none; }
.elsaAlertDialog--panel { width: min(720px, calc(100vw - 32px)); }
.elsaAlertDialog--panel .elsaAlertDialogPanel { position: relative; max-height: calc(100vh - 48px); overflow: auto; }
.elsaAlertDialog--panel .elsaAlertDialogTitle:empty { display: none; }
.elsaFieldHelpDialogText { margin: 0; color: var(--elsa-content-text-color, #333333); font-size: var(--elsa-form-font-size, 16px); line-height: 1.7; overflow-wrap: anywhere; white-space: pre-wrap; }
.elsaAlertDialogDragHandle { cursor: move; touch-action: none; user-select: none; -webkit-user-select: none; }
/*
	Issue #4093 (9): この×は単独Alert時代の名残りで、共通ポップアップの帯
	（`.elsaPopupBand`）へ`elsaAlert.openPanel()`のcompat互換が付ける
	（`core/php/blocks/popup/popup.js`のapplyLevelChrome()）。帯は
	flexで「＋」等の帯ボタンと横並びに置く器なので、この規則が
	`position: absolute; top: 10px; right: 10px;`で右上へ固定してしまうと、
	×だけ帯の外（右上）へ積み上がり「＋」の下に見える（Issue #4093実測）。
	**位置系の3つだけを外す**——マスクアイコン・hover・focus-visibleは
	単独Alertの見た目の名残りではなく×そのものの意匠なので残す。
	`git grep elsaAlertDialogClose`で確認済み: 実際に動くdialogは
	共通ポップアップのshell 1つだけで、この帯を経由しない単独Alert
	dialogは現存しない（`contents/icon_playground/icon_playground.php`は
	静的な見本描画で実dialogを開かない）。将来もし帯を持たない単独Alertが
	復活したら、`.elsaPopupBand .elsaAlertDialogClose`のようにこの規則を
	帯へ限定し、単独側だけ`position: absolute`を別規則で戻すこと。
*/
.elsaAlertDialogClose { appearance: none; display: grid; place-items: center; width: var(--elsa-block-action-height); min-width: var(--elsa-block-action-height); height: var(--elsa-block-action-height); min-height: var(--elsa-block-action-height); padding: 0; border: 0; border-radius: 50%; background: var(--elsa-button-default-bg, #d2d2d2); color: var(--elsa-button-default-color, #667085); cursor: pointer; font: inherit; line-height: 1; }
.elsaAlertDialogClose::before { width: 1em; height: 1em; background: currentColor; content: ""; -webkit-mask: var(--elsa-icon-close) var(--elsa-icon-close-mask-position, center) / var(--elsa-icon-close-mask-size, var(--elsa-icon-mask-size)) no-repeat; mask: var(--elsa-icon-close) var(--elsa-icon-close-mask-position, center) / var(--elsa-icon-close-mask-size, var(--elsa-icon-mask-size)) no-repeat; }
.elsaAlertDialogClose:focus-visible { outline: 2px solid var(--elsa-primary-color, #24333f); outline-offset: 2px; }
@media (hover: hover) { .elsaAlertDialogClose:hover { background: var(--elsa-primary-color, #24333f); color: var(--elsa-primary-contrast, #fff); } }
.elsaPageMessageClose { appearance: none; width: var(--elsa-block-action-height); min-width: var(--elsa-block-action-height); height: var(--elsa-block-action-height); min-height: var(--elsa-block-action-height); padding: 0; border: 0; border-radius: 50%; background: var(--elsa-button-default-bg, #d2d2d2); color: var(--elsa-button-default-color, #667085); cursor: pointer; font: inherit; line-height: 1; }
.elsaPageMessageClose:focus-visible { outline: 2px solid var(--elsa-primary-color, #24333f); outline-offset: 2px; }
@media (hover: hover) { .elsaPageMessageClose:hover { background: var(--elsa-primary-color, #24333f); color: var(--elsa-primary-contrast, #fff); } }
.elsaToastRegion { bottom: 20px; display: grid; gap: var(--elsa-block-spacing, 8px); max-width: min(420px, calc(100vw - 32px)); pointer-events: none; position: fixed; right: 20px; z-index: 10000; }
.elsaToast { background: #1f2937; border: 0; border-left: 4px solid var(--elsa-semantic-danger-color, #ef4444); border-radius: 6px; box-shadow: 0 8px 24px rgba(0,0,0,.22); color: #fff; opacity: 1; padding: 12px 16px; transform: translateY(0); transition: opacity .2s, transform .2s; }
.elsaToast.is-success { border-left-color: var(--elsa-semantic-safe-color, #32d583); }
.elsaToast.is-leaving { opacity: 0; transform: translateY(8px); }
/* 可視文言は上部ALERTだけに出し、ARIA参照先はフォームの高さを変えない。 */
.elsaFieldError { border: 0; clip: rect(0 0 0 0); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; white-space: nowrap; width: 1px; }

@media (max-width: 640px) {
	.elsaAlertDialog { margin: auto; max-width: calc(100vw - 24px); }
	.elsaAlertDialogPanel { max-height: calc(100vh - 24px); padding: 18px; }
	.elsaAlertDialogActions > .button { flex: 1 1 auto; }
}
/*
	入力エラーの赤枠は、エラーになったコントロール自身に付ける。
	TEXTブロックなら`input`／`textarea`そのものであり、ラベルのタブ（.left）と
	エラー文（.elsaFieldError）は枠の外に残る。

	2026-08-13の利用者指摘: 「赤枠はTEXTブロックであれば入力欄の外側に表示して
	ください。ラベルごと囲わないでください。」本番ログイン画面でパスワード未入力に
	すると、`.elsaFieldRow.has-field-error`のoutlineがラベル・入力欄・エラー文の
	3つをまとめて囲っていた。

	赤枠は1箇所だけにする。`.elsaFieldRow`側のoutlineをここへ足し戻さないこと
	（PR #966が二重の枠を嫌って消したのはコントロール側だったが、
	ラベルを囲わない側＝コントロール側こそが残すべき枠である）。
	枠はborderの色替え＋1pxのbox-shadowで作り、レイアウトを動かさない
	（ブロック間の8px規則を壊さないため）。

	CHECKBOXの組は`elsa_feedback.js`が組自身へ`aria-invalid`を付けるが、ここに
	載っていなかったため赤枠が1つも出なかった（`.has-error input`は隠した入力に
	しか当たらない）。一覧のセルの中では組の枠を0にする（Issue #4561）ので、
	赤はbox-shadowだけで示す。
*/
.elsaField[aria-invalid="true"], .elsaCheckboxGroup[aria-invalid="true"], .elsaSelectorSuggestSelectionText[aria-invalid="true"], .elsaSwitchGroup.has-error, .has-error input, .has-error select, .has-error textarea, .has-error .elsaTreeTrigger, [data-file-block].has-error [data-file-dropzone], [data-import-block].has-error [data-import-dropzone], [data-ai-request-images].has-error [data-ai-request-image-drop] { border-color: var(--elsa-danger-color, #b42318) !important; box-shadow: 0 0 0 1px var(--elsa-danger-color, #b42318); }
/*
	一覧のセルの中では、外側の1pxは隣のセルと罫線に覆われてほとんど見えない
	（Issue #4561で実測）。セルの入力部品は枠を0にしているので、赤は内側の2pxで描き、
	セルの罫線と重ねずに読めるようにする。セルを埋める入力部品はどれもここ1か所で
	内側の2pxにそろえる（TEXT・SELECTORの保存欄、CHECKBOXの組、SELECTORのサジェスト型が
	選んだ札＝`.elsaSelectorSuggestSelectionText`）。一覧の外の入力欄は上の共通規則の
	外側1pxのまま。
*/
.elsaList td.elsaListCellField .elsaField[aria-invalid="true"], .elsaList td.elsaListCellField .elsaCheckboxGroup[aria-invalid="true"], .elsaList td.elsaListCellField .elsaSelectorSuggestSelectionText[aria-invalid="true"] { box-shadow: inset 0 0 0 2px var(--elsa-danger-color, #b42318); }
/*
	セルの中のSWITCHのエラーも、ほかのセルの入力と同じ内側の赤2pxにそろえる（Issue #4561）。
	SWITCHは中の選択肢（トグルはつまみの溝）が背景で組を埋めるので、組自身の内側の
	box-shadowは覆われて見えない。赤は組の上に重ねた`::after`が描く（組は`position:relative`
	を持つ）。選択肢型は赤くなった枠（上の共通規則）＋内側で合わせて2px、枠の無いトグルは
	内側の2pxだけ（一覧の組は角丸4pxなので、トグルは溝と同じ丸みを自分で持つ）。外側の1pxは消す。一覧の外のSWITCHは上の共通規則のまま。
*/
.elsaList td.elsaListCellField .elsaSwitchGroup.has-error { box-shadow: none; }
.elsaList td.elsaListCellField .elsaSwitchGroup.has-error::after { content: ""; position: absolute; z-index: 3; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 calc(2px - var(--elsa-form-control-border-width)) var(--elsa-danger-color, #b42318); pointer-events: none; }
.elsaList td.elsaListCellField .elsaSwitchGroup--toggle.has-error::after { border-radius: 999px; box-shadow: inset 0 0 0 2px var(--elsa-danger-color, #b42318); }
@media (max-width: 640px) { .elsaToastRegion { bottom: 12px; left: 12px; max-width: none; right: 12px; } }

/* 外部サービスとの同期方向を◁・▷2つの独立ON/OFFで示す共通ブロック（2026-09-10・Issue #3501）。 */
.elsaSyncDirectionBlock { --elsa-sync-direction-size: var(--elsa-block-action-height, 28px); align-items: center; background: var(--elsa-surface, #ffffff); border: 1px solid var(--elsa-field-control-border-color, #aaa); border-radius: 4px; display: grid; gap: 4px 10px; grid-template-columns: minmax(6rem, .75fr) minmax(13rem, 1.25fr); padding: 5px 8px; }
.elsaSyncDirectionBlock--bulk { background: color-mix(in srgb, var(--elsa-primary-color, #24333f) 6%, var(--elsa-surface, #ffffff)); border-color: var(--elsa-primary-color, #24333f); }
.elsaSyncDirectionCaption { font-size: .9em; line-height: 1.3; margin: 0; }
.elsaSyncDirectionControl { align-items: center; display: grid; gap: 4px; grid-template-columns: minmax(0, 1fr) repeat(2, var(--elsa-sync-direction-size)) minmax(0, 1fr); width: 100%; }
.elsaSyncDirectionEndpoint { font-size: .78em; font-weight: 700; line-height: 1.2; }
.elsaSyncDirectionEndpoint--left { text-align: right; }
.elsaSyncDirectionEndpoint--right { text-align: left; }
.elsaSyncDirectionChoice { display: block; height: var(--elsa-sync-direction-size); position: relative; width: var(--elsa-sync-direction-size); }
.elsaSyncDirectionChoice input { height: 100%; inset: 0; margin: 0; opacity: 0; position: absolute; width: 100%; }
.elsaSyncDirectionChoice label { align-items: center; background: var(--elsa-surface, #ffffff); border: 1px solid var(--elsa-field-control-border-color, #aaa); border-radius: 4px; cursor: pointer; display: flex; height: var(--elsa-sync-direction-size); justify-content: center; line-height: 1; transition: background-color .15s ease, color .15s ease, transform .15s ease; width: var(--elsa-sync-direction-size); }
.elsaSyncDirectionChoice input:checked + label { background: var(--elsa-primary-color, #24333f); border-color: var(--elsa-primary-color, #24333f); color: var(--elsa-primary-contrast, #fff); transform: scale(1.06); }
.elsaSyncDirectionChoice input:focus-visible + label { outline: 3px solid var(--elsa-primary-color, #24333f); outline-offset: 2px; }
/*  SWITCHと同じ理由で共通の無効色へ寄せない（選択中の向きが分からなくなる）。  */
.elsaSyncDirectionChoice input:disabled + label { cursor: not-allowed; opacity: .55; }
.elsaSyncDirectionIcon { color: currentColor; display: block; width: 16px; height: 16px; background: currentColor; }
.elsaSyncDirectionIcon--import { -webkit-mask: var(--elsa-icon-arrow-left) var(--elsa-icon-arrow-left-mask-position, center) / var(--elsa-icon-arrow-left-mask-size, var(--elsa-icon-mask-size)) no-repeat; mask: var(--elsa-icon-arrow-left) var(--elsa-icon-arrow-left-mask-position, center) / var(--elsa-icon-arrow-left-mask-size, var(--elsa-icon-mask-size)) no-repeat; }
.elsaSyncDirectionIcon--export { -webkit-mask: var(--elsa-icon-arrow-right) var(--elsa-icon-arrow-right-mask-position, center) / var(--elsa-icon-arrow-right-mask-size, var(--elsa-icon-mask-size)) no-repeat; mask: var(--elsa-icon-arrow-right) var(--elsa-icon-arrow-right-mask-position, center) / var(--elsa-icon-arrow-right-mask-size, var(--elsa-icon-mask-size)) no-repeat; }
.elsaSyncDirectionNote, .elsaSyncDirectionReason { --elsa-sync-direction-state-text: color-mix(in srgb, var(--elsa-semantic-caution-color) 10%, var(--elsa-content-text-color, #333)); color: var(--elsa-sync-direction-state-text, #8a3d2d); grid-column: 1 / -1; margin: 0; text-align: center; }
.elsaSyncDirectionNote { font-size: .85em; }
.elsaSyncDirectionReason { font-size: .78em; }
.elsaSyncDirectionReason span { background: color-mix(in srgb, currentColor 10%, var(--elsa-surface, #fff)); border: 1px solid color-mix(in srgb, currentColor 45%, transparent); border-radius: 999px; color: inherit; display: inline-block; padding: 2px 8px; }
@media (max-width: 360px) {
	.elsaSyncDirectionBlock { grid-template-columns: minmax(0, 1fr); }
}

/* external_api_credential: 色だけに頼らない統一接続状態。 */
.elsaExternalCredentialState { align-items: center; border: 2px solid var(--elsa-connection-state-idle, var(--elsa-field-control-border-color)); border-radius: 4px; box-sizing: border-box; display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; max-width: 100%; min-height: 32px; padding: 5px 8px; }
.elsaExternalCredentialState[data-state="connected"] { border-color: var(--elsa-connection-state-connected, var(--elsa-primary-color, #24333f)); }
.elsaExternalCredentialState[data-state="connected"] .elsaExternalCredentialState__symbol { color: var(--elsa-connection-state-connected, var(--elsa-primary-color, #24333f)); }
.elsaExternalCredentialState[data-state="connect_failed"], .elsaExternalCredentialState[data-state="autosave_failed"], .elsaExternalCredentialState[data-state="status_unavailable"] { border-color: var(--elsa-connection-state-error, var(--elsa-button-danger-hover-bg)); }
.elsaExternalCredentialState[data-state="connect_failed"] .elsaExternalCredentialState__symbol, .elsaExternalCredentialState[data-state="autosave_failed"] .elsaExternalCredentialState__symbol, .elsaExternalCredentialState[data-state="status_unavailable"] .elsaExternalCredentialState__symbol { color: var(--elsa-connection-state-error, var(--elsa-button-danger-hover-bg)); }
.elsaExternalCredentialState[data-state="unconfigured"], .elsaExternalCredentialState[data-state="incomplete"], .elsaExternalCredentialState[data-state="reconnect_required"] { border-color: var(--elsa-semantic-caution-color, #dc6803); box-shadow: inset 4px 0 0 var(--elsa-connection-state-warning, var(--elsa-button-default-bg, #d2d2d2)); }
.elsaExternalCredentialState[data-state="unconfigured"] .elsaExternalCredentialState__symbol, .elsaExternalCredentialState[data-state="incomplete"] .elsaExternalCredentialState__symbol, .elsaExternalCredentialState[data-state="reconnect_required"] .elsaExternalCredentialState__symbol { color: var(--elsa-semantic-caution-color, #dc6803); }
.elsaExternalCredentialState__symbol { align-items: center; display: inline-flex; flex: 0 0 auto; font-size: 1.2em; font-weight: 700; justify-content: center; line-height: 1; min-height: 20px; min-width: 20px; }
.elsaExternalCredentialState__message { min-width: 0; overflow-wrap: anywhere; }

/*
	「管理画面」を開くリンク（Issue #4428）。入力欄の行の直後に1行で置く。
	**ボタンの姿にしない**——帯（ボタンエリア）のボタンと見分けが付かなくなる。
	長いURLでも横スクロールを作らないよう、折り返しを許す。
*/
.elsaExternalCredentialConsole { margin: 0 0 8px; max-width: 100%; }
.elsaExternalCredentialConsole[hidden] { display: none; }
.elsaExternalCredentialConsole__link { overflow-wrap: anywhere; }

/*
	読み込み中の共通の回転マーク（Issue #3712）。外部API接続確認だけが持っていた
	回転マーク（旧`.elsaExternalCredentialState__spinner`）を共通部品へ昇格させた
	もので、色・太さ・大きさは元のまま変えていない。「読み込み中」の文字は画面へ
	出さず、`core/js/elsa_loading_spinner.js`が`role="status"`
	`aria-label="読み込み中"`を持つこの要素を作る。
*/
.elsaLoadingSpinner { animation: elsaLoadingSpinnerSpin .8s linear infinite; border: 2px solid var(--elsa-connection-state-idle, var(--elsa-field-control-border-color)); border-radius: 50%; border-top-color: var(--elsa-connection-state-connected, var(--elsa-primary-color, #24333f)); box-sizing: border-box; display: inline-block; height: 14px; width: 14px; vertical-align: middle; }
.elsaLoadingSpinner[hidden] { display: none; }
@keyframes elsaLoadingSpinnerSpin { to { transform: rotate(360deg); } }
/*
	メニューを押した瞬間の「移動中」の表示（Issue #4602、`core/js/elsa_loading_spinner.js`の
	`window.elsaNavPending`）。画面の上端の細い帯は幅が伸びていき、押した項目は選ばれた
	見た目になる。文字は出さない。
*/
.elsaNavPendingBar { background: var(--elsa-connection-state-connected, var(--elsa-primary-color, #24333f)); height: 3px; left: 0; pointer-events: none; position: fixed; top: 0; width: 0; z-index: 2147483000; }
.elsaNavPendingBar.is-running { animation: elsaNavPendingGrow 8s cubic-bezier(.1, .7, .3, 1) forwards; }
@keyframes elsaNavPendingGrow { 0% { width: 0; } 10% { width: 35%; } 100% { width: 92%; } }
@media (prefers-reduced-motion: reduce) {
	.elsaNavPendingBar.is-running { animation: none; width: 60%; }
}
.elsaNavMenu .elsaNavLeaf.is-nav-pending { background: var(--elsa-selected-bg, #dceeff); color: var(--elsa-selected-color, #333333); font-weight: 700; }

/*
	右ペイン・本文領域の、いま見えている範囲の中央へ重ねて出す版（タブ・枝の
	切替、一覧の再読み込み）。対象ペインの外枠は内部スクロールでは動かない
	（`docs/architecture.md`「左ツリーと右ペインの使い分け」）ので、
	`core/js/elsa_loading_spinner.js`が対象の`getBoundingClientRect()`と
	ビューポートの共通部分の中心へ`top`/`left`を置けば、内部スクロールでは
	動かず、ページ全体がスクロールする狭い画面ではその動きへ追従する。
*/
.elsaLoadingSpinnerOverlay { position: fixed; top: 0; left: 0; transform: translate(-50%, -50%); pointer-events: none; z-index: 25; }
.elsaLoadingSpinnerOverlay .elsaLoadingSpinner { height: 28px; width: 28px; border-width: 3px; }


/* Issue #3313 Stage 2b: each approved visual row is its own responsive field grid. */
.elsaAppSettingFieldGrid {
	grid-column: 1 / -1;
	min-width: 0;
}
.elsaAppSettingFieldGrid > .left {
	display: none;
}
.elsaAppSettingFieldGrid > .right {
	display: grid;
	min-width: 0;
	grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
	gap: var(--elsa-block-spacing, 8px);
}
.block.elsaAppSettingFieldGridItem {
	min-width: 0;
	margin: 0;
	padding-top: 0;
}

/* Muted copy follows the local foreground/background pair without transparency. */
#elsaLayout {
	--elsa-text-muted: color-mix(in srgb, var(--elsa-content-text-color, #333333) calc(var(--elsa-muted-text-strength, 0.65) * 100%), var(--elsa-surface, #ffffff));
}

/* 上下余白だけはPC専用。左右余白と字下げはPC・スマートフォンで共用する。 */
@media (max-width: 767px) {
	.elsaTreeList {
		--elsa-tree-row-padding-block: 3px;
	}
}

@media (max-width: 640px) {
	.elsaAppSettingFieldGrid > .right {
		grid-template-columns: minmax(0, 1fr);
	}
}


/*
	WIZARD（共通のウィザードの器。Issue #3794 PR1）。ルート要素
	（`.elsaWizard`）は縦マージンを持たない（`tests/block_root_spacing_test.php`）
	——ブロック同士の隙間は共通トークンから流れる。ここが宣言するのは
	内側（見出し・段の間）の余白だけである。
*/
/*
	一号機検収 第6点（実DBプレビュー、PC 784px）: `.block`の共通規則
	（`display:flex;flex-wrap:wrap`。ラベル＋入力欄を横に並べるFIELD ROW等の
	ための既定）を、WIZARDの器自身が継承すると、段の見出し・進み具合
	（STEPPER）・段の中身が横並びで折り返され、STEPPERが左184px・本文が
	残り幅へ収まろうとして横スクロールが出た（実測）。**器は自分のルート
	だけを上書きする**（祖先セレクタには依存しない。`tests/field_block_style_test.php`）。
	STEPPER・見出し・段の中身は常に1列で縦に積む——375pxだけの規則ではなく、
	WIZARDの既定そのものにする。
*/
.elsaWizard {
	display: block;
}
.elsaWizardStepHeading {
	margin: var(--elsa-block-spacing, 8px) 0 0;
	font-size: 1rem;
	font-weight: 600;
}
.elsaWizardSteps {
	margin-top: var(--elsa-block-spacing, 8px);
}
.elsaWizardStep[hidden] {
	display: none;
}
/*
	一号機裁定（実DBプレビュー第3点の再裁定・2026-09-21 07:45、
	core/css/elsa_app_explorer.cssの`.is-search-in-band`と同じ考え方）:
	共通ポップアップの`adoptListSearch()`（core/php/blocks/popup/popup.js）が
	帯（`.elsaPopupActions`）へ移すのは、**LIST自身の検索そのもの**
	（`elsaListTools`。DOM/JSはそのまま）である。ここは見た目だけを、帯の
	アイコンボタン（28px）と並ぶ1行のコンパクトな道具へ整える。主語は
	いずれもLISTの内部要素（`elsaListTools`等）であって、登録済みブロックの
	ルートではないため、`tests/field_block_style_test.php`の祖先依存台帳の
	対象ではない（走査対象は「ブロックのルート」を主語にする規則だけ）。
*/
.elsaPopupActions .elsaListTools {
	display: flex;
	align-items: center;
	flex-wrap: nowrap;
	min-width: 0;
	margin: 0;
	gap: 4px;
}
/*
	一号機裁定（実DBプレビュー2026-09-21 09:50）: 上の規則は2つのクラス
	（`.elsaPopupActions .elsaListTools`。詳細度0,2,0）で、`[hidden]`の
	既定規則（UAスタイルシートの`[hidden]{display:none}`。詳細度0,1,0）に
	勝ってしまい、`adoptListSearch()`が`hidden`を立てても帯の検索欄が
	消えなかった（実測: 基本・確認と作成・結果画面でも検索欄が出続ける）。
	`hidden`のときだけ勝つ、より詳しい規則をここへ足す。
*/
.elsaPopupActions .elsaListTools[hidden] {
	display: none;
}
.elsaPopupActions .elsaListSearch,
.elsaPopupActions .elsaListSearchBox {
	width: auto;
	min-width: 0;
	margin: 0;
}
.elsaPopupActions .elsaListSearchRow {
	flex-wrap: nowrap;
	min-width: 0;
}
.elsaPopupActions .elsaListSearchRow input[type="search"] {
	flex: 0 1 auto;
	box-sizing: border-box;
	width: 12em;
	height: var(--elsa-block-action-height, 28px);
	min-height: 0;
}
.elsaPopupActions .elsaListSearchControls {
	flex: 0 0 auto;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	現場で使う大きな確定ボタン（Issue #3815 第2段階。オーナー決定2026-09-16）

	倉庫の簡易モードの「記録」は、片手がふさがった立ち作業で、画面を見ずに
	何度も押す。**操作面の28px（ボタン文字×2）の原則の閉じた例外**で、
	例外一覧は`docs/development-policy.md`「5. UI品質」の表が正本である。
	画面は`data-action-size="field-confirm"`を名乗るだけにし、寸法はこの
	1か所のトークンだけが持つ。高さはボタン文字×3.43（既定14pxで48px。指で
	押す目標の大きさ）。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
:root { --elsa-field-confirm-action-size: calc(var(--elsa-button-font-size, 14px) * 3.43); }
.button[data-action-size="field-confirm"],
.button.elsaControllerButton[data-action-size="field-confirm"] {
	height: var(--elsa-field-confirm-action-size);
	min-height: var(--elsa-field-confirm-action-size);
	padding: 0 1.6em;
	font-size: calc(var(--elsa-button-font-size, 14px) * 1.2);
	font-weight: bold;
}

/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

	小さく出す入力欄の行（Issue #3815 第2段階。オーナー決定2026-09-16）

	「変えるときだけ触る」欄（倉庫の簡易モードの種別・場所）を、主の入力欄より
	小さく出す。**画面ごとのCSSにしない**——行へ`elsaFieldRow--compact`を足すだけで、
	ラベルのタブと入力欄が同じ割合で小さくなる。入力欄の高さは文字の大きさ（em）から
	決まるので、`.right`の文字を小さくするだけで中の部品の高さも追従する。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.block.elsaFieldRow.elsaFieldRow--compact > .left p {
	min-height: 22px;
	font-size: calc(var(--elsa-field-tab-font-size, 14px) * .8);
}
.block.elsaFieldRow.elsaFieldRow--compact > .right { font-size: .8em; }

/* 画面の準備が終わる前にボタンが押されたときの待ちの表示（Issue #4612）。
   印は core/html/layout_head.php の先頭のscriptが立て、準備が終わると外す。 */
html[data-elsa-js-pending],
html[data-elsa-js-pending] * { cursor: progress !important; }
/* 指で押す画面にはカーソルが出ないので、押したボタンを薄くし、画面の上端に細い帯を流す。 */
[data-elsa-js-pending-press] { opacity: .55; }
html[data-elsa-js-pending] body::after {
	content: "";
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	height: 3px;
	z-index: 2147483647;
	background: var(--elsa-primary-color, #24333f);
	pointer-events: none;
}
