:root{--n-bg:#f8f6f0;--n-surface:#fffefa;--n-surface-sub:#f1eee5;--n-text:#2b2f27;--n-text-soft:#555b4f;--n-muted:#6f7568;--n-border:#e7e3d6;--n-border-strong:#d8d2c0;--n-accent:#2c7a5c;--n-accent-strong:#235f48;--n-accent-soft:#e7f1e6;--n-accent-ring:rgba(44,122,92,.28);--n-ok:#1d5a41;--n-trial:#5c6b1f;--n-trial-soft:#eef0e2;--n-warn:#9a6b1c;--n-warn-soft:#f3ecd8;--n-danger:#b23c2e;--n-danger-soft:#fdf3f1;--n-danger-border:#e5c4bc;--n-on-accent:#ffffff;--n-text-invert:#f4f2e8;--n-fs-xs:.75rem;--n-fs-sm:.8125rem;--n-fs-md:.875rem;--n-fs-lg:.9375rem;--n-fs-xl:1.0625rem;--n-fs-2xl:1.375rem;--n-r-sm:8px;--n-r-md:12px;--n-r-lg:16px;--n-r-full:999px;--n-shadow-1:0 1px 2px rgba(84,72,45,.05);--n-shadow-2:0 2px 10px rgba(84,72,45,.07);--n-font:'Zen Kaku Gothic New', -apple-system, BlinkMacSystemFont, 'Hiragino Sans', 'Noto Sans JP', sans-serif}
* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: var(--n-font);
  color: var(--n-text);
  background: var(--n-bg);
  line-height: 1.65;
  /* 行頭禁則を strict にする(issue #19 / #26)。既定の auto は仕様上 UA 裁量で、
     Chrome は小書き仮名(ぁぃっゃょ 等)と長音符(ー)の行頭を許してしまう。
     エンジン 5 本・catalog.css と同じ規約。
     **投入は容器の潰れを塞いだ後**(#26)。潰れた容器では strict が行数を動かすが、
     それは strict の性質ではなく容器が min-content に貼り付いていることの結果である —
     実測では潰れを塞いだ要素は例外なく行数が動かなくなり、塞ぎ忘れた要素だけが動いた。
     前提: <html lang="ja">(layout.ts / bareLayout の両方にある)。lang が無いと Chrome では
     auto / normal / strict / loose が同一出力になり、この宣言は完全に no-op になる。
     件数・対象文字は在庫と文言で変わるのでここには書かない(§2-3 が唯一の置き場)。 */
  line-break: strict;
}
a { color: var(--n-accent); }
.icon { vertical-align: -0.1875em; flex-shrink: 0; }

/* 認証前ページ */
body.bare { display: grid; place-items: center; min-height: 100vh; }
.bare-main {
  background: var(--n-surface); border: 1px solid var(--n-border); border-radius: var(--n-r-lg);
  padding: 2rem; width: min(420px, calc(100vw - 2rem)); box-shadow: var(--n-shadow-2);
}
.bare-main h1 { font-size: var(--n-fs-2xl); margin-top: 0; line-height: 1.4; }
.bare-brand {
  margin: 0 0 1rem; font-size: var(--n-fs-lg); font-weight: 700;
  color: var(--n-accent); letter-spacing: 0.05em;
}

/* ヘッダ */
/* flex-wrap: wrap は**幅の下限を作るためではなく、下限に達する前に折り返させるため**(issue #26)。
   nav は flex: 1(= 1 1 0%)なので、ブランド名とヘッダ操作が横幅を食うと縮む。
   縮みの床は min-width: auto による自動最小サイズ = nav の min-content だが、
   **日本語のナビラベルは 1 文字ずつ折れるので min-content が 1 文字ぶんしかない**。
   実測(2026-08-01): 375px でナビ幅 62px・「コンテンツ編集」が縦 7 行・ヘッダ高 723px・横スクロールあり。
   min-width: 0 を足すのは逆効果で、床がさらに 0 まで下がる。 */
