/*
Theme Name: OptiB Child
Theme URI: https://optib.with-planning.co.jp/
Description: OptiB の子テーマ。カスタマイズはすべてこちらに書きます。親テーマ (OptiB) を更新しても、この中身は上書きされません。
Author: With-Planning
Author URI: https://with-planning.co.jp/
Template: optib
Version: 1.0.0
Requires at least: 6.4
Requires PHP: 8.2
Text Domain: optib-child
*/

/* ===========================================================
   ここから下に、独自のCSSを書いてください。
   親テーマの assets/css/theme.css より後に読み込まれるので、
   同じセレクタなら、こちらが勝ちます。
   =========================================================== */

/* ===========================================================
   全組み合わせ共通のトークン

   親テーマ OptiB には影のトークンが無く、値がハードコードされている。
   共有部品が上書きできる接点を作るため、ここで定義する。
   共有部品側は presets/_shared/ の palettes / layouts / skins の
   style.css で上書きするだけでよい（palettes/dark がそうしている）。
   =========================================================== */
:root {
  --optib-child-shadow-sm: 0 1px 2px rgb(0 0 0 / 6%);
  --optib-child-shadow-md: 0 2px 8px rgb(0 0 0 / 8%);
  --optib-child-shadow-lg: 0 8px 24px rgb(0 0 0 / 10%);
}

/* ===========================================================
   ウィジェットが空のときの1カラム化

   親テーマの sidebar.php は is_active_sidebar() を見ておらず、
   ウィジェットが空でも <aside class="l-grid__sidebar"> を常に出す。
   そのため空判定は PHP 側で行い、body の
   .optib-child-no-sidebar を起点にここで畳む
   （クラスは inc/frontend.php の optib_child_no_sidebar_class()）。

   配色やレイアウトで分岐しない。ウィジェットが空かどうかは
   装飾の好みではなくサイトの状態だからである。

   詳細度: この2規則は 0,2,0。
   打ち消す相手は親テーマ theme.css の .l-grid__main / .l-grid__sidebar で、
   いずれも 0,1,0。相手は2組ある。
   - メディアクエリの外: .l-grid__col-12, .l-grid__main, .l-grid__sidebar
     { grid-column: span 12 }（main 側は同じ値なので 992px 未満では no-op）
   - @media (min-width: 992px) の中: main が span 8、sidebar が span 4
   メディアクエリは詳細度を上げないので、0,2,0 > 0,1,0 で
   読み込み順に関係なく両方に勝つ。

   ただし勝てるのは「今この2プロパティに競合が無い」ためでもある。
   子テーマ style.css は共有部品より前に読まれるので、共有部品が同じ
   プロパティを書けば後勝ちで負ける。現状 .l-grid__main 自身の
   grid-column を触る規則は共有部品に無い（card-grid/style.css:48 は
   0,3,0 で main 自身に当たるが display / grid-template-columns /
   gap / align-items だけで、grid-column は子 `> *` にしか当てていない）。
   共有部品側に .l-grid__main の grid-column を足すときは、ここが黙って
   負けることに注意すること。

   検索結果ページ（親 search.php）の main は .col-lg-8 であって
   .l-grid__main ではない。親テーマは Bootstrap を読み込んでおらず
   .col-lg-8 の定義も無いため、main は元から全幅である。
   ここで main 側の指定が当たらなくても見え方は変わらない。

   下の「サイドバーの左右」も、この検索結果ページには当たらない。
   ラッパが .l-grid ではなく .row であり、親 theme.css には
   .row の定義が 0 件（.l-grid__col-lg-8 はあるが、素の .col-lg-8 は
   セレクタとして存在しない）。つまり .row は grid コンテナですらない。
   要素そのものは在る。親 search.php は get_sidebar() を呼び、親 sidebar.php
   の早期 return は product/shop/product_category/product_tag だけなので
   検索結果は素通りし、<aside class="l-grid__sidebar"> が出力される。
   セレクタはマッチし grid-column 宣言も適用されている。効かない理由は
   親が grid コンテナでないことだけで、宣言が不活性になっている。
   打ち消しを足していないのは「書く先が無いから」ではなく、宣言が
   不活性で見え方に影響しないためである。同じ理屈で
   .optib-child-no-sidebar .l-grid__sidebar { display:none } のほうは
   grid に依存しないので、検索結果でも実際に効いている。
   =========================================================== */
.optib-child-no-sidebar .l-grid__main {
  grid-column: span 12;
}

.optib-child-no-sidebar .l-grid__sidebar {
  display: none;
}

/* ===========================================================
   サイドバーの左右
   -----------------------------------------------------------
   body の .optib-child-sidebar-left / -right を起点に入れ替える
   （クラスは inc/frontend.php の optib_child_sidebar_position_class()）。

   DOM は親テーマのまま <main> → <aside> の順である。
   テンプレートを持たず、grid-column の指定だけで見た目の左右を決める。

   親テーマ theme.css の実測値（assets/css/src/flocss/layout/_l-container.css
   がソース、配信は assets/css/theme.css）:
   - .l-grid { grid-template-columns: repeat(12, 1fr) }
   - メディアクエリの外: .l-grid__col-12, .l-grid__main, .l-grid__sidebar
     { grid-column: span 12 }
   - @media (min-width: 992px) の中: .l-grid__main { grid-column: span 8 }
     / .l-grid__sidebar { grid-column: span 4 }
   境界は 992px ちょうど1つ。新しい境界は作らない。

   992px 未満では、ここで何も指定しない。
   両者が span 12 のまま縦に積まれ、DOM 順どおり記事一覧が先に来る。
   左を選んでいてもサイドバーは上に出ない。

   right は親の既定と同じ並び（main が先）なので、規則を書かない。
   書かないことが「親のまま」であり、打ち消しの必要が無い。

   -----------------------------------------------------------
   grid-row: 1 が要る理由（これが無いとサイドバーが消える）

   grid-column だけでは足りない。列を入れ替えても、自動配置は
   行方向に後戻りしないからである。
   css-grid-1 §8.5 Grid Item Placement Algorithm の
   「Position the remaining grid items」/ "sparse" packing（既定）:

     If the item has a definite column position:
     Set the column position of the cursor to the grid item's column-start line.
     If this is less than the previous column position of the cursor,
     increment the row position by 1.

   親に grid-auto-flow の指定は 0 件なので既定の row（sparse）である。
   DOM 順は main → aside（親 index.php:22-44 / archive.php:21-47。
   .l-grid の直下の子はこの2つだけで、他に兄弟は無い）。
   order の指定も親子ともに無いので、この順で配置される。

   実際の流れ:
   - main は列開始 5 が確定。cursor の列を 5 にする。5 < 1 ではないので
     行は増えず、1行目に載る。cursor の列位置は 5 になる。
   - aside は列開始 1 が確定。cursor の列を 1 にする。
     1 < 5 なので **row が 1 つ増える**。よって 2 行目へ送られる。

   結果、サイドバーは記事一覧の下に回る。要素も規則も生きているのに
   画面から消えたように見えるのはこれが理由である。
   「main の右端を越えたから」ではなく「直前の cursor 列位置より
   小さいから」が正確な発火条件である。

   値を 1 にした理由:
   .l-grid の直下の子は main と aside の 2 つだけなので、両方を
   1 行目に固定してよい。列は 1–5 と 5–13 で重ならないため衝突しない。
   span は既定の 1 で、これは right（親の既定）のときに自動配置が
   作る形とまったく同じである。つまり grid-row: 1 は新しい見た目を
   足すのではなく、左右で同じ結果に揃えるための指定である。
   将来 .l-grid の直下に3つ目の子が増えたら、ここは見直しが要る。

   grid-auto-flow: dense でも直る（dense は cursor の行を先頭に戻すと
   仕様に明記がある）が、dense は .l-grid 内の他の自動配置にも一律で
   効いてしまうので採らない。ここだけを直す指定のほうが影響が狭い。

   right 側に対称の grid-row を書かなかった理由:
   right では main も aside も列開始が確定しない（親の span 8 / span 4 の
   まま）ので、上の分岐に入らず「両軸とも自動」の経路で素直に 1 行目に
   並ぶ。行送りは起きない。つまり right に grid-row を書いても現状の
   結果は 1 ミリも変わらず、親の既定を打ち消す規則が 1 つ増えるだけに
   なる。「right には規則を書かない」という上の方針を崩す対価に見合わない。
   非対称に見えるのは、行送りが左を選んだときにだけ起きる現象だからで
   ある。この段落がその非対称の理由である。

   詳細度（grid-row について）:
   親テーマ theme.css・子 presets/ のいずれにも grid-row / grid-auto-flow の
   指定は 0 件である（親で grid-area を使うのは .p-post-navigation の
   3 箇所だけで、.l-grid とは別物）。競合が無いので、この 2 宣言は
   詳細度を問わず適用される。セレクタ自体は変えていないので、
   grid-column 側の 0,3,1 という比較も上に書いたまま変わらない。

   詳細度:
   - 相手（親 theme.css）: .l-grid__main / .l-grid__sidebar = 0,1,0
   - 相手（子 style.css 上方）: .optib-child-no-sidebar .l-grid__main = 0,2,0
   - ここ: body.optib-child-sidebar-left:not(.optib-child-no-sidebar) .l-grid__main
     = 要素 body が 1、クラスが .optib-child-sidebar-left / :not() 内の
       .optib-child-no-sidebar / .l-grid__main で 3 → 0,3,1
   0,3,1 > 0,2,0 > 0,1,0 なので、読み込み順に関係なく親にも勝つ。
   メディアクエリは詳細度を上げないため、この比較に影響しない。

   :not(.optib-child-no-sidebar) を挟んでいるのは、詳細度を稼ぐためだけでなく
   ウィジェットが空のときに 1 カラム化と競合させないためである。
   空のときは上のブロックが勝ち、こちらはそもそも当たらない。
   =========================================================== */
@media (min-width: 992px) {
  body.optib-child-sidebar-left:not(.optib-child-no-sidebar) .l-grid__sidebar {
    grid-column: 1 / span 3;
    grid-row: 1;
  }

  body.optib-child-sidebar-left:not(.optib-child-no-sidebar) .l-grid__main {
    grid-column: 4 / span 9;
    grid-row: 1;
  }
}

