@charset "UTF-8";

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

	SKUブロック

	設計は docs/sku-block.md を正とする。
	文字サイズはアプリ設定のフォーム文字サイズへ追従させ、
	固定値を直書きしない。

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

.elsaSku{
	font-size: var(--elsa-form-font-size);
	color: var(--elsa-form-text-color);
	/*
		標準行の`.block > .right`はflexコンテナである。flexアイテムの
		既定は`min-width: auto`で内容幅より縮まないため、指定がないと
		SKU帯が行からはみ出し、ページ全体に横スクロールが発生する。

		0を指定すると帯自身の`overflow-x: auto`が働き、内側だけが
		スクロールする。`docs/architecture.md`「ブロックのCSSは特定画面の
		祖先要素へ依存させない」に沿い、どの親構造へ置いても破綻させない。
	*/
	min-width: 0;
	/*
		枠線で囲み、左の項目ラベルと1つの部品として繋げる。囲まないと
		グレーのラベルへ中身が貼り付いて見え、他の行と揃わない。
		寸法と色はTEXTなど他のフィールドと同じ変数・値を使う。
	*/
	width: 100%;
	padding: var(--elsa-form-control-padding-block) var(--elsa-form-control-padding-inline);
	border: var(--elsa-form-control-border-width) solid #d2d2d2;
	border-radius: 0 4px 4px 0;
	background: #fff;
	}

/*──────────────────┐
	式の骨格

	枠の中は「色 × サイズ ＝ SKU」という1つの式として読ませる。
	左端に固定幅の列を作り、バリエーション名・×・＝を縦へ揃える。

	名前は選択肢の帯（overflow-x: auto）の外に置く。帯の内側に入れると
	選択肢が多いとき右へスクロールした時点で名前が画面から消える。
└──────────────────*/

.elsaSku{
	/*
		名前列の幅は`em`で書かない。`em`は各要素の font-size に対して
		解決されるため、名前（0.9em）・演算子（1.1em）・追加ボタンの
		スペーサー（1em）で幅が変わり、縦の列が揃わない。実測では
		81px / 99px / 90px とずれた。

		フォーム文字サイズを基準に計算すれば、アプリ設定への追従を
		保ったまま、どの要素でも同じ幅になる。
	*/
	--elsa-sku-name-width: var(--elsa-sku-slot-width);
	--elsa-sku-name-gap: 8px;

	/*
		選択肢カード・項目名の箱・SKUカードの内側を同じ幅にする。
		商品画像は正方形にするため、この幅がそのまま画像の一辺になる。
		140pxはJANの13桁が省略されずに収まる幅として実測で決めた。
	*/
	--elsa-sku-slot-width: 140px;
	--elsa-sku-slot-gap: 8px;
	--elsa-file-square-size: var(--elsa-sku-slot-width);

	/*
		選択肢カードが並ぶ幅。追加ボタンと演算子の位置はこの幅を基準に
		決める。枠数（--elsa-sku-slots）はPHPが選択肢の数から渡す。
		選択肢追加の「＋」は含めない。
	*/
	--elsa-sku-run-width: calc(
		var(--elsa-sku-slot-width) * var(--elsa-sku-slots, 1)
		+ var(--elsa-sku-slot-gap) * (var(--elsa-sku-slots, 1) - 1)
	);
	}

/*
	項目名の箱は選択肢カードと高さを揃える。行の中で伸ばし、選択肢の帯が
	スクロールバー用に持つ下paddingの分だけ margin で相殺する。
*/

.elsaSkuAxis{
	margin-bottom: 8px;
	}

/*
	項目名は選択肢カードと同じ枠・寸法の箱にする。上段に名前、下段に
	選択肢の数を置き、この行が1つのバリエーションであることを示す。
	背景を敷いて、右に並ぶ選択肢（白）と役割を区別する。

	帯の中の先頭に置き、左端へ貼り付ける。帯の外に置くと、横スクロール
	バーが出たときに帯だけが高くなり、選択肢カードと高さが揃わない。
	同じ並びの要素にすれば必ず揃う。貼り付けているため、右へスクロール
	しても名前は消えない。カードが下をくぐるので背景は不透明にする。
*/

