.elsaTabBlock {
	display: block;
	width: 100%;
	min-width: 0;
}

/*
	**TABの切替に連動する帯の道具は、どんな祖先の透かし指定よりも必ず隠れる**
	（Issue #3820。`core/php/blocks/tab/tab.php`の`elsa_field_block_tab_band_tools_html()`と
	対）。器はTABブロックの外（窓のボタンエリアや、検索枠を帯へ出す一覧の透かし経路）に
	置かれることがあり、`data-app-explorer-list-scope`のような透かし用の属性を同じ要素が
	兼ねると、隠すための`[hidden]`と透かすための`display: contents`
	（`core/css/elsa_app_explorer.css`の`is-search-in-band`）が競合し、詳しさで透かす側が
	勝ってしまう。ここが「この仕組みで隠すと宣言した器は必ず隠れる」という約束を持つ。
*/
[data-elsa-tab-band-for][hidden] {
	display: none !important;
}

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

	**タブの並びは1つの形だけ**（2026-09-29のオーナー指摘・決定。全タブ共通）

	1. **左端の隙間。** タブ同士の隙間と同じ幅を、一番左のタブの左側にも取る
	   （以前は一番左のタブがペインの境界線に接していた）。値は`core/css/base.css`の
	   `--elsa-tab-gap`だけが持つ。`padding`は送れる箱の内側なので、横にはみ出して
	   スクロールしても先頭では同じ余白が残る。右端の余白は変えない。
	2. **下の線。** 並びの下辺に、並びの幅いっぱい（姿(1)ではペインの左右いっぱい）の
	   線を引き、タブのエリアを本文と区別する。線は並びの背景として描き、
	   **選択中のタブだけが下へ線の太さぶん伸びて線を覆う**ので、選んでいるタブは
	   下の本文とつながって見える。選んでいないタブの見た目は変えない。色・太さは
	   入力欄・タブの枠と同じ`--elsa-field-control-border-color`・
	   `--elsa-form-control-border-width`を読む。背景は送れる箱の外枠に付くため、
	   横スクロールしても線は幅いっぱいに残る。
	3. **本文を送ってもタブの並びは動かない。** ボタンエリアと同じく、並びは本文の
	   スクロールの外の固定の行になり、送られるのは本文（`.elsaTabPanel`）だけで、
	   スクロールバーも本文の範囲だけに付く。置き場所を決めるのはTABではなく
	   **送る箱の枠組み**（右のペインは`core/css/elsa_app_explorer.css`、ポップアップの
	   本文は`core/php/blocks/popup/popup.css`）で、TABは目印を持つだけである:
	     `data-elsa-tab-leading="true"` … 送る箱（右のペイン・ポップアップの本文）の
	        **先頭**に置かれたTAB（前に見える物が無い）。`core/js/elsa_tab.js`が
	        描画のたびに付け外しする。本文の途中に置いたTAB（見出しの後ろ等）と
	        タブの中のタブは固定しない（本文と一緒に流れる）。
	   一覧の帯モード（`is-search-in-band`）は元から窓の固定の行（`grid-area: tabs`）。
	   狭い画面はページ全体が送られ、ボタンエリアが`position: sticky`で残る作りなので、
	   並びも同じ仕組みでボタンエリアの実寸の真下に残る（`elsa_app_explorer.css`）。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.elsaTabList {
	/*
		重なり順の文脈を作らない（z-indexを持たない）。本文の中から開く候補一覧・
		ポップアップ・ツールチップが、並びの行の上へそのまま出る。
	*/
	position: relative;
	display: flex;
	flex-wrap: nowrap;
	align-items: flex-end;
	gap: var(--elsa-tab-gap, 2px);
	box-sizing: border-box;
	padding-bottom: var(--elsa-form-control-border-width, 1px);
	padding-inline-start: var(--elsa-tab-gap, 2px);
	width: 100%;
	overflow-x: auto;
	background:
		linear-gradient(to top, var(--elsa-field-control-border-color, #d4d4d4) var(--elsa-form-control-border-width, 1px), transparent var(--elsa-form-control-border-width, 1px))
		var(--elsa-surface, #ffffff);
}

.elsaTabButton {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	position: relative;
	box-sizing: border-box;
	height: var(--elsa-block-action-height, 28px);
	min-height: var(--elsa-block-action-height, 28px);
	padding: 0 .9em;
	border: 1px solid var(--elsa-field-control-border-color, #aaa);
	border-bottom: 0;
	border-radius: 4px 4px 0 0;
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #667085);
	font: inherit;
	font-size: var(--elsa-button-font-size, 14px);
	text-align: center;
	white-space: nowrap;
	cursor: pointer;
}

/*
	選択中のタブは白（`--elsa-surface`）でパネルと一体にする。文字は本文の
	文字色（2026-09-11、Issue #3555）。地色の切り替えだけで表現し、台形・遠近の
	変形（`perspective` / `rotateX`）は持たない。
*/
.elsaTabButton[aria-selected="true"] {
	/*  並びの下の線を覆う（上の「下の線」）。上端は他のタブと揃ったまま下へだけ伸びる。  */
	height: calc(var(--elsa-block-action-height, 28px) + var(--elsa-form-control-border-width, 1px));
	min-height: calc(var(--elsa-block-action-height, 28px) + var(--elsa-form-control-border-width, 1px));
	margin-bottom: calc(-1 * var(--elsa-form-control-border-width, 1px));
	background: var(--elsa-surface, #ffffff);
	color: var(--elsa-content-text-color, #333333);
}

/*
	**押せないタブ**（`enabled_when`の条件を満たさないとき。Issue #4925。
	`disabled_reason`で常に押せないタブ（Issue #4981）も同じ見た目。共通の仕組み
	`core/js/elsa_feedback.js`が`disabled`を`aria-disabled="true"`へ読み替えるので両方を並べる）。
	消さずにグレーアウトで見せる。色は共通の無効の見た目の変数
	（`--elsa-button-disabled-*`。`core/css/base.css`の`.button[aria-disabled="true"]`と同じ正本）
	だけを参照し、ここで実色を書かない。理由は共通の「押せない理由」が出す。
*/
.elsaTabButton:disabled,
.elsaTabButton:disabled:hover,
.elsaTabButton[aria-disabled="true"],
.elsaTabButton[aria-disabled="true"]:hover {
	background: var(--elsa-button-disabled-bg);
	color: var(--elsa-button-disabled-color);
	opacity: 1;
	cursor: default;
}

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

	**進み具合の印**（Issue #3818 決定2）

	工程をタブで出す画面（賃貸管理 › 契約の 内覧／契約／入居／退去）のために、
	見出しへ「済み」「進行中」の印を差す。**新しい形は作らない。**
	STEPPERの工程玉と同じ2つの形——済みは塗りつぶしの丸＋チェック印、
	進行中は塗りつぶしの丸＋外側の輪——を、タブの見出しの大きさで出す。
	丸の中のチェック印そのものは`.elsaStepperCheck`
	（`core/css/elsa_stepper.css`）をそのまま置くので、線の引き方はここに無い。

	色は工程玉と同じ`--elsa-primary-color`である。大きさだけが文字基準（em）で、
	タブの文字サイズが外観設定で変わっても見出しの中で揃う。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.elsaTabMark {
	font-size: .7em;
	display: inline-grid;
	place-items: center;
	box-sizing: border-box;
	flex: 0 0 auto;
	width: 1.5em;
	height: 1.5em;
	margin-inline-end: .5em;
	border-radius: 50%;
	background: var(--elsa-primary-color, #24333f);
}

/*  進行中は外側の輪を足す（工程玉の現在地と同じ3つめの手がかり）。  */
.elsaTabMark--current {
	box-shadow: 0 0 0 2px color-mix(in srgb, var(--elsa-primary-color, #24333f) 25%, transparent);
}

/*
	**フォーカスの輪はタブの内側に描く**（Issue #4571、2026-10-09のオーナー指摘・375px）。
	並び（`.elsaTabList`）は`overflow-x: auto`で送れる箱なので、外へ張り出した輪
	（以前の`outline-offset: 2px`）は箱の縁で切られ、上下と左が消えて「ユーザー」と
	「グループ」の間の縦の線と左上の切れ端だけが残っていた。並びに余白を足すと
	タブの決まり（左端の隙間・下の線）が崩れるので、輪の方を内側（負のoffset）へ
	寄せ、全周が欠けずに見える形にする（左のメニュー・一覧の検索枠と同じ作法）。
*/
.elsaTabButton:focus-visible {
	z-index: 2;
	outline: 2px solid var(--elsa-primary-color, #24333f);
	outline-offset: -2px;
}

/* ホバーは共通ボタンと同じ規則（地・文字を反転）。選択中のタブは既に白いのでホバーで変えない。 */
@media (hover: hover) {
	.elsaTabButton:not([aria-selected="true"]):not(:disabled):not([aria-disabled="true"]):hover {
		border-color: var(--elsa-primary-color, #24333f);
		background: var(--elsa-primary-color, #24333f);
		color: var(--elsa-primary-contrast, #fff);
	}
}

/*
	**本文の上辺の線は並びが持つ**（2026-09-29のオーナー決定、上の「下の線」）。
	以前はパネルを`margin-top:-1px`で並びの下へ重ね、パネルの上枠を選択中の
	タブで覆っていた。その形だと線はパネルが枠を持つ姿(2)にしか出ず、姿(1)
	（ペイン直下）では並びと本文の境目が無かった。今は並びが自分の下辺に線を
	持ち、選択中のタブが並びの中（`overflow-x:auto`で切られない下余白の中）で
	それを覆う。パネルは上枠を持たず、重ねもしない（左右・下の枠が並びの線の
	両端へつながる）。
*/
/*
	**パネルの内側余白は表示設定「ブロック間の隙間」（`--elsa-block-spacing`）
	へ従う**（Issue #3703、2026-09-14のオーナー決定）。以前は`16px`／狭幅で
	`12px`の固定pxだったが、他のブロックと同じ間隔設定で伸縮するように
	トークンへ差し替えた。狭幅（640px以下）専用の値は持たない——`--elsa-block-spacing`
	の既定8pxはもともと狭幅時の12pxより小さく、専用の上書きを足しても
	トークンと矛盾する2つ目の基準ができるだけなので廃止した。
*/
/*
	2026-09-20、Issue #3799 REOPEN（一号機裁定）。`gap`は持たない
	（`row-gap: 0`）。子の縦の隙間は`core/css/base.css`の一般の兄弟間隔規則
	（`.block`／`[data-block-type]`／`[data-info-hint], [data-fleet-console]`
	の`margin-top`・`padding-top`）だけに委ねる。以前は`gap: var(--elsa-block-spacing)`
	を持っていたため、grid の row-gap と一般規則の margin-top が両方効いて
	隙間が二重計上（テナント概要タブのCAPACITY 2本で実測30px、狙いは15px）
	になっていた。祖先（`.elsaTabPanel`）側でブロックのルートを0へ戻す規則は
	`tests/field_block_style_test.php`の契約（外部の祖先セレクタからブロックの
	ルートを装飾しない。許容祖先は`#elsaLayout`・`:root`・`html`・`body`のみ）
	で禁じられているため、隙間の出どころをgapではなく一般規則の側に一本化する。
	列はすべて1列（`grid-template-columns`を指定していない既定の暗黙1列）
	なので`column-gap`は元から効いておらず、`gap`削除の影響を受ける画面はない。
*/
/*
	Issue #4133。`.elsaTabPanel`は姿(2)で親（ペイン等）から高さを
	そのまま継ぐ場所へ置かれることがあり、中身（FIELDの行など）が
	その高さより低いと、gridの既定`align-content: normal`（＝
	`stretch`相当）が余った高さを行トラックへ均等に配る。1行だけの
	タブ（例: 設定›会計›消費税の「計算方法」タブ、SWITCHが2項目だけ）
	では、この配分が各行の中身（ラベル30px・SWITCH本体36〜40px）の
	何倍もの高さに膨らんで見える形で表面化した（実測: 1項目が約250px）。

	**`align-content: start`で止める。** 行の高さは中身＋規定の余白
	だけになり、余った高さはパネル下部の空白として残るだけになる
	（スクロールで隠れる分には表示上問題ない）。`align-items`は
	既定の`stretch`のまま変えない——単一列グリッドの行の中では
	横方向（1列しかないので実質“その列の中”）の話であり、今回の
	「行そのものの高さ」の膨張とは別の軸なので触る必要がない。
*/
/*
	**先頭に置いたTABを送らない行にする切り替え**（上の3.）。TABのルートを外から
	装飾しない（`tests/field_block_style_test.php`の契約）ので、送る箱の枠組み
	（`core/css/elsa_app_explorer.css`・`core/php/blocks/popup/popup.css`）は2つの変数
	だけを宣言し、形はここが持つ。変数が無い置き場所（狭い画面など）では今までどおり。
*/
.elsaTabBlock[data-elsa-tab-leading="true"] {
	display: var(--elsa-tab-fixed-row-display, block);
	flex-direction: column;
	flex: 1 1 auto;
	min-height: 0;
}
.elsaTabBlock[data-elsa-tab-leading="true"] > .elsaTabList { flex: none; }
.elsaTabBlock[data-elsa-tab-leading="true"] > .elsaTabPanel:not([hidden]) {
	flex: 1 1 auto;
	min-height: 0;
	overflow: var(--elsa-tab-fixed-row-overflow, visible);
	overscroll-behavior: contain;
}

.elsaTabPanel {
	/*  z-indexは持たない（並びと同じ理由。本文の中の候補一覧を並びの下へ閉じ込めない）。  */
	position: relative;
	display: grid;
	align-content: start;
	gap: 0;
	min-width: 0;
	margin-top: 0;
	padding: var(--elsa-block-spacing, 8px);
	border: 1px solid var(--elsa-field-control-border-color, #aaa);
	border-top: 0;
	border-radius: 0 0 4px 4px;
	background: var(--elsa-surface, #ffffff);
}

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

	**本文の枠は置き場所が決める。姿は2つだけ**（Issue #4027、2026-09-22の
	オーナー決定。#4017の「枠は置き場所が持ち、ブロック自身は持たない」の続き）

	上の`.elsaTabPanel`が姿(2)＝**置き場所の枠の中に収まる形**である。フォーム・
	カード・ペインの本文の器のように、置き場所が自分の箱を持つところへ置かれた
	タブはこの姿のままになる（商品の編集の 基本情報／SKU／画像 など）。

	ここが姿(1)＝**ペイン直下の形**を1か所で定義する。本文の枠を持たず、タブの
	帯がペインと一体になり、本文はペインの幅いっぱいに出る。

	**判定は構造だけで行う。** 画面側に直値も専用クラスも書かない——TABが
	統合窓の本文の器（`[data-app-explorer-body]`）の直接の子であれば、帯モード
	（`is-search-in-band`）かどうかに関わらず姿(1)とする。帯モードでは
	`core/css/elsa_app_explorer.css`が右のペインの箱（`.elsaAppExplorerMain`）も
	本文の器も`display: contents`で透かすため、透けた器の直下に居るTABの帯も
	本文も**窓が自分のマスへ直接置く**——つまりCSSセレクタの上ではペインの
	直接の子のままである（`display: contents`は描画上の入れ物を消すだけで、
	DOM上の親子関係もセレクタの一致もそのまま生きている）。箱のまま残る器
	（総合コスト・サーバー管理・Amazon同期・文書保存・倉庫の設定など、一覧の
	帯モードでない画面）でも、TABが本文の器の直接の子であれば同じセレクタが
	当たる。フォーム・カードの中（`elsa_field_draw()`の行の中）に置かれた
	TABや、画面が被せた独自の器（回覧の詳細など）を挟んだTABはこの規則に
	当たらず、姿(2)のままになる。

	**同じ形の画面は自動でそろう。** 設定 › 会計 › 消費税（「計算方法」「税率」）
	は以前、「税率」タブだけが一体化して見え（LISTのパネルを窓が透かすため）、
	「計算方法」タブだけが枠つきの箱として残っていた。今回さらに、総合コスト・
	サーバー管理（共通設定／選択した対象の設定）・Amazon同期（API同期／手動
	同期）・倉庫（設定／入出庫・棚卸）・賃貸管理（大家さんとの契約）・文書保存
	（新規登録／編集）の11画面も同じ姿(1)へ揃う。

	`margin-top: 0`は既定と同じ値の明示である（以前の既定`-1px`は「選択中タブの
	下辺でパネルの上枠を覆う」ための重ねだった。2026-09-29からは並びが下の線を
	持つので既定も0。Issue #4204）。

	**商品の編集（`#itemEditorTabs`）はCSSでは除けない代わりに、置き場所その
	ものをフォームの行へ揃えた**（Issue #4027 2本目、2026-09-24）。以前は
	`elsa_item_editor_tabs_html()`が`[data-app-explorer-body]`へ直接
	`elsa_field_block_tab_markup()`のHTMLを返しており、総合コスト等の11画面と
	DOM構造だけでは見分けが付かなかった（画面名をCSSへ書く`:not(#id)`は
	「置き場所が決める」の決定に反するため使わない）。
	`core/php/function/item_editor_tabs.php`を、`sales_customer.php`の
	`elsa_sales_customer_editor_tab_field()`と同じく**TABを`elsa_field_draw()`の
	行として返す**形へ改め、`contents/item/item.php`の呼び出し文字列は1つも
	変えていない（薄いラッパーが内部で`elsa_field_draw()`を呼ぶ）。3パネルの
	組み立て自体（説明の段の追加フォーム・画像の差し替えフォーム・商品構成の
	別小画面を含む）はblocksの配列へ分解できないため、`tab.php`の
	`option.tabs[]["html"]`（"blocks"の代替経路。fleet・cost_dashboard等が元から
	使っている能力を`elsa_field_draw()`の入口へも開いたもの）をそのまま使う。
	結果、TABは`[data-app-explorer-body]`の直接の子ではなく`.block`（field行）
	の孫になり、姿(2)が構造だけで決まる。

	**`[data-app-explorer-detail]`は1段だけ許す汎用の器**（物件情報の表示内容
	`property_work_pane.php`・契約の工程`property_lifecycle_workspace.php`）。
	どちらも箱を持たない（枠・余白・背景を持たない）AJAX差し替え専用の器
	（`contents/property/property.php`の`data-property-detail`、
	`contents/property_contract/property_contract_workspace.php`の
	`data-lifecycle-detail`）の中にTABが居る。器はJSが`pane.innerHTML = ...`で
	中身だけを差し替える対象そのものなので、回覧の詳細のように器の外へ出すと
	差し替えのたびにTABが器の中へ戻ってしまう（器自体は動かさない）。器は
	画面名ではなく共通の目印`data-app-explorer-detail`（Issue #4027 2本目で追加。
	画面固有の属性`data-property-detail`等はJSの差し替え対象としてそのまま
	残し、CSSはこちらの共通属性だけを見る）を持つので、判定を1段だけ構造で
	広げられる。

┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
.elsaAppExplorer > .elsaPaneWindowPane--main > [data-app-explorer-body] > .elsaTabBlock > .elsaTabPanel,
.elsaAppExplorer > .elsaPaneWindowPane--main > [data-app-explorer-body] > [data-app-explorer-detail] > .elsaTabBlock > .elsaTabPanel,
.elsaPopupBody > .elsaTabBlock > .elsaTabPanel {
	margin-top: 0;
	border: 0;
	border-radius: 0;
}

/*
	**ポップアップの本文の直下に置いたTABも姿(1)**（上の規則の3つ目のセレクタ。
	Issue #4571、2026-10-09のオーナー指摘。隙間の決まり #3489）。ポップアップは
	縁と内側の余白を自分で持つので、そこへ姿(2)の枠と余白を重ねると、縁の内側に
	もう一枚の枠と二重の隙間が出ていた（チャットの「参加者を追加」のユーザー・
	グループ・AI）。判定は構造だけ——本文（`.elsaPopupBody`）の直接の子のTABに
	限り、フォームの行の中のTAB・タブの中のタブは姿(2)のまま。枠は上の規則で
	外し、ここでは左右と下の余白をポップアップの余白に任せて0にする（本文の文字
	はタブの並びとタイトルの左端にそろう）。上だけは並びの下の線から最初の欄
	までの1段（`--elsa-block-spacing`）を残す。
	主語は`.elsaTabPanel`で、ブロックのルートは装飾しない（上と同じ契約）。
*/
.elsaPopupBody > .elsaTabBlock > .elsaTabPanel {
	padding-inline: 0;
	padding-bottom: 0;
}

/*
	**本文はペインの幅いっぱいに出る。** 箱のままの本文の器（帯モードでない
	画面）は、`.elsaPaneWindowPane--main`（`core/css/elsa_pane_window.css`）が
	持つ`--elsa-content-pane-padding`（既定10px）の内側に居るので、姿(1)の
	TABはその余白ぶん左右へ張り出す（`.elsaSettingsExplorerMain--fill` が
	`[data-home-panes]`へ持つのと同じ作法。値は直値ではなくペインの項目から
	導く）。帯（`.elsaTabList`）も本文（`.elsaTabPanel`）も同じ幅で一体に
	揃える。

	**帯モード（`is-search-in-band`）は張り出さない。** 帯モードでは器の
	連鎖が`display: contents`で透け、TABは窓自身のグリッドの本文マスへ
	直接置かれるため、ペインの余白はそもそも掛かっていない（二重に張り出す
	と逆に欠ける）。`:not(.is-search-in-band)`で箱のままの画面だけへ限る。

	主語は`.elsaTabList`／`.elsaTabPanel`（TABブロックの内側の要素）であり、
	ブロックのルート（`.elsaTabBlock`）は外部の祖先セレクタから装飾しない
	（`tests/field_block_style_test.php`の契約）。
*/
.elsaAppExplorer:not(.is-search-in-band) > .elsaPaneWindowPane--main > [data-app-explorer-body] > .elsaTabBlock > .elsaTabList,
.elsaAppExplorer:not(.is-search-in-band) > .elsaPaneWindowPane--main > [data-app-explorer-body] > .elsaTabBlock > .elsaTabPanel,
.elsaAppExplorer:not(.is-search-in-band) > .elsaPaneWindowPane--main > [data-app-explorer-body] > [data-app-explorer-detail] > .elsaTabBlock > .elsaTabList,
.elsaAppExplorer:not(.is-search-in-band) > .elsaPaneWindowPane--main > [data-app-explorer-body] > [data-app-explorer-detail] > .elsaTabBlock > .elsaTabPanel {
	margin-inline: calc(-1 * var(--elsa-content-pane-padding, 10px));
}
.elsaAppExplorer:not(.is-search-in-band) > .elsaPaneWindowPane--main > [data-app-explorer-body] > .elsaTabBlock > .elsaTabList,
.elsaAppExplorer:not(.is-search-in-band) > .elsaPaneWindowPane--main > [data-app-explorer-body] > [data-app-explorer-detail] > .elsaTabBlock > .elsaTabList {
	width: auto;
}

/*
	**タブの中のLISTは枠を持たない**（Issue #4017。SKUブロックの外側の枠を
	無くしたのと同じ形の二重線）。TABは子ブロックを`elsa_field_block_tab()`が
	直接resolveして呼ぶため、`elsa_field_draw()`の行（`.block`）を経由せず、
	LISTの実体（`.elsaListScroll`。`core/css/base.css`が自分の外枠を持つ）が
	`.elsaTabPanel`の直下へそのまま置かれる画面がある（総合コストの「明細」
	タブ、文書保存の版一覧・承認履歴タブなど）。統合窓の`is-search-in-band`は
	同じ理由で既に`.elsaListScroll`の枠を0にしている
	（`core/css/elsa_app_explorer.css`）——ここはその外（統合窓を使わない
	タブ）を同じ考え方で直す。枠は置き場所（タブ）が持ち、ブロック自身は
	持たない。
*/
.elsaTabPanel .elsaListScroll {
	border: 0;
	border-radius: 0;
}

/*
	最下段の下線を戻す。`core/css/base.css`の
	`.elsaList tbody tr:last-child:not(.elsaListSection) td { border-bottom: none; }`は、
	表を囲む`.elsaListScroll`自身の外枠と最下段の下線が二重に見えないための省略で、
	上の規則で外枠を0にしたタブの中では省略する理由が無い
	（`elsa_app_explorer.css`の`is-search-in-band`と同じ理由・同じ値）。
*/
.elsaTabPanel .elsaList tbody tr:last-child td {
	border-bottom: 1px solid var(--elsa-border-color, #d4d4d4);
}

/*
	**非表示パネルは、どんな祖先の透かし指定よりも必ず隠れる**（Issue #3820）。一覧の
	検索枠を帯へ出す仕組み（`core/css/elsa_app_explorer.css`の`is-search-in-band`）は、
	`data-app-explorer-list-scope`を持つ任意の器を`display: contents`で透かして中の
	検索枠を帯のマスへ直接置く。TABの非表示パネルがその器を兼ねる画面（消費税設定の
	「税率」タブなど）では、隠すための`[hidden]`と透かすための`display: contents`が
	同じ要素で競合し、`display: contents`の詳しさ（`.elsaAppExplorer.is-search-in-band
	[data-app-explorer-list-scope]`＝3）が素の`.elsaTabPanel[hidden]`（＝2）に勝ってしまう
	——本来は隠れているはずの面がそのまま透けて見える。`!important`で必ず隠す側を
	勝たせる。TABは他画面でも汎用に使うため、ここは特定の透かし相手を名指しせず、
	「非表示パネルは常に隠れる」という自分自身の約束として持つ。
*/
.elsaTabPanel[hidden] {
	display: none !important;
}

/*
	**中身の無いパネルは箱そのものを出さない**（Issue #3820、375pxの実画面確認で発覚）。
	消費税設定の「税率」タブは、実体（共通LIST）をTABブロックの外に置き、パネル自身は
	タブの見出し・キーボード操作・ARIAだけを持つ空の器である。選択中はこの空の器も
	`[hidden]`が外れるため、`.elsaTabPanel`の余白・枠・地色だけの空箱が1行分見えて
	いた（狭い画面ほど縦積みで目立つ）。`:empty`（子要素もテキストも無い）ときは高さ・
	余白・枠を持たせない。ARIAの対応（`aria-labelledby`・`aria-controls`）はDOMの
	タブ・パネルの結びつきだけで保たれるので、`display: none`にしても壊れない。
*/
.elsaTabPanel:empty {
	display: none;
	margin: 0;
	padding: 0;
	border: 0;
	min-height: 0;
}