/* ===========================================================
   サイドバー幅（right 側にも揃える）
   -----------------------------------------------------------
   幅の基準は参照サイト（with-planning.co.jp）の #sidebar 固定
   300px。12カラムグリッドでは 3/12 列がその近似値になる
   （実測 302px、コンテナ幅 1280px 時）。

   left 側は上のブロックで 1 / span 3・4 / span 9 に変更済み。
   right（既定の並び、DOM 順のまま main が先）はここまで
   「right は親の既定と同じ並びなので規則を書かない」として
   親テーマの span 8 / span 4 のままだったが、それだと left と
   幅が揃わない。順序（grid-row・列の開始位置）は変えず、
   span 数だけを揃える。

   :not(.optib-child-sidebar-left) はここでは無くても良い
   （left 側は詳細度 0,3,1 で常に勝つ）が、対象を明示するために
   付けている。:not(.optib-child-no-sidebar) は他ブロックと同じ
   理由（ウィジェットが空で 1 カラム化しているときと競合させない）。
   =========================================================== */
@media (min-width: 992px) {
  body:not(.optib-child-sidebar-left):not(.optib-child-no-sidebar) .l-grid__main {
    grid-column: span 9;
  }

  body:not(.optib-child-sidebar-left):not(.optib-child-no-sidebar) .l-grid__sidebar {
    grid-column: span 3;
  }
}

/* ===========================================================
   サイドバーの追従（下スクロール時）
   -----------------------------------------------------------
   body の .optib-child-sidebar-sticky-on を起点に効かせる
   （クラスは inc/frontend.php の optib_child_sidebar_sticky_class()）。
   既定は -off で、-off 側には規則を書かない。書かないことが
   「親のまま」であり、更新しただけでは挙動が変わらない。

   追従そのものは position: sticky が受け持つ。JavaScript は
   「サイドバーが画面より高いときだけ」に絞るためだけに使い、
   スクロール位置の計算や top / bottom の書き換えはしない
   （assets/js/sidebar-sticky.js、詳しくは下の【絞り込み】を見よ）。

   -----------------------------------------------------------
   境界を 992px にした理由

   親テーマ theme.css（ソースは
   optib-theme/wp-content/themes/optib/assets/css/src/flocss/layout/_l-container.css）
   の実測値:
   - _l-container.css:36-43  .l-grid__main / .l-grid__sidebar { grid-column: span 12 }
   - _l-container.css:46     @media (min-width: 992px)
   - _l-container.css:47-49    .l-grid__main { grid-column: span 8 }
   - _l-container.css:51-53    .l-grid__sidebar { grid-column: span 4 }
   .l-grid__sidebar に当たる規則は親テーマのソース全体でこの2箇所だけである
   （grep "l-grid__sidebar" assets/css/src/ → _l-container.css:41 と :51 の2件）。
   つまり 2 カラムになる境界は min-width: 992px のちょうど1つ。
   上の「サイドバーの左右」と同じ境界を使い、新しい境界は作らない。

   992px 未満では main と sidebar が span 12 のまま縦に積まれる。
   縦積みで追従させると、サイドバーが記事一覧の下に居座って
   ずっと画面を占め続けることになるので、効かせない。

   -----------------------------------------------------------
   なぜ top ではなく bottom なのか

   要件は「サイドバーの中身が画面より高いとき、サイドバー全体を
   いったんスクロールさせ、下端まで見たところで固定する」である。

   top: 0 だと、上端が画面の上に着いた時点で貼り付く。
   サイドバーが画面より高い場合、下端は画面の外に出たまま固定され、
   そこから先はどれだけスクロールしても下端が読めない。

   bottom: 0 は逆に、下端が画面の下辺に着くまでは普通に流れ、
   着いた時点で貼り付く。到達するまでの間にサイドバー全体が
   画面を通過するので、下端まで読める。読み終えた位置で止まる。
   これが要件そのものである。

   サイドバー内に独立したスクロールバーは作らない（overflow を
   与えていない）。先頭ウィジェットだけを固定する方式も採らない
   （固定するのは .l-grid__sidebar 自身であって、その子ではない）。

   上へ戻すときは追従しない。position: sticky で「下スクロールでは
   追わせ、上スクロールでは即座に外す」ことはできず、そこを作るには
   スクロール位置を見る JavaScript が要る。そこまではやらない。

   -----------------------------------------------------------
   align-self: start が要る理由（これが無いと 1px も動かない）

   .l-grid__sidebar はグリッドアイテムであり、align-self の初期値は
   normal（グリッドでは stretch と同じ振る舞い）である。
   つまりサイドバーの高さは行の高さ、すなわち記事一覧と同じ高さまで
   引き伸ばされている。親テーマにも子テーマの presets/ にも
   .l-grid__sidebar の align-self / align-items を触る規則は無い
   （presets 側で align-items を書いているのは
   presets/_shared/layouts/card-grid/style.css:54 だけで、対象は
   .l-grid__main であり、その中の子の並びを決めるためのものである）。

   sticky の可動域は、その要素を含むブロック（ここではグリッドエリア
   ＝行の高さ）から要素自身の高さを引いた分しかない。引き伸ばされて
   いると両者が等しく、可動域が 0 になる。規則は適用されているのに
   1px も動かない、という見え方になる。

   align-self: start で高さを内容ぶんに戻すと、
   可動域 = 行の高さ − サイドバーの高さ、が生まれる。
   記事一覧のほうが高いあいだだけ追従し、追い越すことはない。

   なお align-self: start は .optib-child-sticky-ready の「外」に、
   sticky-on の下で無条件に置いてある。JS が測る高さをクラスの
   付け外しで変えないためである。理由は下の規則の直前に書いた。

   -----------------------------------------------------------
   祖先の overflow / contain の実測（sticky が殺されていないか）

   sticky は、祖先にスクロールコンテナがあると、そちらを基準に貼り付く。
   祖先チェーンは実測で
     html > body > section.l-site-content > div.l-container > div.l-grid > aside.l-grid__sidebar
   （親 index.php:19-22 / archive.php:19-21 と、親 sidebar.php:26 の <aside>。
   get_sidebar() は index.php:43 / archive.php:46 にあり、いずれも
   div.l-grid の直下で呼ばれている。だから .l-grid > .l-grid__sidebar と
   直下結合子で書ける）。

   セレクタを .l-grid の直下に閉じてあるのは検索結果ページのためである。
   親 search.php:22 のラッパは <div class="row">、その中の main は
   search.php:23 の .col-lg-8 で、どちらも CSS 定義が 0 件（親 assets/css 配下・
   子テーマの CSS すべてに .row のセレクタ定義は無い）。つまり .row は
   grid コンテナではない。それでも search.php:48 で get_sidebar() を呼ぶので
   <aside class="l-grid__sidebar"> は出力される。
   上の「サイドバーの左右」が検索結果で無害なのは grid-column が
   grid コンテナの外で不活性だからであって、セレクタが外れているからではない。
   position / bottom / align-self は grid に依存しないので、同じ書き方をすると
   検索結果ページで実際に効き、サイドバーが結果一覧に重なる。
   .l-grid > を挟むと search.php にはマッチしない（.row は .l-grid ではない）。
   footer.php:23 にも .l-grid はあるが、その中に .l-grid__sidebar は無い。
   single.php / page.php は get_sidebar() を呼ばない（親テーマ内の
   get_sidebar() 呼び出しは index.php:43 / archive.php:46 / search.php:48 の3件）。

   - contain: 親テーマ・子テーマの CSS を通して 0 件
     （grep "contain:" assets/css/src/ → 出力なし）。
   - overflow: 親テーマのソース全体で 15 件あるが、上の祖先に当たるのは
     assets/css/src/flocss/foundation/_base.css:15 の
     :where(body) { overflow-x: hidden } ただ1つである。
     残りは .wp-block-latest-posts li / .code-tabs / .c-card /
     .p-post-navigation / .p-widget__recent-post-thumb / .l-header__* /
     .u-overflow-* などで、いずれもサイドバーの祖先ではない。
   - height / min-height / max-height: 祖先の 4 ファイル
     （_l-container.css / _l-section.css / _base.css / _reset.css）で
     当たるのは _reset.css:51 の height: auto のみ。高さを固定していない。
   - .l-site-content は margin-block だけ（_l-section.css:31-33、
     992px 以上でも 36-40 行で margin-block を変えるだけ）。

   残る body の overflow-x: hidden は sticky を殺さない。
   css-overflow-3 §3.3 の viewport への伝播による。
   ルート要素（html）の overflow が visible のとき、HTML 文書では
   body の overflow が viewport へ伝播し、body 自身は visible として
   扱われる。親テーマ・子テーマともに html への overflow 指定は 0 件
   なので、この経路に入る。つまり body はスクロールコンテナにならず、
   サイドバーは viewport を基準に貼り付く。
   （overflow-x: hidden が sticky を壊す、として知られている形は
   html 側に書かれた場合や、body より内側の中間要素に書かれた場合である。
   ここはどちらでもない。）

   -----------------------------------------------------------
   詳細度

   ここには規則が2つある。

   [A] align-self 用（ready の外・無条件）
     body.optib-child-sidebar-sticky-on:not(.optib-child-no-sidebar) .l-grid > .l-grid__sidebar
   要素 body が 1、クラスが .optib-child-sidebar-sticky-on /
   :not() 内の .optib-child-no-sidebar / .l-grid / .l-grid__sidebar で
   4 → 0,4,1。

   [B] sticky 用（ready 付き）
     body.optib-child-sidebar-sticky-on:not(.optib-child-no-sidebar) .l-grid > .l-grid__sidebar.optib-child-sticky-ready
   [A] に .optib-child-sticky-ready が 1 つ増えて 5 → 0,5,1。
   （> は結合子なので詳細度に加算しない。
     :not() 自身も加算せず、引数の中身だけを数える。）

   [A] と [B] はプロパティが重ならない（[A] は align-self のみ、
   [B] は position / bottom のみ）ので、両者のあいだで打ち消しは起きない。
   [B] のほうが高いが、その差は使っていない。

   競合相手を、宣言するプロパティごとに数える。
   - position / bottom / align-self を .l-grid__sidebar に当てている規則は、
     親テーマ theme.css にも子 presets/ にも 0 件である
     （親で .l-grid__sidebar を含むセレクタの宣言ブロックは実測 2 件、
      _l-container.css:41-43 と :51-53 に対応する
      .l-grid__col-12,.l-grid__main,.l-grid__sidebar{grid-column:span 12} と
      .l-grid__sidebar{grid-column:span 4} で、どちらも grid-column のみ。
      親で position: sticky を使うのは .l-header だけ。
      子の presets/ 配下で align-items を書いているのは
      presets/_shared/layouts/card-grid/style.css:54 のみで、対象は
      .l-grid__main であってサイドバーではない）。
     競合が無いので、この3宣言は詳細度を問わず適用される。
   - 同じ要素に他のプロパティを当てている規則は 3 つある。
     親 .l-grid__sidebar = 0,1,0（grid-column）
     子 .optib-child-no-sidebar .l-grid__sidebar = 0,2,0（display）
     子 body.optib-child-sidebar-left:not(...) .l-grid__sidebar = 0,3,1
       （grid-column / grid-row）
     どれもプロパティが重ならないので、打ち消し合わない。
   0,5,1 は最後のもの（0,3,1）より高いが、宣言が重ならないため
   打ち消しは起きず、順序も問題にならない。

   -----------------------------------------------------------
   【絞り込み】サイドバーがビューポートより低いときの押し下げ

   bottom: 0 は「下端がスクロールポートの下辺より上に来てはならない」という
   制約であり、sticky のオフセットは初期位置から即座に適用される。
   サイドバーがビューポートより低いと、スクロール 0 の時点で既に違反しており、
   ブラウザは要素を下へ押し下げる。押し下げの上限は包含ブロック
   （＝グリッドエリア＝行の高さ）で、align-self: start により
   行は記事一覧ぶん高くサイドバーは低いので、押し下げ量は大きい。
   結果、初期表示からサイドバーが画面下端に貼り付き、上に空白が空く。
   上の「下端が着くまでは普通に流れる」が成り立つのは、
   サイドバーがビューポートより高いときだけである。

   検討した選択肢と、それぞれの代償:
   - top: 0 を併記する
       → 不可。両方指定時は top 制約が勝ち、ビューポートより高い
         サイドバーは上端で固定され、下端が永久に読めない。要件が壊れる。
   - min-block-size: 100vh を足す
       → 押し下げは消え、高いときの振る舞いも保たれる。ただし
         min-block-size はグリッドの auto 行のサイズ計算に寄与するため、
         行が 100vh まで伸びる。記事一覧とサイドバーの両方が 100vh より
         低いページで、フッタの手前に空白が出る。
   - 「低いときは追従させない」を CSS だけで選り分ける
       → 手段が無い。top / bottom のパーセンテージは包含ブロックの高さ基準で、
         要素自身の高さを参照する記法が無い。コンテナクエリでも
         「自分の高さ vs ビューポート」は条件にできない。
         ラッパを 1 枚噛ませる古典的な手法は DOM 変更になる。

   採ったのは3つ目を JavaScript で作る道である。
   assets/js/sidebar-sticky.js が、サイドバーの高さとビューポートの
   高さを比べ、高いときだけサイドバー要素へ .optib-child-sticky-ready を
   付ける。低いときは付けない（付いていれば外す）。
   高さが変わる場面（リサイズ・回転・画像の遅延読み込み・ウィジェットの
   非同期描画）に追随するため、ResizeObserver（要素の寸法）と
   resize イベント（ビューポートの高さ）の両方を見ている。
   JS がするのはこの付け外しだけで、スクロール位置は見ないし
   top / bottom も書き換えない。追従は下の sticky のままである。

   下の規則が .optib-child-sticky-ready を要求しているのは、
   既定を「効かない側」に置くためである。JS が読み込まれない・
   失敗する、のいずれでもクラスは付かず、sticky が宣言されないので
   親テーマのままの流し込みになる。
   壊れ方は「追従しない」だけで、レイアウトは崩れない。

   ResizeObserver が無い古いブラウザは、これには当たらない。
   assets/js/sidebar-sticky.js は update() を無条件に 1 回呼び、
   resize リスナも無条件に登録する（RO の有無を見るのはその後）。
   したがって RO が無くても初回描画時とリサイズ時にクラスは付き、
   追従は効く。効かないのは中身の高さがあとから変わったときの
   追随だけである。

   min-block-size: 100vh は採らない。押し下げは消えるが、
   グリッドの auto 行が 100vh まで伸びて、短いページでフッタの手前に
   空白が出るためである。

   :not(.optib-child-no-sidebar) を挟んでいるのは、ウィジェットが空のときに
   効かせないためである。空のときは上のブロックの display: none が勝ち、
   ここは当たっても意味を持たない。条件を明示しておくほうが、
   後から読んだときに「空でも追従の指定が生きている」と誤読されない。

   左右のどちらでも効く。セレクタが
   .optib-child-sidebar-left / -right を見ていないためである。
   追従は左右とは別の軸であり、片方でだけ効く理由が無い。
   =========================================================== */
