/*
 * AdvantageSearch 追加スタイル。
 *
 * futureshop の「アイテム」へアップロードして配信する。
 *   アップロード先: /item/assets/css/as.css
 *   配信URL:       https://wako.itembox.cloud/item/assets/css/as.css
 * 読み込みは html/original-css.css（futureshopの「オリジナルCSS」へ登録）から
 * アイテム置換文字 {% items[/assets/css/as.css] %} で行う。
 * 置換文字経由なら ?t=<更新日時> が futureshop 側で自動付与される。
 *
 * 独自の状態・操作部品だけを as- 接頭辞で定義する。
 * 商品カードと検索結果本文はメンバーズ納品の c-* DOM/CSSへ合わせる。
 * 色・余白・フォント等の最終的な視覚仕様はワイヤーフレーム／Figma を正とする。
 */
  /* ============ 絞り込みボタン ============ */
  .as-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0 20px;
    border: 1px solid #222;
    background: #fff;
    color: #222;
    font-size: 13px;
    letter-spacing: .04em;
    cursor: pointer;
  }
  .as-btn:hover { background: #222; color: #fff; }

  /* ============ 入力内容を消す「削除」 ============
     メンバーズのマークアップには無いのでこちらで作る。
     `.p-search-input` は先方の指定で `display: flex; align-items: center` なので、
     最後の子として置き `margin-left: auto` で右端へ寄せる。
     **幅を持たせない。** 入力欄（`.p-search-input__text`）の伸縮に影響させない。
     文字の大きさ・太さは先方の `u-text u-font--R` に任せる。 */
  .as-search-clear {
    flex: 0 0 auto;
    margin-left: 16px;
    padding: 0;
    border: 0;
    background: transparent;
    color: #212121;
    font-family: inherit;
    white-space: nowrap;
    cursor: pointer;
  }
  /* 入力欄が伸びる形（検索結果ページ）でも右端に付ける */
  .p-search-input .as-search-clear { margin-left: auto; }
  /* `display` を持たせていないので hidden は効くが、
     先方の CSS が `button { display: … }` を当てた場合の保険 */
  .as-search-clear[hidden] { display: none; }

  /* ============ 検索候補パネル ============
     既存の検索エリア（.l-header__search / .l-footer__search）の中に差し込む。
     入力中は futureshop 側の「注目のワード」を隠してこちらを見せる。 */
  .as-suggest {
    max-height: min(70vh, 640px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 8px 0 16px;
  }
  .as-suggest__section + .as-suggest__section { margin-top: 20px; }
  .as-suggest__heading {
    margin: 0 0 8px;
    font-size: 11px;
    font-weight: 400;
    letter-spacing: .1em;
    color: #999;
  }
  .as-suggest__loading,
  .as-suggest__empty {
    margin: 0;
    padding: 8px 0;
    font-size: 12px;
    color: #999;
  }

  /* ---- キーワード候補・履歴 ---- */
  .as-suggest__list { list-style: none; margin: 0; padding: 0; }
  .as-suggest__button {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 44px;
    padding: 0 4px;
    border: 0;
    background: transparent;
    font-size: 14px;
    text-align: left;
    cursor: pointer;
  }
  .as-suggest__button:hover,
  .as-suggest__button.is-active { background: #f5f5f5; }
  .as-suggest__icon {
    flex: 0 0 auto;
    width: 14px;
    height: 14px;
    border: 1px solid #999;
    border-radius: 50%;
    position: relative;
  }
  .as-suggest__icon::after {
    content: "";
    position: absolute;
    right: -4px;
    bottom: -2px;
    width: 6px;
    height: 1px;
    background: #999;
    transform: rotate(45deg);
  }
  /* 履歴は時計アイコン風に区別する */
  .as-suggest__item--history .as-suggest__icon::after {
    right: auto;
    bottom: auto;
    top: 2px;
    left: 5px;
    width: 1px;
    height: 5px;
    transform: none;
  }
  .as-suggest__text { flex: 1; }
  /* ---- 商品候補 ----
     クラス構成はメンバーズ（MEM）納品の `c-product-list` に準拠。
     マークアップはフリーパーツの as-tpl-suggest-product を clone して作る。
     MEM 側の CSS が入ったら、このブロックは削るか上書きされる想定。 */
  .as-suggest .c-product-list {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px 12px;
    list-style: none;
    margin: 0;
    padding: 0;
  }
  .as-suggest .c-product-list__link { display: block; text-decoration: none; color: inherit; }
  .as-suggest .c-product-list__img-wrapper img {
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    background: #f4f4f4;
  }
  .as-suggest .c-product-list__info { margin-top: 6px; }
  .as-suggest .c-product-list__name {
    font-size: 12px;
    line-height: 1.5;
    /* 2 行で省略 */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
  }
  .as-suggest .c-product-list__price-box { margin-top: 2px; font-size: 12px; }
  .as-suggest .c-product-list__status { margin-left: 6px; font-size: 11px; color: #999; }
  .as-suggest .c-product-list__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 4px;
    font-size: 10px;
    color: #666;
  }

  .as-suggest__seeAll {
    display: block;
    width: 100%;
    min-height: 44px;
    margin-top: 16px;
    border: 1px solid #222;
    background: #fff;
    font-size: 13px;
    letter-spacing: .04em;
    cursor: pointer;
  }
  .as-suggest__seeAll:hover { background: #222; color: #fff; }

  @media screen and (max-width: 767px) {
    .as-suggest { max-height: min(60vh, 480px); }
    .as-suggest .c-product-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }

  /* ============ 一覧の共通操作部品 ============ */
  .as-btn--filter,
  .as-sort__button {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border: 0;
    background: transparent;
    color: #111;
    font-size: 13px;
    letter-spacing: .04em;
    cursor: pointer;
  }
  .as-btn--filter:hover,
  .as-sort__button:hover { color: #666; }
  .as-btn__text { white-space: nowrap; }

  /* 絞り込みと並び替えの間の区切り線 */
  .as-sort {
    margin-left: 16px;
    padding-left: 16px;
    border-left: 1px solid #ddd;
  }

  /* 選択中の並び順は開いたメニューの中で示すので、ボタンには出さない */
  .as-sort__current { display: none; }

  .as-sort__menu {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    z-index: 20;
    min-width: 200px;
    padding: 8px 0;
    border-radius: 10px;
    background: #fff;
    box-shadow: 0 4px 20px rgba(0, 0, 0, .16);
  }
  .as-sort__menu[hidden] { display: none; }
  .as-sort__menuTitle {
    margin: 0;
    padding: 8px 20px;
    color: #aaa;
    font-size: 14px;
    font-weight: 400;
  }
  .as-sort__list { list-style: none; margin: 0; padding: 0; }
  .as-sort__option {
    display: block;
    width: 100%;
    padding: 10px 20px;
    border: 0;
    background: transparent;
    color: #111;
    font-size: 14px;
    text-align: left;
    white-space: nowrap;
    cursor: pointer;
  }
  .as-sort__option:hover { background: #f5f5f5; }
  .as-sort__option.is-selected { background: #f0f0f0; }

  .as-pager { padding: 24px 0; }
  .as-pager .fs-c-pagination { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }

  @media screen and (max-width: 767px) {
    .as-btn--filter,
    .as-sort__button { padding: 8px 4px; }
    .as-sort { margin-left: 12px; padding-left: 12px; }
  }

  /* ============ 0 件ヒット再検索の案内 ============ */
  .as-searchNotice { margin: 24px 32px 0; font-size: 12px; color: #666; }

  /* ============ メンバーズ CSS に無い分の補い ============
     検索結果ページの CSS はメンバーズがページに同梱している（実測: インライン
     <style> 17,109 字）。使っているクラス 36 個のうち 33 個は先方にあり、
     **こちらが持つ必要があるのは下の 3 つだけ。** */
  /* 先方のカード見出しは class を持たない `<h3 class="u-h4 u-font--B">`。
     こちらは `c-card__title` を足しているので、余白はこちらで打ち消す。 */
  .c-tab-content .c-card__title { margin: 0; }
  /* 0 件表示の「もしかして」の見出し。
     先方のマークアップにはあるが CSS の指定が無い。 */
  .c-suggestion__heading { margin: 0 0 12px; }
  /* **0 件表示の出し入れ。**
     先方の検索結果ページ CSS は `.c-no-result { display: none }` が既定で、
     JS が出す前提のマークアップ。属性は src/as.setting-render.js が付ける。
     `[data-as-list] .c-no-result` のように無条件で block にすると、
     結果があるときも 0 件表示が居座る（実測で踏んだ）。 */
  [data-as-list] .c-no-result[data-as-zero] { display: block; }
  /* **`c-no-result__main`（おすすめのアイテム）は出さない**（和光様回答でトルツメ）。
     先方 CSS が左カラムに 34.7% を当てているので、そのままだと
     右に 65.3% の空白ができる。 */
  .c-no-result__sidebar:only-child { width: 100%; }

  /* ============ お知らせ・FAQ の矢印 ============
     カテゴリナビの次へ矢印（`.c-product-category-nav__arrow--next::before`、
     先方 CSS）と同じ Material Icons の chevron_right（\e5cc）を使う。
     テンプレートの `c-card__arrow` は空にし、先方 CSS の文字指定（20px・太字）は
     疑似要素側で上書きする。 */
  .as-card-arrow::before {
    display: block;
    font-family: "Material Icons"; content: "\e5cc";
    font-size: 24px; font-weight: 400; line-height: 1; color: #212121;
  }

  /* ============ エラー ============ */
  .as-error { padding: 48px 0; text-align: center; }
  .as-error__text { margin: 0 0 16px; color: #c0392b; font-size: 14px; }
  /* 「再試行」と「条件をリセットして表示」が並ぶ。SP では縦に折り返す */
  .as-error__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px 16px;
  }

  /* ============ 検索中の一覧（スケルトン） ============
     実カードと同じ list item にすることで、メンバーズ CSS のグリッドと画像領域を
     そのまま使う。初回検索中と、条件変更（絞り込み・並び替え・ページ送り）の応答が
     遅いときに出る。 */
  .as-productSkeleton { pointer-events: none; }
  .as-productSkeleton__image,
  .as-productSkeleton__line {
    display: block;
    background: linear-gradient(90deg, #f1f1f1 25%, #e7e7e7 37%, #f1f1f1 63%);
    background-size: 400% 100%;
    animation: as-skeleton-shimmer 1.4s ease infinite;
  }
  /* 先方の CSS が `li.c-product-list__item` へ `align-items: center` を当てており、
     幅を持たない子は中身の幅（0）に縮む。そのままだと画像も線も 0 幅で何も見えない。 */
  .as-productSkeleton__image,
  .as-productSkeleton__body { align-self: stretch; }
  /* 高さは実物のカードに合わせる。
     画像は幅の 4/3（3:4 固定。`[data-as-root] .c-product-list__img-wrapper img` と同じ）。
     商品情報は商品ごとに 94〜159px で変わるので、よくある値で固定する
     （商品名 1〜2 行 + 価格 + タグ。余白 16 / 16 / 24px、行間 12px は実物と同じ）。
     先方の文字サイズは 1024px を境に変わる（12px → 14px）。

       1024px 以上 … 商品名 21 + 価格 21 + タグ 26 → 132px
       1023px 以下 … 商品名 36 + 価格 18 + タグ 23 → 141px

     線は 14px で、行の高さとの差を上下の余白（`padding`）で持たせる。 */
  .as-productSkeleton__image { aspect-ratio: 3 / 4; }
  .as-productSkeleton__body {
    display: flex;
    flex-direction: column;
    gap: 12px;
    box-sizing: border-box;
    height: 141px;
    padding: 16px 16px 24px;
  }
  .as-productSkeleton__line {
    box-sizing: content-box;
    height: 14px;
    background-clip: content-box;
  }
  .as-productSkeleton__line--title { width: 82%; padding: 11px 0; }
  .as-productSkeleton__line--price { width: 42%; padding: 2px 0; }
  .as-productSkeleton__line--tags { width: 36%; padding: 4.5px 0; }
  @media screen and (min-width: 1024px) {
    .as-productSkeleton__body { height: 132px; }
    .as-productSkeleton__line--title { padding: 3.5px 0; }
    .as-productSkeleton__line--price { padding: 3.5px 0; }
    .as-productSkeleton__line--tags { padding: 6px 0; }
  }
  @keyframes as-skeleton-shimmer {
    0% { background-position: 100% 0; }
    100% { background-position: 0 0; }
  }
  @media (prefers-reduced-motion: reduce) {
    .as-productSkeleton__image,
    .as-productSkeleton__line { animation: none; }
  }

  /* ============ カテゴリトップで一覧領域を出す ============
     サイト側 CSS はカテゴリトップ（cat1 のページ）で `.l-pl-page__body` を
     display:none にしており、ヒーローと「商品を見る」だけを見せる作りになっている。
     新デザインではカテゴリトップにも一覧を出すため解除する。

     `data-as-list="category"` は AS がそのページの一覧を引き受けたときだけ付く。
     AS が動かないページ（対象外カテゴリ・JS エラー時）は元のまま隠れる。

     サイト側が `!important` で隠しているため、こちらも `!important` が要る（実測）。 */
  [data-as-list='category'] .l-pl-page__body { display: block !important; }

  /* ============ hidden 属性を効かせる ============
     **`hidden` だけでは消えない。** 先方の CSS がこれらへ `display: flex` を
     当てており、作者スタイルが UA スタイル（`[hidden] { display: none }`）に勝つ。

     実測で踏んだもの:
       - ツールバー       … 0 件のとき「968件中1-60件表示」（静的の値）が残った
       - さらに表示ボタン … 0 件のときも残った

     属性はいずれも JS 側が付ける（`render-search-page` / `render-list-page` 区画）。
     先方の指定（詳細度 0,1,0）に勝つよう、属性セレクタを重ねている。 */
  [data-as-list] .c-product-toolbar[hidden],
  [data-as-list] .c-product-list__more-btn[hidden],
  [data-as-list] .c-tab__item[hidden] { display: none !important; }

  /* 既定の並び（絞り込み・並び替えなし、1 ページ目）だけに出す編集コンテンツ
     （`PRISTINE_ONLY`）。2 ページ目以降・絞り込み中は JS が `hidden` を付けるが、
     先方の CSS が `display: flex` / `block` を当てているため、そのままでは
     一覧の下にバナー・ピックアップ・特集が残る（実測: バッグ・革小物の 2 ページ目）。 */
  [data-as-list] .c-product-pickup-banner[hidden],
  [data-as-list] .c-product-ranking[hidden],
  [data-as-list] .c-product-pickup-section[hidden],
  [data-as-list] .c-product-feature[hidden],
  [data-as-list] .c-store-brands[hidden] { display: none !important; }

  /* 差し込み先そのものが隠されている場合に解除する。
     メンバーズの商品一覧ページ用 CSS（as/product-group/style.css）が

       #fs-page-error-container, .fs-c-subgroup, .fs-c-productList {
         display: none !important;
       }

     で futureshop 標準の一覧を丸ごと隠している。メンバーズDOMを検出できない
     カテゴリページでは `.fs-c-productList` をフォールバック描画先にするため解除する。

     `[data-as-root]` は **AS が実際に引き受けた要素にだけ** 付く属性なので、
     この解除は AS が動いたときにしか効かない。検索結果ページは先方の
     `ul.c-product-list` へ描くので、この指定の対象外。 */
  .fs-c-productList[data-as-root] { display: block !important; }

  /* ============ 引き受けなかったページで標準の一覧を戻す ============
     上と同じメンバーズの指定が、**AS が動かないページでも効いたままになる。**
     辞書に無いカテゴリ（キャンペーン用など実測で 1,200 URL 超）や
     起動に失敗したページは、一覧が空白のまま何も出ない。
     AS を入れる前は普通に表示できていたページなので、標準の表示へ戻す。

     `data-as-fallback` は `markUnsupportedListPage()` が
     futureshop の一覧ページ（`fs_ProductCategory` / `fs_ProductSearch`）で
     引き受けを断ったときだけ付ける。

     `!important` と、メンバーズの指定（詳細度 0,1,0）より高い詳細度の両方が要る。
     先方の CSS はこちらより後に読まれるため、同じ詳細度では負ける（実測）。

     **恒久対応は先方に隠す条件を絞ってもらうこと。** ここでの解除は
     JS が動いた場合にしか効かず、バンドルの読み込みが失敗すると空白のままになる。
     依頼内容は deliver の README「フリーパーツの棚卸し」に載せている。 */
  [data-as-fallback] .fs-c-productList,
  [data-as-fallback] .fs-c-subgroup { display: block !important; }

  /* ============ 検索窓マークアップとのレイアウト調整 ============
     `data-as-new-header` は `.l-header__overflow` を見て JS が付ける。

     検索窓側の CSS を更新したときは、これらの補正が必要か、
     同じ指定が重複していないか確認する。

     1. `.p-search` が `display: flex` になったため、候補パネルを子として足すと
        横並びに入ってしまう（実測で入力欄の 504px 上に出た）。重ねて出す。
     2. 静的な絞り込みパネルが同じ中に入っている。選択肢は AS のデータから作るので
        使わない。**我々のパネルは body 直下なので、この指定では消えない。** */
  /* 候補パネルを重ねて出す指定は本文の検索バーと共通。下方にまとめてある。 */
  /* 検索窓パーツの中に入っているメンバーズ側の絞り込みパネルを隠す。
     本来は search-box-keyword_stg-as から search-filter-* の呼び出しを
     外してもらう話（deliver の README「0. フリーパーツの棚卸し」）。
     外してもらえるまでの保険で、外れた後もこの指定は無害なので残す。 */
  [data-as-new-header] .l-header__search .p-filter--container { display: none; }


  /* ============ 候補パネルを重ねて出す ============
     ヘッダー検索の中に候補パネルを足すと、次の 2 つの理由でそのままでは出せない。

       1. `.p-search` が `display: flex`（新マークアップ）なので横並びに入る
          （実測で入力欄の 504px 上に出た）
       2. 通常フローに入っているとヘッダーの高さを押し広げ、
          入力するたびに一覧が下へずれる

     どちらも「重ねて出す」で解決するため、ヘッダーの検索窓
     （data-as-new-header）と、検索結果ページ本文の検索バー
     （`.fs-l-main > .p-search`）で指定を共有する。 */
  /* サイト側が `overflow-y: auto` を当てており、絶対配置した候補パネルが
     スクロールボックスに切られて見えなくなるため戻す。

     打ち消す相手は 2 つある。新マークアップでは `.l-header__overflow`
     （`height: 100%; overflow-y: auto`）が入力欄の直近の祖先で、
     実測でこれが唯一のクリップ元だった（高さ 128px の中に候補パネルが入らない）。

     **`overflow-y` だけを戻せば足りる。** CSS の規則で、片方の軸が
     `visible` 以外だともう片方の `visible` は `auto` に計算されるため、
     相手が `overflow-x` を書いていない状態では `overflow-y` を戻すと
     両軸とも `visible` に戻る（実測で確認）。
     `overflow: visible` と書くと、相手が後から横方向のクリップを
     入れた場合にそれも消してしまうので広げない。 */
  [data-as-new-header] .l-header__search .p-search,
  [data-as-new-header] .l-header__search .l-header__overflow {
    overflow-y: visible;
  }
  /* **`.p-search` に position を足さない。** メンバーズの既存レイアウトが崩れる。
     候補パネルの基準は `positionPanel()` が `offsetParent` を実測して
     `--as-suggest-top` に入れるので、どの祖先が基準になっても位置は合う。
     実測: relative あり → 基準 .p-search / 無し → 基準 .l-header__search、
     どちらも入力欄の 19px 下に出る（無しの方が幅が広く、検索エリアに揃う）。 */
  /* 候補パネルの商品カード。
     メンバーズの一覧用 CSS が `li.c-product-list__item { width: calc(25% - 1px) }` を
     当てており、そのままだと狭い候補パネルの中で 1/4 幅（実測 114px）に潰れる。
     パネル側は grid で列数を決めているので、幅の指定を打ち消す（実測 270px の 2 列）。 */
  .as-suggest .c-product-list__item { width: auto; }

  /* 本文の検索バー（検索結果ページ）も同じ出し方にする。
     メンバーズが `.p-search { position: relative; overflow-y: initial }` を
     当てているので、包含ブロックもクリップの解除もそのまま使える。 */
  [data-as-new-header] .l-header__search .as-suggest,
  .fs-l-main > .p-search .as-suggest {
    position: absolute;
    /* --as-suggest-top は入力欄の行の下端を実測して JS が入れる。
       .p-search の下 padding（40px）に引きずられないようにするため */
    top: var(--as-suggest-top, 100%);
    left: 0;
    right: 0;
    z-index: 30;
    padding: 16px 20px 20px;
    background: #fff;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
  }

  /* ============ 商品画像の高さを固定する ============
     和光サイトの画像は 900×1200（3:4）が大半だが 700×700（1:1）も混在し、
     **読み込み前は高さが確定しない**。
     そのままだと戻る復元時に上方の遅延画像が未読込で document が短くなり、
     スクロール位置が必ずズレる。比率を固定して読み込み前から高さを確保する。

     マークアップは `<img width="1000" height="1333">` を持つので
     既存静的 HTML では成立するが、**こちらは実寸を知らないので属性を出せない。**
     既存CSS にも `.c-product-list__img-wrapper` の指定は無いため、ここで持つ。

     object-fit は cover。枠から外れる比率の画像（実測で商品 300 枚中 11 枚が 1:1）は
     切れるが、コンテンツ側のカード（CSS で cover）と表示を揃えるため。
     切りたくない画像は下の「-contain」で個別に contain へ戻す。 */
  [data-as-root] .c-product-list__img-wrapper img {
    width: 100%;
    height: auto;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    background: #f4f4f4;
  }

  /* ============ 「-contain」が付いた画像だけ contain に戻す ============
     拡張子の直前が `-contain` のファイルだけ、枠に収める。
     例: `https://.../foo-contain.webp?size=l&w=OTAw` → contain

     **判定を CSS の属性セレクタで行っているのは、静的 HTML で管理する
     カード（静的タブ・手動メンテナンスの商品枠）にも同じ規約を効かせるため。**
     JavaScript で属性を付ける方式だと、こちらが描画したカードにしか効かない。

     `i` フラグは `-Contain` のような表記ゆれを拾うため。
     クエリ文字列が付いても `-contain.` は拡張子の直前に残るので判定できる。

     対象は、JSが描画した商品カード（`[data-as-root]`）・
     コンテンツ／お知らせのカード（`[data-as-result-kind]`）・
     ランキングのスライド（`[data-as-ranking]`）・候補パネルの 4 か所。
     コンテンツ側は先方が検索ページ内の `<style>` で
     `.c-card__img { object-fit: cover }`（詳細度 0,1,0）、ランキングは
     `as/product-group/style.css` で
     `div.c-product-ranking__img-wrapper img { object-fit: cover }`（詳細度 0,1,2）
     を持つため、属性セレクタを足して詳細度で上回らせている。 */
  [data-as-root] .c-product-list__img-wrapper img[src*="-contain." i],
  [data-as-result-kind] .c-card__img[src*="-contain." i],
  [data-as-ranking] .c-product-ranking__img-wrapper img[src*="-contain." i],
  .as-suggest .c-product-list__img-wrapper img[src*="-contain." i] {
    object-fit: contain;
    background: #f4f4f4;
  }

  /* ============ ランキングに出せる商品が無いとき ============
     タブを押して 0 件だった場合の文言。スライダーごと差し替える。
     **文言・体裁とも仮。** 先方の確定を待って差し替える。
     タイポグラフィは納品のユーティリティ（`u-text` / `u-font--R`）に乗せている。 */
  [data-as-ranking] .as-rankingEmpty {
    /* 差し込み先（`.c-product-ranking__body`）が flex 行なので、
       幅を取らないと 1 文字ずつ折り返す（実測で幅 14px・高さ 500px になった） */
    flex: 1;
    margin: 0;
    padding: 40px 0;
    text-align: center;
    color: #666;
  }

  /* ============ 候補パネルの商品件数 ============
     クラス構成は納品の `.c-product-toolbar` に準拠。
     納品物には「絞り込み」「並び替え」も並ぶが、候補パネルには不要なため
     件数だけ出している。 */
  .as-suggest .c-product-toolbar { margin: 0 0 8px; }
  .as-suggest .c-product-toolbar__count {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 0;
    color: #666;
    font-size: 12px;
    letter-spacing: .04em;
  }

  /* ============ 並び替え（メンバーズのツールバー内） ============
     先方の `<select>` を自前のドロップダウンに差し替えている。
     矢印アイコンはラッパーの `::before`（`position: absolute; left: 24px`）で、
     先方の `<select>` は `padding-left: 22px` を持つことでアイコンの上に重なり、
     アイコンごとクリックできるようになっていた。
     こちらのボタンにも同じ余白を持たせて、アイコン部分を当たり判定に含める。
     アイコン自体は `pointer-events: none` なのでクリックは下のボタンに届く。 */
  .c-product-toolbar__select-wrapper .as-sort {
    display: flex;
    /* ラッパーの内容開始位置＝アイコンの位置。ここから始めないとアイコンが
       ボタンの外に出る。自前の `.as-sort` は「絞り込み」との区切り線として
       margin-left / padding-left / border-left を持つが、先方のツールバーでは
       区切り線は `.c-product-toolbar__btn--filter` の border-right が担うので外す。 */
    margin: 0;
    padding: 0;
    border-left: 0;
  }
  .c-product-toolbar__select-wrapper .as-sort__button {
    padding-left: 22px;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    cursor: pointer;
  }

  /* ============ 絞り込みパネル ============
     **クラスの役割はメンバーズ（MEM）の定義に合わせている。**
     ドロワー本体（`.p-filter--container`）・スクロール領域（`.p-filter--overflow`）・
     ファセットの器（`.filter-panel`）・操作ボタン（`.filter-actions` / `.reset-btn` /
     `.submit-btn`）の見た目は**先方の CSS が持つ**。ここでは書かない。

     同じクラス名を違う役割で使うと、先方の商品一覧用 CSS が読み込まれた
     ページで衝突する（幅・transform・padding が上書きされ、パネルが中央へ寄る）。
     役割を合わせているので打ち消しは書かない。

     **先方の CSS が外されると無装飾になる。** HTML（search-filter-*）は
     入稿不要だが、CSS は残してもらう必要がある（返信で依頼済み）。

     ここに書くのは先方に無い要素と、body 直下へ移したことによる差分だけ。 */

  /* 背景。先方のパネルは検索窓の中にあり背景を持たない */
  .as-filter { position: fixed; inset: 0; z-index: 100000; }
  .as-filter[hidden] { display: none; }
  .as-filter__backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, .4); }

  /* ドロワーは先方の CSS（幅・右固定・スライドイン）に任せる。
     body 直下へ移したぶん、重なり順だけこちらで持つ。 */
  .as-filter .p-filter--container { z-index: 1; }

  /* 先方の `padding-top: calc(145px + 24px)` はサイトヘッダーを避けるための余白。
     こちらは独自のヘッダー（見出し＋閉じる）を上に置くので詰める。 */
  .as-filter .p-filter--overflow { padding-top: 0; }

  /* 見出しと閉じるボタン。先方のパネルには無い（検索窓の × で閉じる作りだった） */
  .as-filter__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid #eee;
  }
  .as-filter__title { margin: 0; font-size: 16px; letter-spacing: .08em; }
  .as-filter__title:focus { outline: none; }
  .as-filter__close {
    width: 40px; height: 40px; border: 0; background: transparent;
    color: #111; font-size: 22px; line-height: 1; cursor: pointer;
  }

  /* ファセットが 1 つも無いときの文言。先方に対応する要素が無い */
  .as-dialog__empty { padding: 32px 20px; color: #666; font-size: 13px; }

  /* パネルを開いている間は背後をスクロールさせない */
  body.as-dialog-open { overflow: hidden; }

  /* ============ 絞り込みの各項目 ============ */
  .filter-group { border-bottom: 1px solid #eee; }
  .filter-group:last-child { border-bottom: 0; }

  /* 選択肢・トグルの 1 行。ラベルが左、コントロールが右 */
  .row {
    display: flex; align-items: center; gap: 8px;
    min-height: 44px; padding: 0 20px; font-size: 13px; cursor: pointer;
  }
  .row > span:first-child { flex: 1; }

  /* 件数「(89)」。
     **`width: fit-content` が要る。** 先方の `.u-text` を併用しているため、
     flex アイテムになると基準サイズが行の残り幅いっぱいに解決され、
     隣のラベルが min-content まで潰される。日本語の min-content は 1 文字なので、
     「ウオッチ」が縦に 1 文字ずつ並ぶ状態になっていた（実測：ラベル 15px / 件数 327px）。
     `flex: 0 0 auto` だけでは直らない（基準サイズ側の問題なので 379px に増えた）。

     **`!important` が要る。** 先方の CSS は as.css より後に読み込まれるため、
     同じ詳細度では後勝ちになる（実測の <link> 順）。 */
  .filter-count {
    flex: 0 0 auto !important;
    width: fit-content !important;
    white-space: nowrap;
    color: #999;
    font-size: 11px;
  }

  .square-input,
  .circle-input {
    flex: 0 0 auto; width: 18px; height: 18px; margin: 0; accent-color: #111;
  }

  /* トグルスイッチ。checkbox の見た目を差し替える */
  .toggle-input {
    flex: 0 0 auto; appearance: none; -webkit-appearance: none; position: relative;
    width: 44px; height: 24px; margin: 0; border: 1px solid #111; border-radius: 12px;
    background: #fff; cursor: pointer; transition: background-color .15s;
  }
  .toggle-input::after {
    content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px;
    border-radius: 50%; background: #111; transition: transform .15s, background-color .15s;
  }
  .toggle-input:checked { background: #111; }
  .toggle-input:checked::after { transform: translateX(20px); background: #fff; }
  .toggle-input:focus-visible { outline: 2px solid #111; outline-offset: 2px; }

  /* アコーディオン */
  .js-accordion-header { position: relative; min-height: 52px; font-weight: 700; }
  .filter-accordion--text { flex: 1; letter-spacing: .06em; }
  .filter-accordion--icon { position: relative; width: 18px; height: 18px; flex: 0 0 auto; }
  /* `.c-product-toolbar__select-wrapper::before`（先方CSS）と同じ Material Icons を使う。
     keyboard_arrow_down（\e313）を開閉で180度回転させ、v/^を切り替える */
  .filter-accordion--icon::before {
    font-family: "Material Icons"; content: "\e313";
    position: absolute; top: 50%; left: 50%; font-size: 18px; line-height: 1;
    transform: translate(-50%, -50%); transition: transform .15s;
  }
  .js-accordion-header.is-open .filter-accordion--icon::before {
    transform: translate(-50%, -50%) rotate(180deg);
  }

  /* 見出し全体をクリック領域にする。label 内の透明ボタン */
  .filter-accordion--button {
    position: absolute; inset: 0; width: 100%; border: 0;
    background: transparent; cursor: pointer;
  }

  .filter-accordion--content[hidden] { display: none; }
  .filter-accordion--inner,
  .filter-group__inner { padding-bottom: 12px; }

  .filter-more {
    margin: 4px 20px 8px; border: 0; background: transparent; color: #111;
    font-size: 12px; text-decoration: underline; cursor: pointer;
  }

  /* カラーのスウォッチ。色は slug ごとに定義する（colors.json が slug の出所） */
  [class^="filter-color--"]::before,
  [class*=" filter-color--"]::before {
    content: ""; display: inline-block; width: 14px; height: 14px; margin-right: 8px;
    border: 1px solid rgba(0, 0, 0, .15); border-radius: 50%; vertical-align: -2px;
  }
  .filter-color--beige::before { background: #D9C6A5; }
  .filter-color--black::before { background: #000000; }
  .filter-color--blue::before { background: #3A6EA5; }
  .filter-color--brown::before { background: #6B4A2F; }
  .filter-color--camel::before { background: #C19A6B; }
  .filter-color--gold::before { background: #C9A741; }
  .filter-color--gray::before { background: #9E9E9E; }
  .filter-color--green::before { background: #4A7A4A; }
  .filter-color--multicolored::before { background: linear-gradient(135deg, #C0392B, #E8C547, #4A7A4A, #3A6EA5, #6C4A7A); }
  .filter-color--navy::before { background: #1B2A4A; }
  .filter-color--orange::before { background: #D97B36; }
  .filter-color--pink::before { background: #E8A6B0; }
  .filter-color--purple::before { background: #6C4A7A; }
  .filter-color--red::before { background: #C0392B; }
  .filter-color--silver::before { background: #BFC1C2; }
  .filter-color--white::before { background: #FFFFFF; }
  .filter-color--yellow::before { background: #E8C547; }

  /* ============ 価格帯（デュアルレンジスライダー） ============
     納品は noUiSlider 前提だが、上限＝未指定の判定を持つ自前実装を使う。
     クラス構成だけ合わせている。 */
  .p-price-range { padding: 12px 20px 16px; }
  .p-price-range__header { min-height: 28px; font-weight: 700; letter-spacing: .06em; }
  .p-price-range__slider { position: relative; height: 24px; margin-top: 8px; }
  .p-price-range__line {
    position: absolute; top: 11px; left: 0; right: 0; height: 2px; background: #ddd;
  }
  .p-price-range__range {
    position: absolute; top: 10px; height: 4px; background: #111;
  }
  .p-price-range__input {
    position: absolute; inset: 0; width: 100%; margin: 0;
    appearance: none; -webkit-appearance: none; background: transparent; pointer-events: none;
  }
  .p-price-range__input::-webkit-slider-runnable-track { height: 24px; background: transparent; }
  .p-price-range__input::-webkit-slider-thumb {
    -webkit-appearance: none; width: 18px; height: 18px; margin-top: 3px;
    border: 1px solid #111; border-radius: 50%; background: #fff;
    pointer-events: auto; cursor: pointer;
  }
  .p-price-range__input::-moz-range-track { height: 24px; background: transparent; }
  .p-price-range__input::-moz-range-thumb {
    width: 18px; height: 18px; border: 1px solid #111; border-radius: 50%;
    background: #fff; pointer-events: auto; cursor: pointer;
  }
  /* 単一価格しかない場合の固定表示（操作不可） */
  .p-price-range__input:disabled::-webkit-slider-thumb { cursor: default; }
  .p-price-range__input:disabled::-moz-range-thumb { cursor: default; }
  .p-price-range__labels {
    display: flex; align-items: center; justify-content: space-between;
    margin-top: 4px; font-size: 12px;
  }

  /* ============ SP ============ */
  @media screen and (max-width: 767px) {
    .p-filter--overflow { width: 100%; }
  }