.elsaSkuAxisName{
	display: flex;
	position: sticky;
	left: 0;
	z-index: 1;
	flex: 0 0 var(--elsa-sku-name-width);
	width: var(--elsa-sku-name-width);
	flex-direction: column;
	justify-content: center;
	align-items: center;
	gap: 2px;
	padding: 6px;
	overflow-wrap: anywhere;
	text-align: center;
	border: 1px solid #d8dee8;
	border-radius: 6px;
	background: #f2f4f7;
	color: #344054;
	}

.elsaSkuAxisLabel{
	font-weight: bold;
	}

/*
	選択肢の件数を下段へ置く。選択肢を1つ足したときに 2×2=4 が
	3×2=6 へ変わるのが見え、SKUが増えた理由を説明なしに伝えられる。
*/

.elsaSkuAxisCount{
	font-size: 0.85em;
	color: #667085;
	}

/*
	×と＝は式の要。選択肢カードが並ぶ範囲の中央へ置き、大きく表示する。
	帯の幅いっぱいで中央寄せにすると、画面が広いとき選択肢から遠く離れた
	位置へ行ってしまう。追加ボタンと同じ基準幅を使って揃える。

	狭い画面では基準幅が親を超えるため、上限で親幅に収まり、結果として
	画面の中央に来る。

	演算子は説明のための飾りで、押す対象ではない。当たり判定を残すと
	選択肢やSKUカードのクリックを遮ることがあるため無効にする。
*/

.elsaSkuOperatorRow{
	display: flex;
	gap: var(--elsa-sku-name-gap);
	margin: 2px 0 6px;
	pointer-events: none;
	}

.elsaSkuOperator{
	display: flex;
	flex: 0 1 auto;
	width: var(--elsa-sku-run-width);
	max-width: 100%;
	min-width: 0;
	justify-content: center;
	align-items: center;
	font-size: 2em;
	font-weight: bold;
	line-height: 1;
	color: #98a2b3;
	}

/*
	＝は縦向きにする。バリエーションは横へ掛け合わせ、その結果である
	SKUは下へ続くため、記号の向きが関係の方向と一致する。

	回転は記号そのものへ掛ける。中央寄せのために横幅いっぱいへ広げた
	外側を回すと、変形後の矩形が縦長の帯になって隣の行へ覆いかぶさる。
	実測では 30px × 949px の帯になっていた。
*/

.elsaSkuOperatorMark{
	display: inline-block;
	}

.elsaSkuOperatorEquals .elsaSkuOperatorMark{
	transform: rotate(90deg);
	}

.elsaSkuOptions{
	display: flex;
	align-items: stretch;
	min-width: 0;
	gap: var(--elsa-sku-name-gap);
	overflow-x: auto;
	padding-bottom: 4px;
	}

.elsaSkuOption{
	position: relative;
	flex: 0 0 auto;
	}

.elsaSkuOptionSelect{
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	width: var(--elsa-sku-slot-width);
	padding: 6px;
	font-size: 1em;
	color: inherit;
	text-align: left;
	border: 1px solid #d8dee8;
	border-radius: 6px;
	background: #fff;
	cursor: pointer;
	}

.elsaSkuOptionSelect:hover{
	border-color: #b6c0d0;
	}

.elsaSkuOption.is-selected .elsaSkuOptionSelect{
	border: 2px solid var(--elsa-primary-color);
	padding: 5px;
	}

/*
	「扱わない」組み合わせによって到達できなくなった選択肢。
	暗くするだけで押せなくはしない。押せば扱わないSKUを確認できる。
	選択中は選択の表示を優先する。
*/

