/* domain_data_stock — 公開サイト共通スタイル
 *
 * トークンは docs/overview.html から切り出したもの。**系列色（--series-*）の値は
 * 変えないこと** —— 凡例・ドット・グラフが同じ値を前提にしている。
 *
 *   --series-1  dns    --series-2  http    --series-3  gtm
 *
 * ⚠ ライトモードで --series-3（GTM 緑）は surface 比 2.67:1 で 3:1 未満。
 *   **channel を色だけで示さない。** .badge は必ず文字を持つ（下の .badge を使う）。
 *
 * ⚠ 文字は常に text トークンか --link を着る。**系列色を文字色にしない。**
 *   色は隣のドット（.swatch）が持つ。以前は `a` だけがこの約束を破って
 *   --series-1 を着ていた（ライトで 4.19:1 と AA 不足）。
 *
 * ⚠ **文字色のコントラストは web/tools/qa_site.py が毎回測る。**
 *   ここの値を触ったら必ず回すこと。手で目視すると必ず見落とす
 *   （実測で 110 箇所落ちていたのに、誰も気づいていなかった）。
 *
 * ⚠ **ダークモードは持たない。トークンは下の `:root` 1組だけ。**
 *   以前は `@media (prefers-color-scheme: dark)` と `:root[data-theme="dark"]` の
 *   2つ（＝同じトークンの**3通りの値**）があり、片方だけ直す事故が実際に起きた
 *   —— 地図の段は逆順、`--text-muted` と `--link` は別の値、`--mono-*` も別で、
 *   どれが正かはコメントしか知らなかった。この面は住所・従業員数・シグナルの値と
 *   **細かい字がいちばん多い**ので、白地1本に絞ってコントラストをそこだけで測る。
 *   `<meta name="color-scheme" content="light">`（`layout/base.html`）と対。
 *
 * このファイルは全ページで共有する1本。個票5万枚に埋め込まないこと
 * （docs/design/tech_stack.md §4.2 のストレージ試算がこれを前提にしている）。
 */

:root {
  color-scheme: light;
  --plane:           #f9f9f7;
  --surface-1:       #fcfcfb;
  --text-primary:    #0b0b0b;
  --text-secondary:  #52514e;
  /* ⚠ **`#898781` に戻さないこと。** 地（`#f9f9f7`）に載せると **3.41:1** で
     AA（4.5:1）に足りない。このトークンは 11.5〜14px の小さい文字にしか
     使っていないので、大きい文字の緩和（3:1）も効かない。**実測でページあたり
     12〜20 箇所**がこれ1つで落ちていた（注記・単位・日付・パンくず・フッタ・
     ドメイン名）。色相と彩度はそのままに明度だけ下げた最小の変更で 4.56:1。 */
  --text-muted:      #74726d;
  /* リンクの青。⚠ **`--series-1` を流用しない。** このファイルの冒頭に
     「系列色を文字色にしない」と書いてあるのに、`a` だけがそれを破っていた。
     しかも `#2a78d6` はライトの地で **4.19:1** と AA に届いていない。
     系列色は凡例とドットの色で、値を動かすと DNS の色まで動く。
     **文字として読ませる青は別トークン**にして、そちらだけ暗くする
     （`--map-*` を `--step-*` から切り出したのと同じ理由）。 */
  --link:            #2772cd;
  --border:          rgba(11, 11, 11, 0.10);
  --gridline:        #e1e0d9;
  --baseline:        #c3c2b7;
  /* categorical: 固定順。決して循環させない */
  --series-1:        #2a78d6;  /* dns  */
  --series-2:        #eb6834;  /* http */
  --series-3:        #1baf7a;  /* gtm  */
  /* ordinal（単一ヒュー・明→暗）。⚠ **順序尺度だが、地図では使わない。**
     `--step-*` はボタンの hover やバーの塗りにも使っていて、そこには
     `color: #fff` / `#0b0b0b` が紐づいている（下の `.btn:hover` / `.sg__kind--p`）。
     モードで明暗をひっくり返すとその文字が消えるので、**地図は別トークン**。 */
  --step-1:          #86b6ef;
  --step-2:          #5598e7;
  --step-3:          #2a78d6;
  --step-4:          #1c5cab;
  /* 地図の4段（choropleth）。⚠ **「値が大きいほど地から遠い」が絶対。**
     白地なので **明 → 暗**。逆にすると、いちばん数の多い県がいちばん見えなくなる
     （実際にそうなっていた）。`--map-0` は「検出0」で、地に沈めてよい唯一の段。
     ⚠ `--step-*` から切り出してあるのは、あちらがボタンの hover やバーの塗りを
     兼ねていて、**同じ値を動かすと文字が消える**から。借りないこと。 */
  --map-0:           #e1e0d9;
  --map-1:           #bcd6f6;
  --map-2:           #7fb0ee;
  --map-3:           #3d82d8;
  --map-4:           #1c5cab;
  /* ⚠ **緑は持たない。** `--good` と `--success-text` があったが、どちらも
     一度も使われていなかった。このサイトに「良い/悪い」の色は要らない ——
     非検出は推論であって失敗ではなく、検出は成功ではない（`.afeed__sign` /
     `.tl--dropped` / `parts/_chart.html` が揃ってそう書いてある）。
     **緑赤の good/bad を足さないこと。**
     ⚠ `--critical` は残す。これは「悪い」ではなく**警告帯**の赤で、
     `.ribbon`（サンプルデータの帯）と `/optout/` の注記だけが使う。 */
  --critical:        #d03b3b;

  /* ===== ガラスと影と角丸 ====================================================
   * ⚠ **トークンは `:root` 1組にまとめてある。** 以前は「基本色」「ガラス＋
   *   文字サイズ」「モノグラム」で `:root` が3つに割れていて、
   *   **「この値はどこで決まっているか」の答えが3箇所**あった。
   *   増やすときはこの1組に足すこと（`tests/web/test_stylesheet.py` が見ている）。 */
  --glass:        rgba(255, 255, 255, 0.70);
  --glass-strong: rgba(255, 255, 255, 0.88);
  --glass-edge:   rgba(11, 11, 11, 0.08);
  --glass-top:    rgba(255, 255, 255, 0.85);
  --shadow-1: 0 1px 2px rgba(11,11,11,.04), 0 10px 26px -16px rgba(11,11,11,.16);
  --shadow-2: 0 2px 6px rgba(11,11,11,.05), 0 28px 56px -28px rgba(11,11,11,.22);
  /* 貼り付いた列見出しの「蓋」の深さ。**2つの表（`/search/` と `/product/`）が
   * これ1つを共有する** —— 同じサイトに貼り付く見出しが2つあるので、
   * 片方だけ触ると必ず形が割れる（実際に割れていた）。
   *
   * ⚠⚠ **使うのは「貼り付いているあいだ」だけ**（`.is-stuck`）。常に出していたら
   *   **「この shadow が強すぎるね」**と言われた（5回目）。表の先頭を見ている
   *   あいだは下に流れている行が無いので、影はただの飾りで、だから強く見える。
   *   ⚠ **濃さを下げて直そうとしないこと。** 2回目（濃すぎ）と4回目（弱くて
   *     読めない / 重い）は**同じ軸の上を往復していた**。軸は「出すタイミング」。
   * ⚠ **これは「煤」ではない。** 2026-10-08 に `::after` で 7px の下向き
   *   グラデーションを敷いて「header の shadow が変」と言われたが、あれは
   *   **硬い縁が無いまま、ぼけた帯だけ**を置いたから宙に浮いて見えた。
   *   ここは必ず **1px の `--baseline` の罫とセット**で使う（罫が境目を決め、
   *   影は「行がその下をくぐっている」ことだけを言う）。
   * ⚠⚠ **濃さだけを落とす。ぼかし半径を広げて薄めない。** 半径で薄めると
   *   2026-10-08 の「グラデーション＝煤に見える」へ戻る。**半径は小さいまま。**
   *   実測（1440px・2倍・見出しの真下で行がちょうど半分に切れる位置）の
   *   「罫のすぐ下の画素」と「面（#fcfcfb）へ戻るまで」:
   *     `.26` / 5px … #e1e1e1 から 5px → **「強すぎる」**（5回目の指摘）
   *     `.22` / 3px … #e9e9e9 から 3px → **まだ「強い」**（6回目の指摘）
   *     `.09` / 3px … #f6f6f6 から 3px → いまここ
   * ⚠ **`spread` の負値を外さない。** 外すと影がセルの横にも広がり、
   *   列の継ぎ目で二重になって縦の筋が出る。 */
  --shadow-lid: 0 2px 3px -2px rgba(11,11,11,.09);
  /* ⚠ **角丸は4段。** 実測で画面に 2/4/7/9/14/50%/999px の **7種**あり、
   *   「同じ部品に見えるのに角だけ違う」が各所に出ていた（8px の凡例ドットが
   *   2px の角丸、28px のモノグラムだけ 7px、丸いものが 50% と 999px の2通り）。
   *   ⚠ **5段目を作らない。** 箱に対して角が小さすぎる／大きすぎると思ったら、
   *     角ではなく箱の大きさを疑う。
   *   ⚠ **`50%` を書かない。`--radius-pill` を使う。** 正方形なら見た目は同じで、
   *     長方形になったときに `50%` は楕円、`999px` は小判型になる。このサイトに
   *     楕円は1つも無い（ドット・ピル・バーだけ）。 */
  --radius: 14px;
  --radius-sm: 9px;
  --radius-xs: 4px;
  --radius-pill: 999px;
  --blur: 18px;
  --tint-1: rgba(42, 120, 214, 0.13);   /* series-1 由来。**彩度は上げない** */
  --tint-2: rgba(235, 104, 52, 0.09);
  --tint-3: rgba(27, 175, 122, 0.09);
  /* トップバーの高さ。⚠ **ここを肥やさない**（本文が主役）。
   * ⚠ 2026-10-09 に 52 -> 58。ブランド名とタグラインが小さすぎたので
   *   1段ずつ上げた分。**これ以上は上げない。**
   * ⚠ 実測は `static/app.js` の `trackTopbar()` が `--fd-top` に写す。
   *
   * ⚠⚠ **「390px では2段になって 132px」は、もう嘘（2026-10-10 に直した）。**
   *   ここには長らく「この設計値を `scroll-padding-top` の真値だと思わないこと」と
   *   書いてあった。そのとおりで、720px 以下の `.topbar-in` は `flex-wrap: wrap` ＋
   *   `.nav { width: 100% }` で**3段に折れ、390px の実測で 137px（画面の16%）**あった。
   *   いまは**どの幅でも1段**にしてある（下の「トップバー」節の `@media` ——
   *   ナビは横スクロール、検索窓は縮む）ので、**58px がどの幅でも真値**。
   *   ⚠ **折り返しを戻さない。** 戻すと `scroll-padding-top` のフォールバックと
   *     `static/app.js` の `rootMargin` が揃って嘘になる（JS が死んだ面で
   *     スキップリンクの着地点がヘッダの裏へ 68px 潜った、という実測がある）。
   *   ⚠ **`--bar-h` を下げて「56px 以内」に合わせない。** 同じバーの高さの答えが
   *     広い画面と狭い画面で2つになる。1段に畳んだ時点で狙いは足りている。 */
  --bar-h: 58px;

  /* ===== 割合バーの高さ ======================================================
   * ⚠ **割合を示すバーは2種類しかない。** 3種類目を足さないこと。
   *   以前は 12px（集計の横棒）/ 6px（併用リスト）/ 5px（表の中）の3つがあり、
   *   後ろの2つは**同じ役割なのにプロダクト個票の同じ画面に違う高さで並んでいた**。
   *   角丸は px ではなく 999px で書く（高さを変えても端が丸いまま）。
   *
   * ⚠ **`--bar-h` という名前を使わないこと。** あれは**トップバーの高さ**（52px）で、
   *   `scroll-padding-top` と `static/finder.css` の sticky 3箇所が参照している。
   *   一度ここを `--bar-h` と名付けて、県別の棒が 52px の灰色の箱になった。
   *
   *   `--meter-h`    … 見出しつきの横棒（`.btrack` / `.bfill`）
   *   `--meter-h-sm` … 表やリストの行に埋める極小バー（`.mini` / `.co__track`） */
  --meter-h: 12px;
  --meter-h-sm: 6px;

  /* ===== 部品の内側の余白 ====================================================
   * ⚠ **同じ役割のものは同じ値にする。** 文字の大きさは6段に絞ってあるのに、
   *   余白は野放しで、**同じ部品の値が面ごとに割れていた**:
   *     パネル  … `.panel` 20px / `.psec .panel` 18px / `.prof` 18px
   *     チップ  … `.chip` 2px 9px の値を `finder.css` が3箇所に手で写していた
   *     ボタン  … 10px 18px / 7px 14px / 4px 11px / 4px 9px / 6px 14px … と6種
   *   トークンにすると、片方を動かしたときにもう片方が黙って剥がれることが無くなる。
   *
   * ⚠ **表のセルの余白はここに入れない。** あちらは列数と行数で決めるもので
   *   （141行の一覧は 6px、6行のサマリ表も 6px、`/search/` は 10px 12px）、
   *   それぞれの理由がそのルールの隣に書いてある。**役割が違う。**
   *
   * ⚠ レイアウトの `gap`（グリッド・リストの間隔）はまだトークン化していない。
   *   アイコンと文字の間だけは下の `--gap-ic` に寄せてある。 */
  --pad-panel: 18px 22px;   /* 面（パネル）の内側 */
  --pad-chip: 2px 9px;      /* 丸いチップ・バッジ・タグ */
  --pad-btn: 10px 18px;     /* 主ボタン */
  --pad-btn-md: 7px 14px;   /* 副ボタン（絞り込みなど） */
  --pad-btn-sm: 4px 9px;    /* 文字の隣に置く小さいボタン */

  /* 本文の最大幅。⚠ **幅を2箇所に書かない。** `.wrap` と `.foot-in` が同じ数を
     持っていて、`static/finder.css` の `--fd-bleed`（本文の外へはみ出す量）も
     この数を前提に計算している。3箇所に写すと、広げた日に表だけがずれる。 */
  --page-max: 1140px;

  /* ===== アイコンと文字の間 ==================================================
   * ⚠ **「アイコン＋文字を横に並べる」は同じ役割。** 実測したら 4/5/6/7/8/9px の
   *   6通りあり、しかも**同じ 16px のアイコンに 5/6/7/8px** が付いていた。
   *   数えると 5px（密なチップ）と 8px（行・見出し・ボタン）が既に多数派で、
   *   残り6つが外れ値だった。その2段に寄せる。
   * ⚠ **3つ目を足さない。** 迷ったら「密なチップの中か、そうでないか」で選ぶ。
   *   `tests/web/test_stylesheets.py` が `inline-flex` の中の生の px を弾く。 */
  --gap-ic: 5px;      /* 密なチップ・帯の中（.chip--ic / .fd-tag / .badge） */
  --gap-ic-lg: 8px;   /* 行・見出し・ボタンの中（.with-ic / .si / .pcell / .facts） */

  /* ===== 部品どうしの間（レイアウトの gap）==================================
   * ⚠ **5段しか使わない。** 実測したら画面の `gap` が **17種**
   *   （2/3/4/5/6/7/8/9/10/11/12/14/16/18/20/24/28px）あった。同じ役割のものが
   *   面ごとに 1〜2px ずれているだけで、読み手にはどちらも「ちょっとした隙間」に
   *   しか見えない —— **違いが伝わらないのに、触るたびに増える**。
   *   `--pad-*`（部品の内側）と `--fs-*`（文字）を段で持っているのに、
   *   ここだけ野放しだった。
   *
   *   --gap-1   4px   2段組の行間・字の真下に続くもの（最小）
   *   --gap-2   8px   チップ・インラインの列
   *   --gap-3  12px   行の中の塊どうし
   *   --gap-4  16px   節の中のブロック
   *   --gap-5  24px   面と面
   *
   * ⚠ **6段目を作らない。** 迷ったら近いほうへ寄せる。段を増やすくらいなら
   *   「この2つは同じ役割か」を先に疑うこと。
   * ⚠ **アイコンと文字の間は上の `--gap-ic` / `--gap-ic-lg`。** 役割が違う
   *   （あちらは**1つの部品の中**、ここは**部品どうし**）。値が近いからといって
   *   混ぜると、アイコンの間隔を詰めたいだけでページ全体の段が動く。
   * ⚠ **面ごとの CSS（home / finder / saas / company / method）で生の px を
   *   書かない。** `tests/web/test_stylesheets.py` が弾く。 */
  --gap-1: 4px;
  --gap-2: 8px;
  --gap-3: 12px;
  --gap-4: 16px;
  --gap-5: 24px;

  /* ===== 本文と帯の左右の余白 ================================================
   * ⚠ **4箇所が同じ値を読む。** `.wrap`（本文）/ `.topbar-in`（トップバー）/
   *   `.ribbon`（警告帯）/ `.foot-in`（フッタ）。以前はそれぞれが生の px を持ち、
   *   しかも**狭くする閾値まで違っていた**（トップバーは 720px 以下で 36px、
   *   本文は 640px 以下で 36px）。641〜720px ではブランドと `<h1>` の左端が
   *   **8px ずれて**見えていた。
   * ⚠ **`body` に持たせない。** 全幅で出したいもの（sticky なバー・赤帯・フッタの面）
   *   まで内側に寄る（上の `body` の注記）。
   * ⚠ 44px は 24（もとの `.wrap`）+ 20（`body` から外したぶん）。
   * ⚠ **狭い画面の段は下の `@media` でこのトークンだけを差し替える。**
   *   個別の要素に px を書くと、また閾値が割れる。 */
  --gutter: 44px;

  /* ===== 文字の太さ ==========================================================
   * ⚠ **4段しか使わない。** 実測したら画面の `font-weight` が **11種**
   *   （400 / 500 / 520 / 560 / 580 / 600 / 620 / 640 / 650 / 660 / 680 / 700）あった。
   *   20〜40 の差は `system-ui` では**ほとんど、あるいは全く描き分けられない**ので、
   *   書いた人の意図（「ここは少し強く」）は画面に届いていない。届かない区別を
   *   増やすと、本当に効かせたいところ（見出しと本文）の差まで埋もれる。
   *
   *   --fw-normal    400  本文・弱く見せるもの
   *   --fw-medium    560  少しだけ立てる（リンクになる社名・プロダクト名・単位）
   *   --fw-semibold  640  見出し・ラベル・ボタン・表の列見出し
   *   --fw-bold      700  ブランド名・主役の数字・モノグラム
   *
   * ⚠ **弱く見せたいところに `--fw-medium` を書かない。** `500` を寄せ先にすると
   *   **太くなって逆の意味になる**（`.past .cname` / `.si--past .si__name` が
   *   まさにそれ）。弱めるときは `--fw-normal` と色で。
   * ⚠ **5段目を作らない。** 「見出しより少しだけ細く」は描き分けられない。 */
  --fw-normal: 400;
  --fw-medium: 560;
  --fw-semibold: 640;
  --fw-bold: 700;

  /* ===== 文字の段階 =========================================================
   * ⚠ **この6段しか使わない。** 実測したら画面に font-size が **20種**あり、
   *   `10.5px` が617箇所、`9px` が57箇所という読めない大きさまで混ざっていて、
   *   「フォントの大きさがバラバラで読みづらい」と言われた。
   *
   *   --fs-xs    ラベル・バッジ・注記。**これより小さくしない**（可読性の下限）
   *   --fs-sm    副次的な文・フッタ・チップ
   *   --fs-md    表のセル・密度の高い UI
   *   --fs-base  本文（body がこれ）
   *   --fs-lede  リード文
   *   --fs-h2 / --fs-h1  見出し
   *
   * ⚠ **面ごとの CSS（home / finder / saas / company / method）で
   *   生の px を書かないこと。** 書くと必ずまた 20種に戻る。
   *
   * ⚠ **数字を大きく出す場所は、いまサイトに2つしか無い。**
   *   トップの「毎週見ている会社」（`.home-geo__nums dd`）と、
   *   トップの見出し（`.hero-title`）。どちらも**1画面に1つだけ**の主役なので、
   *   画面幅で伸びる `clamp()` を持ち主の CSS 側に置いてある。
   *   ⚠ **3つ目を作らない。** 同じ役割の数字が増えたら、上の6段に入るかを先に見る
   *   （以前 27 / 25 / 24 / 22px の4種が「カードの中の KPI」に使われていて、
   *   並べると段差に見えた。その4種はカードごと消えた）。 */
  --fs-xs:   11.5px;
  --fs-sm:   12.5px;
  --fs-md:   14px;
  --fs-base: 15px;
  --fs-lede: 17px;
  --fs-h2:   20px;
  --fs-h1:   32px;

  /* ===== モノグラムの面 ======================================================
   * 段（1〜4）は **`product_id` から決まる**（`web/view/icons.py` の `mono_step`）。
   * ⚠ 表示名からではない —— 短縮名を渡した箇所と元の名前を渡した箇所で、
   *   同じ製品が違う色になっていた。
   *
   * ⚠ **`--step-*` を流用しない。** 以前はそうしていて、ライトの `--step-3`
   *   （`#2a78d6`）が**黒 4.46:1 / 白 4.42:1 と、どちらを載せても AA に届かない**
   *   谷に座っていた。文字を反転しても直らない種類の詰みなので、面のほうを動かす。
   *   `--step-*` はバーと系列の色なので、そちらを動かすとグラフの意味が変わる。
   *   ⚠ **`.jp--*` も借りない。** あちらは地図の `<path>` 用（`fill` しか持たない）で、
   *   偶然クラス名が一致していただけ。地図の段を増減するとモノグラムが道連れになる。
   *
   * ⚠ **面と文字は必ず対で決める。** 明るい段は黒、暗い段は白。文字色に
   *   `--text-*` を使わないのは、面の明暗と無関係に決まってしまうから。 */
  --mono-1: #86b6ef; --mono-ink-1: #0b0b0b;  /* 9.33:1 */
  --mono-2: #5598e7; --mono-ink-2: #0b0b0b;  /* 6.59:1 */
  --mono-3: #1c5cab; --mono-ink-3: #ffffff;  /* 6.63:1 */
  --mono-4: #10386c; --mono-ink-4: #ffffff;  /* 11.64:1 */
}