.app-header {
  display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap;
  background: var(--n-bg); padding: 0.75rem 1.25rem;
  border-bottom: 1px solid var(--n-border);
  position: sticky; top: 0; z-index: 10;
}
.brand { font-weight: 700; }
.app-header nav { display: flex; gap: 0.25rem; flex: 1; flex-wrap: wrap; align-items: center; }
/* ナビのラベルは項目の中で折らない。折り返しは nav の flex-wrap が項目**間**で行う。
   これが無いと .app-header を折り返しても 768px の潰れが直らない(実測 327px のまま)。
   逆にこれだけ入れて .app-header を折り返さないと、375px でリンクが溢れて横スクロールになる。
   **2 つで 1 組**である。 */
.app-header nav a {
  text-decoration: none; color: var(--n-text-soft); padding: 0.375rem 0.75rem;
  border-radius: var(--n-r-full); font-size: var(--n-fs-md);
  display: inline-flex; align-items: center; gap: 0.375rem;
  white-space: nowrap;
}
.app-header nav a .icon { color: var(--n-muted); }
.app-header nav a.active { background: var(--n-accent-soft); color: var(--n-accent); font-weight: 500; }
.app-header nav a.active .icon { color: var(--n-accent); }
/* ナビと同じ潰れがここにもある(issue #26)。375px でヘッダが折り返した先の 1 行に
   ボタン 3 つが入りきらず、「サイトを表示」が 2〜3 行に割れていた。
   **ナビだけ直しても残る** — 実測では潰れを塞いだ要素は行数が動かなくなり、
   塞ぎ忘れたこの 3 つだけが line-break: strict で動いた(9 面中 3 面 × 3 ノード)。 */
.header-actions { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.header-actions > * { white-space: nowrap; }

.app-main { max-width: 760px; margin: 0 auto; padding: 1.5rem 1rem 4rem; }
.app-main--wide { max-width: none; }

/* ボタン(ピル型) */
button, .btn, .btn-primary, .btn-ghost, .btn-danger {
  font: inherit; font-weight: 500; cursor: pointer; border-radius: var(--n-r-full);
  padding: 0.5rem 1.125rem; border: 1px solid var(--n-border-strong);
  background: var(--n-surface); color: var(--n-text);
  text-decoration: none; display: inline-flex; align-items: center; gap: 0.375rem;
}
.btn-primary { background: var(--n-accent); border-color: var(--n-accent); color: var(--n-on-accent); }
.btn-primary:hover { background: var(--n-accent-strong); border-color: var(--n-accent-strong); }
.btn-primary:disabled { opacity: 0.5; cursor: default; }
.btn-ghost { border-color: transparent; background: transparent; color: var(--n-text-soft); }
.btn-danger { border-color: var(--n-danger-border); color: var(--n-danger); background: var(--n-danger-soft); }
.btn-disabled { opacity: 0.55; cursor: not-allowed; pointer-events: none; }
button:focus-visible, .btn:focus-visible, .btn-primary:focus-visible, .btn-ghost:focus-visible,
.btn-danger:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: none; box-shadow: 0 0 0 3px var(--n-accent-ring);
}

/* フォーム */
.field { margin-bottom: 1rem; }
.field label { display: block; font-weight: 500; font-size: var(--n-fs-sm); margin-bottom: 0.25rem; }
/* 幅を揃え、border / padding / background をトークンで塗るコントロールの型リスト。
   select はこちら側 — 外すと幅が option の文字数任せになり、上の focus-visible だけが
   他のコントロールと揃うちぐはぐな出方になる。「入れない」側の判断は下の checkbox のコメントを見ること */
.field input[type="text"], .field input[type="url"], .field input[type="tel"],
.field input[type="email"], .field textarea, .field select, .notify-form-row input {
  width: 100%; font: inherit; padding: 0.5rem 0.75rem; color: var(--n-text);
  border: 1px solid var(--n-border-strong); border-radius: var(--n-r-sm); background: var(--n-surface);
}
.field textarea { resize: vertical; }
/* チェックボックスは上の共有ルールの型リストに入れない — width:100% だと横いっぱいに伸びる。
   auto を明示しておけば、後から型リストへ巻き込まれても伸びない */