@media (min-width: 992px) {
  /* align-self: start は .optib-child-sticky-ready の外に置く。
     これは体裁の都合ではなく、JS の測定が成り立つための前提である。

     align-self の初期値は normal（グリッドでは stretch 相当）なので、
     クラスが無いあいだのサイドバーの高さは「行の高さ」＝記事一覧の高さに
     引き伸ばされている。この規則を ready の中に入れると、
     クラスの有無でサイドバー自身の高さが変わってしまい、
     assets/js/sidebar-sticky.js の
     getBoundingClientRect().height vs window.innerHeight の比較が
     次の2つの形で壊れる。

       (1) 中身が短くても記事一覧が長ければ「高い」と判定され、
           bottom: 0 による初期表示からの押し下げが再現する。
       (2) クラスを付けると高さが内容ぶんに縮み、ResizeObserver が
           再発火して「低い」に戻り、また付く……と発振する（点滅する）。

     ready の外に無条件で置けば、JS が測る値はクラスの付け外しで
     変化しない。だから比較が安定し、付け外しも収束する。
     この2つは切り離すと壊れる関係にある。片方だけ動かすな。

     ready の外に出しても見た目は変わらない。.l-grid__sidebar および
     aside 単独のセレクタに background / border / box-shadow / outline を
     与えている規則は親テーマ・子テーマとも 0 件で、高さが縮んでも
     塗りの差が出ないためである。
     セレクタを body.optib-child-sidebar-sticky-on の下に置いてあるので、
     設定が off の利用者には当たらない。 */
  body.optib-child-sidebar-sticky-on:not(.optib-child-no-sidebar) .l-grid > .l-grid__sidebar {
    align-self: start;
  }

  body.optib-child-sidebar-sticky-on:not(.optib-child-no-sidebar) .l-grid > .l-grid__sidebar.optib-child-sticky-ready {
    position: sticky;
    bottom: 0;
    /* 実際の追従は assets/js/sidebar-sticky.js が transform: translateY()
       で行っている（このファイル冒頭のコメント、および同スクリプトの
       冒頭コメントを参照。grid + bottom 指定では position: sticky が
       Chrome で効かないための代替）。will-change は、ブラウザに
       「この要素の transform は動く」と事前に伝え、専用の合成レイヤーを
       あらかじめ用意させるための指定。無いと、transform を書き換える
       たびに新しくレイヤーを作り直すことがあり、それがスクロール中の
       カクつきの一因になる。 */
    will-change: transform;
  }
}


/* ===========================================================
   記事一覧カード（thumb-list）：見出しを大きく、上下の余白を均一に
   -----------------------------------------------------------
   親テーマの thumb-list プリセット
   (presets/_shared/layouts/thumb-list/style.css) は
   - タイトルを 16px 固定
   - サムネイルを float: left、本文を margin-left で右に
     寄せるだけ（.p-post__body は display: block のまま上詰め）
   にしていた。カードの高さは float したサムネイルの高さで決まる
   一方、本文側は中身の高さぶんしか使わないため、本文が短い記事
   ほど下側に余白が偏っていた（本文が長い記事はほぼ埋まる）。

   タイトルは 16px → 20px に拡大。

   余白の均一化は、本文ブロック（.p-post__body）全体を
   align-items: center で中央に寄せる方式を最初に試したが、
   それは失敗だった。.p-post__excerpt の margin-bottom: 32px
   （同プリセット (9) のコメントにある通り、ホバーで出る
   .p-post__more の「居場所」として意図的に確保されたスペース）
   が本文ブロックの高さに含まれてしまい、見えるテキスト
   （meta + title + excerpt）の重心が中心より上にずれ、
   「上が詰まって下だけ余る」という、直した意味が無い見た目に
   なった（実機で確認済み）。

   採ったのは、32px のスペースを中央揃えの計算そのものから
   除外する方式である。
   - .p-post__body を flex-direction: column にする
   - 最初の要素 .p-post__meta に margin-top: auto
   - 最後のテキスト要素 .p-post__excerpt に margin-bottom: auto
     （固定 32px をやめて auto に置き換える）
   - .p-post__body::after で高さ 32px の空ボックスを1つ追加する
     （flex-shrink: 0 で潰れないようにする。ボタン用スペースの
     置き場所を、テキストのマージンから本文末尾の専用の1マスへ
     移すのが目的で、疑似要素はそのための場所でしかない）
   auto マージンは flex の余白を均等に分け合うため、
   meta〜excerpt のかたまりが「本文の高さ − 32px」の中で中央に
   揃い、32px は常に下端に固定される。
   さらに .p-post--list.has-post-thumbnail の align-items は
   center ではなく stretch にする。center のままだと本文の高さが
   中身ぶんに縮み、auto マージンが分け合う余白が生まれない
   （stretch で本文をカード（画像）の高さいっぱいまで伸ばして
   初めて auto マージンが効く）。

   .p-post__more（ホバーで右からスライドインする「続きを読む」）
   は thumb-list (14) で position: relative; z-index: 1 を与え
   られており、絶対配置の基準は記事カード自身（同 (1) の
   position: relative）。本文側を上記のとおり変更しても、
   ボタンの基準・オフセットには触れていないので変化しない
   （実機ホバーで、テキストとボタンが重ならないことを確認済み。
   before: excerpt margin-bottom を単純に 0 にする案も試したが、
   その場合はテキストがボタンの直下まで下がり、ホバー時に
   重なったため不採用にした）。

   float を外すのはサムネイルの並び方向のみで、比率
   （37.377% / 残り + 1.6% の隙間）は元の値をそのまま使う。
   =========================================================== */