/* ---------------------------------------------------------------- base */

* { box-sizing: border-box; }

/* ⚠ **トップバーが sticky なので、飛んだ先がその裏に潜る。**
 *   `/faq/#q3` のようなページ内リンクも、Tab でフォーカスを送ったときの
 *   自動スクロールも、既定では対象を**ビューポートの最上端**に置く。そこは
 *   高さ 53px のバーの下なので、見出しが隠れて「どこへ飛んだのか分からない」。
 *   `scroll-padding-top` はブラウザのスクロール計算そのものに効くので、
 *   JS も個別の `scroll-margin` も要らない。バーの実測は `--fd-top`
 *   （`static/app.js` の `trackTopbar()`）、無いときは設計値 `--bar-h`。 */
html {
  scroll-padding-top: calc(var(--fd-top, var(--bar-h)) + 12px);
  /* ⚠⚠ **縦スクロールバーの幅を常に確保する（2026-10-10、指摘）。**
     「プロダクトから探す」と「サービスについて」でヘッダーのロゴが左へ動いて見える、
     という指摘の原因はここ。CSS でもテンプレートでもなく、**スクロールバーの有無**だった。

     `.wrap` は `margin: 0 auto` で**使える幅の中央**に置かれる。スクロールバーが
     幅を取る設定（macOS の「常に表示」／マウス接続時）だと、

       縦スクロールするページ   … 使える幅が約15px 狭い → 中央が約 7.5px 左
       縦スクロールしないページ … そのまま              → 約 7.5px 右

     で、面を移るたびに**約15px 動く**。実測（playwright・1280/1366/1440/1600px）では
     全ページ同じ位置に出るが、それは**ヘッドレスがオーバーレイ表示だから**。
     窓を高くすると `/product/`（1,014px）と `/method/`（1,125px）だけスクロールが消える
     —— 指摘された2面が、ちょうど**一番短い2ページ**だった。

     ⚠ **`overflow-y: scroll` で代用しない。** あれは中身が短い面にも
       「掴めない灰色の溝」を描く。`scrollbar-gutter` は**場所だけ空けて溝は描かない**。
     ⚠ **対応していないブラウザでは何も起きない**（いまの挙動のまま）。
       壊れる方向の副作用が無いので、分岐も JS も要らない。 */
  scrollbar-gutter: stable;
}
/* ⚠⚠ **狭い画面の受け皿（`var(--fd-top, 137px)`）は消した（2026-10-10）。**

   ここには 720px 以下だけ `scroll-padding-top: calc(var(--fd-top, 137px) + 12px)` と
   いう上書きがあった。理由はこうだった ——「`--fd-top` を書くのは `static/app.js` の
   `trackTopbar()` なので、**JS が死ぬと設計値 `--bar-h`（58px）に落ちる**が、
   720px 以下では `.topbar-in` が折り返して実高 137px になる。実測: JS 無し・390px で
   スキップリンクの着地点が**ヘッダの裏に 68px 潜った**（`/` `/faq/` `/method/`
   `/disclaimer/` `/privacy/` `/optout/` の6面）」。

   ⚠⚠ **137px は「折り返したときの実高」を当てた数字で、折り返しをやめた時点で嘘になる。**
   2026-10-10 に `.topbar-in` を**どの幅でも1段**にした（下の「トップバー」節）ので、
   JS が無くても実高は `--bar-h`（58px）。上書きを残すと、**58px のバーに対して
   137px ぶん余白を空ける**ことになり、`#anchor` で飛ぶたびに見出しが画面の中ほどへ落ちる。

   ⚠ **折り返しを戻すなら、この上書きも一緒に戻すこと**（高さと数字は対）。
   ⚠ **`--bar-h` を大きくして解かない。** あれは1段のときの高さで、広い画面が無駄に空く。
   ⚠ JS があるときは `--fd-top`（実測）が勝つので、どのみちこの枝は使われない。 */

/* ⚠ **`body` の下に余白を入れない。** ここに `96px`、下の方にも `80px` と
 *   二重に入っていて、**フッタの下に何も無い帯**が全ページで出ていた。
 *   フッタは自前で内側に余白を持っている（`.foot-in`）。
 *
 * ⚠ **左右の余白も `body` で取らない。** `padding: 0 20px` があったせいで、
 *   `body` の直下にある**全幅で出したいもの**（sticky なトップバー・サンプルデータの
 *   赤帯・フッタの面と罫）まで画面端から 20px 内側に収まり、スクロール中は
 *   その溝から背景（`.aurora`）が透けていた。とくに `.ribbon` は
 *   「公開してはいけません」の警告帯なので、全幅でないと弱く見える。
 *   余白は**中身側**（`.wrap` / `.topbar-in` / `.ribbon` / `.foot-in`）が持つ。
 *   ⚠ 打ち消す負のマージンは CSS 全体に無い（`100vw` / `margin-inline` / 負値を
 *     走査して確認済み）ので、ここを消せば素直に端まで届く。
 *   ⚠ `static/finder.css` の `--fd-bleed`（本文の外へはみ出す量）は
 *     `(100vw - 1140px) / 2` で、この 20px を勘定に入れていなかった
 *     ——**常に 20px 多く見積もっていた**。`body` から消すと、あの式が
 *     そのまま正しくなる。 */
/* ⚠⚠ **フッタを下へ押し下げる（2026-10-10）。**
   以前は短いページで**フッタが浮き、下に最大 287px の空き地**ができていた
   （1080px の窓で `/product/valimail/` のフッタ下端が 793px）。
   **効く範囲が広い** —— 検出0件のプロダクト個票が 996 枚ある。
   ⚠ `min-height: 100vh` だけでは足りない（本文が伸びるだけでフッタは浮いたまま）。
     **flex の縦並びにして、`footer` を `margin-top: auto` で落とす。**
   ⚠ `100dvh` にしない —— モバイルでアドレスバーが出入りするたびに
     高さが変わり、スクロールが跳ねる。 */
body {
  margin: 0; padding: 0;
  min-height: 100vh;
  display: flex; flex-direction: column;
  background: var(--plane); color: var(--text-primary);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: var(--fs-base); line-height: 1.7;
}
body > footer { margin-top: auto; }
/* ⚠⚠ **`min-width: 0` が要る（2026-10-10）。** flex の子は既定で
   `min-width: auto`＝**中身より縮まない**。`body` を flex にした瞬間、
   `<main>` が中の広い表（`/product/` の 5列）に押し広げられ、
   **`/product/` が 768px で 43px、390px で 373px 横スクロールした**（実測）。
   表の横スクロールを受けるのは内側の `.sx-scroll` / `.ct-scroll` で、
   **ページごと横に伸びてはいけない。** */
body > * { min-width: 0; width: 100%; }
/* ⚠⚠ **`width: 100%` を落とさない（`min-width: 0` だけでは足りない）。**
   flex の子は既定で `align-self: stretch`＝器の幅に広がるが、
   **交差軸に `margin: 0 auto` があると auto マージンが stretch より優先され**、
   幅が `fit-content`（＝中身の max-content）になる。
   `.wrap` は `margin: 0 auto` を持っているので、中の表の `min-width: 660px` に
   引き伸ばされ、**390px の画面で `main.wrap` が 763px** になっていた（実測）。
   表の横スクロールを受けるのは内側の `.sx-scroll` / `.ct-scroll`。 */

/* 本文への近道（`layout/base.html` の先頭）。**フォーカスするまで見えない。**
 * ⚠ `display: none` にしない —— Tab の順路から消えて、リンクそのものが無意味になる。
 * ⚠ `<main>` は `tabindex="-1"` を持つ（無いとフォーカスが移らないブラウザがある）。
 *   その焦点枠は出さない —— マウスで本文をクリックしただけでも付いてしまう。 */
.skip { position: absolute; left: -9999px; top: 0; z-index: 100; }
.skip:focus {
  left: 8px; top: 8px; padding: var(--pad-btn-md);
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: var(--radius-sm); color: var(--text-primary);
}
main:focus { outline: none; }

/* 目で見えないが読み上げられる文字。**図や列に「何の値か」を足すのに使う。**
 * ⚠ `display: none` / `visibility: hidden` は支援技術からも消えるので使えない。
 * ⚠ `white-space: nowrap` が要る（幅 1px に押し込むと1文字ずつ折れる実装がある）。 */
.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ⚠ **裸の `header` に余白を当てない。** サイト内の `<header>` は
 *   `layout/base.html` のトップバー1箇所だけで、ここに `padding: 40px 0 20px` が
 *   効くと、`--bar-h`（52px）のつもりの帯が**実測113px**になる。
 *   「ヘッダーが大きすぎる」と言われ続けた正体がこれ。 */
/* ⚠ **`.wrap` / `footer` / `h2` はここには無い。** それぞれ下の
 *   「ガラス層」「フッタ」「見出し」節が**1箇所で**持つ。ここに書き足すと
 *   同じ要素の答えが2箇所になる（`tests/web/test_stylesheet.py` が落とす）。 */
footer a { color: var(--text-secondary); }

h1 { font-size: var(--fs-h1); line-height: 1.3; margin: 0 0 8px; letter-spacing: -0.01em; }
h3 { font-size: var(--fs-base); margin: 28px 0 6px; }
p  { margin: 10px 0; max-width: 72ch; }
/* ⚠⚠ **面（パネル・表のカード）の中では、散文向けの 72ch を解く（2026-10-09）。**

   上の `p { max-width: 72ch }`（≈582px）は**器の幅が決まっていない散文**のためのもの。
   パネルの中はすでに器が幅を決めているので、重ねて切ると
   **1,000px あるパネルの中で文だけが 582px で折れ、右半分が空く**。

   ⚠⚠ **これを個別に直すのをやめた。** 同じ罠を **5回**踏んでいる:
     `.nearby__list` / `/faq/` の回答 / `.m-fact` / `.co` / `.sum__rivals` / `.clause__*`。
     指摘も毎回同じ言い方だった（「左によりすぎじゃない？右はなぜ使わないの？」）。
     **見つけ次第直すやり方では終わらない**ので、器の側で一度に解く。
   ⚠ **散文の既定を消さない。** 面の外（`/faq/` の外側、読み物の段落）では
     72ch は正しい。解くのは**幅が決まっている器の中だけ**。
   ⚠ 個別に狭めたいときは、その要素で `max-width` を明示すればよい（後勝ち）。 */
.panel p, .tablecard p, .clauses p, .phero p { max-width: none; }
ul { padding-left: 20px; max-width: 72ch; }
li { margin: 5px 0; }
strong { font-weight: var(--fw-semibold); }
a { color: var(--link); text-underline-offset: 2px; }

/* ⚠⚠ **入力欄の文字を 16px 未満にしない（2026-10-10）。**
 *
 *   iOS Safari は **16px 未満の入力欄に触れるとページごと拡大し、自動では戻らない。**
 *   以後そのセッションはずっと横スクロールになる —— 好みの話ではなく、
 *   **踏むと戻らない事故**。実測（2026-10-10・9画面×10面）で画面に出ていた入力欄は
 *   **3種すべてが 16px 未満**だった: `input` 14px（ヘッダーの検索窓）/
 *   `.sg--wide` 15px（トップの検索窓）/ `.fd-input` 12.5px（`/search/` の絞り込み）。
 *
 * ⚠ **`user-scalable=no` / `maximum-scale=1` で黙らせない。** 拡大を奪うのは
 *   WCAG 1.4.4 (AA) 違反で、`layout/base.html` の `<meta viewport>` は**今のままが正しい**
 *   （`tests/web/test_responsive.py::test_the_viewport_still_allows_zoom` が落とす）。
 *   直す手は「文字を 16px 以上にする」の一手だけ。
 * ⚠ **`--fs-*` に段を増やさない。** 16px は**トークンではなく OS の制約**なので、
 *   段として持たず `max()` で下駄を履かせる。地の文が将来 16px を超えたら
 *   `--fs-md` 側が勝つ（下駄は自動で外れる）。
 * ⚠ **これは一番弱い土台。** クラスを持つ入力欄（`.sg input` / `.fd-input`）は
 *   特異度で勝ってしまうので、**そちらにも同じ `max()` を書く**こと。
 *   `.fd-input` は `static/finder.css` の持ち場。 */
input, select, textarea { font-size: max(16px, var(--fs-md)); }

/* 見出しの下の1文。
 * ⚠ **`text-wrap: balance` を落とさない（2026-10-09）。** `ch` は半角の `0` の幅なので
 *   **日本語の行長を測れていません**。`/disclaimer/` の一文は 62ch=568px で
 *   2行に折れ、**2行目が「取っていません。」だけ**になっていた
 *   （親は 1,052px あるので、右半分が空いたまま端が余る——「変なところで
 *   折り返してる」と言われたのがこれ）。`balance` は行数を変えずに
 *   **各行の長さを揃える**ので、端の孤立した短い行が消える。
 * ⚠ **`max-width` を消して器の幅いっぱいにしない。** 1,052px は日本語で
 *   1行 60 字超で、読むときに行を見失う（40〜50字が上限）。
 * ⚠ `balance` は**数行まで**の要素にしか効かない（ブラウザが打ち切る）。
 *   長い本文に付けても無駄なので、`p` の既定には入れていない。 */