.field input[type="checkbox"] { width: auto; }
/* boolean は「チェック → ラベル」を横並びにする。.field label が display:block なので、
   何もしないとチェックが次の行へ落ちる(以前ここにあった margin-right は効いていなかった)。
   表示切り替えは 1 セクションに何個も並ぶので、縦積みのままだと列がひどく間延びする。
   .field-error は flex-basis:100% で必ず下の行へ回す(エラー文でチェックが押し出されないように)。
   ※ この CSS は TS のテンプレートリテラルの中にある。コメントにバッククォートを書かないこと */
.field--boolean { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; }
.field--boolean input[type="checkbox"] { order: 1; margin: 0; }
.field--boolean label { order: 2; margin-bottom: 0; }
.field--boolean .field-error { order: 3; flex-basis: 100%; margin-top: 0; }
.field-error { color: var(--n-danger); font-size: var(--n-fs-sm); min-height: 1.25em; margin: 0.25rem 0 0; }
.req { color: var(--n-danger); font-size: var(--n-fs-xs); margin-left: 0.375rem; }
.note { color: var(--n-muted); font-size: var(--n-fs-sm); margin: 0.25rem 0 0; }
/* 「このままでは保存できない」状態の注意書き。muted のままだと読み飛ばされる */
.note--warn { color: var(--n-danger); font-weight: 500; }

/* セクションカード */
.content-section {
  background: var(--n-surface); border: 1px solid var(--n-border); border-radius: var(--n-r-md);
  padding: 1.25rem; margin-bottom: 1.25rem; box-shadow: var(--n-shadow-1);
}
.content-section h2 { margin-top: 0; font-size: var(--n-fs-xl); }
/* 節の説明文。見出しのすぐ下に muted で置く(フィールドのラベルより弱く見せる) */
.section-description { color: var(--n-muted); font-size: var(--n-fs-sm); margin: 0 0 1rem; }

/* 節の並び順。項目名を左、↑↓ を右に寄せる(繰り返し項目の操作列と同じ見た目にする) */
.section-order__list { list-style: none; margin: 0; padding: 0; }
/* **flex-wrap: wrap が要る**(issue #58)。子は最大 4 つ(ラベル・ヒント・↑・↓)で、
   ヒントが出ている行は 375px で入り切らない。.field--boolean が同じ処方を採っている。
   実測(probe-cms.mjs の content-order のページ):
     wrap 無し … 375px でラベルが 5 行・ヒントが 2 行に潰れる(1 行あたり 1〜2 文字)
     wrap 有り … 3 幅とも全行 1 行
   ヒントを持たない節(表示フラグが無い節)だけは子が 3 つで、wrap 無しでも 1 行に
   収まっていた —— **4 つ目が入った行だけが崩れる**ので、ヒントの出ている行を含めずに
   測ると一度も踏まない(probe のページはその行を必ず含めてある) */
.section-order__item {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem;
  padding: 0.5rem 0.75rem; margin-bottom: 0.375rem;
  background: var(--n-bg); border: 1px solid var(--n-border); border-radius: var(--n-r-sm);
}
/* **min-width が無いと flex-wrap は効かない。** 和文は文字単位で折れるので min-content が
   1 文字になり、ラベルは幅 0 まで縮んで「折り返す必要がない」と判定され続ける
   (それが 5 行の正体)。下限を与えて初めて溢れ、wrap が働く。
   flex-basis: 100% で常に 1 行占有させる形は採らない —— 1280px でも各行が 2 段になり、
   実測で文書高さが +124px 増えた(折り返しの要らない幅でも折り返すため) */
.section-order__label { flex: 1; min-width: 8em; }
/* 非表示の節に出すヒント。**display を指定しない** —— hidden 属性にブラウザ既定の
   display:none を効かせるため(クライアント JS がチェックに合わせて hidden を付け外しする)。
   ここに display を書くと hidden が効かなくなり、常に見えたままになる */