body.optib-layouts-thumb-list .p-post--list .p-post__title {
  font-size: 20px;
}

body.optib-layouts-thumb-list .p-post--list.has-post-thumbnail {
  display: flex;
  align-items: stretch;
}

body.optib-layouts-thumb-list .p-post--list.has-post-thumbnail .p-post__thumbnail-wrap {
  flex: 0 0 37.377%;
}

body.optib-layouts-thumb-list .p-post--list.has-post-thumbnail .p-post__thumbnail {
  float: none;
  width: 100%;
  margin: 0;
}

body.optib-layouts-thumb-list .p-post--list.has-post-thumbnail .p-post__body {
  margin-left: 1.6%;
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

body.optib-layouts-thumb-list .p-post--list.has-post-thumbnail .p-post__meta {
  margin-top: auto;
}

body.optib-layouts-thumb-list .p-post--list.has-post-thumbnail .p-post__excerpt {
  margin-bottom: auto;
}

body.optib-layouts-thumb-list .p-post--list.has-post-thumbnail .p-post__body::after {
  content: "";
  display: block;
  height: 32px;
  flex-shrink: 0;
}

/* ===========================================================
   記事一覧カード（thumb-list）：サムネイルを 16:9 に統一
   -----------------------------------------------------------
   親テーマは .p-post__thumbnail { aspect-ratio: auto } と
   .p-post__thumbnail img { object-fit: contain; height: auto }
   で、画像そのものの縦横比のまま表示していた。実際にアップロード
   されている画像はほぼ 845x522（比率約 1.62 : 1）で 16:9
   （比率 1.78 : 1）になっていなかった（1件だけ 798x445 で
   別の比率）。記事によって高さがまちまちになるため、
   .p-post__thumbnail に aspect-ratio: 16 / 9 を固定し、
   img は object-fit: cover; height: 100% でその枠を埋める
   （contain のままだと枠の中で余白ができるだけで、比率は揃わない）。

   .p-post__thumbnail は親テーマ側で overflow: hidden 済みなので、
   cover ではみ出す部分は自動でクリップされる。
   =========================================================== */
body.optib-layouts-thumb-list .p-post--list .p-post__thumbnail {
  aspect-ratio: 16 / 9;
}

body.optib-layouts-thumb-list .p-post--list .p-post__thumbnail img {
  object-fit: cover;
  height: 100%;
}

/* ===========================================================
   サイドバーウィジェット：内側に余白を追加
   -----------------------------------------------------------
   親テーマ theme.css の .widget は
     { background: #fff; margin-bottom: 40px }
   で、そもそも padding が無い。ライトパレット（白背景）のときは
   目立たなかったが、ダークパレットで背景がグレー系の面色に
   なると、中身（カレンダーの日付セルなど）が箱の縁に接して見え、
   バランスが悪く見える。
   .widget-title には元から margin-bottom: 15px があるので、
   タイトルと本文の間隔はここでは触らない。box 全体の外周だけに
   16px の padding を足す。
   .widget-title:before の横線は width: 100% を widget の
   content box 基準で引いているだけなので、padding を足しても
   幅は変わらず特に副作用は無い（実機のカレンダーウィジェットで
   確認済み。テキスト系の他ウィジェットは今回未確認）。
   =========================================================== */
.widget {
  padding: 16px;
}

/* ===========================================================
   ウェブプッシュ購読フォーム：ラベル文字が読めない
   -----------------------------------------------------------
   ウェブプッシュ系プラグインが出す .p-webpush-manager__rule
   （チェックボックスのラベル）は、プラグイン側の CSS で
   background: #fff を直接指定している。一方でテーマ側は
   本文の文字色をダークパレット用の明るいグレー
   （rgb(227,227,227)）にしており、これがそのまま
   .p-webpush-manager__rule / 中の span.p-webpush-manager__rule-label
   に継承されるため、白地に薄いグレー文字でほぼ読めなくなって
   いた（実機のチェックボックス「ウェブプッシュのテスト」で確認）。
   ラベル側だけ、白背景に合う暗い文字色を明示する。
   =========================================================== */
.p-webpush-manager__rule,
.p-webpush-manager__rule-label {
  color: #1f2124;
}

/* ===========================================================
   記事一覧カード（thumb-list）：スマホ幅では縦積みにする
   -----------------------------------------------------------
   親テーマの thumb-list プリセットは画面幅を問わず横並び
   （サムネイル 37.377% + 本文 残り）で、メディアクエリを
   一切持っていない（実装時に確認済み）。デスクトップでは
   問題ないが、スマホ幅（実測 iframe 375px 相当）では画像が
   小さくつぶれ、タイトル・本文が狭い右カラムに押し込まれて
   読みにくくなる（実機スクリーンショットで指摘を受けて確認）。

   599px 以下では、上に置いた flex 化した本文レイアウトを
   flex-direction: column に切り替え、サムネイルを幅いっぱい、
   本文をその下に縦積みにする。
   - サムネイル側の flex-basis（37.377%）を解除して幅 100% に
   - 本文の margin-left（横並び用の隙間）を margin-top に置き換え
   - 本文末尾の 32px スペーサー（thumb-list (15) のホバー用の
     居場所、このファイル内で .p-post__body::after として追加
     したもの）は、縦積みでは本文の下がそのままカード下端に
     近いため不要。表示を消して、ホバー時の右スライドインで
     ボタンがそのまま出るのに任せる。
   ブレークポイントは 599px。親テーマ唯一の 992px は
   サイドバー有無の切り替えであり、この崩れとは無関係な値
   なので流用しない。600px 前後は一般的なスマホ幅の上限として
   採用した。
   =========================================================== */
@media (max-width: 599px) {
  body.optib-layouts-thumb-list .p-post--list.has-post-thumbnail {
    flex-direction: column;
    align-items: stretch;
  }

  body.optib-layouts-thumb-list .p-post--list.has-post-thumbnail .p-post__thumbnail-wrap {
    flex: none;
    width: 100%;
  }

  body.optib-layouts-thumb-list .p-post--list.has-post-thumbnail .p-post__body {
    margin-left: 0;
    margin-top: 16px;
  }

  body.optib-layouts-thumb-list .p-post--list.has-post-thumbnail .p-post__body::after {
    display: none;
  }
}

/* ===========================================================
   ページネーション（nav-links）：枠付きボタン化
   -----------------------------------------------------------
   親テーマは .nav-links / .page-numbers に規則を持たない
   （検証環境の全スタイルシートを走査して確認。WooCommerce の
   ul.page-numbers 用の規則だけがある）。素のままだと
   テキストリンクの羅列で、「次のページ」リンクは中身が
   <span class="screen-reader-text">次のページ</span> だけなので、
   目に見える文字が一切無い空リンクになる（実機で確認）。

   ここが唯一の置き場所である。レイアウト（thumb-list / card-grid）
   には依存させない。以前は layouts/thumb-list と skins/thumb-list-*
   の (12) にも同じ要素への規則があり、共有部品は本体より後に
   読まれるため float: left / padding: 5px 9px / line-height: 14px
   が勝って数字が箱の上寄りにずれ、card-grid では何も当たらなかった。
   その (12) は削除した。ここに集めたので !important も要らない。

   - 各 .page-numbers を枠線 + 背景付きのボタンにする
   - current は --color-primary で塗って強調する
   - .next / .prev には ::after / ::before で見えるラベルを足す
     （中の screen-reader-text はそのまま残るので、スクリーン
     リーダーには「次のページ」、目には「次へ ›」の両方が
     独立して存在する形になる。読み上げが二重になる心配はない
     ——::after の content はアクセシビリティツリーに乗らない）
   色は共通トークン（presets/_shared/palettes 配下で定義される
   --color-border / --color-bg-light / --color-text /
   --color-primary / --color-bg）を使うため、ライト/ダークどちらの
   パレットでも自動で馴染む。

   参照デザイン（ユーザー提示画像）にあった「1 / 6」の現在ページ数
   表示と「最後 »」ボタンは、WordPress 標準の paginate_links() の
   出力（このテーマでは prev/numbers/next のみ）には要素そのものが
   無く、CSS だけでは追加できない（ページ総数は動的な値で、
   ::before の content には差し込めない）。追加するならテンプレート
   側で paginate_links() の引数を変える改修が要る。
   =========================================================== */
main .nav-links {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  clear: both;
  padding: 20px 0;
  font-size: 14px;
  line-height: 1;
  overflow: visible;
}

main .nav-links .page-numbers {
  display: inline-flex;
  text-decoration: none;
  align-items: center;
  justify-content: center;
  float: none;
  margin: 0;
  min-width: 36px;
  height: 36px;
  padding: 0 12px;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-bg-light);
  color: var(--color-text);
  box-sizing: border-box;
}

main .nav-links a.page-numbers:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

main .nav-links .page-numbers.current {
  background: var(--color-primary);
  color: var(--color-bg);
  border-color: var(--color-primary);
  font-weight: bold;
}

main .nav-links .page-numbers.next,
main .nav-links .page-numbers.prev {
  padding: 0 16px;
}

main .nav-links .page-numbers.next::after {
  content: "次へ ›";
}

main .nav-links .page-numbers.prev::before {
  content: "‹ 前へ";
}

/* ===========================================================
   白背景ボックスの中の文字が読めない問題（複数プラグインで共通）
   -----------------------------------------------------------
   ダークパレット（presets/_shared/palettes/dark）は本文の文字色を
   明るいグレー（--color-text: #e3e3e3 系）にしている。これは
   ページの地の背景（#16181a 系）を前提にした配色だが、個々の
   プラグインが自分のUI部品に「白背景」を直接ハードコードして
   いる箇所では、文字色だけダークパレットの明るい色を継承して
   しまい、白地に薄いグレー〜白文字でほぼ読めなくなる。
   このパターンで実際に見つかったものを都度ここに足していく
   （汎用的に「白背景の要素」を CSS だけで検出する方法が無いため、
   一括では直せない。汎用選択子が無い理由: プラグインの背景色は
   インラインstyleではなくCSSファイル側でハードコードされており、
   属性セレクタでは拾えない）。

   - .p-webpush-manager__rule / -label: ウェブプッシュ購読
     チェックボックスのラベル（上のブロックで対応済み）
   - .wew-conversation-bubble: 会話形式ウィジェットの吹き出し
   同じ症状（白背景 + 明るいグレー文字）を他所で見つけたら、
   同じ要領で対象セレクタに直接暗い文字色を当てて追加すること。
   =========================================================== */