.lede {
  color: var(--text-secondary); font-size: var(--fs-lede); margin: 0;
  /* ⚠⚠ **`max-width` を 62ch に戻さない（2026-10-09）。** `ch` は半角 `0` の幅で
     **日本語の行長を測れていない** —— `/disclaimer/` の1文が 568px で2行に折れ、
     器が 1,052px あるのに右半分が空いていた（「左によりすぎじゃない？」）。
     長さは `text-wrap: balance` が面倒を見る（行数を変えずに各行を揃える）。 */
  max-width: none; text-wrap: balance;
}
.sub  { color: var(--text-secondary); font-size: var(--fs-md); margin-top: 2px; }
.muted{ color: var(--text-muted); }

/* ⚠ **`0.87em` だけにしない —— 下限（`--fs-xs` = 11.5px）を割る。**
 *   地の文（15px）なら 13.05px で問題ないが、`code` は**小さい字の中にも入る**:
 *     `.fs-sm` の文の中（12.5px）→ 実測 **10.88px**（`/method/detect/`）
 *     `.fine` の注記の中（11.5px）→ 実測 **10.01px**（`/search/`）
 *   このファイルの冒頭で「`--fs-xs` より小さくしない（可読性の下限）」と宣言して
 *   いるのに、**等幅の中だけその約束が破れていた**（しかも破れるのは
 *   「観測した値」や「シグナルの値」—— このサイトで一番読ませたい文字）。
 *   `max()` で「地の文には比例、ただし下限は割らない」を1行で書く。
 * ⚠ `0.87em` を上げて揃えないこと —— 地の文の中で等幅が大きく見える。 */
code {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: max(var(--fs-xs), 0.87em); background: var(--surface-1);
  border: 1px solid var(--border); border-radius: var(--radius-xs); padding: 0.1em 0.35em;
}

/* ⚠ **`.card` は消した。** どのテンプレートも使っておらず、`10px` という
 *   どこにも無い角丸を1つだけ抱えていた。面は `.panel`（節まるごと）/
 *   `.tablecard`（表）/ `.scard`（押せるカード）の3つで足りている。
 *   **4つ目の汎用カードを足さないこと。** */

/* パンくずの見た目は**下の「パンくず」節1箇所**が持つ（ここには書かない）。
 * ⚠ 以前はここと下の2箇所にあり、下の `gap: 4px` が上の `margin: 0 6px` を
 *   上書きして、**間隔がページごとに違って見えていた**。 */

/* ⚠ **`.hero` / `.tiles` / `.tile` は消した。** どれも焼いた HTML に1つも出ない
 *   （`.hero` は呼び出し元が無く、タイルは `parts/_stat.html` の `tiles()` ごと
 *   死んでいた）。しかも `.tiles`/`.tile` は base 層とガラス層に**二重定義**され、
 *   角丸が `10px` と `var(--radius)`、面が `--surface-1` と `--glass` で
 *   食い違ったまま残っていた。**同じクラスを2箇所に書かない。**
 *   いま生きている数字の見せ方は、トップの `.home-geo__nums`（主役の1つ）と
 *   プロダクト個票の `.sum`（表）だけ。 */

/* ------------------------------------------------------------ badges */

/* channel バッジ。**必ず文字を持つ。** 色は左のドットだけが担う。
 * ライトモードで GTM 緑が 3:1 を満たさないため、色単独の識別に依存しない。 */
.badge {
  display: inline-flex; align-items: center; gap: var(--gap-ic);
  font-size: var(--fs-xs); padding: 1px 8px 1px 6px; border-radius: var(--radius-pill);
  border: 1px solid var(--border); color: var(--text-secondary);
  white-space: nowrap; margin-right: 4px;
}
.swatch { width: 8px; height: 8px; border-radius: var(--radius-xs); flex: none; }
.badge--dns  .swatch { background: var(--series-1); }
.badge--http .swatch { background: var(--series-2); }
.badge--gtm  .swatch { background: var(--series-3); }

/* confidence。strong 以外だけ出す（strong が既定だから）。
   ⚠ **赤にしない。** タイムラインや表に赤字が並ぶと「エラー」に見えるが、
     medium / weak は「共用基盤の可能性がある」程度の意味しかない。色ではなく文字で伝える。
   ⚠ **以前は `--critical`（赤）の定義が上に、`--text-muted` の定義が下にあり、
     後ろが勝つので前は1つも効いていなかった** —— しかも理由のコメントは効いていない
     ほうに付いていて、**コメントと見た目が逆**だった。定義はここ1箇所に置く
     （`tests/web/test_stylesheet.py` が二重定義を落とす）。 */
.conf { font-size: var(--fs-xs); color: var(--text-muted); }
.conf--medium, .conf--weak { color: var(--text-muted); }

/* ⚠ **`.pill` は消した。** `class="pill"` は焼いた 2,853 ページに1件も無い
 *   （`.count-pill` が別物として下にある）。丸いチップは `.chip` / `.badge` /
 *   `.count-pill` の3つで足りている。**4つ目を足さないこと。** */

/* ------------------------------------------------------------- table */

table { border-collapse: collapse; width: 100%; margin: 14px 0; font-size: var(--fs-md); }
th, td {
  text-align: left; padding: 9px 12px;
  border-bottom: 1px solid var(--border); vertical-align: top;
}
th { color: var(--text-muted); font-weight: var(--fw-semibold); font-size: var(--fs-sm); }
/* 縦に揃う数字だけ等幅 */
td.num, th.num { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }

/* ------------------------------------------------------- 横棒（集計） */

.bars { margin: 14px 0 4px; display: flex; flex-direction: column; gap: var(--gap-3); }
/* ⚠ **棒の定義はこの節1箇所。** 以前は列幅（`grid-template-columns`）と塗り
 *   （`background`）と `text-align` だけが下の「棒」節に離れていて、
 *   前の宣言（`180px` 決め打ち・`var(--series-1)`）は**1つも効いていなかった**。
 * ⚠ **ラベル列を固定幅にしない。** 180px 決め打ちだと狭い画面で棒が潰れる。 */
.brow { display: grid; grid-template-columns: minmax(120px, 200px) 1fr 84px; gap: var(--gap-3); align-items: center; }
.blabel { display: flex; align-items: center; gap: var(--gap-2); font-size: var(--fs-md); color: var(--text-secondary); }
.btrack { background: var(--gridline); border-radius: var(--radius-xs); height: var(--meter-h); }
/* データ端だけ丸める。⚠ **ベースライン側は角のまま**（0 から始まることを見せる）。 */
.bfill  { height: var(--meter-h); border-radius: 0 var(--radius-xs) var(--radius-xs) 0; background: linear-gradient(90deg, var(--step-3), var(--step-4)); }
.bval   { font-size: var(--fs-md); font-weight: var(--fw-semibold); font-variant-numeric: tabular-nums; text-align: right; }
/* 棒が1本も無いとき（`templates/parts/_stat.html` の `bars()`）。
 * ⚠ **空の `.bars` を出さない。** 以前は `<div class="bars"></div>` だけが焼かれ、
 *   見出しと説明文しか無いパネルの抜け殻になっていた（検出0社のプロダクト個票）。
 * ⚠ **ここ（共有の `app.css`）に置く。** `bars()` はトップと個票の両方が呼ぶので、
 *   面ごとの CSS に置くと片方の画面だけ素の `<p>` になる。 */
/* ⚠ **「0件の注記」の組はここが正。** 同じ役割のものが2つあり
 *   （`.bars__none` / `.pnone`）、かつて行間が 1.7 と 1.8、幅が 68ch と 72ch で
 *   **同じページに並んでいるのに組が違っていた**。読み手には
 *   「意味が違うのだろう」と見える差で、実際にはどれも「出せるものが無い」だけ。
 *   ⚠ **文面は別。** セレクタを分けてある理由は `static/saas.css` の `.pnone` にある
 *     （「観測が足りない」と「観測はしたが検出できなかった」）。**揃えるのは組だけ。**
 *   ⚠ 上の余白だけは隣に来るもので違う（ここは見出しの下、あちらは面の先頭）。 */
.bars__none {
  margin: 10px 0 0; font-size: var(--fs-sm); line-height: 1.8;
  color: var(--text-secondary); max-width: 72ch;
}

/* ⚠ **`.activity` / `.act` は消した。** 初版の「個票アクティビティ(git風)」で、
 *   焼いた 2,853 ページに1件も出ない。いまアクティビティを描いているのは
 *   トップの `.afeed`（`static/home.css`）と、
 *   企業個票の `.timeline` / `.tl`（`static/company.css`）。
 *   ⚠ **1行に1ファイルだけ書く。** 2つの置き場所を1行に混ぜると、
 *     `tests/web/test_stylesheet.py` の突合が「どちらの selector がどちらの
 *     ファイルのものか」を判定できない（そして人も読み違える）。
 *   ⚠ **色の方針はそちらに引き継いである** —— adopted だけ色を持たせ、
 *   dropped はミュートグレー。good/bad の緑赤は使わない（シグナル消失は
 *   「悪いこと」ではなく、そもそも非検出にもとづく**推論**なので弱く出す）。
 *
 * ⚠ **`.teaser` / `.teaser .fade` / `.cta` も消した。** 有料境界のぼかしは
 *   HTML ごと存在しない。⚠ 復活させるなら**隠す行を HTML に入れないこと**
 *   （網かけは装飾でしかない。docs/design/tech_stack.md §3 / web_design.md）。 */

/* -------------------------------------------------------------- 注意書き */

/* ⚠ **`.warn` の見た目は下の「注意書き」節1箇所が持つ。** ここにも一式あって、
   `--critical`（赤）の左罫と `padding-left: 14px` を指定していたが、全プロパティが
   下で上書きされて死んでいた —— **意図と逆の赤が、消えているから無害だっただけ。**
   見出し（`.warn .h`）の太さもそちらに畳んだ。ここに書き戻さないこと。 */

/* ⚠ **`pre` の装飾も消した。** どのテンプレートも `<pre>` を出していない
 *   （このサイトはコードを見せる場所ではない）。`.card` と同じく `10px` を
 *   1つだけ抱えていた。必要になったら、そのとき `--radius` で書くこと。 */

/* ------------------------------------------------------------ 反応 */

/* ⚠ **狭い画面の `.brow` は、下の 640px ブロック1箇所が持つ。** ここにも
 *   同じ `grid-template-columns: 1fr 74px` があって**完全に重複**していた。
 *   `.blabel` の折り返しだけがここにしか無いので、そちらは下へ移した。 */

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ==========================================================================
   公開サイトの層（ここから下）

   上のトークンは docs/overview.html から切り出した**検証済みの値**なので触らない。
   ここで足すのは「面」と「余白」と「部品」だけ。

   ### ガラスの使い方に1つだけ規則がある

   **文字は必ず面の上に置く。** ガラスは半透明なので、後ろの背景（.aurora）が
   そのまま文字のコントラストを下げる。だから:

     - 面の不透明度を 0.70 以上に保つ
     - backdrop-filter が効かない環境では**不透明な surface に落とす**（@supports）
     - prefers-reduced-transparency でも同じく不透明に落とす
     - 表とコードは **--glass-strong**（0.88）。密度が高いところほど透けさせない

   ### 部品はここで1つだけ定義する

   **カードを個別に書かない。** `.card-grid > .cardc` を使う。高さは
   `grid-auto-rows: 1fr` と `.cardc__foot { margin-top:auto }` で必ず揃う
   （バラバラになるのは、カードごとに別のスタイルを書いたとき）。
   ========================================================================== */

/* ⚠ **ガラス・角丸・余白・文字サイズのトークンは、この節にはもう無い。**
 *   ファイル冒頭の `:root` 1組に畳んである。ここに `:root { ... }` を書き足すと、
 *   同じトークンの答えが2箇所になる（`tests/web/test_stylesheet.py` が落とす）。 */


/* ⚠ **`body` の下に余白を入れない。** かつて `padding: 0 0 80px` が入っていて、
 *   フッタの**下に 80px の空白**が全ページで出ていた（何も無い帯に見える）。
 *   フッタ自身が `.foot-in` で内側に余白を持っているので、外側は要らない。 */
/* ⚠ **幅はトークン（`--page-max`）1箇所だけが持つ。** 以前は上の base 節にも
 *   `max-width: 980px` があって常に負けていた。`static/finder.css` の `--fd-bleed` は
 *   この幅を前提に計算しているので、**生の数を2箇所に書かない。**
 * ⚠ 左右 44px は **24（もとの `.wrap`）+ 20（`body` から外したぶん）**。
 *   全幅で出したいもの（トップバー・警告帯・フッタ）と中央寄せしたいものが
 *   `body` の子に混ざっているので、余白は中身側で取る。 */
.wrap { max-width: var(--page-max); margin: 0 auto; padding: 0 var(--gutter); }

/* ------------------------------------------------------------- 背景の光 */

/* ガラスは「後ろに何かある」ときだけ成立する。**淡い光を3つだけ**置く。
   ⚠ 面積が広いので彩度を上げない。ここが濃いと全ページの文字が読みにくくなる。 */
.aurora { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.aurora i { position: absolute; display: block; border-radius: var(--radius-pill); filter: blur(90px); }
.aurora .a1 { width: 52vw; height: 52vw; top: -16vw; left: -10vw;  background: var(--tint-1); }
.aurora .a2 { width: 36vw; height: 36vw; top: 26vw;  right: -12vw; background: var(--tint-2); }
.aurora .a3 { width: 42vw; height: 42vw; top: 92vw;  left: 16vw;   background: var(--tint-3); }

/* --------------------------------------------------------------- ガラス */

.glass {
  position: relative;
  background: var(--glass);
  -webkit-backdrop-filter: blur(var(--blur)) saturate(150%);
  backdrop-filter: blur(var(--blur)) saturate(150%);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
}
/* 上辺のハイライト1本。これが無いと「白い箱」に見える */
.glass::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 1px;
  border-radius: var(--radius) var(--radius) 0 0;
  background: linear-gradient(90deg, transparent, var(--glass-top) 22%, var(--glass-top) 78%, transparent);
  pointer-events: none;
}

/* ⚠ **透過に読みやすさを払わない。** 効かない環境・嫌う設定では不透明に落とす。 */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass { background: var(--surface-1); }
}
@media (prefers-reduced-transparency: reduce) {
  .glass { background: var(--surface-1); backdrop-filter: none; }
  .aurora { display: none; }
}

/* =========================================================== トップバー */

/* ⚠ **高さを増やさない。** 本文が主役で、ここは道しるべ。
   強み（何のサイトか）は1行だけ、ブランドの隣に置く。 */
/* ⚠ **トップバーだけはガラスにしない（2026-10-08）。** `--glass`（0.70）＋ blur で
   やっていたが、**下を流れる行が透けて読めた** —— とくに `/search/` は
   `thead` が `--fd-top`（＝このバーの高さ）に貼り付くので、バーと見出し行が
   隙間なく縦に並び、**透けた行が見出しの裏を突き抜けて見える**。
   「変なところで sticky になっている」と報告されたのはこれ。
   ⚠ **`.glass`（カード類）は 0.70 のままでよい。** あちらは下に本文が来ない。
     透けて困るのは**固定されて本文が裏を流れるもの**だけ。
   ⚠ 不透明にしたので `backdrop-filter` は要らない（合成レイヤを1枚減らせる）。 */
.topbar {
  position: sticky; top: 0; z-index: 30;
  background: var(--surface-1);
  border-bottom: 1px solid var(--border);
}
/* ⚠ 左右の余白は**ここ（中身側）で取る。** `body` に付けていた 20px を外したので、
   帯そのものは画面端まで届き、中身だけが `.wrap` と同じ位置に揃う。

   ⚠⚠ **`max-width` を落とさない（2026-10-09 に足した）。** 上の1文は前から
   書いてあったのに、**`max-width` が無いので嘘だった** ——
   `.wrap` と `.foot-in` は `--page-max`（1140px）で中央に寄るのに、ここだけが
   画面幅いっぱいに広がっていた。実測の左端のずれ:

   | 画面幅 | ロゴの左 | 本文（h1・フッタのロゴ）の左 | ずれ |
   |---|---|---|---|
   | 1180 | 44 | 64 | 20px |
   | 1280 | 44 | 114 | 70px |
   | 1440 | 44 | 194 | **150px** |
   | 1680 | 44 | 314 | **270px** |

   右側も同じで、1440px では検索窓の右端が本文の右端より **150px 外**に出ていた。
   ＝ **「ロゴや文字の中心が合っていない」の正体はこれ**（縦の 1px ではない）。
   同じ `--page-max` を読む3箇所目として、`.foot-in` と1文字も違えないこと。 */
.topbar-in {
  display: flex; align-items: center; gap: var(--gap-4);
  height: var(--bar-h); max-width: var(--page-max); margin: 0 auto; padding: 0 var(--gutter);
}
/* ⚠⚠ **縦は `baseline`。`center` に戻さない（2026-10-09・指摘）。**
   「これ**そろってるように見えない**よ？『日本企業9,192社の…』この文言は**少し下**が
   いいのでは？」—— そのとおりで、**大きさの違う文字を箱の中心で揃えると揃って見えない。**
   17px の `SonarStax` と 12.5px のタグラインは、箱の中心を合わせると
   **ベースラインが 2.19px ずれる**（実測。タグラインのほうが上に浮く）。

   実測（1440px・`.topbar` の上端を 0 とする）:
     center   … 名前 35.55 / タグライン 33.36 → **ずれ 2.19px**
     baseline … 名前 35.55 / タグライン 35.55 → **ずれ 0.00px**（タグラインが 2.19px 下がる）

   ⚠⚠ **印（SVG）には `align-self: center` が要る。** SVG にはベースラインが無いので、
     `baseline` のままだと**下端がベースラインに吸い付いて**跳ね上がる
     （`.area-head` で踏んだのと同じ罠）。印は下の `.brand-mark` で中心そろえに戻す。
   ⚠ フッタの `.foot-brand` も同じ組にしてある。**片方だけ触らないこと。** */