.elsaSkuOption.is-unavailable:not(.is-selected) .elsaSkuOptionSelect{
	color: #98a2b3;
	border-style: dashed;
	background: #fafbfc;
	}

.elsaSkuOption.is-unavailable:not(.is-selected) .elsaSkuOptionThumb{
	opacity: 0.5;
	}

/*
	選択肢の画像もSKUと同じ正方形にする。商品画像は各モールで正方形の
	ため、選択肢に画像を割り当てたときも登録時と同じ比率で確認できる。
*/

.elsaSkuOptionThumb{
	flex: 0 0 auto;
	width: 100%;
	aspect-ratio: 1 / 1;
	margin-bottom: 4px;
	border-radius: 3px;
	background: #f2f4f7;
	}

.elsaSkuOptionLabel{
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	}

.elsaSkuOptionEdit{
	display: none;
	gap: 4px;
	margin-top: 4px;
	}

.elsaSkuOption.is-selected .elsaSkuOptionEdit{
	display: flex;
	}

.elsaSkuOptionInput{
	width: 68px;
	min-width: 0;
	padding: 2px 4px;
	font-size: 0.9em;
	border: 1px solid #d8dee8;
	border-radius: 4px;
	}

.elsaSkuOptionDelete,
.elsaSkuOptionAdd{
	flex: 0 0 auto;
	font-size: 1em;
	color: #667085;
	border: 1px solid #d8dee8;
	border-radius: 4px;
	background: #fff;
	cursor: pointer;
	}

.elsaSkuOptionDelete{
	width: 24px;
	}

.elsaSkuOptionAdd{
	width: var(--elsa-sku-slot-width);
	align-self: stretch;
	border-style: dashed;
	}

/*
	バリエーションの追加は行そのものを増やす操作なので、選択肢の帯と
	同じ幅の横長ボタンにして「下に増える」ことを形で示す。左の名前列は
	跨がない。選択肢を足す「＋」がカード型の四角なのに対し、こちらは
	横長の帯とすることで、幅が同じでも役割の違いが分かる。
*/

.elsaSkuAxisAddRow{
	display: flex;
	gap: var(--elsa-sku-name-gap);
	margin-bottom: 8px;
	}

.elsaSkuOperatorSpacer{
	flex: 0 0 var(--elsa-sku-name-width);
	width: var(--elsa-sku-name-width);
	}

/*
	幅を選択肢カードの並びへ合わせる。1行あたりの枠数はPHPが
	--elsa-sku-slots で渡す（選択肢の数＋選択肢追加の「＋」）。

	親いっぱいに広げると、画面が広いときボタンだけが選択肢の列より
	右へ長く伸び、何を増やす操作なのか分からなくなる。狭い画面では
	親を超えないように上限を付ける。
*/

.elsaSkuAxisAdd{
	flex: 0 1 auto;
	width: var(--elsa-sku-run-width);
	max-width: 100%;
	padding: 0 12px;
	font-size: 1em;
	color: #667085;
	border: 1px dashed #d8dee8;
	border-radius: 6px;
	background: #fff;
	cursor: pointer;
	}

/*──────────────────┐
	SKU
└──────────────────*/

/*
	絞り込み解除は件数の右へ並べる。「3件 / 全 9件」という表示が絞り込みの
	結果そのものなので、解除の操作を同じ行に置くと対応が分かる。

	絞り込み中だけ表示する。横に並ぶだけなので、出現しても下の内容は
	上下に動かない。
*/

.elsaSkuListHead{
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	align-items: center;
	min-height: 28px;
	}

.elsaSkuListFoot{
	display: flex;
	margin-top: 12px;
	}

.elsaSkuListTitle{
	font-weight: bold;
	}

.elsaSkuCount{
	font-size: 0.9em;
	color: #667085;
	}

.elsaSkuListSpacer{
	flex: 1 1 auto;
	}