.wew-conversation-bubble {
  color: #1f2124;
}

/* ===========================================================
   サイドバーウィジェット内リンクの色（カテゴリー一覧など）
   -----------------------------------------------------------
   親テーマ theme.css の
     .wp-block-categories-list .cat-item a:not(:hover)
       { color: rgb(28, 29, 31) }
   は詳細度 0,3,1 で、ダークパレット側の
     :where(a){ color: var(--color-link) }
   （:where() は詳細度 0 を持つため実質 0,0,1）に確実に勝ち、
   常に暗い固定色が使われる。ウィジェットの背景はダークパレットで
   #1f2124 系のグレーになるため、ほぼ同化して読めなくなっていた
   （実機のカテゴリーウィジェット「未分類」で確認）。
   サイドバーのウィジェット内リンクに限定して、共通トークン
   --color-link で上書きする（記事本文側のリンク色には触れない）。
   =========================================================== */
.l-grid__sidebar .widget a {
  /* 親テーマ .wp-block-categories-list .cat-item a:not(:hover) が
     詳細度 0,3,1 でこのルール（0,2,1）に勝ってしまうため、
     color だけ !important で確実に上書きする。 */
  color: var(--color-link) !important;
}

/* ===========================================================
   「アイコン」ブロック（WordPress コア wp-block-icon）の色
   -----------------------------------------------------------
   ブロックのスタイルで色を選ぶと、svg 要素に
   class="has-text-color has-vivid-red-color" と style="color: …" が
   付く。しかしコアのブロック CSS は :root :where(.wp-block-icon svg)
   に width: 24px しか当てておらず、path の fill は SVG の既定値
   （黒）のまま残る。color は正しく解決されているのに、
   fill: currentColor が無いので見た目に反映されない
   （WordPress 7.1 の検証環境で、計算値 color=rgb(207,46,46) /
   fill=rgb(0,0,0) を確認）。

   ここで fill を currentColor に繋ぐ。サイドバーに限定しないのは、
   同じブロックを本文に置いても同じことが起きるためである。
   ブロックが色を持たないときは currentColor が周囲の文字色になり、
   ダークパレットでも自動で馴染む。
   =========================================================== */
.wp-block-icon svg {
  fill: currentColor;
}

/* ===========================================================
   画像ウィジェットは内側の余白を持たない
   -----------------------------------------------------------
   上の「サイドバーウィジェット：内側に余白を追加」で .widget 全体に
   padding: 16px を足したが、画像だけを表示する
   widget_media_image では、画像の四辺に白背景の縁ができてしまい
   不自然に見える（ユーザー指摘の実機スクリーンショットで確認）。
   画像ウィジェットだけ padding を 0 に戻す。
   =========================================================== */
.widget_media_image {
  padding: 0;
}

/* ===========================================================
   カレンダーウィジェットの日付色がページによって不安定
   -----------------------------------------------------------
   WordPress コアのブロックライブラリ CSS
   (wp-includes/css/dist/block-library/style.min.css) に
     .wp-block-calendar :where(table:not(.has-text-color)) { color: #404650 }
   がある。:where() で詳細度 0 だが、table 要素へ「直接」当たる
   宣言のため、祖先（.widget や .wp-block-calendar）で
   color: var(--color-text) を指定していても、継承より直接指定が
   優先されて負ける。

   このコア CSS は、そのページで実際に使われているブロックの
   構成によって読み込まれたり読み込まれなかったりする
   （WordPress のブロックスタイル最適化）。カレンダーウィジェットの
   HTML 自体は全ページ共通なのに、そのページに他のブロックが
   何もないとこの CSS が読み込まれず、逆に読み込まれるページでは
   コアの暗い固定色が勝つ、という不安定さが起きていた
   （実機でトップページと 2 ページ目・検索結果ページを比較して確認）。

   table 要素に対して直接 color を指定し、コア CSS の有無に
   左右されないようにする。
   =========================================================== */
.wp-block-calendar table {
  color: var(--color-text);
}

/* ===========================================================
   検索結果ページ（search.php）：本文とサイドバーが未スタイリング
   -----------------------------------------------------------
   親テーマの search.php は他のアーカイブ（.l-grid ベース）と違い、
   .row > .col-lg-8（本文）+ .l-grid__sidebar（サイドバー）という
   Bootstrap 風の別マークアップを出す。ところが .row / .col-lg-8 に
   対応する CSS がこのテーマ・子テーマのどこにも存在せず、素の
   ブロック要素のまま縦に積まれていた。結果、サイドバーが記事一覧の
   「下」にフル幅で表示され、これまで .l-grid 側に施した幅調整
   （3/12・9/12）も一切効いていなかった（実機で発見・確認）。

   .l-grid 側と同じ比率（サイドバー 3/12 ＝ 25%、本文 9/12 ＝ 75%）に
   なるよう、flexbox で幅と左右順序を再現する。左右の切り替えは
   他のページと同じ body.optib-child-sidebar-left を見る。

   これは見た目（幅・左右）だけの対応であり、下スクロール追従
   （assets/js/sidebar-sticky.js）はこのページを対象にしていない
   （同スクリプトのセレクタは .l-grid > .l-grid__sidebar に閉じて
   あり、.row 配下の検索結果ページは元から対象外という設計。
   今回はそこまで広げていない）。
   =========================================================== */
@media (min-width: 992px) {
  body.search .row {
    /* .l-grid（repeat(12,1fr); gap:24px）と同じ列計算にして、
       サイドバー幅をトップ・アーカイブと完全に一致させる
       （flex + % 指定だと gap 分の誤差が出て、実測でトップ302px
       に対し検索結果476px、gap込みに直しても320pxとズレていた）。 */
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 24px;
    align-items: start;
  }

  body.search.optib-child-sidebar-left .row > .l-grid__sidebar {
    grid-column: 1 / span 3;
  }

  body.search.optib-child-sidebar-left .row > .col-lg-8 {
    grid-column: 4 / span 9;
  }

  body.search:not(.optib-child-sidebar-left) .row > .col-lg-8 {
    grid-column: span 9;
  }

  body.search:not(.optib-child-sidebar-left) .row > .l-grid__sidebar {
    grid-column: span 3;
  }
}

/* ===========================================================
   検索結果ページ：本文の最大幅がトップ・アーカイブと違う
   -----------------------------------------------------------
   .l-grid 側は祖先の .l-container が
     width: 100%; max-width: var(--container-max-width);
     padding-inline: var(--container-padding); margin-inline: auto;
   でコンテンツ全体の幅を制限しているが、検索結果ページの .container
   （.row の親、Bootstrap 風マークアップ）にはこの制限が一切無く、
   画面幅いっぱいまで広がっていた。

   1回目の修正では max-width: 1440px; padding: 0 80px を
   @media (min-width: 992px) の中にハードコードしたが、これは
   親テーマの実際の値（--container-max-width / --container-padding、
   ビューポート幅に応じて連続的に変わる clamp() 系のトークン）と
   一致せず、かつ 992px 未満ではこの制限自体が外れてしまう
   （親テーマ側はブレークポイント無しに常時効く作りだった）ため、
   992px 付近の画面幅で本文がまた広がって見える崩れが残っていた
   （実測で発覚: トップはサイドバー302px、検索結果は当初476px、
   ハードコード後も320pxで一致せず。992px 未満の iframe 検証でも
   .l-container 側は 700px 幅でも max-width が効き続けていた）。

   共通トークン（親テーマ theme.css で定義）をそのまま使い、
   .l-container と全く同じ計算式にする。ブレークポイントを設けない
   （.l-container 側にも無いため）。
   .row 内の列比率も .l-grid と同じ grid-template-columns:
   repeat(12,1fr) + gap: var(--spacing-lg) にして、2 カラムに
   なる 992px 以上でだけ列を分ける。
   =========================================================== */
body.search .container {
  width: 100%;
  max-width: var(--container-max-width);
  padding-inline: var(--container-padding);
  margin-inline: auto;
  box-sizing: border-box;
}

@media (min-width: 992px) {
  body.search .row {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: var(--spacing-lg);
    align-items: start;
  }

  body.search.optib-child-sidebar-left .row > .l-grid__sidebar {
    grid-column: 1 / span 3;
  }

  body.search.optib-child-sidebar-left .row > .col-lg-8 {
    grid-column: 4 / span 9;
  }

  body.search:not(.optib-child-sidebar-left) .row > .col-lg-8 {
    grid-column: span 9;
  }

  body.search:not(.optib-child-sidebar-left) .row > .l-grid__sidebar {
    grid-column: span 3;
  }
}

/* ===========================================================
   検索ブロックの送信ボタンをテーマカラーに追従させる

   WordPressコアの検索ブロック（.wp-block-search__button）は
   テーマ側でスタイルを持たず、コアのブロックライブラリCSSが
   既定色 #32373c を当てている。OptiB本体のCustomizer「プライマリカラー」
   変更に追従させたいという依頼により、ここで上書きする。
   --color-primary は親テーマ theme.css の :root で
   var(--primary-color, #384d7a) を参照しているCSS変数なので、
   Customizer側の値変更だけで自動的に反映される。
   =========================================================== */
.wp-block-search__button {
  background-color: var(--color-primary);
  color: #fff;
}

.wp-block-search__button:hover {
  background-color: color-mix(in srgb, var(--color-primary) 80%, black);
  color: #fff;
}


/* ===========================================================
   単体投稿ページ（single-post）を参考サイトのデザインに寄せる

   対応する子テーマテンプレート: template-parts/post/content.php
   （親テーマ optib/template-parts/post/content.php を上書き）

   方針: 色は固定値を書かず、既存の親テーマ :root トークン
   （--color-text / --color-bg-light / --color-border / --color-primary 等）
   だけを使う。これらはパレット preset（dark / light-blue）ごとに
   値が変わるカスタムプロパティなので、ここで固定色を書かなければ
   ダーク配色・ライト配色のどちらでも自動的に馴染む。
   （実際に有効なパレットは DB オプション optib_child_preset で決まり、
   ファイル側からは固定できないため、両方で破綻しない書き方にしている）
   =========================================================== */