/* ⚠ **`flex: none` をやめた（2026-10-10）。** `.brand-sub` を出す段を 1000px から
   899px に寄せたので、**900〜1000px はタグラインが戻る帯**になる。そこで
   ブランドが縮めないと、入りきらないぶんが**トップバーを横に突き破る**
   （`overflow-x: hidden` で蓋をするのは禁じ手 —— `docs/design/responsive.md` §4.6）。
   ⚠ **`min-width: 0` だけでは `.brand-text` は縮まない**（min-content が
     「SonarStax」1語ぶんあるので、そこで止まる）。**縮むのはタグラインだけ** ——
     それが狙い（名前は絶対に削らない）。 */
/* ⚠ `min-width: 0` は**タグライン（`.brand-sub`）を縮ませるため**に要る
   （900〜1000px の帯）。⚠ **サービス名（`.brand-text`）は `flex: none` で
   譲らない** —— 両方が縮むと、器より広い文字がナビの上に乗る（下の注記）。 */
.brand { display: inline-flex; align-items: baseline; gap: var(--gap-ic-lg); color: var(--text-primary); text-decoration: none; flex: 0 1 auto; min-width: 0; }
/* ⚠⚠ **グラデーションの四角をやめ、ソナーの絵にした（2026-10-09）。**
   前は 17px の四角で、**何の印なのか読めなかった**。サービス名が
   SonarStax なので、トップの `dish()` と同じモチーフを印にする。
   ⚠ **実体は `parts/_sonar.html` の `mark()`**（`dish()` を縮めたものではない ——
     あちらは 240px 前提で、縮めるとただの灰色の円になる）。
   ⚠ **動かさない。** 全ページに出るので、回り続ける絵は邪魔になる。
   ⚠ ブランド名を 17px に上げたのに合わせて 20px。
     小さいままだと名前の横で汚れに見える。 */
/* ⚠ **`align-self: center` を外さない。** 親が `align-items: baseline` なので、
   これが無いと**印の下端が文字のベースラインに吸い付いて**跳ね上がる
   （SVG はベースラインを持たないため。`.area-head .with-ic > svg` と同じ）。 */
.brand-mark { width: 20px; height: 20px; flex: none; overflow: visible; align-self: center; }
/* ⚠ **線は `--series-1`、扇と点はその濃淡で作る。** 新しい色を作らない。
   ⚠ `stroke-width` は viewBox 24 で 1.4（20px に落とすと約 1.17px）。
     これより細くすると、標準的な画面でリングが消える。 */
.brand-mark__ring {
  fill: none; stroke: var(--series-1); stroke-width: 1.4; opacity: .55;
}
.brand-mark__sweep { fill: var(--series-1); opacity: .16; }
.brand-mark__dot { fill: var(--series-1); }
/* ⚠ 2026-10-09 に `--fs-md`(14) -> `--fs-lede`(17)。サービス名がナビと
   同じ大きさで、**どれが名前なのか見て分からなかった**。

   ⚠⚠ **縦のずれを `text-box` でも nudge でも直さない（2026-10-09 に実測して見送った）。**
   行ボックスは字の下にディセンダぶんの空きを持つので、`align-items: center` だと
   欧文がわずかに沈む。実測（1440px・実寸4倍の画素・印の中心を 0 とする）:

       印 0.00 ／ SonarStax **+1.00** ／ タグライン +0.25 ／ ナビ −0.63 px

   `text-box: trim-both cap alphabetic`（箱を「大文字の上端〜ベースライン」にする）を
   実際に入れて測ったが、**字は 0.03px しか動かなかった** —— このフォントの
   宣言上の cap height（0.774em）と実際の字面（0.72em）の差が、ちょうど
   half-leading の非対称を打ち消していたため。**効かないものを入れておかない。**
   ⚠ **`translateY` / `margin` の生の px で詰めない。** ずれ量はフォントの
     ascent / descent / capHeight で決まるので、OS ごとのフォールバック書体では
     必ず別の値になる（直したつもりで他の環境を壊す）。
   ⚠ **「中心が合っていない」の正体は縦ではなく横だった**（`.topbar-in` の
     `max-width`。上の表を見ること）。1px 未満の縦を追う前にそちらを疑う。 */
/* ⚠⚠ **サービス名は縮まない（2026-10-10・実測で踏んだ）。**
   `.brand` は `flex: 0 1 auto; min-width: 0` で、**自分の文字より狭く潰れられる**。
   `.brand-text` にそれを受ける仕掛けが無かったので、潰れたぶん**文字が器から
   はみ出してナビの上に乗った**（390px の実測で「SonarStax」と「プロダクトから探す」が
   23x29 重なり、`qa_mobile.py` の `collide` が検出）。
   ⚠ **`min-width: 0` を `.brand` から外さない。** あれは 900〜1000px で
     タグライン（`.brand-sub`）を省略記号にするために要る。**縮む役はあちら。**
   ⚠ **ここで `overflow: hidden` + 省略記号にしない。** サービス名が
     「SonarSt…」になるのは、畳むより悪い（何のサイトか分からなくなる）。
     **譲らないと宣言して、隣（ナビ）に畳ませる。** */
.brand-text {
  font-weight: var(--fw-bold); letter-spacing: -0.015em; font-size: var(--fs-lede);
  flex: none; white-space: nowrap;
}
/* サービス名の**隣**に「何のサイトか」を1行。⚠ **縦に積まない。** 積むと
   トップバーが2行ぶんの高さを要求して、ナビと検索窓が押し出される。 */
.brand-sub {
  /* ⚠ 2026-10-09 に `--fs-xs`(11.5) -> `--fs-sm`(12.5)、色も muted -> secondary。
     11.5px の muted は**読むものとして扱われていなかった**。 */
  font-size: var(--fs-sm); color: var(--text-secondary); font-weight: var(--fw-medium); letter-spacing: 0;
  padding-left: 10px; margin-left: 2px; border-left: 1px solid var(--border);
  white-space: nowrap;
  /* ⚠ **入りきらないときは省略記号で詰める（2026-10-10）。** 900〜1000px は
     タグラインが出る帯のいちばん狭いところで、ブランド＋ナビ3本＋検索窓が
     そのままでは収まらない。`min-width: 0` が無いと flex の子は
     **中身より縮まない**ので、バーごと横に伸びる（この面で何度も踏んでいる形）。
     ⚠ **`.brand-text` には付けない。** サービス名が「SonarSt…」になる。 */
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
  /* ⚠ **区切り線の高さはこの行ボックスそのもの。** 既定（1.7）だと 21.25px あって、
     12.5px の字に対して縦線だけが長く伸びる。1.25 で 15.6px ——
     **字に付いている区切り**に見える高さにする。
     ⚠ `line-height` を触っても**ベースラインは動かない**（上の `.brand` の整列は
       そのまま）。動くのは線の長さだけ。 */
  line-height: 1.25;
}
.nav { display: flex; gap: var(--gap-1); margin-left: auto; align-items: center; }
.nav a {
  color: var(--text-secondary); text-decoration: none; font-size: var(--fs-md);
  padding: 6px 10px; border-radius: var(--radius-sm); white-space: nowrap;
}
.nav a:hover { color: var(--text-primary); background: var(--glass-strong); }
/* いまどこにいるか。
   ⚠⚠ **太字だけにしない（2026-10-09）。** 「太字になるだけだとわかりづらい」と
   言われた。太さの差は**他の選肢と並べて比べないと読めない**上に、
   日本語のゴシック体は欧文より太さの差が出にくい。**下線で位置を言う。**
   ⚠ `border-bottom` ではなく `::after`。縁を足すと**選んでいるときだけ
     高さが 2px 伸びて**、ナビ全体が上下に跨ねる。
   ⚠ 線は**文字の幅だけ**（`padding` の外側まで引かない）。
     器いっぱいに引くとタブのバーに見えて、押せるものが増えたように読める。
   ⚠ 色と太字は**残す**。線だけにすると、線が見えない環境（強制色モード）で
     現在地が完全に消える。 */
.nav a[aria-current="page"] {
  color: var(--text-primary); font-weight: var(--fw-semibold); position: relative;
}
.nav a[aria-current="page"]::after {
  content: ""; position: absolute; left: 10px; right: 10px; bottom: 0;
  height: 2px; border-radius: var(--radius-pill); background: var(--link);
}
/* ⚠ **`.nav .btn-sm` は消した。** `web/emit/render.py` の `NAV_ITEMS` は
 *   `(href, label, seg)` の3つ組で、class を持たせる口が無い。ナビに CTA の
 *   ボタンは**一度も出ていない**。戻すなら `NAV_ITEMS` の形から変わる。 */

/* ⚠⚠ **トップバーはどの幅でも1段（2026-10-10 に直した）。**
 *
 *   直前までここは `@media (max-width: 720px)` で
 *   `.topbar-in { height: auto; flex-wrap: wrap }` ＋ `.nav { width: 100% }` だった。
 *   ＝ ブランド / ナビ / 検索窓が**縦に3段**に折れ、**390px の実測で 137px
 *   （画面の16%）**。設計値 `--bar-h`（58px）の **2.4倍**で、固定物だけで
 *   最初の画面の1/6を食っていた（`docs/design/responsive.md` §0）。
 *
 *   折り返す代わりに、**入らないものを縮めて横に逃がす**:
 *     - `.nav` … 幅を譲って**横スクロール**（3本とも消さずに残る）
 *     - `.sg--bar` … `flex-shrink` で縮む（下の「検索窓」節に寸法がある）
 *     - `.brand-sub` … wide でだけ出す（下）
 *
 * ⚠ **`display: none` でナビや検索窓を消さない。** 消すとその入口が
 *   この面のどこにも無くなる（`docs/design/responsive.md` §1.2）。
 * ⚠ **ハンバーガーを足さない。** ナビは3本しかないので、畳んでも1タップ増えるだけ。
 * ⚠ **`height: auto` に戻さない。** 戻すと `--bar-h` と
 *   `html { scroll-padding-top }` のフォールバックが同時に嘘になる（上の2箇所に注記）。
 * ⚠ compact（≤599px）ではさらに**検索窓をアイコンに畳む**（設計 §4.4）。器と
 *   アイコンを出すのは `parts/_searchbox.html` の `collapsible=true` で、
 *   **広い画面でただの検索窓に戻すのはこの CSS の役目** ——
 *   下の「狭い画面では検索窓をアイコンに畳む」節（`.sg-open` / `.sg-pop`）。
 *   ⚠⚠ **あの節を消すと、ヘッダーの検索窓がどの幅でも画面から消える**
 *     （`[popover]:not(:popover-open) { display: none }` という UA の既定が効く）。 */
/* 狭いときはサブタイトルを落とす。**ナビと検索窓のほうが先に要る。**
   ⚠ **ブランド名（`.brand-text`）は残るので、これは消してよい `display: none`**
     —— 「何のサイトか」の1行が落ちるだけで、入口はどこにも消えない
     （`docs/design/responsive.md` §1.2 の表で⭕と判定された唯一のもの）。
   ⚠ 2026-10-10 に **1000px -> 899px**。段を 599 / 899 の2つに寄せたため
     （`tests/web/test_responsive.py`）。**900〜1000px はタグラインが戻る帯**になるので、
     入りきらないぶんは `.brand-sub` が省略記号で詰まる（下の `.brand` の注記）。 */
@media (max-width: 899px) {
  .brand-sub { display: none; }
  /* ⚠⚠ **`.nav { overflow-x: auto }` はここから消した（2026-10-10）。**
     横スクロールで3本を押し込む手だったが、**必要な 376px に対して残りは
     129px しか無く**、押し込んだ結果**ブランド名の上にナビが乗っていた**
     （`collide` 検出）。いまは下の「狭い画面ではナビを畳む」節が
     `popover` のシートにする。**横スクロールへ戻さないこと。** */
}
@media (max-width: 599px) {
  /* ⚠ **`--gap-4`(16px) では2つぶん 32px が効く。** 350px しかない画面では
     ナビ1本ぶんに近いので1段詰める。**高さは詰めない**（`--bar-h` のまま）。 */
  .topbar-in { gap: var(--gap-2); }
}

/* サンプルデータの帯。**出所を隠さない。**
   ⚠ **全幅で出す。** 「公開してはいけません」の警告帯が画面端から 20px 内側に
      浮いていると、それだけで弱く見える（`body` の左右 padding を外した理由）。 */
.ribbon { background: var(--critical); color: #fff; font-size: var(--fs-sm); padding: 6px var(--gutter); text-align: center; }
.ribbon strong { margin-right: 8px; }
.ribbon b { text-decoration: underline; text-underline-offset: 2px; }

/* ============================================================== 見出し */

/* ⚠⚠ **下は `padding` で持つ（2026-10-11、指摘）。** `footer` は
   `margin-top: 64px` を持っているが、**隣接マージンの相殺**で最後の節の
   `margin-bottom`（`section` は 40px）に飲まれ、どのページでも実測 **40px** だった。
   `.fd`（/search/）と `.psec`（製品個票）は `margin-bottom: 0` なので **0px** ——
   フッタが本文にくっついて見える。
   ⚠ **`footer` の `margin-top` を増やして直さない。** 相殺される側なので
     増やしても最後の節の値より小さいうちは1pxも効かない。
   ⚠ **面ごとに `padding-bottom` を足して回らない。** 2026-10-11 に `/search/` だけ
     そうして、製品個票で同じことが起きているのを見落とした。**器がまとめて持つ。** */
main.wrap { padding-top: 28px; padding-bottom: 56px; }
section { margin: 0 0 40px; }
.eyebrow { font-size: var(--fs-sm); color: var(--text-muted); margin: 0 0 6px; }
.eyebrow a { color: var(--text-secondary); }
/* ⚠ **`h2` の定義はここ1箇所だけ。** 節の区切りは `<section>` の margin と
 *   `.sec-head` が作るので、罫（`border-top`）も上余白も持たせない。以前は base 節に
 *   `margin: 48px 0 6px; padding-top: 22px; border-top: 1px solid` の一式があり、
 *   **4つとも下で打ち消されていた**（打ち消し用の `h2:first-of-type { border-top: 0 }`
 *   もろとも意味を失っていた）。 */
h2 { font-size: var(--fs-h2); margin: 0 0 4px; letter-spacing: -0.005em; }
.sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--gap-4); flex-wrap: wrap; margin-bottom: 10px; }
.sec-head .sub { margin-top: 0; }
.page-head { margin-bottom: 22px; }
.page-head h1 { margin: 0 0 8px; }
/* 見出しの横に「この画面がいま何件を相手にしているか」を置く行（2026-10-09）。
 *
 * ⚠ **件数は表の中に入れない**（指摘）。`/product/` の「1,133 プロダクト」も
 *   `/search/` の「7,736 社（7,581 ドメイン）…」も、表カードの中の帯に入っていて
 *   **表に付いている操作のように見えていた**。どちらも「この画面は何を相手に
 *   しているか」の話なので、題の横が正しい場所。
 * ⚠ **`align-items: baseline`。** 32px の `h1` と 12.5px の注記を箱の中央で
 *   揃えると、小さいほうが宙に浮く。**文字どうしは足元で揃える。**
 * ⚠ **狭い画面では折り返す。** 390px で `h1` と件数を1行に詰めると、
 *   どちらも読めない幅になる。
 * ⚠ `h1` の下マージンはこの行が持つので、中では 0 に戻す（二重に空く）。 */
.page-head__top {
  display: flex; align-items: baseline; flex-wrap: wrap;
  gap: var(--gap-1) var(--gap-3); margin: 0 0 8px;
}
.page-head__top h1 { margin: 0; }
/* 件数に**付いてくる**もの（`/product/` の「絞り込みを解除」と、`/search/` の
   「この表の単位」の `?`）。
   ⚠ **`margin-left: auto` で右端へ飛ばさない（試してやめた）。** 1440px では
     件数から 1,000px 以上離れ、**何に付いているボタンなのか読めなくなった**。
     `?` が答えるのは「なぜ 7,736 社が 7,581 ドメインなのか」で、
     「絞り込みを解除」が戻すのは隣の「21 / 1,133」。どちらも**数のすぐ後ろ**が正しい。
   ⚠ 数の一部に見えないように、親（`.page-head__top`）の `gap` ぶんは必ず空ける
     （どちらも枠を持つ部品なので、それで十分に別物に見える）。 */
.page-head__end { display: flex; align-items: center; gap: var(--gap-2); }
.head-badges { margin-top: 12px; display: flex; flex-wrap: wrap; gap: var(--gap-2); align-items: center; }
/* ⚠ **`display` を持つので `[hidden]` の打ち消しが要る**（下の `.facts[hidden]` と
   同じ理由。UA の `[hidden] { display: none }` は作者スタイルより弱い）。
   焼かない会社のページ（`pages/company_not_listed.html`）は、JS がドメインの
   チップを入れるまでここを `hidden` にしている —— 無いと **12px の空行**が
   見出しの下に先に出る。検査は `tests/web/test_stylesheets.py`。 */
.head-badges[hidden] { display: none; }
.more { font-size: var(--fs-md); margin: 12px 0 0; }
.more a { text-decoration: none; }
.more a:hover { text-decoration: underline; }
.fine { font-size: var(--fs-sm); }
/* 見出しの隣の件数。
   ⚠ **見出しとの間を詰めない（2026-10-09、指摘）。** くっつくと
   「導入している企業166社」で見出しの一部に見える。 */