.elsaSkuClear,
.elsaSkuBulk{
	padding: 0 10px;
	font-size: 0.9em;
	color: #667085;
	border: 1px solid #d8dee8;
	border-radius: 4px;
	background: #fff;
	cursor: pointer;
	}

.elsaSkuBulk{
	color: var(--elsa-primary-color);
	border-color: var(--elsa-primary-color);
	}

.elsaSkuList{
	display: flex;
	gap: 8px;
	overflow-x: auto;
	margin-top: 10px;
	padding-bottom: 6px;
	}

/*
	内側の入力欄が選択肢カードと同じ幅になるようにする。padding 8px と
	枠線 1px の分だけ外寸を広げる。内側140pxはJANの13桁が省略されずに
	収まる幅として実測で決めた。
*/

.elsaSkuCard{
	flex: 0 0 auto;
	width: calc(var(--elsa-sku-slot-width) + 18px);
	padding: 8px;
	border: 1px solid #d8dee8;
	border-radius: 6px;
	background: #fff;
	}

.elsaSkuCard[hidden]{
	display: none;
	}

.elsaSkuCard.is-inactive{
	background: #f9fafb;
	}

.elsaSkuCard.is-inactive .elsaSkuCardImage,
.elsaSkuCard.is-inactive .elsaSkuCardField{
	opacity: 0.5;
	}

.elsaSkuCardHead{
	display: flex;
	gap: 6px;
	align-items: flex-start;
	margin-bottom: 6px;
	}

.elsaSkuCardLabels{
	display: flex;
	flex: 1 1 auto;
	flex-wrap: wrap;
	gap: 4px;
	min-width: 0;
	}

.elsaSkuCardLabel{
	font-size: 0.85em;
	color: #667085;
	}

.elsaSkuCardLabel[hidden]{
	display: none;
	}

.elsaSkuCardToggle{
	flex: 0 0 auto;
	font-size: 0.75em;
	color: #667085;
	border: 1px solid #d8dee8;
	border-radius: 4px;
	background: #fff;
	cursor: pointer;
	}

/*
	画像はFileブロックが描画する。ブロックの高さは中身（プレビュー、
	ドロップ領域、操作）で決まるため、ここで固定値を与えない。

	固定高さを残すと、後続の価格・在庫がカードからはみ出す。
	プレースホルダー（Playground）だけ高さを持たせる。
*/

.elsaSkuCardImage{
	margin-bottom: 8px;
	}

/*
	Fileブロックが用意している寸法変数で、SKUカードの幅に合わせる。
	ブロックの内部構造へは踏み込まない。
*/

.elsaSkuImagePlaceholder{
	display: block;
	height: 68px;
	border-radius: 3px;
	background: #f2f4f7;
	}

.elsaSkuCardField{
	margin-bottom: 6px;
	}

.elsaSkuCardCaption{
	display: block;
	font-size: 0.75em;
	color: #98a2b3;
	}

/*
	在庫の詳細画面への導線。拠点別在庫を使う会社では在庫欄が読み取り
	専用になり、**この印がその会社にとって在庫を触れる唯一の入口になる。**

	値の直下へ右寄せで置く。同じ枠の中に収め、どの項目の詳細なのかを
	離れた場所へ持って行かない。印そのものの見た目はlist_actionブロックが
	持つため、ここでは位置だけを決める。

	**`position: relative`を外さない。** list_actionはアクセシブルな名前を
	`position: absolute`の読み上げ専用テキスト（`.elsaVisuallyHidden`）で
	持つ。位置指定した祖先が無いと、その絶対配置の基準が`.elsaSkuList`
	（`overflow-x: auto`）の外側になり、横スクロールで隠したはずの右端の
	カードぶんだけページ全体へ横スクロールが出る。2026-08-10の本番実測で、
	幅1536pxのとき`document.scrollWidth`が1911（+390px）、幅375pxのとき
	1227（+870px）だった。この1行で両方とも0になる。
*/