.section-order__hint {
  font-size: var(--n-fs-sm); color: var(--n-muted);
  padding: 0.125rem 0.5rem;
  background: var(--n-surface); border: 1px solid var(--n-border); border-radius: var(--n-r-sm);
}
/* 並べ替えの下に置く規則の説明。ページ上部の .note と見た目を共有し、余白だけ詰める */
.section-order .note { margin: 0.5rem 0 0; }

/* 繰り返しグループ(spec 2026-08-03 §3-3)。項目の境目を線で見せるのは、
   同じラベルの入力が縦に何度も並ぶので「どこからが次の 1 件か」が要るため */
.repeat-group {
  margin: 1.5rem 0; padding: 1rem;
  border: 1px solid var(--n-border); border-radius: var(--n-r-md);
}
.repeat-group h3 { margin: 0 0 0.5rem; font-size: var(--n-fs-lg); }
.repeat-item { padding: 0.75rem 0; border-bottom: 1px solid var(--n-border); }
.repeat-item:last-child { border-bottom: none; }
.repeat-actions { display: flex; gap: 0.5rem; justify-content: flex-end; }

/* ダッシュボード */
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; }
.card {
  display: block; background: var(--n-surface); border: 1px solid var(--n-border);
  border-radius: var(--n-r-md); padding: 1.25rem;
  text-decoration: none; color: inherit; box-shadow: var(--n-shadow-1);
}
.card:hover { box-shadow: var(--n-shadow-2); border-color: var(--n-border-strong); }
.card h2 {
  margin: 0 0 0.5rem; font-size: var(--n-fs-lg); color: var(--n-accent);
  display: flex; align-items: center; gap: 0.5rem;
}
.card p { margin: 0; font-size: var(--n-fs-md); color: var(--n-muted); }
.trial-banner {
  background: var(--n-warn-soft); color: var(--n-warn);
  border-radius: var(--n-r-md); padding: 0.75rem 1rem; margin: 0 0 1rem; font-size: var(--n-fs-lg);
}
.checklist {
  background: var(--n-surface); border: 1px solid var(--n-border); border-radius: var(--n-r-md);
  padding: 1rem 1.25rem; margin: 0 0 1rem; box-shadow: var(--n-shadow-1);
}
.checklist-head { display: flex; align-items: baseline; gap: 0.75rem; }
.checklist-head h2 { font-size: var(--n-fs-lg); margin: 0; display: flex; align-items: center; gap: 0.5rem; }
.checklist-progress { color: var(--n-muted); font-size: var(--n-fs-xs); }
.checklist-bar { height: 4px; background: var(--n-surface-sub); border-radius: 2px; margin: 0.625rem 0 0.75rem; }
.checklist-bar-fill { height: 4px; background: var(--n-accent); border-radius: 2px; }
.checklist-items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.checklist-item { display: flex; align-items: center; gap: 0.5rem; font-size: var(--n-fs-sm); }
.checklist-item .checklist-mark { color: var(--n-muted); display: inline-flex; }
.checklist-done .checklist-mark { color: var(--n-accent); }
.checklist-done .checklist-label { text-decoration: line-through; color: var(--n-muted); }
.checklist-link { margin-left: auto; font-size: var(--n-fs-xs); }
/* お問い合わせ(ダッシュボード・公開後のみ) */
.inquiries {
  background: var(--n-surface); border: 1px solid var(--n-border); border-radius: var(--n-r-md);
  padding: 1rem 1.25rem; margin: 0 0 1rem; box-shadow: var(--n-shadow-1);
}
.inquiries-head { display: flex; align-items: center; gap: 0.75rem; }
.inquiries-head h2 { font-size: var(--n-fs-lg); margin: 0; display: flex; align-items: center; gap: 0.5rem; }
.inquiries-sub { color: var(--n-muted); font-size: var(--n-fs-xs); }
.inquiries-count { font-size: var(--n-fs-md); margin: 0.5rem 0; }
.inquiries-count b { font-size: var(--n-fs-2xl); font-variant-numeric: tabular-nums; }
.inquiries-notify { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; font-size: var(--n-fs-sm); }
.notify-form-row { display: flex; gap: 0.5rem; margin-top: 0.5rem; }
.notify-form-row input { flex: 1; width: auto; }
.inquiries .form-note { color: var(--n-muted); font-size: var(--n-fs-sm); margin: 0.375rem 0 0; }