.count-pill {
  font-size: var(--fs-sm); color: var(--text-secondary); background: var(--glass-strong);
  border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 2px 10px;
  margin-left: 12px;
  font-variant-numeric: tabular-nums;
}

/* ====================================================== カード（部品） */

/* ⚠ **カードは `.scard`（このファイルの下の方）1つだけ。**
 *
 * ここには `.card-grid` / `.cardc`（`parts/_card.html`）という**2つ目のカード**が
 * あった。「カードはこれ1つだけ」と書いてあるのに、**どのテンプレートからも
 * 呼ばれていない**（焼いた HTML に `cardc` が1文字も出ない）。実際に使われて
 * いるのはトップの `.scard` のほうで、つまり
 * **「正だと書いてあるほうが死んでいる」**状態だった。
 *
 * 死んだほうを残すと、次に誰かがカードを足すときここを読んで**3つ目**を作る。
 * だから消す。**新しいカードを足すなら `.scard` を育てること。** */

/* ================================================================ チップ */

.chips { display: flex; flex-wrap: wrap; gap: var(--gap-1); }
.chip {
  font-size: var(--fs-xs); padding: var(--pad-chip); border-radius: var(--radius-pill);
  border: 1px solid var(--border); color: var(--text-secondary);
  background: var(--glass-strong); white-space: nowrap;
}
.chip--more, .chip--muted { color: var(--text-muted); }
a.chip--link { text-decoration: none; }
a.chip--link:hover { border-color: var(--series-1); color: var(--link); }

/* ================================================================== 表 */

/* ⚠ 一番密度が高いところ。**透過を弱める**（0.88）。
   ⚠ **thead を sticky にしない。** トップバーと2重になって1行目が隠れる。 */
.tablecard { background: var(--glass-strong); overflow: hidden; margin: 12px 0 0; }
.tablecard table { margin: 0; }
.tablecard th { background: transparent; }
.tablecard th, .tablecard td { padding: 10px 16px; }
.tablecard tbody tr:last-child td { border-bottom: 0; }
/* ⚠ **生の `rgba()` を書かない。** ここは `rgba(42,120,214,.045)`（＝`--series-1` の
   生値を 4.5% で薄めたもの）が直書きされていて、系列色を動かしても追従しなかった。
   同じ役割のトークンが `--tint-1` にあり、`/search/` の表
   （`static/finder.css` の `.fd-table tbody tr:hover`）は正しくそちらを使っている
   —— **同じサイトの表で片方だけトークンから外れている**状態だった。 */
.tablecard tbody tr:hover { background: var(--tint-1); }
/* ⚠⚠ **太字にしない（2026-10-09）。** `--fw-medium`(560) で出していたが、
   60〜150行が全部太いと**表そのものが重く**見える（「太字なのがちょっと微妙だな
   と思っているんだよね。全部。細く」）。
   ⚠ **これで上下の表の太さが揃う。** 「検出できなくなった企業」側は
     `.past .cname { font-weight: var(--fw-normal) }` で前から 400 だったので、
     **同じページの2つの表で社名の太さが違っていた**（指摘「何で上と下で
     企業の文字のサイズって違うの？」の正体）。
   ⚠ 押せることは**色（`--link`）とホバーの下線**が言っている。太さは要らない。 */
.cname { font-weight: var(--fw-normal); text-decoration: none; }
.cname:hover { text-decoration: underline; }
/* 個票が無い会社へのリンク（`/company/not-listed/?n=`）。
   ⚠ **リンクに見せるが、個票と同じ強さにしない。** 行き先は共通の1枚で、
     その会社について書いてあるのは商号・所在地・ドメインだけ。
     同じ見た目にすると「個票がある」と期待させる。
   ⚠ **`static/company.css` へ戻さない。** 出しているのは共有部品の
     `parts/_table.html` で、その表はプロダクト個票にも出る。あそこには
     `company.css` が配られないので（`web/emit/render.py` の `STYLESHEETS_BY_TEMPLATE`）、
     **個票がある会社と無い会社が見た目で区別できなくなる**。 */
.cname--none { color: var(--text-secondary); text-decoration-style: dotted; }
.dom, .city {
  display: block; font-size: var(--fs-xs); color: var(--text-muted);
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
}
.city { font-family: inherit; }
.place { white-space: nowrap; }
.also { font-size: var(--fs-sm); color: var(--text-secondary); max-width: 28ch; }
/* 併用プロダクトの列。⚠ **2行で打ち切る。** 3行に伸びた行だけが背が高くなって、
   150行の表が波打っていた（`Microsoft 365、Microsoft 365（テナント名の露出）`）。
   ⚠ **`<td>` ではなく中の `<span>` に当てる。** `display: -webkit-box` を `<td>` に
   当てるとそのセルが表のレイアウトから外れ、**列幅と罫線が崩れる**（実測）。 */
.also__t {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
td.when { font-size: var(--fs-sm); color: var(--text-muted); }
/* 確からしさは日付の下の段。⚠ **同じ行に並べない**（`td.num` が nowrap なので
   `2023-10確度中` と繋がって読めなくなる）。 */
.when__conf { display: block; }

/* 表の中の極小バー。**数字の代わりではなく、数字の隣に置く。**
 *
 * ⚠ **高さと角丸は `--meter-h-sm` / 999px で、`.co__track`（`static/saas.css`）と揃える。**
 *   この2つは同じ「割合を示す極小バー」で、**プロダクト個票では同じ画面に並ぶ**のに
 *   5px と 6px、44px 幅と可変幅で微妙に違っていた。揃っていないと、読み手は
 *   「違う意味なのだろう」と考えてしまう。幅だけは役割が違う（こちらは表のセルの中で
 *   固定、あちらはリストの列）ので別でよい。
 * ⚠ 角丸に px を書かない。高さを変えると「端が丸い」が崩れる。999px なら常に丸い。 */
.mini {
  display: inline-block; width: 44px; height: var(--meter-h-sm);
  background: var(--gridline); border-radius: var(--radius-pill);
  vertical-align: middle; margin-right: 7px;
}
.mini-fill { display: block; height: var(--meter-h-sm); border-radius: var(--radius-pill); background: var(--step-3); }

/* 「検出できなくなった」側の表は**弱く出す**。推論にもとづくので。 */
.past .tablecard { background: var(--glass); }
/* ⚠ **`--fw-medium` に寄せない。** あれは 560 で、素の `.cname`（560）と同値に
   なるうえ、400 より**太い**。ここは弱めたい場所なので `--fw-normal`。 */
.past .cname { font-weight: var(--fw-normal); }
.past table { color: var(--text-secondary); }

/* ================================================================== 棒 */

/* ⚠ **`.brow` / `.bfill` / `.bval` そのものは上の「横棒（集計）」節が持つ。**
 *   ここに書き足すと同じ要素の答えが2箇所になる。ここはリンクと単位だけ。 */
.blabel a { text-decoration: none; color: var(--text-secondary); }
.blabel a:hover { color: var(--link); text-decoration: underline; }
.bval .unit { font-size: var(--fs-xs); color: var(--text-muted); margin-left: 2px; font-weight: var(--fw-medium); }

/* ============================================== 根拠（popover で出す） */

/* 根拠は**毎行に出さない**。クレーム対応では必要だが、読むときは邪魔。
   HTML の popover API だけで開く（**JS を1行も書かない**）。 */
/* ⚠ **高さ 24px を切らない。** `padding: 4px` だと実測 22px で、指で押すには
   小さい（WCAG 2.2 の Target Size は 24x24 が下限）。カードの中に並ぶので
   幅は詰めたいが、**高さだけは確保する**。 */
.ev-btn {
  font: inherit; font-size: var(--fs-xs); line-height: 1;
  min-height: 24px; padding: var(--pad-btn-sm); border-radius: var(--radius-pill); cursor: pointer;
  border: 1px solid var(--border); background: transparent; color: var(--text-muted);
}
.ev-btn:hover { color: var(--text-primary); border-color: var(--baseline); }
.pop {
  border: 1px solid var(--glass-edge); border-radius: var(--radius);
  background: var(--surface-1); color: var(--text-primary);
  box-shadow: var(--shadow-2); padding: 18px 20px; max-width: 420px;
}
.pop::backdrop { background: rgba(11,11,11,.30); }
/* popup の見出し。⚠ **`<h1>`〜`<h6>` を使わない。**
 * popup は `<section>` の中に書くので、`h2` の節の中に `h4` が現れて
 * **見出しの階層が飛ぶ**（支援技術は見出しだけを拾って読むので、そこで迷子になる）。
 * popup は自己完結した小窓で、ページの目次に載せたいものではない。
 * `parts/_hint.html` が先に `<b class="pop__h">` にしてあったので、そちらに揃えた。 */
.pop__h {
  display: block; margin: 0 0 10px;
  font-size: var(--fs-md); font-weight: var(--fw-semibold); color: var(--text-primary);
}
.pop dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: var(--gap-2) var(--gap-4); font-size: var(--fs-sm); }
.pop dt { color: var(--text-muted); }
.pop dd { margin: 0; }
.pop code { font-size: var(--fs-xs); word-break: break-all; }
.pop .note { margin: 12px 0 0; font-size: var(--fs-xs); color: var(--text-muted); }
/* popover 非対応のブラウザで中身が常時見えてしまうのを防ぐ */
@supports not selector(:popover-open) { [popover] { display: none; } }

/* ============================================================== 一覧 */

/* ⚠⚠ **`max-width: none`（2026-10-09）。** 散文向けの既定 `ul { max-width: 72ch }`
   がここにも乗り、`/disclaimer/` の条項が**パネル 1,052px に対して
   582px で止まっていた**（実測）。「左によりすぎじゃない？右はなぜ使わないの？」
   の半分はこれ。`ul.plain` は**飾りを外した器**であって散文ではない。 */
ul.plain { list-style: none; padding: 0; max-width: none; }
ul.plain li { padding: 6px 0; border-bottom: 1px solid var(--border); font-size: var(--fs-md); }
ul.plain li:last-child { border-bottom: 0; }
/* ⚠ **`ul.rank` は消した。** 順位つきの一覧は `.co`（よく併用されているプロダクト）
 *   と `.bars`（横棒）が担っていて、`class="rank"` は1件も出ない。 */

/* 定義リスト（製品の素性など）。**文章で説明しない。事実を並べる。** */
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--gap-4) var(--gap-5); margin: 0; }
.facts dt { font-size: var(--fs-xs); color: var(--text-muted); }
.facts dd { margin: 2px 0 0; font-size: var(--fs-md); }
.facts a { text-decoration: none; }
.facts a:hover { text-decoration: underline; }
/* ⚠ **`display` を持たせたクラスには、必ず `[hidden]` の打ち消しを書く。**
   UA の `[hidden] { display: none }` は**作者スタイルより弱い**ので、
   `.facts { display: grid }` のほうが勝つ。`/company/not-listed/` は JS が
   値を入れるまでこの `<dl>` を `hidden` で隠しているので、これが無いと
   **空の枠が先に出る**（`.fd-btn[hidden]` が `static/finder.css` で同じことをしている）。
   検査は `tests/web/test_stylesheets.py`。 */
.facts[hidden] { display: none; }

/* ⚠ **`.psec .panel`（saas.css）と `.prof`（company.css）と同じ値にする。**
 *   以前ここだけ 20px で、プロダクト個票と企業個票を行き来すると面の内側が
 *   2px ずれていた。トークンを動かせば3箇所とも動く。 */
.panel { padding: var(--pad-panel); }
/* ⚠ **面の内側の余白を、中身の margin で二重にしない。** 素の `p` は上下 10px
 *   持つので、先頭が `<p>` のパネルだけ上が 30px、`margin: 0` の中身から始まる
 *   パネルは 20px になり、**同じ見た目のはずの面で余白が食い違っていた**
 *   （`/method/` に3枚並んでいて気づいた）。 */
.panel > :first-child { margin-top: 0; }
.panel > :last-child { margin-bottom: 0; }
/* ⚠ **パネルの中だからといって見出しを小さくしない。** `--fs-lede`（17px）に
 *   落としていたので、同じ節の見出しが**面に載っているかどうかだけで 17px と
 *   20px に割れていた**（`/product/<id>/` は5つの h2 のうち3つが 17px、2つが
 *   20px）。読み手には同じ階層に見えるので、大きさが違う理由が無い。
 *   階層を下げたいときは `h2` ではなく `h3` を書く。 */
.panel h3 { margin-top: 0; font-size: var(--fs-md); }
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-4); align-items: start; }
.two-col--wide-left { grid-template-columns: 1.4fr 1fr; }

/* ================================================================ 出口 */

/* ⚠ これが無いと SEO は自己満足で終わる（docs/design/tech_stack.md §4.4）。 */
/* ⚠ **`.cta-card` / `.cta-h` は消した。** 対になるマクロ（`teaser.cta()`）が
 *   どのページからも呼ばれておらず、焼いた 2,887 ページに `cta-card` が0件だった。
 *   理由と、作り直すときの条件は `templates/parts/_teaser.html` に書いてある。 */
.btn {
  flex: none; display: inline-block; text-decoration: none; white-space: nowrap;
  background: var(--series-1); color: #fff; font-size: var(--fs-md); font-weight: var(--fw-semibold);
  padding: var(--pad-btn); border-radius: var(--radius-pill);
}
.btn:hover { background: var(--step-4); }

/* 注意書き。**目立たせるが、赤で威嚇しない。** */
.warn {
  border-left: 3px solid var(--baseline);
  background: var(--glass); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: 13px 17px; margin: 16px 0;
}
.warn .h { font-weight: var(--fw-semibold); font-size: var(--fs-md); }
.warn p { font-size: var(--fs-sm); margin: 5px 0 0; }
/* ⚠ **`.mono` は消した。** `class="mono"` はテンプレートにも app.js にも無い
 *   （`pico--mono` は別のクラス）。等幅が要るのは `code` と `.dom` で、
 *   どちらも自前で指定している。 */

/* ============================================================ パンくず */

/* ⚠ **ここがパンくずの唯一の定義。** 2箇所に分けると、どちらが勝つかで
 *   間隔がページごとに違って見える（実際にそうなっていた）。
 * ⚠ **間隔は `gap` だけで持つ。** `.crumbs span` に margin を当てると、区切り記号
 *   だけでなく現在地のラベルにも乗って、左右が非対称（6px と 12px）になる。 */
/* ⚠ **中身は `<ol><li>`**（`parts/_crumbs.html`）。並んだリンクの羅列では
 *   「何番目の階層か」が支援技術に伝わらない。見た目は今までどおりなので、
 *   リストの既定（記号・左の余白・行の margin）だけ落とす。 */
.crumbs ol {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 var(--gap-2);
  list-style: none; margin: 0; padding: 0; max-width: none;
}
.crumbs li { margin: 0; display: flex; align-items: baseline; gap: 0 var(--gap-2); }
.crumbs {
  font-size: var(--fs-sm); color: var(--text-muted); margin: 0 0 14px;
}
.crumbs a { color: var(--text-secondary); text-decoration: none; }
.crumbs a:hover { text-decoration: underline; }
/* ⚠ **`--baseline` まで薄くしない。** 地との比が足りず、パンくずが
   「トップ プロダクト Google Workspace」と区切り無しに見えていた。
   区切り記号は読ませる文字ではないが、**見えないと役に立たない**。 */
.crumbs__sep { color: var(--text-muted); }
.crumbs__here { color: var(--text-muted); }

/* ============================================================== フッタ */

/* ⚠ **フッタの見た目はここ1箇所だけが持つ。** 以前は色と文字サイズだけが base 節に
 *   離れていて、「フッタの文字色はどこ?」の答えが2箇所あった。 */
footer {
  margin-top: 64px; border-top: 1px solid var(--border);
  background: var(--glass);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  color: var(--text-muted); font-size: var(--fs-sm);
}
.foot-in { max-width: var(--page-max); margin: 0 auto; padding: 32px var(--gutter) 22px; }
.foot-grid { display: grid; grid-template-columns: 1.7fr 1fr 1fr 1fr; gap: var(--gap-5); }
/* ⚠ **ヘッダーの `.brand` と同じ組**（`baseline` ＋ 印だけ `align-self: center`）。
   同じ印と同じ名前を2箇所で違う揃え方にしない。 */
.foot-brand { display: flex; align-items: baseline; gap: var(--gap-2); font-weight: var(--fw-bold); font-size: var(--fs-md); color: var(--text-primary); }
/* ⚠ **`ch` は「0」の幅**（プロポーショナルなので約 7px）で、全角の1文字（12.5px）
   とは別物。34ch のつもりで 238px しか無く、22文字のタグラインが
   `…毎週 / 検出` と割れていた。全角を数えるなら `em` で持つ。 */
.foot-lede { margin: 8px 0 0; font-size: var(--fs-sm); color: var(--text-secondary); max-width: 24em; }
/* ⚠⚠ **列の見出しは「見出しだ」と分かる重さにする（2026-10-10・指摘）。**
   以前は `--fs-xs`(11.5px) の `--text-muted` で、すぐ下のリンク（`--fs-sm` 12.5px
   の `--text-secondary`）と **1px・1段階しか違わなかった**。4列に並んでいても
   「探す / データ / 掲載について」が列名なのか1本目のリンクなのか読めない。
   ⚠ **広い画面でも同じ。** 狭い画面だけの話として扱っていたのが漏れだった。
   ⚠ **大きくしすぎない。** フッタの主役はリンクで、見出しはその札。
     `--fs-sm` + `--fw-semibold` + `--text-primary` で、**大きさではなく
     濃さと太さ**で差を付ける（`--fs-md` にすると本文と並んで主従が狂う）。
   ⚠ **リンクと間を空ける。** 札と中身がくっついていると群に見えない。 */