.elsaSkuStockLink{
	position: relative;
	display: flex;
	justify-content: flex-end;
	margin-top: 2px;
	}

/*
	寸法・枠線・文字サイズは`.elsaText`の共通定義（base.css）が担当する。
	ここではSKUカード固有の右寄せとフォーカス表示だけを指定する。
*/

input.elsaText.elsaSkuValue{
	text-align: right;
	}

input.elsaText.elsaSkuValue:focus{
	outline: 2px solid var(--elsa-primary-color);
	outline-offset: -2px;
	}

/* Action buttons share the V2 neutral resting color. Selection cards keep their selected-state styling. */
.elsaSkuOptionDelete,
.elsaSkuOptionAdd,
.elsaSkuAxisAdd,
.elsaSkuClear,
.elsaSkuBulk,
.elsaSkuCardToggle {
	box-sizing: border-box;
	height: var(--elsa-block-action-height, 30px);
	min-height: var(--elsa-block-action-height, 30px);
	background: var(--elsa-button-default-bg, #d2d2d2);
	color: var(--elsa-button-default-color, #555);
}

.elsaSkuOptionDelete:focus-visible,
.elsaSkuOptionAdd:focus-visible,
.elsaSkuAxisAdd:focus-visible,
.elsaSkuClear:focus-visible,
.elsaSkuBulk:focus-visible,
.elsaSkuCardToggle:focus-visible {
	outline: 2px solid var(--elsa-primary-color);
	outline-offset: 2px;
}

@media (hover: hover) {
	.elsaSkuOptionAdd:hover,
	.elsaSkuAxisAdd:hover,
	.elsaSkuClear:hover,
	.elsaSkuBulk:hover,
	.elsaSkuCardToggle:hover {
		background: var(--elsa-button-hover-bg, var(--elsa-primary-color));
		color: var(--elsa-button-hover-color, #fff);
	}

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

.elsaSkuEmpty{
	margin: 0;
	padding: 12px 0;
	color: #667085;
	}

.elsaSkuEmpty[hidden]{
	display: none;
	}

/*
	操作前の説明はAlert基盤の確認ダイアログ（elsaAlert.confirm）へ統合した。
	SKU独自の確認バー（.elsaSkuConfirm 系）は生成されなくなったため、
	指定を残さない。使われないCSSは、次に触る人へ現役だと誤解させる。
*/

.elsaSkuOptionNew{
	display: flex;
	flex: 0 0 auto;
	flex-direction: column;
	gap: 4px;
	justify-content: center;
	width: 140px;
	}

.elsaSkuOptionHint{
	font-size: 0.75em;
	color: #667085;
	white-space: nowrap;
	}

.elsaSkuBulkForm{
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
	margin-top: 10px;
	}

.elsaSkuBulkForm input{
	width: 140px;
	}

@media (max-width: 670px){

	/*
		狭い画面では枠を1つ小さくする。カード・選択肢・画像・項目名が
		同じ変数を見るため、1箇所の変更で全部が揃って縮む。
	*/

	.elsaSku{
		--elsa-sku-slot-width: 112px;
		}

	/*
		狭い画面では演算子を画面の中央へ置く。名前列の分の余白を残すと、
		選択肢が画面幅に収まらない状況で記号だけが右へ寄って見える。
		実測では画面中心188pxに対し中心248pxだった。
	*/

	.elsaSkuOperatorSpacer{
		display: none;
		}

	.elsaSkuOperator{
		width: 100%;
		}

	}

/*
	狭い幅では項目ラベルが上へ積まれ、下辺だけが繋がる。共通CSSの
	`.elsaCheckLabel` や `.elsaFileBlockDropZone` と同じ扱いにする。
	名前列も詰めて、選択肢の帯に幅を残す。
*/

@media (max-width: 640px){

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

	}