/* 本文幅を参考サイト（with-planning.co.jp/blog/...）の記事本文幅
   798px に合わせる。.l-grid__center-8 は grid-column: 3/11 で
   広めの列を確保するので、その内側でさらに max-width を絞り、
   margin-inline: auto でセンタリングする（サイドバーは元々無い）。

   width: 100% を明示している理由。
   .l-grid__center-8 はグリッドアイテムであり、本来は justify-items の
   既定（stretch）でトラック幅いっぱいに広がるはずだが、実際には
   「タイトルが短い投稿」で中身の内容幅（date badge + タイトル文字数ぶん）
   まで縮んでしまう現象が起きていた（自動最小サイズがトラック幅を下回る
   場合に縮む、Grid のアイテムサイズ決定の既定挙動によるもの）。
   結果、幅が縮んだ上に margin-inline: auto が効いて中央寄せになり、
   本文（.p-post__content 側は文章が長いため縮まない）と左端がズレて
   見えていた。width: 100% を明示して、内容量に関係なく必ずトラック幅
   いっぱいを取るようにし、この縮みを起こさせない。 */
.single-post .optib-child-post-width {
  width: 100%;
  max-width: 798px;
  margin-inline: auto;
}

.single-post .p-post__thumbnail-wrap {
  max-width: calc(798px + var(--container-padding) * 2);
  margin-inline: auto;
  padding-inline: var(--container-padding);
  box-sizing: border-box;
}

/* パンくずの帯。ヘッダーの直下、コンテナ幅いっぱいに敷く薄いグレー。

   出しているのは template-parts/breadcrumb-bar.php で、子テーマの
   page.php / archive.php / index.php / search.php / single.php が
   get_header() の直後で呼んでいる。帯そのものは <section class="l-site-content">
   の外にあり、幅の制約はこの中の .l-container が持つ。

   背景に var(--color-bg-light) を使うのは、ダーク配色がこのトークンを
   すでに差し替えているためである（presets/_shared/palettes/dark/style.css）。
   実値で #f0f0f0 と書くと、ダークのときだけ帯が白く浮く。
   フォールバックの #f0f0f0 は、親テーマの :root が読めない環境向け。

   帯と本文の間隔は、この margin-bottom と .l-site-content の margin-top が
   隣り合って相殺（margin collapsing）した結果になる。大きいほうが残るので、
   .single では 24px、それ以外のテンプレートでは親テーマの 80px が出る。
   足し算にならないので、片方だけを見て詰めれば済む。 */
.optib-child-breadcrumb-bar {
  background: var(--color-bg-light, #f0f0f0);
  padding-block: 10px;
  margin-bottom: 24px;
  color: var(--color-text-muted);
  font-size: 13px;
  line-height: 1.6;
}

/* 単体記事だけ、帯の下の間隔を 24px に詰める。
   親テーマ .l-site-content の margin-top 80px は、ページ見出し帯がある
   テンプレート向けの値である。帯が入った今、単体記事では空きすぎる。
   .single-post ではなく .single にしてあるのは、single.php が投稿タイプを
   問わず使われるため（FluentCart の商品 single-fluent-products など）。
   .single-post に限ると、商品ページだけ 80px のまま残る（実機で確認）。 */
/* 帯の直後に来る .l-site-content の上余白（親は 80px）を 0 にし、
   帯の margin-bottom 24px だけを残す。帯が出ないページ（Elementor の
   テンプレートなど）では親の余白のまま。 */
.optib-child-breadcrumb-bar + .l-site-content {
  margin-top: 0;
}

/* 中身は2通りある。Yoast SEO があれば Yoast の出力（.optib-child-crumbs__yoast、
   中身は素の <a> と区切り文字）、無ければ自前の <ol>（.optib-child-crumbs）。
   どちらも同じ帯に収まるよう、色と字送りは両方に当てる。 */
.optib-child-breadcrumb-bar .optib-child-crumbs__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

.optib-child-breadcrumb-bar .optib-child-crumbs__item {
  display: flex;
  align-items: center;
}

/* 区切りの「>」。文字として持たせず ::before に置くのは、
   読み上げに「大なり」を混ぜないためである。 */
.optib-child-breadcrumb-bar .optib-child-crumbs__item + .optib-child-crumbs__item::before {
  content: ">";
  margin: 0 0.5em;
  color: var(--color-text-muted);
}

/* 家アイコン。画像ファイルを持たず、SVG をマスクにして塗る
   （headers/bar の虫眼鏡と同じ方式）。currentColor ではなく
   var(--color-text-muted) を書いているのは、この ::before が
   <li> の直下にあり、リンクの色（hover で変わる）を継がないためである。 */
.optib-child-breadcrumb-bar .optib-child-crumbs__item--home::before {
  content: "";
  display: inline-block;
  width: 14px;
  height: 14px;
  margin-right: 0.4em;
  flex: none;
  background-color: var(--color-text-muted);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 11l9-8 9 8'/%3E%3Cpath d='M5 10v10h14V10'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 11l9-8 9 8'/%3E%3Cpath d='M5 10v10h14V10'/%3E%3C/svg%3E") center / contain no-repeat;
}

.optib-child-breadcrumb-bar a {
  color: var(--color-text-muted);
  text-decoration: none;
}

.optib-child-breadcrumb-bar a:hover,
.optib-child-breadcrumb-bar a:focus-visible {
  color: var(--color-primary);
  text-decoration: underline;
}

/* 現在地。リンクにしていないので、色と太さで「ここ」だと示す。 */
.optib-child-breadcrumb-bar .optib-child-crumbs__current {
  color: var(--color-text);
  font-weight: 700;
}

/* Yoast の出力。Yoast は <span class="breadcrumb_last"> で現在地を包み、
   区切りは設定した文字をそのまま地の文として出す。
   <p> の余白だけ落として、色は上の a と帯の色をそのまま使う。 */
.optib-child-breadcrumb-bar .optib-child-crumbs__yoast,
.optib-child-breadcrumb-bar .optib-child-crumbs__yoast p {
  margin: 0;
}

.optib-child-breadcrumb-bar .optib-child-crumbs__yoast .breadcrumb_last {
  color: var(--color-text);
  font-weight: 700;
}

/* 見出しエリア全体: 左に日付バッジ、右にカテゴリー行+タイトルの2カラム */
.optib-child-headline-row {
  display: flex;
  align-items: stretch;
  gap: var(--spacing-md);
  margin-bottom: var(--spacing-md);
}

.optib-child-headline-col {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* 日付・カテゴリー・著者を横並びにする上段行（右カラムの中の1行目） */
.optib-child-post-topline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--spacing-sm) var(--spacing-md);
  margin-bottom: var(--spacing-xs);
}

.optib-child-headline-col .p-post__title {
  margin: 0;
}

/* 日付バッジ（月・日・年を3段スタック表示。参考サイトの縦長バッジに合わせ、
   見出しエリアの高さいっぱいに広がる） */
.optib-child-date-badge {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  line-height: 1.15;
  min-width: 4.5em;
  padding: 0.5em 0.75em;
  border-radius: var(--radius-sm, 2px);
  background: var(--color-bg-light);
  border: 1px solid var(--color-border);
  color: var(--color-text);
  flex-shrink: 0;
}

.optib-child-date-badge__m {
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

.optib-child-date-badge__d {
  font-weight: 700;
  font-size: 1.5rem;
}

.optib-child-date-badge__y {
  font-size: 0.6875rem;
  color: var(--color-text-muted);
}

/* カテゴリーピルバッジ（アーカイブ一覧の配色統一に合わせテーマカラーを使用） */
.optib-child-cat-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375em;
  list-style: none;
  margin: 0;
  padding: 0;
}

.optib-child-cat-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 2px;
  background: var(--color-primary);
  color: #fff;
  font-size: 0.75rem;
  text-decoration: none;
  line-height: 1.6;
}

.optib-child-cat-badge:hover {
  background: color-mix(in srgb, var(--color-primary) 80%, black);
  color: #fff;
}

.optib-child-post-author {
  display: inline-flex;
  align-items: center;
  gap: 0.25em;
  font-size: 0.875rem;
  color: var(--color-text-muted);
}

.optib-child-post-author a {
  color: inherit;
}


/* ===========================================================
   ブログサイドバー（blog-sidebar）表示時の調整

   通常（サイドバー無し）は本文を798pxに絞ってセンタリングしているが、
   サイドバーが表示される2カラムレイアウトのときは、l-grid__main の
   幅（親テーマ theme.css で 992px以上は8/12列）にそのまま追従させる。
   798px固定をやめて、幅・センタリングを打ち消す。
   =========================================================== */
.optib-child-single-with-sidebar .optib-child-post-width {
  max-width: none;
  margin-inline: 0;
}

.optib-child-single-with-sidebar .p-post__thumbnail-wrap {
  max-width: none;
  margin-inline: 0;
  padding-inline: 0;
}

/* ブログサイドバーのウィジェット。既存の main-sidebar と見た目を揃える
   （固定色を使わず、既存トークンのみで両パレット対応）。 */
#secondary .widget {
  margin-bottom: var(--spacing-lg);
  padding-bottom: var(--spacing-lg);
  border-bottom: 1px solid var(--color-border);
}

#secondary .widget:last-child {
  border-bottom: none;
}

#secondary .widget-title {
  margin: 0 0 var(--spacing-md);
  font-size: 1rem;
  color: var(--color-text);
}


/* ===========================================================
   main-sidebar が空でも blog-sidebar は独立して機能させる

   inc/frontend.php の optib_child_no_sidebar_class() は main-sidebar の
   空判定だけを見て body に .optib-child-no-sidebar を付け、
   このファイル冒頭の規則で .l-grid__sidebar を display:none にし、
   .l-grid__main を span 12 に強制する。

   single.php（子テーマ版）の2カラム分岐は blog-sidebar というmain-sidebarとは
   別のウィジェットエリアの有無で出し分けているため、main-sidebarが空でも
   blog-sidebarが有効なら表示されなければならない。しかし上記の規則が
   同じ .l-grid__main / .l-grid__sidebar を狙い撃ちしているため、
   何もしなければ .optib-child-no-sidebar 側に潰される。

   詳細度は同じ 0,2,0 なので、このファイルの下方（後勝ち）に置くことで
   打ち消す。.optib-child-single-with-sidebar は single.php が
   blog-sidebar 有効時だけ出すラッパークラスなので、意図せぬ場所には効かない。
   =========================================================== */