.foot-h {
  font-size: var(--fs-sm); color: var(--text-primary);
  font-weight: var(--fw-semibold); margin: 0 0 10px; letter-spacing: .02em;
}
/* ⚠ `max-width` を**明示する**（値は何でもよいが、書かないと散文の 72ch を
   無意識に被る）。ここはフッタの細い列なので実害は無いが、
   `tests/web/test_stylesheet.py::test_a_list_used_as_layout_opts_out_of_the_prose_width`
   が「決めたことを書け」と言っている。 */
.foot-links { list-style: none; margin: 0; padding: 0; max-width: none; }
.foot-links li { margin: 0; }
.foot-links a { display: block; color: var(--text-secondary); text-decoration: none; padding: 3px 0; font-size: var(--fs-sm); }
.foot-links a:hover { color: var(--text-primary); text-decoration: underline; }
.foot-bar {
  margin-top: 26px; padding-top: 14px; border-top: 1px solid var(--border);
  display: flex; gap: var(--gap-4); justify-content: space-between; flex-wrap: wrap;
  font-size: var(--fs-xs); color: var(--text-muted);
}
.foot-bar p { margin: 0; max-width: 78ch; }
/* ⚠ フッタの段も下の「反応」節がまとめて持つ（860 / 520 からここへ移した）。
   **同じ「狭い画面の話」を2箇所に置かない。** */

/* ================================================================ 反応

   ⚠⚠ **幅の段は 599 と 899 の2つだけ（2026-10-10）。**

   実測したらサイト全体で閾値が **14種**あり、`app.css` だけでも
   **480 / 520 / 640 / 720 / 760 / 860 / 900 / 1000** の8種が混ざっていた。
   `--gap-*`（17種 → 5段）と `--fs-*`（20種 → 6段）が既に通った道とまったく同じ病気で、
   **620px と 640px の違いは誰にも伝わらないのに、触るたびに増える**。

     compact  ≤ 599px   スマホ縦（最大 430px）。1列。固定物は最小
     medium   600–899   タブレット縦・スマホ横。1列だが余裕がある
     wide     ≥ 900px   2段組が成立する（実測の下限 884px = 300 + 24 + 560）

   ⚠ **599 / 899 と書く（600 / 900 ではない）。** `max-width: 600px` は 600px を
     **含む**ので、`min-width: 600px` と重なって両方効く幅が 1px できる。
   ⚠ **3つ目を作らない。** `tests/web/test_responsive.py` が落とす。
   ⚠ **寄せ方は機械的ではない。** 760px で畳んでいたものを 599px にすると
     600〜760px で**畳まれないまま**になる。**中身でどちらの段かを決める。**
     ここでの判断（2026-10-10）:
       900 → 899   `.two-col`。2段組そのものの境なので動かしていない
       860 → 899   `.foot-grid` の 4列→2列。4列が入らなくなるのは medium の話
       760 → 899   `.tablecard` の横スクロール退避。下の注記で理由を確かめた
       720 → 899   `--gutter` 44→36
       640 → 599   `--fs-h1` と `.brow`。どちらも「指で1列」側
       520 → 599   `.foot-grid` の 2列→1列
       480 → 599   `--gutter` 36→20
   ⚠ **`(pointer: coarse)` / `(hover:)` / `(prefers-*)` は段に数えない。** 幅ではない
     （当たり判定は下の `@media (pointer: coarse)` が持つ）。 */

/* ---------------------------------------------------- medium 以下（≤899） */

@media (max-width: 899px) {
  /* 左右の余白を1段詰める。⚠ **ここで `--gutter` だけを差し替える。**
     `.wrap` / `.topbar-in` / `.ribbon` / `.foot-in` に個別の px を書くと、
     また閾値が割れる（かつてトップバーだけ 720px、本文は 640px になっていて、
     641〜720px でブランドと `<h1>` の左端が 8px ずれていた）。
     36 = 16（もとの `.wrap`）+ 20（`body` から外したぶん）。 */
  :root { --gutter: 36px; }
  .two-col, .two-col--wide-left { grid-template-columns: 1fr; }
  /* ⚠ **4列を 2列へ。** 744px（iPad mini 縦）で4列だと1列 150px を切り、
     「掲載の停止」のような語が1文字ずつ折れる。 */
  .foot-grid { grid-template-columns: 1fr 1fr; }
}

/* 表の横スクロール退避。⚠ **退避は表の最小幅より広いところから効かせる**
 *   （`.sx` の最小幅 660px ＋ 左右の余白 72px ＝ 732px で、そのあたりから
 *   はみ出し始める）。以前は 640px 以下にしか無く、**641〜760px では親が
 *   `overflow: hidden` のままはみ出しが切り落とされていた**（スクロールバーも
 *   出ないので、列が1つ足りないことにすら気づけない）。企業リストの `.ct` は
 *   `.ct-scroll`（`static/saas.css`）が常時受けており、同じ面で扱いが割れていた。
 * ⚠ 2026-10-10 に **760px -> 899px**。段を2つに寄せたぶん退避が早く始まるが、
 *   `overflow-x: auto` は**はみ出していなければ何も起こさない**ので副作用が無い
 *   （`tests/web/test_stylesheet.py` が「閾値 ≥ 最小幅 + 72px」を見ている）。
 * ⚠⚠ **下の `min-width: 660px` は、この `.tablecard` の外にも効く。**
 *   企業個票の長い表は saas.css のスクロール容器 .ct-scroll に入っていて、
 *   あちらは両軸の `overflow: auto`。ここで最小幅を与えると、あの器は
 *   **縦だけでなく横にも動く器**になる —— だから `parts/_table.html` はあの器に
 *   `tabindex="0"` と `role="region"` を付けている（キーボードで中へ入れないと
 *   WCAG 2.1.1 / 2.1.3 違反）。**この数字を動かすときは、あちらも一緒に見ること。**
 * ⚠⚠ **`<table>` を行カードに畳まない。** `display` を変えると支援技術から
 *   表として読まれなくなる（`docs/design/responsive.md` §4.1）。畳んでよいのは
 *   `<div>` + grid で組んだ行（`home.css` の `.afeed` 型）だけで、ここは
 *   `parts/_table.html` が出す**本物の `<table>`**。**横に逃がすのが唯一の手。**
 * ⚠ **列を落とさない**（落とすと根拠が消える）。
 * ⚠ `.fd-result`（`/search/`）はここに含めない。あちらは sticky な列見出しを
 *   自分で切ってから横スクロールに替えている（`static/finder.css`）。 */
@media (max-width: 899px) {
  .tablecard { overflow-x: auto; }
  .tablecard table { min-width: 660px; }
}

/* -------------------------------------------------------- compact（≤599） */

@media (max-width: 599px) {
  /* ⚠ 狭い画面での縮小は**トークンを差し替える**。個別の要素に px を書くと、
     同じ役割の文字が画面幅によって別々にずれる（それで 20種に増えた）。
     ⚠ **36px は狭い端末では広すぎる。** 375px の実測で本文幅が 303px しか無く、
       画面の 19% が左右の余白だった。住所・ドメイン・シグナルの値という
       **折り返しにくい文字**が多い面なので、ここは文字に回す。 */
  :root { --gutter: 20px; --fs-h1: 25px; }
  /* 県別の横棒を2行に畳む（`.afeed` 型 —— ラベルを行の上へ、値を右肩へ）。
     ⚠ **`display: block` で縦に積むだけにしない。** それだと「数字が縦に
       並んでいる」だけになり、どれが何の値か読めなくなる。 */
  .brow { grid-template-columns: 1fr 74px; }
  .blabel { grid-column: 1 / -1; }
  /* ⚠ **1列になったら段を一つ詰める。** `--gap-5` のままだと基準と同値で、この
     規則が1行も効かない（縦1列で 24px 空けると4段で画面十数枚分になる）。 */
  .foot-grid { grid-template-columns: 1fr; gap: var(--gap-4); }

  /* ⚠⚠ **フッタにメリハリを付ける（2026-10-10・指摘「モバイルのフッターが
   *   メリハリがなくてわかりづらい」）。**
   *
   *   原因は**見出しとリンクが同じ重さに見えていた**こと:
   *     `.foot-h`（探す / データ / 掲載について） … `--fs-xs` 11.5px・`--text-muted`
   *     `.foot-links a`                           … `--fs-sm` 12.5px・`--text-secondary`
   *   **1px しか違わず、どちらも淡い灰色。** しかも `pointer: coarse` で
   *   リンクが 44px になったぶん行間が開き、**全部が等間隔の灰色の列**になって
   *   群の切れ目が消えていた。
   *
   *   ⚠ **広い画面では変えない。** あちらは4列に分かれているので、
   *     列そのものが群を示している。**1列に畳んだときだけ**の問題。
   *   ⚠ **文字を大きくして解決しない。** 見出しを**濃く**して、群の頭に
   *     罫を引く。フッタの文字が本文と並ぶ大きさになると主従が狂う。 */
  /* ⚠⚠ **縦を詰める（2026-10-10・指摘「フッターは縦に取りすぎ」）。**
   *   1列 × リンク7本 × 44px で `.foot-grid` が **553px**（footer 全体で 608px）
   *   あった。**44px は譲れない**（指で押す当たり判定）ので、**列を2つにして
   *   行数のほうを半分にする**。
   *   ⚠ ブランドの塊（名前・タグライン・最終更新）だけは全幅のまま
   *     —— 2列に割ると1行が 150px を切って、日付が折り返す。 */
  .foot-grid { grid-template-columns: 1fr 1fr; gap: var(--gap-3) var(--gap-4); }
  .foot-grid > :first-child { grid-column: 1 / -1; }
  /* 罫は**群の頭**にだけ。⚠ 2列になったので「`* + *` に上罫」だと
     右の列にも引かれて、横に切れ目が2本並ぶ。ブランドの直後に1本引く。 */
  .foot-grid > :first-child { border-bottom: 1px solid var(--gridline); padding-bottom: var(--gap-3); }
  /* ⚠ 見た目（大きさ・太さ・濃さ）はベースの `.foot-h` が持つようになった
     —— **狭い画面だけの話ではなかった**ので上へ移した。ここは詰めるだけ。 */
  .foot-h { margin-bottom: 0; }
  /* ⚠ **行間を詰めても当たり判定は 44px のまま**（`pointer: coarse` が持つ）。
     詰めるのはリンクとリンクの**隙間**であって、押せる高さではない。 */
  .foot-links a { padding: 0; }
  .foot-in { padding-top: 24px; padding-bottom: 16px; }
}

/* ======================================================= 指で触る端末だけ

   ⚠⚠ **幅はレイアウトを決める。当たり判定を決めるのは `pointer`（2026-10-10）。**

   この2つを混ぜたのが、このサイトの CSS のいちばん深い間違いだった。幅で代用すると
   **両方向に外す**:

     iPad 横（1024px・指）      … 「広いからマウス」→ 当たり判定が小さいまま
     PC の窓を 500px に狭めた  … 「狭いから指」→ 無駄に大きく、hover まで殺す

   実測（2026-10-10・9画面×10面）で 44px を切っていた共有部品:
     `a.cname` **8x20**（1文字の社名。WCAG 2.5.8 の 24x24 すら割っていた）
     `button.ev-btn` 24px / `button.hint__btn` 24px / `summary` 24px
     `a.chip.chip--link.chip--ic` 26px / `a.brand` 29px / `.foot-links a` 24px

   基準: **44px が目標、24px が WCAG 2.2 AA の必須ライン。**

   ⚠ **本文中のインラインリンク（素の `a`）は対象外。** WCAG 2.5.8 も除外している
     —— 文の途中のリンクを 44px にすると行間が壊れる。ここに並べてあるのは全部
     「一覧・ナビ・ボタン」で、文の中には出ないもの。
   ⚠ **`a.skip` も直さない。** フォーカスしたときだけ出るもので、指では踏まない。
   ⚠ **`min-height` だけでは効かない要素がある。** インライン（`a` / `summary`）は
     高さを持てないので、`inline-flex` にしてから当てる。
   ⚠ **幅に戻さない。** 「`@media (hover: none)` は検証しにくい」はもう理由にならない
     —— `web/tools/qa_mobile.py` が `has_touch` / `is_mobile` を渡すので、
     タッチ端末としての描画を機械で見られる。
   ⚠ **文字を大きくして高さを稼がない。** `--fs-*` は読みやすさの段で、
     当たり判定の道具ではない。広げるのは `padding` と `min-height` だけ。 */

@media (pointer: coarse) {
  /* ⚠⚠ **ブランドとナビは `min-height` ではなく上下の `padding` で広げる。**
     どちらも `align-items: baseline` の整列の中に居る（`.brand` は
     2026-10-09 に「大きさの違う文字は足元で揃える」と実測して決めた組、
     `.nav a` は現在地の下線 `::after { bottom: 0 }` を持つ）。`min-height` で
     伸ばすと**余りが下に付いて字が上へ寄り**、下線だけが離れて見える。
     `padding` なら字は中央のまま、箱だけが 44px になる。
     ⚠ **左右は 10px のまま。** 下線は `left: 10px / right: 10px` で
       **字の幅ぴったり**に引いてある（器いっぱいに引くとタブのバーに見える）。 */
  .brand { padding: 8px 0; }
  .nav a { padding: 10px; }

  /* 表の中の社名・プロダクト名（`parts/_table.html` / `parts/_saas.html`）。
     ⚠ **1文字の社名が 8px だった。** 高さだけ足しても横が足りないので
       `min-width` も要る（`docs/design/responsive.md` §4.2 の実測表）。
     ⚠ **`display: block` にしない。** セルの中で全幅になり、行の余白が
       クリックできる帯に見える。`inline-flex` で**字のまわりだけ**広げる。 */
  .cname { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; }

  /* 押せるチップ・ダウンロード・パンくず・フッタの一覧・棒グラフのラベル。
     ⚠ **`.chip` 全部ではなく `a.chip--link` だけ。** 押せないチップ（`.chip--more` /
       `.chip--muted` はただのラベル）まで 44px にすると、ただ背が高い帯が並ぶ。 */
  a.chip--link, .dl, .crumbs a, .foot-links a, .blabel a {
    display: inline-flex; align-items: center; min-height: 44px;
  }

  /* 根拠ボタンと `<details>` の見出し。
     ⚠ `summary` に `display: flex` を当てない —— 三角のマーカーが消える実装がある
       （`list-item` でなくなるため）。`min-height` ＋ `align-content` で中へ寄せる。 */
  .ev-btn { min-height: 44px; }
  summary { min-height: 44px; align-content: center; }

  /* ヘッダーの検索窓。16px の文字＋上下 7px で実測 43.2px と、1px だけ足りない。 */
  .sg input { min-height: 44px; }

  /* ⚠⚠ **`?` だけは見た目を 24px のまま、当たり判定だけ 44px にする。**
     `width` / `height` を 44px にすると、14px の見出しの隣に **44px の丸**が出て
     「何かの大きなボタン」に見える（丸の大きさは枠そのものが決めるので、
     中の `?` を小さくしても丸は縮まない）。透明な `::after` をボタンの中心に
     置けば、**レイアウトを1px も動かさずに**押せる範囲だけ広がる。
     ⚠ **`pointer: coarse` の中だけ。** マウスの画面に置くと、見出しの周りに
       見えない板が張り出して隣の語を選びにくくなる。
     ⚠ **`.hint__pop`（吹き出し）より手前に出さない。** `::after` は
       `.hint__btn` の子なので、開いた吹き出し（`z-index: 60`）には重ならない。 */
  .hint__btn { position: relative; }
  .hint__btn::after {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: 44px; height: 44px; transform: translate(-50%, -50%);
  }
}

/* ⚠ **「手当て（実測して直した分）」という節は畳んだ。** 役割ではなく**作業の
 *   タイミング**で区切った節だったので、片付け先が決まらず中身が溜まっていた。
 *   実際そこに残っていた `.stack-grid` / `.si` / `.tl__body` は**企業個票にしか
 *   出ないクラス**で、本体の定義は `static/company.css` にあった（＝同じクラスの
 *   答えが2ファイルにあり、次に触る人が片方だけ直す形）。しかも `/` や `/product/`
 *   にも配られる app.css に、その面では一度も当たらない規則が3本混ざっていた。
 *   3本とも company.css の本体定義へマージ済み。`.conf--medium, .conf--weak` は
 *   上の「バッジ」節（`.conf` の隣）へ移した。**この節を作り直さないこと。**
 *   検査は `tests/web/test_stylesheet.py`（ファイルをまたいだ二重定義も見る）。 */

/* ==========================================================================
   図版とアイコン

   このサイトには写真が1枚も無い（表と文字のデータサイト）。
   だから**線画だけ**で組み立てる: インライン SVG + currentColor。
   色は CSS 変数で持つ（`currentColor` と `--series-*`）。**SVG に色を直書きしない。**
   ========================================================================== */

.ic { flex: none; vertical-align: -0.18em; }

/* アイコン付きの見出し・カード */
.with-ic { display: inline-flex; align-items: center; gap: var(--gap-ic-lg); }
/* ⚠ **`.cardc__icon` は消した。** 親の `.card-grid` / `.cardc` は上で消してあり
 *   （「⚠ カードは `.scard` 1つだけ」）、これだけ取り残されていた。 */
.area-head .ic { color: var(--link); }

/* ------------------------------------------------------------------ 図版 */

.art { width: 100%; height: auto; display: block; }


/* ------------------------------------------------------- ダウンロード */