/* 一覧テーブル */
.page-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.list-table {
  width: 100%; border-collapse: collapse; background: var(--n-surface);
  border-radius: var(--n-r-md); overflow: hidden; border: 1px solid var(--n-border);
}
.list-table th, .list-table td {
  text-align: left; padding: 0.625rem 1rem; border-bottom: 1px solid var(--n-surface-sub); font-size: var(--n-fs-lg);
}
.list-table th { background: var(--n-surface-sub); font-size: var(--n-fs-sm); color: var(--n-muted); }
/* セルの中身は来訪者の入力(お名前・メールアドレスは 2000 字まで通る)。
   空白を 1 つも含まない長い値を送られると、表は内容幅で伸びるので .app-main(760px)を
   突き抜けて横スクロールになる。break-word ではなく anywhere を使うのは、
   **overflow-wrap の 2 値のうち最小内容幅にも効くのは anywhere だけ**で、
   表の幅を決めているのがその最小内容幅だから
   (.image-card figcaption の word-break: break-all と同じ流儀) */
.list-table td { overflow-wrap: anywhere; }
.badge {
  display: inline-block; font-size: var(--n-fs-xs); padding: 0.125rem 0.625rem;
  border-radius: var(--n-r-full); background: var(--n-surface-sub); color: var(--n-muted); font-weight: 500;
}
.badge-published { background: var(--n-accent-soft); color: var(--n-ok); }
.badge-trial { background: var(--n-trial-soft); color: var(--n-trial); }
.empty {
  color: var(--n-muted); background: var(--n-surface); border: 1px solid var(--n-border);
  padding: 2rem; text-align: center; border-radius: var(--n-r-md);
}
/* 問い合わせの詳細(ラベルと値の 2 列) */
.detail-list {
  display: grid; grid-template-columns: max-content 1fr; gap: 0.5rem 1.25rem;
  margin: 1.25rem 0; background: var(--n-surface); border: 1px solid var(--n-border);
  border-radius: var(--n-r-md); padding: 1.25rem;
}
.detail-list dt { color: var(--n-muted); font-size: var(--n-fs-sm); }
/* .detail-message も .detail-list の中の dd なのでこの規則が直接当たる ——
   ここ 1 箇所でご用件まで折り返せる。white-space: pre-wrap は**空白でしか折り返さない**ため、
   これが無いと空白を含まない 2000 字で 1fr の列が伸びて横スクロールになる */
.detail-list dd { margin: 0; font-size: var(--n-fs-lg); overflow-wrap: anywhere; }
/* ご用件は来訪者が入力した改行をそのまま見せる */
.detail-message { white-space: pre-wrap; }
.form-actions { display: flex; gap: 0.75rem; align-items: center; margin-top: 1rem; }

/* サイト一覧 */
.site-scope { font-size: var(--n-fs-md); font-weight: 400; color: var(--n-muted); }
.site-list { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: 0.75rem; }
.site-card {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  background: var(--n-surface); border: 1px solid var(--n-border);
  border-radius: var(--n-r-md); padding: 1rem 1.25rem; box-shadow: var(--n-shadow-1);
}
/* flex: 1(= 1 1 0%)+ min-width: 0 は**下限を持たない**ので、バッジ・日付・ボタンが
   横幅を食うと 0 まで潰れ、サイト名とテンプレ名が 1 文字ずつ折れる(issue #26)。
   flex-basis を与えると、入りきらない幅では .site-card の flex-wrap が
   **潰す代わりに折り返す**ようになる。min-width: 0 は残す —— 折り返した先で
   長いサイト名が溢れないようにするため(basis は希望幅であって下限ではない)。
   12rem の根拠は実測(2026-08-01、320〜1280px を 20px 刻み):
   現状は 13 幅で文字が折れ最悪 10 行 / 10rem では 560px だけ残る / **12rem で 0 幅**。
   14rem も 0 幅だが折り返しが早く始まるぶん不利なので採らない。 */