.optib-child-single-with-sidebar .l-grid__sidebar {
  display: block;
}

@media (min-width: 992px) {
  .optib-child-single-with-sidebar .l-grid__main {
    grid-column: span 8;
  }

  .optib-child-single-with-sidebar .l-grid__sidebar {
    grid-column: span 4;
  }
}


/* ===========================================================
   サイドバー表示時、本文とアイキャッチの幅を揃える

   content.php 側の見出し・本文は親テーマのクラス .l-grid__center-8
   （中の12列グリッドで grid-column: 3/11 = 8/12列に絞る指定、
   theme.css）を持っている。先に追加した .optib-child-post-width の
   max-width 解除だけでは、この grid-column による絞り込みは消えず、
   l-grid__main（954px前後）の中でさらに8/12へ狭まっていた。
   一方アイキャッチ（.p-post__thumbnail-wrap）は .l-grid__center-8 を
   持たないため全幅のままで、本文とアイキャッチの横幅がズレて見えていた。

   詳細度 0,2,0 で .l-grid__center-8 自身（0,1,0、メディアクエリ内でも
   0,1,0）に確実に勝つため、幅を丸ごと解放する。
   =========================================================== */
.optib-child-single-with-sidebar .l-grid__center-8 {
  grid-column: 1 / -1;
}


/* ===========================================================
   画像ライトボックスの背景を配色（ダーク/ライト）に追従させる

   WordPressコアの画像ブロックのライトボックス機能
   （.wp-lightbox-overlay .scrim）は既定で白固定（background-color:#fff,
   opacity:.9）であり、サイトがダーク配色でも常に白い背景で開いていた。
   var(--color-bg) は親テーマの :root で配色ごとに値が変わる
   （ライト:#fff寄り／ダーク:#16181a寄り）ため、これに差し替えるだけで
   ダーク/ライトどちらでも背景がサイトの配色に自動的に馴染む。
   スクリム自体の不透明度（WP コア側の指定）はそのまま触らない。

   !important が要る理由:
   WordPressコアはこの背景色を外部CSSではなく、要素に直接
   style="background-color: #fff" というインラインstyleとして
   JS（Interactivity API）で付与している。インラインstyleは
   詳細度に関係なく外部CSSの通常規則より常に勝つため、
   !important を付けない限りセレクタをどれだけ強くしても打ち消せない。 */
.wp-lightbox-overlay .scrim {
  background-color: var(--color-bg) !important;
}

/* ===========================================================
   FluentCart の定期課金プランの支払い説明文
   -----------------------------------------------------------
   functions.php の optib_child_fluentcart_subscription_terms() が文を
   組み替えて .optib-child-subscription-terms で包む。文の中に「税込」を
   書いているので、プラグインが直後に付ける接尾辞「（税込み）」は重複する。
   組み替えた文の直後だけ隠す（買い切りや年額の商品では接尾辞を残す）。
   =========================================================== */
.optib-child-subscription-terms + .fct_price_suffix {
  display: none;
}

.optib-child-subscription-terms {
  line-height: 1.7;
}

/* ===========================================================
   単体記事のスマホ表示（767px 以下）
   -----------------------------------------------------------
   実機（390px 幅）で見て直した箇所。数値はすべてその観測から来ている。

   - 見出しエリア: 日付バッジ（72px 幅・見出しの高さいっぱい）が
     タイトル列を 249px まで狭め、タイトルが 7 行になっていた。
     バッジを 1 行の横長チップにしてタイトルの上へ置き、
     タイトルを全幅にする。年月日の順にするため order で並べ替え、
     「年」「日」は ::after で足す（「月」はテンプレートが出している）。
   - パンくず: 記事タイトルまで含むため 3 行に折り返していた。
     1 行に固定して末尾を省略する。ホーム » までは常に読める。
   - 上の余白: 親テーマ .l-site-content の margin-top 48px を
     ヘッダー直下で半分にする。
   - アイキャッチ: .p-post__thumbnail-wrap の padding-inline が
     コンテナの余白と二重になり、本文より両側 26px ずつ狭かった。
   - 会話ブロック（親テーマの wp-block-optib-conversation）:
     アバター列が 120px 固定で、337px の本文幅の 3 分の 1 を取り、
     吹き出しが 1 行 8 文字程度になっていた。64px に縮める。
   =========================================================== */
@media (max-width: 767.98px) {
  /* パンくずの帯は1行に収め、あふれたら横に流す。
     折り返すと帯の高さが2倍になり、深い階層のページだけ
     ヘッダーの下が分厚くなる。省略記号で切ると、
     現在地（いちばん右）が真っ先に読めなくなる。
     横スクロールなら、指で辿れば全部たどり着ける。 */
  .optib-child-breadcrumb-bar {
    margin-bottom: 16px;
    font-size: 12px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  .optib-child-breadcrumb-bar .optib-child-crumbs__list,
  .optib-child-breadcrumb-bar .optib-child-crumbs__yoast {
    flex-wrap: nowrap;
    white-space: nowrap;
  }

  .optib-child-headline-row {
    flex-direction: column;
    align-items: stretch;
    gap: var(--spacing-sm, 12px);
    margin-bottom: 0;
  }

  .optib-child-date-badge {
    flex-direction: row;
    align-items: baseline;
    gap: 0.3em;
    align-self: flex-start;
    min-width: 0;
    padding: 0.3em 0.7em;
    line-height: 1.2;
    font-size: 0.8125rem;
  }

  .optib-child-date-badge__y {
    order: 1;
    font-size: inherit;
    color: var(--color-text);
  }

  .optib-child-date-badge__y::after {
    content: "年";
  }

  .optib-child-date-badge__m {
    order: 2;
    font-size: inherit;
    color: var(--color-text);
  }

  .optib-child-date-badge__d {
    order: 3;
    font-size: inherit;
    font-weight: 600;
  }

  .optib-child-date-badge__d::after {
    content: "日";
  }

  .optib-child-headline-col .p-post__title {
    font-size: 1.375rem;
    line-height: 1.45;
  }

  .single-post .p-post__thumbnail-wrap {
    padding-inline: 0;
  }

  .wp-block-optib-conversation .wew-conversation-avatar {
    width: 64px;
    flex-basis: 64px;
  }

  .wp-block-optib-conversation .wew-conversation-avatar img {
    width: 48px;
    height: 48px;
  }

  .wp-block-optib-conversation .wew-conversation-participant-name {
    font-size: 0.6875rem;
  }
}

/* ヘッダーの追従を止める。
 *
 * 親テーマの .l-header は素で position: sticky; top: 0 を持っており
 * （親 assets/css/src/flocss/layout/_l-header.css）、管理バーが出ている
 * ときは top をその高さに差し替えている。だから既定は「追従する」で、
 * ここで打ち消すのは「追従しない」を選んだときだけである。
 *
 * position を static に戻せば top も z-index も効かなくなるので、
 * 親の admin-bar 用の指定を1つずつ打ち消す必要はない。
 * 1行で済むぶん、親が top の値を変えてもここは追随しなくてよい。
 *
 * 詳細度: 要素 body が 1、クラスが .optib-child-header-sticky-off と
 * .l-header で 2、計 0-2-1。親の .l-header（0-1-0）に勝つ。
 * 共有部品を作らず子テーマの style.css に置いてあるのは、
 * この規則がヘッダーのデザイン（theme / bar）のどちらでも同じだけ効き、
 * どの共有部品にも属さないためである。 */
body.optib-child-header-sticky-off .l-header {
  position: static;
}

/* ===========================================================
   ヘッダーの色（親のまま／バー型 共通）

   ここにあるのは「濃い帯の上に白い文字を置く」ための色だけである。
   高さ・ロゴの寸法・1行化・スマホの右ドロワーといった「形」は、
   バー型のときだけ効かせたいので共有部品
   （presets/_shared/headers/bar/style.css）に残してある。

   なぜ子テーマの style.css に置くのか。
   共有部品 headers/bar は、外観設定のヘッダーが「バー型」のときしか
   読み込まれない。色をあちらに置いたままでは「親テーマのまま」
   （body.optib-header-theme）に届かない。この style.css は
   どちらを選んでいても読まれるので、色はこちらへ移した。

   セレクタの起点は body:is(.optib-headers-bar, .optib-header-theme) である。
   .optib-headers-bar は共有部品が読まれていることを表すクラス、
   .optib-header-theme は設定そのものを表すクラスで、
   どちらも inc/frontend.php が body に付けている。

   詳細度は body（要素1）＋ :is の中の最大（クラス1）で、
   移す前の .optib-headers-bar（クラス1）より 1 段高い。
   この style.css は共有部品より前に読まれるので、高くしておかないと
   同じ宣言を持つ規則があったときに負ける。いまは形と色で
   宣言が重ならないようにしてあるが、詳細度の側でも安全側に倒してある。

   帯の色は var(--color-primary) を使い、実値を書かない。
   親テーマの :root が --color-primary: var(--primary-color, #384d7a) と
   定義しており、--primary-color はカスタマイザーの「メインカラー」を
   PHP がインラインで注入している。この1本に乗せておくだけで、
   OptiB の一般設定を変えたときにヘッダーの帯もそのまま追随する。

   帯の上に乗る文字は #fff 固定である。主色は濃色である前提を置いている。
   明るい主色を選ぶと読みにくくなるが、そこを color-mix で自動調整すると
   「主色をそのまま出す」という狙いが崩れる。
   =========================================================== */

/* 帯そのもの。
   親の .l-header は background-color: var(--color-bg) と
   border-bottom: 1px solid var(--color-border) を持つ。
   帯にすると下線は帯の中に埋もれて濁るだけなので消す。 */
body:is(.optib-headers-bar, .optib-header-theme) .l-header {
  background-color: var(--color-primary);
  border-bottom: 0;
  color: #fff;
}

/* ロゴ画像が未設定のとき、親テーマはサイト名とキャッチフレーズを出す。
   .l-header__brand-link と .l-header__phrase は親テーマのどの CSS にも
   定義が無く（クラス名があるだけ）、素のリンクとして出ている。
   バー型ではキャッチを消すが（共有部品側）、親のままでは残るので、
   両方に白を当てる。 */
body:is(.optib-headers-bar, .optib-header-theme) .l-header__brand-link,
body:is(.optib-headers-bar, .optib-header-theme) .l-header__phrase {
  color: #fff;
}

/* メニューの項目。親の .c-nav__link は色 var(--color-text-dark)。 */
body:is(.optib-headers-bar, .optib-header-theme) .l-header__nav .c-nav__link {
  color: #fff;
}

/* hover は色を変えず不透明度で落とす。
   親は :hover で var(--color-primary) にするが、帯そのものが
   その色なので、ホバーした項目が帯に溶けて消える。
   フォーカスにも同じものを当てる。キーボードで辿るときに
   「いまどこにいるか」が見えないと、1行の帯では位置を見失う。 */
body:is(.optib-headers-bar, .optib-header-theme) .l-header__nav .c-nav__link:hover,
body:is(.optib-headers-bar, .optib-header-theme) .l-header__nav .c-nav__link:focus-visible {
  color: #fff;
  opacity: 0.75;
}

/* 子メニューを持つ項目の下向き三角。
   親は border-top: 4px solid currentColor で描いており、
   currentColor は上で白にしてあるので、実は何もしなくても白くなる。
   それでも書いてあるのは、この矢印が .c-nav__link ではなく
   ::after 側にあり、色の出どころが一目で追えないためである。 */
body:is(.optib-headers-bar, .optib-header-theme) .l-header__nav .c-nav__item.has-children > .c-nav__link::after {
  border-top-color: #fff;
}

/* ドロップダウン（子メニュー）。
   実際に付くクラスは "sub-menu c-dropdown__menu" で、
   親テーマの functions.php の nav_menu_submenu_css_class フィルタが
   既定の sub-menu に c-dropdown__menu を足している。

   ドロップダウンは帯の外に落ちる白い箱なので、帯の白文字が
   そのまま降りてくると白地に白で読めなくなる。ここで戻す。
   リンクを a で受けているのは、子の <a> に .c-nav__link と
   .c-dropdown__link のどちらが付くかが階層で変わるためで、
   どちらでも同じ1規則で当てたい。 */
body:is(.optib-headers-bar, .optib-header-theme) .l-header__nav .c-dropdown__menu {
  background-color: #fff;
}

body:is(.optib-headers-bar, .optib-header-theme) .l-header__nav .c-dropdown__menu a {
  color: var(--color-text);
  opacity: 1;
}

body:is(.optib-headers-bar, .optib-header-theme) .l-header__nav .c-dropdown__menu a:hover,
body:is(.optib-headers-bar, .optib-header-theme) .l-header__nav .c-dropdown__menu a:focus-visible {
  color: var(--color-primary);
  opacity: 1;
}

/* 検索ボタン。親は色 var(--color-text-dark)、hover で var(--color-primary)。
   メニューと同じ理由で、hover は色ではなく不透明度で落とす。 */
body:is(.optib-headers-bar, .optib-header-theme) .p-search__btn {
  color: #fff;
}

body:is(.optib-headers-bar, .optib-header-theme) .p-search__btn:hover,
body:is(.optib-headers-bar, .optib-header-theme) .p-search__btn:focus-visible {
  color: #fff;
  opacity: 0.75;
}

/* 検索オーバーレイ。
   親は「ヘッダーいっぱいに白い帯を被せ、素の input を置く」だけで、
   濃い帯の上に白い帯が唐突に現れ、プレースホルダーが左端で切れて見えていた。
   帯の色はそのまま（メインカラー）に保ち、その中に丸い白の入力欄を置く。
   左に虫眼鏡、右に閉じるボタン。入力欄の最大幅を絞って中央に寄せる。

   ここは形と色が分けられない。丸い白の入力欄という「形」が、
   帯を濃い色にしたことの結果だからである。まとめてこちらに置く。 */
body:is(.optib-headers-bar, .optib-header-theme) .p-search__overlay {
  gap: 12px;
  padding: 6px 0;
  background-color: var(--color-primary);
}

body:is(.optib-headers-bar, .optib-header-theme) .p-search__form {
  position: relative;
  flex: 1;
  max-width: 640px;
  margin: 0 auto;
}

/* 虫眼鏡。画像ファイルを持たず、SVG をマスクにして background-color で塗る。
   白い入力欄の中に置くので、帯の白ではなくグレー（#8a8a8a）にする。 */
body:is(.optib-headers-bar, .optib-header-theme) .p-search__form::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 14px;
  width: 18px;
  height: 18px;
  transform: translateY(-50%);
  background-color: #8a8a8a;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5'/%3E%3C/svg%3E") center / contain no-repeat;
  pointer-events: none;
}