.dl {
  display: inline-flex; align-items: center; gap: var(--gap-ic-lg); white-space: nowrap;
  font-size: var(--fs-sm); font-weight: var(--fw-semibold); text-decoration: none;
  color: var(--text-secondary); background: var(--glass-strong);
  border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 6px 14px 6px 11px;
}
.dl:hover { color: var(--link); border-color: var(--series-1); }
.dl .n { font-weight: var(--fw-medium); color: var(--text-muted); }

/* セクション見出しの右側に置く道具（CSV など）。 */
.sec-tools { display: flex; align-items: center; gap: var(--gap-4); flex-wrap: wrap; }

/* ------------------------------------------------------- SaaS のアイコン */

/* ⚠ **ロゴは各社の商標。** 製品を識別する目的で出している（/method/ の「出典」に帰属表示）。
   取れなかった製品は**モノグラム**（頭文字）で、同じ大きさの枠に収める。
   実測で 222/285 製品は favicon が取れている（`products/fetch_favicons.py`）。 */
/* プロダクトのアイコン。3サイズ（xs 16 / 既定 28 / lg 38）。
 * ⚠ **角丸は2段だけ**（xs は `--radius-xs`、28 と 38 は `--radius-sm`）。
 *   以前は「箱のおよそ 1/4」として 4 / 7 / 9 の3種を使い分けていたが、
 *   **28px のためだけに 7px という段が1つ増えていた**（角丸は全体で7種あった）。
 *   28 と 38 を同じ 9px にしても、並べて置いた実物で差は読めない。
 *   ⚠ **サイズを足すときも角丸の段は足さない。** 16px 以下なら `--radius-xs`、
 *     それ以上は `--radius-sm`。 */
.pico {
  width: 28px; height: 28px; border-radius: var(--radius-sm); flex: none;
  display: grid; place-items: center; overflow: hidden;
  background: var(--glass-strong); border: 1px solid var(--glass-edge);
}
.pico img { width: 20px; height: 20px; object-fit: contain; display: block; }
.pico--mono { font-size: var(--fs-sm); font-weight: var(--fw-bold); border: 0; }
/* ⚠ **`border-radius` をここに書かない。** `.pico` と同じ `--radius-sm` なので、
   書いても1行も効かないうえ「ここで決まっている」と読ませる。 */
.pico--lg { width: 38px; height: 38px; }
.pico--lg img { width: 26px; height: 26px; }
.pico--lg.pico--mono { font-size: var(--fs-base); }
/* モノグラムの面。**値は冒頭の `:root` 1組が持つ**（`--mono-*` / `--mono-ink-*`）。
 *   段（1〜4）は `product_id` から決まる（`web/view/icons.py` の `mono_step`）。
 *   ⚠ **ここに `:root { --mono-* }` を書き戻さない。** 理由は冒頭のトークンの隣。 */

.pico--m1 { background: var(--mono-1); color: var(--mono-ink-1); }
.pico--m2 { background: var(--mono-2); color: var(--mono-ink-2); }
.pico--m3 { background: var(--mono-3); color: var(--mono-ink-3); }
.pico--m4 { background: var(--mono-4); color: var(--mono-ink-4); }

/* 表の中の「アイコン + 名前」。**高さを揃える**ので必ずこの組で使う。 */
.pcell { display: inline-flex; align-items: center; gap: var(--gap-ic-lg); }

/* SaaSページの見出しのアイコン */
.head-ic { display: flex; align-items: center; gap: var(--gap-3); margin-bottom: 6px; }

/* ==========================================================================
   検索と絞り込み（このサイトで唯一 JS が要るところ）
   ========================================================================== */

/* -------------------------------------------------------------- 検索窓 */

.sg { position: relative; display: flex; align-items: center; flex: none; }
.sg__ic { position: absolute; left: 11px; color: var(--text-muted); display: grid; place-items: center; pointer-events: none; }
/* ⚠ **`font-size` は 16px の下駄つき（2026-10-10）。** 素の `input` には base 節で
   `max(16px, var(--fs-md))` を当ててあるが、**クラスを持つここが特異度で勝つ**ので
   同じ式を書く。14px のままだと iOS Safari が触れた瞬間にページごと拡大し、
   自動では戻らない（実測でヘッダーの検索窓が 14px だった）。理由は base 節の注記。
   ⚠ **`--fs-*` に 16px の段を足して揃えない。** OS の制約であって文字の段ではない。 */
.sg input {
  /* ⚠⚠ **`max(16px, …)` の下駄を外さない（2026-10-11 に指摘を受けて検討し、残した）。**
     「placeholder の文字が他より大きい」という指摘は正しい —— ナビは 14px、
     タグラインは 12.5px で、ここだけ 16px ある。それでも下げない:
     **iOS は 16px 未満の入力欄にフォーカスすると画面を自動拡大する**ので、
     14px にすると**スマホで検索欄をタップするたびにページが拡大する**。
     ⚠ `@media (pointer: fine)` でデスクトップだけ下げる案は、iPad など
       中間のデバイスで判定が揺れるので採らない。
     ⚠ `::placeholder` だけ小さくする案も採らない —— 入力した文字は 16px のままで、
       **打った瞬間に文字が大きくなる**。 */
  font: inherit; font-size: max(16px, var(--fs-md)); width: 230px;
  padding: 7px 12px 7px 34px; border-radius: var(--radius-pill);
  border: 1px solid var(--border); background: var(--glass-strong);
  color: var(--text-primary);
}
.sg input:focus { outline: 2px solid var(--series-1); outline-offset: 1px; border-color: transparent; }
.sg input::placeholder { color: var(--text-muted); }
.sg--wide { margin-top: 18px; }
/* ⚠ **ここも 16px の下駄（2026-10-10）。** `--fs-base` は 15px で、**1px 足りないだけで
   iOS は拡大する**（実測でトップの検索窓が 15px）。理由は base 節の注記。 */
.sg--wide input { width: min(520px, 100%); font-size: max(16px, var(--fs-base)); padding: 13px 16px 13px 42px; border-radius: var(--radius); }
.sg--wide .sg__ic { left: 15px; }

/* ------------------------------------- 狭い画面では検索窓をアイコンに畳む */

/* ⚠⚠ **この2つは「見た目の調整」ではなく前提（2026-10-10）。**

   `parts/_searchbox.html` の `collapsible=true`（ヘッダーだけ）が、検索窓を
   **アイコン（`.sg-open`）＋ ネイティブ popover の器（`.sg-pop`）**で包むようになった。
   包んだだけだと、ブラウザの UA スタイル
   `[popover]:not(:popover-open) { display: none }` が効いて、
   **ヘッダーの検索窓がどの幅でも出ない。** `display: contents` の1行で
   「器を透かして、中の `form.sg` を `.topbar-in` の直接の子に戻す」のが既定。

   なぜ畳むか: 実測（2026-10-10）で 390px のトップバーが **137px（画面の16%）**、
   設計値 `--bar-h`（58px）の **2.4倍**あった。折り返しの最大の原因が
   **230px 固定の検索窓**（`docs/design/responsive.md` §4.4）。

   ⚠⚠ **`@supports not selector(:popover-open) { [popover] { display: none } }`
     （上の「根拠」節）より後ろに置くこと。** 詳細度が同じ `[popover]` と `.sg-pop` なので、
     前に書くと**popover 非対応のブラウザでヘッダーの検索窓が丸ごと消える**。
   ⚠ **`display: contents` を `display: block` に替えない。** 器が箱を持つと
     `form.sg` が `.topbar-in` の flex の子でなくなり、`.sg--bar` の
     `flex: 0 1 230px`（縮む約束）が効かなくなってバーが折り返しに戻る。
   ⚠ **ハンバーガーにしない。** 畳むのは検索窓だけで、**ナビ3本は1段に残す**。 */
.sg-pop { display: contents; }
/* ⚠ 既定は出さない。compact でだけ出す（下の `@supports` + `@media`）。
   ⚠ **`width` / `height` を 44px で持つ。** `min-height` だけだと横が 20px の
     アイコンぶんしか無く、WCAG 2.5.8 の 24x24 は満たしても指では外す。
   ⚠ **見た目は `.ev-btn` / `.hint__btn` と同じ組**（`--border` の枠＋`--radius-pill`）。
     同じサイトに「押せる丸」の作りを3通り持たない。 */
.sg-open {
  display: none; flex: none;
  align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0;
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  background: var(--glass-strong); color: var(--text-secondary); cursor: pointer;
}
.sg-open:hover { color: var(--text-primary); border-color: var(--baseline); }

/* ⚠⚠ **`@supports` で囲う理由（囲わないと壊れる向きが変わる）。**
   `:popover-open` を知らないブラウザでは `.sg-pop:not(:popover-open)` の規則が
   **まるごと捨てられる**ので、上の `display: contents` が残って検索窓はそのまま出る
   ——「畳めないが、従来どおり使える」という素直な劣化。ところが `.sg-open` を
   この外に置くと、**その劣化した画面に「押しても何も起きないアイコン」が並ぶ**。
   ⚠ **`@media` を外に出さない。** 当たり判定ではなく**レイアウト**の話なので幅で切る
     （`docs/design/responsive.md` §1.1）。指で触る iPad 横（1024px）では
     1段に収まっているので、畳む必要が無い。 */
@supports selector(:popover-open) {
  @media (max-width: 599px) {
    .sg-open { display: inline-flex; }
    /* ⚠ **閉じているときだけ `none`。** `.sg-pop` 単体（`display: contents`）より
       詳細度が1つ高いので、こちらが勝つ。 */
    .sg-pop:not(:popover-open) { display: none; }
    /* 上から降りてくるシート。**トップバーの真下に貼る。**
       ⚠ **`top` は `--fd-top`（実測）を先に読む。** 書いているのは
         `static/app.js` の `trackTopbar()` で、無いときだけ設計値 `--bar-h`。
         `finder.css` の sticky 3箇所と同じ式にしてあるので、**片方だけ触らないこと**。
       ⚠ **`100dvh` にしない。** アドレスバーの出入りで高さが跳ねる（`body` の注記）。
         ここは高さを持たせていないので、そもそも要らない。
       ⚠ **`overflow: visible` が要る。** `[popover]` の UA 既定は `overflow: auto` で、
         候補リスト（`.sg__list` は `position: absolute`）がシートの下端で切られる。
       ⚠ **`inset: 0` / `margin: auto`（UA 既定）を打ち消す。** 残すと画面の
         ど真ん中に浮いた小窓になり、「どこから出てきたのか」が読めない。 */
    .sg-pop:popover-open {
      display: block; position: fixed;
      top: var(--fd-top, var(--bar-h)); left: 0; right: 0; bottom: auto;
      width: auto; max-width: none; height: auto; margin: 0;
      padding: var(--gap-3) var(--gutter);
      background: var(--surface-1);
      border: 0; border-bottom: 1px solid var(--border);
      box-shadow: var(--shadow-2); overflow: visible;
    }
    /* ⚠ **後ろを少しだけ暗くする。** 「本文はまだそこにある」と伝えるため
       （`.pop::backdrop` と同じ濃さ。2つの popover で別の暗さにしない）。 */
    .sg-pop::backdrop { background: rgba(11,11,11,.30); }
    /* シートの中では窓は全幅。⚠ 230px のままだと 350px の画面で右が空いて、
       「なぜか左に寄った入力欄」に見える。 */
    .sg-pop .sg--bar { flex: none; width: 100%; }
    /* ⚠ 候補も全幅に。`width: min(320px, 92vw)` のままだと、シートの幅との
       食い違いが**段差**として出る（上と下の端が揃わない）。
       ⚠⚠ **`.sg--bar` を挟んで詳細度を1つ上げてある。** 寄せ先の
         `.sg--bar .sg__list`（下の「検索窓」節の末尾）は**同じ詳細度でこれより後ろ**に
         あるので、`.sg-pop .sg__list` と書くと**後ろが勝って1行も効かない**。
         ⚠ この節を `.sg--bar .sg__list` より後ろへ動かすなら、そのときは
           `.sg--bar` を外してよい（**どちらか片方**。両方やると今度は過剰になる）。 */
    .sg-pop .sg--bar .sg__list { left: 0; right: 0; width: auto; }
  }
}

/* ====================== 狭い画面ではナビを畳む（2026-10-10・指摘） ==========
 *
 * ⚠⚠ **「ナビは3本だから畳まない」という以前の判断は、実測で否定された。**
 *   `.nav a` は `--fs-md`(14px) + `padding: 6px 10px`。ラベル全角22文字 ≒ 308px、
 *   + padding 60px + gap ≒ **376px 要る**のに、390px の画面で `.nav` に残るのは
 *   `390 − gutter − ブランド − 検索アイコン ≒ **129px**`。**3倍足りない。**
 *   横スクロールで押し込んでいたため、**ブランド名の上にナビが乗っていた**
 *   （`qa_mobile.py` の `collide` が `span.brand-text` × `a` を 23x29 で検出）。
 *
 * ⚠ **`@supports not selector(:popover-open) { [popover] { display: none } }`
 *   （上の「根拠」節）より後ろに置くこと。** 詳細度が同じなので、前に書くと
 *   popover 非対応ブラウザで**ナビが丸ごと消える**。
 * ⚠ `.sg-open` / `.sg-pop` と**同じ型**。新しい作法を作らない。 */

/* 既定（wide）= popover を打ち消して、いまの横並びのまま。**見た目は1px も変えない。** */
.nav[popover] {
  display: flex; position: static;
  inset: auto; width: auto; height: auto; max-width: none; max-height: none;
  margin: 0; margin-left: auto; border: 0; padding: 0;
  background: none; color: inherit; overflow: visible;
}
.nav-open { display: none; }

@supports selector(:popover-open) {
  @media (max-width: 899px) {
    /* 開く口。⚠ **`.sg-open` と同じ寸法・同じ組**（隣に並ぶので揃っていないと目立つ）。 */
    .nav-open {
      display: inline-flex; align-items: center; justify-content: center;
      flex: none; width: 44px; height: 44px; margin-left: auto;
      border: 1px solid var(--glass-edge); border-radius: var(--radius-pill);
      background: var(--surface-1); color: var(--text-secondary); cursor: pointer;
    }
    .nav-open:hover { color: var(--text-primary); border-color: var(--baseline); }
    /* ⚠ 開く口が `margin-left: auto` を持つので、`.nav` 側からは外す
       （両方が持つと、閉じている幅ゼロの器が右端を取り合う）。 */
    .nav[popover] { margin-left: 0; }
    .nav[popover]:not(:popover-open) { display: none; }
    /* ⚠⚠ **下から出す。上から降ろさない（2026-10-10・実測で踏んだ）。**
     *
     *   最初は `top: var(--fd-top)` で上から降ろしたが、**ヘッダーを覆った**。
     *   `--fd-top` は**バーの高さ**（実測 59px）であって、**ビューポート上端からの
     *   距離ではない**。上に何かが乗っている場合（サンプルの赤帯 55px）、
     *   バーの実体は `[55..114]` なのにシートは 59px から始まり、
     *   **ヘッダーごと、開く口のアイコンごと隠れた**（閉じる手が Esc と
     *   外側タップだけになる）。
     *   ⚠ **`--fd-top` を「バーの下端」に作り替えない。** あれはスクロールで
     *     変わる値で、追うには JS に scroll 監視を足すことになる
     *     （このサイトは `app.js` 1本・ビルド工程ゼロが方針）。
     *   ⚠ **下から出せば、ヘッダーの位置に一切依存しない。** 条件シート
     *     （`finder.css` の `.fd-side[popover]`）が同じ形なので、**作法も揃う**。 */
    .nav[popover]:popover-open {
      display: flex; flex-direction: column; align-items: stretch;
      position: fixed; top: auto; left: 0; right: 0; bottom: 0;
      width: auto; max-width: none; height: auto; max-height: 85vh; margin: 0;
      padding: var(--gap-3) var(--gutter) var(--gap-4);
      background: var(--surface-1); border: 0; border-top: 1px solid var(--border);
      border-radius: var(--radius) var(--radius) 0 0;
      box-shadow: var(--shadow-2); overflow-y: auto;
    }
    /* ⚠ **1行1本、当たり判定 44px。** 横並びのままだと畳んだ意味が無い。 */
    .nav[popover]:popover-open a {
      display: flex; align-items: center; min-height: 44px;
      padding: 0 var(--gap-2); font-size: var(--fs-base);
      border-radius: var(--radius-sm);
    }
    /* いまいる面は塗って示す（`aria-current` はテンプレートが付けている）。 */
    .nav[popover]:popover-open a[aria-current="page"] {
      color: var(--text-primary); font-weight: var(--fw-semibold);
      background: var(--tint-1);
    }
    /* ⚠ 現在地の下線（`.nav a::after`）はシートでは出さない —— 縦積みでは
       「下の項目との区切り」に見えて、現在地の意味が消える。 */
    .nav[popover]:popover-open a::after { display: none; }
    .nav[popover]::backdrop { background: rgba(11,11,11,.30); }
  }
}