.site-card-main { display: flex; flex-direction: column; flex: 1 1 12rem; min-width: 0; }
.site-name { font-weight: 700; }
.site-template { font-size: var(--n-fs-sm); color: var(--n-muted); }
.site-card-meta { display: flex; align-items: center; gap: 0.75rem; }
.site-date { font-size: var(--n-fs-sm); color: var(--n-muted); }
.site-card .btn { flex-shrink: 0; }
.site-actions { margin-top: 1.25rem; }

/* 画像 */
#upload-form {
  display: flex; gap: 0.75rem; align-items: center; flex-wrap: wrap;
  background: var(--n-surface); border: 1px solid var(--n-border);
  padding: 1rem; border-radius: var(--n-r-md);
}
.image-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 1rem; margin-top: 1.5rem; }
.image-card { margin: 0; background: var(--n-surface); border: 1px solid var(--n-border); border-radius: var(--n-r-sm); padding: 0.5rem; }
.image-card img { width: 100%; height: 100px; object-fit: cover; border-radius: 6px; }
.image-card figcaption { font-size: var(--n-fs-xs); color: var(--n-muted); word-break: break-all; }
.image-field .image-preview {
  display: block; max-width: 240px; max-height: 140px; object-fit: contain;
  border: 1px solid var(--n-border); border-radius: var(--n-r-sm); margin-bottom: 0.5rem; background: var(--n-surface);
}
.image-actions { display: flex; gap: 0.5rem; }

/* 画像ピッカー */
dialog#image-picker {
  border: 1px solid var(--n-border); border-radius: var(--n-r-lg); padding: 1.25rem;
  width: min(640px, calc(100vw - 2rem)); background: var(--n-surface); color: var(--n-text);
}
dialog#image-picker::backdrop { background: rgba(43, 47, 39, 0.4); }
.picker-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; }
.picker-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 0.75rem; min-height: 120px; }
.picker-grid img {
  width: 100%; height: 90px; object-fit: cover; border-radius: 6px;
  cursor: pointer; border: 2px solid transparent;
}
.picker-grid img:hover { border-color: var(--n-accent); }
.picker-upload-label { display: block; margin-top: 1rem; font-size: var(--n-fs-md); }

/* トースト */
.toast {
  position: fixed; bottom: 1.5rem; left: 50%; transform: translateX(-50%);
  background: var(--n-text); color: var(--n-text-invert); padding: 0.625rem 1.25rem;
  border-radius: var(--n-r-full); font-size: var(--n-fs-lg); z-index: 100; box-shadow: var(--n-shadow-2);
}
.toast-error { background: var(--n-danger); color: var(--n-on-accent); }
.toast-success { background: var(--n-accent); color: var(--n-on-accent); }

/* プレビュー画面(デバイスフレーム) */
.preview-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; }
.device-tabs { display: flex; gap: 0.25rem; }
.device-tab { border-color: transparent; background: transparent; color: var(--n-text-soft); }
.device-tab.active { background: var(--n-accent-soft); color: var(--n-accent); }
.preview-stage { margin-top: 1rem; background: var(--n-surface-sub); padding: 1rem; border-radius: var(--n-r-md); }
.preview-frame {
  width: 100%; max-width: 100%; margin: 0 auto; transition: width 0.2s;
  background: var(--n-surface); box-shadow: var(--n-shadow-2); border-radius: 4px; overflow: hidden;
}
.preview-frame iframe { display: block; width: 100%; height: 75vh; border: 0; }

/* コンテンツ編集の 2 カラムとプレビューペイン(spec 2026-08-15-content-preview-pane §4)。
   **既定(狭い画面)は 1 カラムで、ペインは描かれていても出さない。**
   min-width で 2 カラムへ切り替えるのは、max-width で書くと 1179.5px のような
   小数の幅がどちらの規則にも当たらないため —— mobile-first にすれば
   「1180px 未満は従来の見た目」が幅の刻みに関係なく必ず成り立つ。
   なお 1 カラムに戻ったときのフォーム幅は従来より 32px 広い(.app-main の 760px は
   左右 padding 1rem を含む border-box だが、こちらは列の内容幅が 760px になるため)。
   **意図した差**で、見た目の破綻は無い。 */