body:is(.optib-headers-bar, .optib-header-theme) .p-search__input {
  height: 40px;
  padding: 0 16px 0 42px;
  font-size: 15px;
  color: var(--color-text, #333);
  background-color: #fff;
  border: 0;
  border-radius: 999px;
  box-sizing: border-box;
}

body:is(.optib-headers-bar, .optib-header-theme) .p-search__input:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.35);
}

body:is(.optib-headers-bar, .optib-header-theme) .p-search__input::placeholder {
  color: #8a8a8a;
}

body:is(.optib-headers-bar, .optib-header-theme) .p-search__close {
  color: #fff;
  opacity: 0.85;
}

body:is(.optib-headers-bar, .optib-header-theme) .p-search__close:hover,
body:is(.optib-headers-bar, .optib-header-theme) .p-search__close:focus-visible {
  color: #fff;
  opacity: 1;
}

/* スマホ幅。境は親テーマに合わせて 991px。 */
@media (max-width: 991px) {
  /* ハンバーガー。線は background-color: currentColor で描かれているので、
     ボタンの色を変えれば3本とも白になる。 */
  body:is(.optib-headers-bar, .optib-header-theme) .l-header__toggle {
    color: #fff;
  }

  /* 開いたメニューの面。帯より一段濃くする。
     帯と同じ色にすると、境目が消えて1枚の面に見える。
     color-mix で主色から派生させてあるので、
     一般設定でメインカラーを変えてもここだけ取り残されない。 */
  body:is(.optib-headers-bar, .optib-header-theme) .l-header__mobile-nav {
    background-color: color-mix(in srgb, var(--color-primary) 85%, #000);
    border-bottom: 0;
  }

  /* 区切り線の色。0.15 ではなく 0.12 なのは、移す前のバー型が
     実際に描いていた値がこちらだったからである（同じ詳細度の2規則が
     あって、後に書かれたドロワー側の 0.12 が勝っていた）。
     見た目を変えないほうを採った。 */
  body:is(.optib-headers-bar, .optib-header-theme) .c-nav--mobile .c-nav__link {
    color: #fff;
    border-bottom-color: rgba(255, 255, 255, 0.12);
  }

  body:is(.optib-headers-bar, .optib-header-theme) .c-nav--mobile .c-nav__link:hover,
  body:is(.optib-headers-bar, .optib-header-theme) .c-nav--mobile .c-nav__link:focus-visible {
    color: #fff;
    opacity: 0.75;
  }

  body:is(.optib-headers-bar, .optib-header-theme) .c-nav--mobile .c-nav__item.has-children > .c-nav__link::after {
    border-top-color: rgba(255, 255, 255, 0.7);
  }

  /* 子メニューは閉じた状態が既定。親テーマの JS がスマホではタップで
     li.c-dropdown に is-open を付け外しするので、それに合わせて開く。

     開閉そのものは「形」に見えるが、ここに置いてある。
     親は PC 用のドロップダウン（白地・濃い文字）をスマホの子メニューにも
     そのまま当てるため、濃い面の中に薄いグレーの箱が出て白文字が消える。
     この打ち消しは帯を濃い色にした側の責任で、
     バー型か親のままかに関わらず要る。 */
  body:is(.optib-headers-bar, .optib-header-theme) .c-nav--mobile .c-dropdown__menu {
    position: static;
    display: none;
    margin: 0 12px 8px;
    padding: 4px 0;
    background-color: rgba(255, 255, 255, 0.08);
    border: 0;
    border-radius: 8px;
    box-shadow: none;
  }

  body:is(.optib-headers-bar, .optib-header-theme) .c-nav--mobile .c-dropdown__menu a {
    display: block;
    padding: 12px 20px 12px 28px;
    color: rgba(255, 255, 255, 0.9);
    font-size: 14px;
    font-weight: 500;
    border-bottom: 0;
    opacity: 1;
  }

  body:is(.optib-headers-bar, .optib-header-theme) .c-nav--mobile .c-dropdown__menu a:hover,
  body:is(.optib-headers-bar, .optib-header-theme) .c-nav--mobile .c-dropdown__menu a:focus-visible {
    color: #fff;
    background-color: rgba(255, 255, 255, 0.08);
    opacity: 1;
  }

  body:is(.optib-headers-bar, .optib-header-theme) .c-nav--mobile .c-dropdown.is-open > .c-dropdown__menu {
    display: block;
  }

  /* 開いている親項目の矢印は上向きにして、閉じられることを示す。 */
  body:is(.optib-headers-bar, .optib-header-theme) .c-nav--mobile .c-dropdown.is-open > .c-nav__link .ti-angle-down,
  body:is(.optib-headers-bar, .optib-header-theme) .c-nav--mobile .c-dropdown.is-open > a .ti-angle-down {
    display: inline-block;
    transform: rotate(180deg);
  }

  /* 孫メニューは、さらに一段だけ内側へ。 */
  body:is(.optib-headers-bar, .optib-header-theme) .c-nav--mobile .c-dropdown__menu .c-dropdown__menu {
    margin: 0 8px 4px;
    background-color: rgba(255, 255, 255, 0.06);
  }
}

/* ダーク配色のときは帯を黒にする。
   ダークパレットはメインカラーを明るい青に差し替えるため、帯全体が
   青くなって暗い画面から浮いていた（実機で確認）。ダークでは帯を #111、
   ドロワーと検索の帯もそれに合わせる。メインカラーはリンクやボタンに残る。
   フッターのサイトマップも同じ扱いにしてあり
   （presets/_shared/footers/sitemap/style.css）、上下で黒に揃う。 */
body.optib-palettes-dark:is(.optib-headers-bar, .optib-header-theme) .l-header,
body.optib-palettes-dark:is(.optib-headers-bar, .optib-header-theme) .p-search__overlay {
  background-color: #111;
}

@media (max-width: 991px) {
  body.optib-palettes-dark:is(.optib-headers-bar, .optib-header-theme) .l-header__mobile-nav {
    background-color: #000;
  }
}