/* 候補。**プロダクトと企業を型のラベルで分ける**（どちらに飛ぶか分かるように）。 */
.sg__list {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 40;
  max-height: 340px; overflow-y: auto;
  background: var(--surface-1); border: 1px solid var(--glass-edge);
  border-radius: var(--radius); box-shadow: var(--shadow-2); padding: 6px;
}
/* ⚠⚠ **ヘッダーの検索窓だけは縮む（2026-10-10）。**
   `.sg` の既定は `flex: none`（トップの `.sg--wide` は本文の中なので縮む必要が無い）。
   ヘッダーのほうは **`.topbar-in` の flex の子**で、ブランド＋ナビ3本＋この窓を
   1段に収めるには**ここが譲るしかない**:

     744px（iPad mini 縦・`--gutter` 36px）… 使える幅 672px に対し、素のままだと
       ブランド 113 + ナビ 376 + 窓 230 + gap 32 = **751px** 要る

   以前はこれを `flex-wrap: wrap` で折り返して逃がしていて、390px の実高が
   **137px** だった（上の「トップバー」節）。畳むのをやめた以上、**縮むのはこちらの役目**。

   ⚠ **compact（≤599px）では、そもそもこの窓はアイコンに畳まれている**
     （下の `.sg-open` / `.sg-pop`）。ここが効くのは **medium（600〜899px）**と、
     タグラインが戻る **900〜1000px** の帯。

   ⚠ **`min-width: 0` を両方に書く。** flex の子は既定で `min-width: auto`
     ＝**中身より縮まない**。`<input>` は `size` 属性ぶんの min-content を持つので、
     器（`.sg--bar`）だけ 0 にしても中の `<input>` がつっかえ棒になる。
   ⚠ **`width: 230px` を消さずに `flex-basis` で持つ。** 広い画面での見た目は
     1px も変えない（230px から始まり、足りないときだけ縮む）。
   ⚠ **`display: none` で逃げない。** 検索はこのサイトの主動線で、
     ヘッダーから消すと入口が1つ減る（`docs/design/responsive.md` §1.2）。 */
.sg--bar { flex: 0 1 230px; min-width: 0; }
.sg--bar input { width: 100%; min-width: 0; }
/* 候補は窓の右端から左へ伸ばす。
   ⚠ **`320px` の決め打ちをやめた（2026-10-10）。** 上の `flex: 0 1 230px` で窓が
     縮むようになったぶん、狭い画面では窓の右端が画面の右端（`--gutter` ぶん内側）
     に近い。そこから 320px 伸ばすと、**320px の端末で画面の左外へ 20px はみ出す**
     （実測の試算。中身が読めないまま切り落とされる）。`min()` で画面側にも上限を置く。
   ⚠ **`left: 0` にして窓幅に合わせない。** 縮んだ窓は 100px を切ることがあり、
     候補（プロダクト名＋提供元）がその幅では読めない。**窓より広くてよい。** */
.sg--bar .sg__list { left: auto; width: min(320px, 92vw); right: 0; }
/* 候補1件。**名前と提供元を縦に積み、型のラベルは右の添え物**（2026-10-09）。
 *
 * ⚠ **先頭 42px の青いバッジには戻さない。** 「検索画面の『製品』とかのやつが
 *   とてもダサい」と言われた形がそれ。悪かったのは3つ:
 *   - **色で主張していた**（製品だけ `--step-1` の青地）。候補の中でいちばん
 *     目立つのが、いちばんどうでもいい情報だった。
 *   - **本体を押しのけていた。** 42px の列に取られて、名前と提供元が
 *     1行に押し込まれ、320px の幅では提供元が `Salesforce, I…` で切れていた。
 *   - **先頭に置くと読む順が型→名前になる。** 読み手は名前を探しに来ている。
 * ⚠ **色だけで種別を示さない。** 企業と製品の区別が色だけになると、色覚と
 *   白黒印刷で消える。**区別は文字（「プロダクト」/「企業」）が持つ。**
 *   `--p` / `--c` の修飾クラスは残してあるが、**色を当てていない。**
 * ⚠ 文字の大きさはトークンの5段から選ぶ（`docs/design/web_design.md` §7.3）。 */
.sg__item {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 0 var(--gap-3); align-items: center;
  padding: 7px 9px; border-radius: var(--radius-sm); text-decoration: none; color: var(--text-primary);
}
/* ⚠ **生の `rgba()` を書かない**（上の `.tablecard tbody tr:hover` と同じ理由）。
   ここは `.is-active` が**キーボード選択の唯一の目印**なので、薄まるのがいちばん痛い。 */
.sg__item:hover, .sg__item.is-active { background: var(--tint-1); }
.sg__name {
  grid-area: 1 / 1;
  font-size: var(--fs-md); font-weight: var(--fw-medium); line-height: 1.45;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sg__sub {
  grid-area: 2 / 1;
  font-size: var(--fs-xs); color: var(--text-muted); line-height: 1.45;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 提供元が無い候補で、2行目ぶんの空きを残さない。 */
.sg__sub:empty { display: none; }
/* 型のラベル。**サイト共通の `.tag` と同じ地味な枠**にそろえてある
   （同じ意味の部品を2つの見た目で持たない）。 */
.sg__kind {
  grid-area: 1 / 2 / span 2 / auto;
  font-size: var(--fs-xs); line-height: 1.5; padding: 1px 8px;
  border: 1px solid var(--border); border-radius: var(--radius-pill);
  color: var(--text-muted); white-space: nowrap;
}

/* 一覧の中の小さいアイコン。チップに並べても行が波打たない大きさ。 */
.pico--xs { width: 16px; height: 16px; border-radius: var(--radius-xs); }
.pico--xs img { width: 12px; height: 12px; }
/* ⚠ **ここだけ `--fs-*` を使わない。** モノグラムは「読む文字」ではなく
 *   16px の枠に収める**図形**。可読性の下限（--fs-xs = 11.5px）を当てると
 *   枠からはみ出す。トークンを増やす価値も無いので生の値で持つ。 */
.pico--xs.pico--mono { font-size: 9px; }
.chip--ic { display: inline-flex; align-items: center; gap: var(--gap-ic); padding-left: 5px; }

/* ===================================== 0. 注意書きの `?`（全ページ共通） */

/* `parts/_hint.html` のマクロ。**トップ専用ではない。**
   ⚠ **以前は `static/home.css` にあった。** トップ・企業個票・`/search/` の
   3面で使うのに、「STYLESHEETS が全ページに全部配っているから効く」という
   偶然に頼っていた（そのことがコメントにも書いてあった）。配り方を面ごとに
   変えた瞬間、`/search/` と `/company/` から `?` が消える作りだった。

   ⚠ **色もサイズも既存のトークンに合わせる。** `.ev-btn`（シグナルのボタン）と
      同じ `--fs-xs` / 999px / --border で、2つが並んでも大きさが揃う。
      `--fs-xs` は**可読性の下限**なので、これより小さくしないこと。
   ⚠ **`.pop` の器は app.css が持っている。** ここでは中の文字だけ足す。 */
/* ⚠ `inline` ではなく `inline-block` + `position: relative`。
   吹き出しをこのボタンの真下に吊るすための基準になる。
   ⚠ `inline-block` にすると見出しの行の中で縦が揃わなくなるので、
     `vertical-align` はボタン側（下）が持つ。 */
.hint { display: inline-block; position: relative; }
.hint__btn {
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  line-height: 1;
  /* ⚠ **24px を下回らない。** 18px だと指でもマウスでも外す（WCAG 2.2 の
     Target Size は 24x24 が下限）。丸の見た目は中の `?` の大きさが決めるので、
     枠を広げても重くならない。 */
  width: 24px;
  height: 24px;
  padding: 0;
  margin-left: 6px;
  vertical-align: 0.1em;
  border-radius: var(--radius-pill);
  cursor: pointer;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-muted);
}
.hint__btn:hover { color: var(--text-primary); border-color: var(--baseline); }
/* 中身は注意書きなので、本文より小さく・行間は広めに。
   ⚠ **`white-space` を明示する。** 呼び出し元が見出しや表のセルの中なので、
      そこの `nowrap` を継いで**最後の行が枠の外へ切れて消える**
      （`.afeed__who` のような nowrap の列に置いたときに実際に起きる）。 */
/* ⚠⚠ **ホバーで `?` の真下に出る吹き出し（2026-10-09）。**
   直前まで HTML の popover API を使っていたが、あれは **top layer に出る＝
   画面の中央**で、「どの `?` を押したのか」が見た目から消えていた
   （「modal っぽくしないでほしいな。hover で近くに出てくる感じにしたいな」）。

   ⚠ **`display: none` で隠さない。** `opacity` + `visibility` にしてあるのは
     アニメーションさせるため（`display` は遷移しない）。
   ⚠ **`visibility: hidden` を落とさない。** `opacity: 0` だけだと
     **見えないのに押せる板**が見出しの下に残る。
   ⚠ **`pointer-events` を `auto` に戻さない。** 中のリンクを押せるようにすると、
     吹き出しの上を通るときに下の要素が押せなくなる場面が出る。
     リンクを辿りたい人のために `.hint__pop a` だけ戻してある（下）。
   ⚠ **祖先に `overflow: hidden` があると切れる。** 置く場所を増やすときは
     実測すること（`tests/web/test_markup.py` が5か所を見ている）。 */
.hint__pop {
  position: absolute;
  /* ⚠⚠ **既定は「右の横」。下に出さない（2026-10-09）。**
     真下だと、見出しのすぐ下にある本文や表を覆ってしまい、**読んでいたものが隠れる**
     （「tooltips の hover だけど下じゃなくて、右とか余白が多い方にしたいな」）。
     横なら、`?` は行の端にあることが多いぶん空いている。
     ⚠ **右端に近い `?` は左へ回す。** CSS だけでは空きを測れないので、
       はみ出す場所は面ごとに `.hint--left` 相当の上書きを置いてある（下と各シートの末尾）。
       置き場所を増やしたら**必ず実測すること**（1440 / 700 / 390px）。 */
  top: 50%;
  left: calc(100% + 8px);
  transform: translateY(-50%);
  z-index: 60;
  width: max-content;
  max-width: min(360px, 78vw);
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-1);
  box-shadow: var(--shadow-2);
  opacity: 0;
  visibility: hidden;
  /* ⚠ **閉じているあいだだけ `none`。** 開いたら `auto` に戻す（下）。
     `visibility: hidden` でも当たり判定は消えるが、**二重に塞いでおく**。 */
  pointer-events: none;
  transition: opacity .13s ease, visibility .13s ease;

  font-size: var(--fs-sm);
  line-height: 1.8;
  color: var(--text-secondary);
  white-space: normal;
  text-align: left;
  /* ⚠ **太さと字間も戻す。** `<h2>` の中から呼ぶので、書かないと
     `font-weight: 700` と見出しの `letter-spacing` を継いで**注意書き全体が太字**
     になる（実際になった）。`<b>` で強調したところが効かなくなる。 */
  font-weight: var(--fw-normal);
  letter-spacing: normal;
}
.hint__pop b { font-weight: var(--fw-semibold); color: var(--text-primary); }
/* ⚠ **`:focus-within` を落とさない。** マウスが無い人（キーボード・タッチ）は
   ホバーできない。ボタンにフォーカスが入った時点で開く。 */
.hint:hover .hint__pop,
.hint:focus-within .hint__pop {
  opacity: 1;
  visibility: visible;
  /* ⚠⚠ **開いているあいだは乗れる（2026-10-10）。** `pointer-events: none` のままだと
     吹き出しの上にマウスを移した瞬間に `.hint:hover` が切れて**消える**ので、
     中の「なぜ」が**一度も押せなかった**（指摘「tooltip にある注釈がクリックできません」）。
     `.hint__pop a` だけ `auto` にしてあったが、**リンクに辿り着く前に閉じる**ので
     効いていなかった。
     ⚠ **`.hint__pop` の既定（閉じた状態）は `none` のまま。** 開いていないときに
       当たり判定が残ると、見えない板が見出しの下を覆う。
     ⚠ 吹き出しは `.hint` の子なので、乗っているあいだ `.hint:hover` は続く
       （CSS の `:hover` は子孫への当たりも含む）。**だから JS は要らない。** */
  pointer-events: auto;
}
/* 右に空きが無いときは左へ回す。**呼び出し側が選ぶ**（CSS では測れない）。 */
.hint--left .hint__pop {
  left: auto; right: calc(100% + 8px);
}
/* ⚠⚠ **狭い画面は「ボタン基準」をやめて、画面の左右に突っ張らせる（2026-10-10）。**

   直前までここは `right: 0`（ボタンの右端から左へ 300px 伸ばす）だった。
   実測で**2方向に壊れていた**:

   - **768px**: この切り替えは 760px 以下なので**効かず**、横に出たまま。
     `?` が左端から 468px の位置にあると 468+30+8+360 = 866px となり、
     `/search/` が **98px 横スクロール**した（48通り中、横スクロールはここだけ）。
   - **390px**: 切り替わった先でも、`?` が本文の左寄りにあると 300px の箱が
     **画面の左外へ出る**。実測で最大 **170px** はみ出し、文字が読めなかった（7箇所）。

   どちらも「ボタンを基準に伸ばす」ことが原因なので、**基準を画面に変える**。
   `position: fixed` + 左右を `--gutter` で突っ張れば、`?` がどこにあっても
   **左右どちらにも出られない**。`top` を指定しないので、縦はボタンの行のまま。

   ⚠ **`fixed` にすると祖先の `overflow` からも抜ける。** `/search/` の条件パネル
     （`overflow-y: auto`）の中の `?` も切られなくなるので、`finder.css` 側の
     逃げ（下に出す・幅を詰める）はこの幅では要らない。
   ⚠ **切り替えを 760px に戻さない。** 横に出す余地があるかは `?` の位置で決まり、
     画面幅だけでは決まらない。**余裕を見て広めに切る。**
     1024px は実測で横に出しても収まっていた（48通りの計測）。
   ⚠⚠ **2026-10-10 に 1000px -> 899px。** 幅の段を 599 / 899 の2つに寄せたため
     （`tests/web/test_responsive.py`）。**余裕がそのぶん削れている**ので、ここは
     残っているいちばん際どい帯:
       768px の実測 … `?` が左から 468px のとき 468+30+8+360 = **866px** で 98px 溢れた
       900px で同じ式 … 本文が 812px（`--gutter` 44×2）なので `?` は最大 500px 付近、
                        500+30+8+360 = **898px** で**2px しか残らない**
     ＝ **900〜999px は計算上ぎりぎり収まっているだけ。** ここで溢れたら、
       直す手は「3つ目の段を作る」ではなく **`.hint--left` を呼び出し側で当てる**
       （右に空きが無い `?` は左へ回す、という既にある逃げ）。
   ⚠ **`top` を書かない。** 書くと画面の上端からの位置になり、ボタンから離れる。 */
@media (max-width: 899px) {
  .hint__pop,
  .hint--left .hint__pop {
    position: fixed;
    left: var(--gutter); right: var(--gutter);
    transform: none; max-width: none; width: auto;
  }
}
/* ⚠ `.pop__h` の定義は `app.css` に移した。**`?` の popup だけの部品ではない**
   （シグナルの popup も同じ見出しを使う）。ここに置いたままだと、トップ以外の
   画面で「home.css を読んでいるから効いている」という偶然に頼ることになる。 */

/* 業務カテゴリの見出し。⚠ **企業個票の「観測できた技術スタック」と、
 *   プロダクト一覧（`.sx-sec`）の大分類行の両方で使う共有部品。**
 *   `company.css` に置いたら `/product/` から罫線と余白が消えた（実測で
 *   見出し行が 44px から 43px になり、表全体が 7px 縮んだ）。
 *   **1面でしか使わないと決めつけて面ファイルへ動かさないこと。** */
.area-head {
  display: flex; align-items: baseline; gap: var(--gap-ic-lg); margin: 0 0 8px;
  font-size: var(--fs-md); font-weight: var(--fw-semibold);
}
/* ⚠⚠ **「営業」と「21プロダクト」がずれて見えるのを直した（2026-10-09・指摘）。**

   原因は**文字の大きさではなく、flex のベースラインの取られ方**だった（実測）。
   `.area-head` は `align-items: baseline` で正しいが、左側の `.with-ic` は
   それ自体が flex コンテナで、**先頭の要素が SVG のアイコン**。
   SVG にはベースラインが無いので、ブラウザは `.with-ic` のベースラインを
   **アイコンの下端から合成する**（CSS Flexbox §8.5）。つまり
   「アイコンの下端」と「21プロダクトの文字のベースライン」を揃えていた。

   実測（1440px・`/product/` の「営業」の行）:
     いま … 名前の字の下端 285.64 / 件数の字の下端 287.53（**1.89px ずれ**）
     直後 … 285.64 / 284.64（**+1.00px** = 14px と 11.5px のディセンダ差そのもの）
   ＝ 真のベースライン揃えに対して **2.89px ずれていた。**

   ⚠ **手当ては「アイコンをベースラインの持ち主から外す」こと。**
     `.with-ic` を `align-items: baseline` にしたうえで、アイコンだけ
     `align-self: center` にすると、ベースラインを決めるのは**文字のほう**になる。
     アイコンの見た目の位置は1px も動かない（実測で同一）。
   ⚠ **`.area-head` の中だけに効かせる。** `.with-ic` は他の面でも使っている
     共有クラスで、そちらはベースライン揃えの親を持たない。
   ⚠ **`align-items: center` に逃げない。** 大きさの違う2つの文字は
     ベースラインで揃えるのが正しい（中央そろえだと行ごとに揺れる）。 */
.area-head .with-ic { align-items: baseline; }
.area-head .with-ic > svg { align-self: center; }
/* ⚠ 件数は**見出しより1段小さく、太さも落とす**（指摘「21プロダクトはもっと
   小さくするとか？」）。`--fs-xs` は可読性の下限なので**これ以上下げない**。
   ⚠ **`pages/company.html` の「観測できた技術スタック」と共有している。**
     あちらでも同じ「名前＋件数」なので、**2画面で同じ形にする**という
     `parts/_saas.html` の決めごとに従って、両方いっしょに変える
     （片方だけに効くセレクタにはしない。実機で両方見て決めた）。 */
.area-head .n { font-size: var(--fs-xs); color: var(--text-muted); font-weight: var(--fw-normal); }