.content-layout__form { max-width: 760px; margin: 0 auto; }
/* **display: none は既定側に置く。** loading="lazy" の iframe は display:none の間
   読み込まれないので、スマホで編集する顧客にはプレビュー Worker へのリクエストが 1 本も出ない */
.content-layout__preview { display: none; }
/* 境界のハンドルも既定では出さない(幅を変えられるのは 2 カラムのときだけ)。
   **[hidden] の規則を別に書くのが要る** —— 下の media query が display: block を与えるので、
   hidden 属性のブラウザ既定 display:none がそのままでは負ける。
   詳細度 (0,2,0) が (0,1,0) に勝つので、書く順序に関わらずこちらが効く
   (.preview-pane__body が「display を一切書かない」で解いたのと同じ問題を、
   幅の切り替えで display が要るこちらは詳細度で解いている) */
.content-layout__resizer { display: none; }
.content-layout__resizer[hidden] { display: none; }
/* **ドラッグ中はプレビューの iframe からポインタイベントを取り上げる。** ポインタが
   iframe の上に入ると中の文書がイベントを受け取り、pointermove が親へ届かなくなって
   **掴んだまま離した扱い**になる(iframe を挟むリサイザの定番の壊れ方)。
   user-select: none は、境界を動かすたびにフォームの文字が選択されるのを防ぐ */
.content-layout.is-resizing { user-select: none; cursor: col-resize; }
.content-layout.is-resizing .preview-pane__body iframe { pointer-events: none; }
@media (min-width: 1180px) {
  /* **align-items: start が要る。** 既定の stretch だとペインの列が行の高さ
     (= 長いフォーム)まで引き伸ばされ、sticky が動く余地を失って追随しなくなる。
     max-width は横に広いディスプレイでペインが際限なく太らないための蓋
     (spec §6 —— ペインは当たり確認用で、正確な確認は従来の /preview が担う)

     **左列の幅の正典はこの var ひとつ**で、app.js は変数を書き換えるだけにしてある。
     **既定の 760px は JS 側の DEFAULT_WIDTH と同じ数でなければならない**
     (ずれると初回のドラッグで幅が跳ね、ダブルクリックの戻り先も食い違う)——
     test/pages.test.ts が両方から数を抜いて突き合わせる。

     **真ん中の 1.5rem がハンドルの列で、gap は 0 にする。** ハンドルを溝そのものに
     することで、見た目の溝は従来と同じ 24px のまま掴める幅が 24px 手に入る
     (gap: 1.5rem を残したまま列を足すと溝が 72px になり、プレビューが 48px 痩せる) */
  .content-layout {
    display: grid;
    grid-template-columns: minmax(0, var(--content-form-width, 760px)) 1.5rem minmax(0, 1fr);
    gap: 0; align-items: start; max-width: 1600px; margin: 0 auto;
  }
  /* **左列の幅は grid の列だけが決める。** ここに max-width: 760px を残すと、
     ハンドルを右へ引いても列が伸びるだけでフォームは 760px で止まる
     (1180px 未満は上の規則が効くので、1 カラムのときは従来どおり 760px)。
     min-width: 0 が無いと、長い値の入った入力や表が列を押し広げる */
  .content-layout__form { max-width: none; min-width: 0; margin: 0; }
  /* 掴めるのは列いっぱいの 24px で、見えるのは中央の 2px だけ。
     **align-self: stretch が無いと掴めない** —— コンテナが align-items: start なので
     高さが 0 になる。伸ばした先はフォーム列の高さ(= 一番高い行)なので、
     どこまでスクロールしても境界を掴める */
  .content-layout__resizer {
    display: block; align-self: stretch; position: relative;
    background: transparent; cursor: col-resize; touch-action: none;
  }
  .content-layout__resizer::before {
    content: ''; position: absolute; inset: 0 calc(50% - 1px);
    background: var(--n-border); border-radius: 1px;
  }
  .content-layout__resizer:hover::before,
  .content-layout__resizer:focus-visible::before { background: var(--n-accent); }
  /* フォーカスリングは他のコントロールと同じ形(outline を消して box-shadow) */
  .content-layout__resizer:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--n-accent-ring); }
  /* top はヘッダの高さぶん下げる。**ヘッダは 1 行とは限らない** —— ナビとボタンが
     折り返すので、実測(Chromium・試用テナント)では 1180〜1366px で 99.2px・
     1440px 以上で 69.4px だった。狭いほうに合わせて 6.75rem = 108px にしてある
     (99.2px のヘッダに 8.8px の余白が残る)。**4.75rem = 76px では足りず、
     スクロールするとツールバーがヘッダの下に潜った** */
  .content-layout__preview { display: block; position: sticky; top: 6.75rem; }
}
.preview-pane__bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem; flex-wrap: wrap; margin-bottom: 0.5rem;
}
.preview-pane__title { font-weight: 700; }
.preview-pane__actions { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
/* **.preview-pane__body に display を書かない。** hidden 属性のブラウザ既定 display:none を
   効かせるため(.section-order__hint と同じ理由)。ここに display を書いた瞬間、
   「たたむ」を押しても閉じなくなる */
.preview-pane__body .note { margin: 0 0 0.5rem; }
/* 高さはビューポートから、ペインの上端までの距離とツールバー・注記のぶんを引いた値。
   **引く量は一番かさむ場合に合わせる** —— ツールバーは幅で折り返し、実測(Chromium・
   vh=900・試用テナント)では 1180〜1200px で 3 行(135px)・1280px で 2 行(83px)・
   1366px 以上で 1 行(44px)だった。注記と余白を足した「iframe の上にあるもの」は
   最大 172.6px になる。またペインの上端は**スクロール前のほうが下**で(ヘッダ 99.2px +
   .app-main の上余白 24px = 123.2px)、sticky の 108px より深い。この 2 つを足した
   295.8px が最悪値なので 19rem = 304px 引いて 8px ほど残す。
   **広い画面では 120px ほど余る** —— 幅ごとに値を変えると折り返しの境目
   (テナント名の長さやプランで動く)を CSS に焼き付けることになるので、
   「はみ出さない」を全幅で満たすほうを採った。
   min-height は縦の短いウィンドウで枠だけになるのを防ぐ下限 */
.preview-pane__body iframe {
  display: block; width: 100%; height: calc(100vh - 19rem); min-height: 320px;
  border: 1px solid var(--n-border); border-radius: var(--n-r-md);
  background: var(--n-surface);
}

/* 購入ページ・公開中チップ */
.status-chip {
  background: var(--n-accent-soft); color: var(--n-ok); border-radius: var(--n-r-full);
  padding: 0.25rem 0.75rem; font-size: var(--n-fs-sm); font-weight: 500;
  display: inline-flex; align-items: center; gap: 0.375rem;
}
a.status-chip { text-decoration: none; }
.status-chip.is-suspended { background: var(--n-danger-soft); color: var(--n-danger); }
.upgrade-form { max-width: 480px; }
.host-input-row { display: flex; align-items: center; gap: 0.25rem; }
.host-input-row input { flex: 1; }
.host-suffix { color: var(--n-muted); white-space: nowrap; }
.radio-row { display: flex; align-items: center; gap: 0.5rem; margin: 0.375rem 0; }
.form-note.is-ok { color: var(--n-ok); }
.form-note.is-ng { color: var(--n-danger); }
.form-status { min-height: 1.5em; }
.form-status.is-error { color: var(--n-danger); }
.price-figure { font-variant-numeric: tabular-nums; }

/* 独自ドメイン(spec 2026-07-27-custom-domain §11) */
.custom-domain { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid var(--n-border); }
.dns-record { border-collapse: collapse; margin: 0.75rem 0; }
.dns-record th, .dns-record td {
  border: 1px solid var(--n-border); padding: 0.375rem 0.75rem;
  text-align: left; font-weight: normal;
}
.dns-record code { user-select: all; }

@media (prefers-reduced-motion: reduce) {
  .preview-frame { transition: none; }
}
