/*
 * accessibility.css
 *
 * Issue #35 (WCAG 2.1 AA アクセシビリティ) / #32 (レスポンシブ・モバイル44pxタッチターゲット)
 * / #34 (LCP/CLS最適化) の共通スタイルを一元化したプレーンCSS。
 *
 * 取り込み方:
 *   Propshaft が app/assets/stylesheets/ 配下を配信するため、この
 *   ファイルは論理名 "accessibility" として参照できる。
 *   レイアウトの <head> に下記を追記する(integration_notes 参照):
 *     <%= stylesheet_link_tag :accessibility, "data-turbo-track": "reload" %>
 *   ※Tailwind のビルド(builds/tailwind.css)とは独立した素のCSSとして読み込む。
 *     Tailwind v4 の生成物より後段で読み込むことで、focus-visible 等の
 *     上書きが安定して効く(CSSカスケード順)。
 *
 * 設計方針:
 *   - 既存デザイン(slate / sky)を壊さない最小の上乗せ。色は Tailwind の slate/sky 系に合わせる。
 *   - Tailwind のユーティリティが付いていない要素にも効くよう、ベース要素にも保険をかける。
 *   - prefers-reduced-motion / prefers-contrast / forced-colors に配慮。
 */

/* =========================================================================
 * (B) #35: フォーカスリング(キーボード操作の可視化)
 *   マウス操作では出さず、キーボード(:focus-visible)時のみ明確なリングを出す。
 *   sky-600 相当(#0284c7 近似)を採用し、コントラストを確保。
 * ========================================================================= */
:where(a, button, input, select, textarea, summary, [tabindex], [role="button"], [role="link"], [role="tab"], [role="menuitem"]):focus-visible {
  outline: 3px solid #0369a1; /* sky-700 相当: 背景白でAAコントラスト確保 */
  outline-offset: 2px;
  border-radius: 4px;
}

/* :focus-visible 非対応(古い)環境向けフォールバック。
   対応ブラウザでは下の @supports で打ち消し、マウスフォーカスのリングを抑止する。 */
:where(a, button, input, select, textarea, summary, [tabindex]):focus {
  outline: 3px solid #0369a1;
  outline-offset: 2px;
}
@supports selector(:focus-visible) {
  :where(a, button, input, select, textarea, summary, [tabindex]):focus:not(:focus-visible) {
    outline: none;
  }
}

/* =========================================================================
 * (B) #35: skip-to-content(本文へスキップ)リンク
 *   キーボード/スクリーンリーダー利用者が反復するナビをスキップできるようにする。
 *   通常は視覚的に隠し、フォーカス時に左上へ出現させる。
 *   レイアウトに <a class="skip-to-content" href="#main-content"> を置き、
 *   <main id="main-content"> を付与する(integration_notes 参照)。
 * ========================================================================= */
.skip-to-content {
  position: absolute;
  left: 8px;
  top: -48px;
  z-index: 100;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 16px;
  background-color: #0c4a6e; /* sky-900 相当 */
  color: #ffffff;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.2;
  border-radius: 6px;
  text-decoration: none;
  transition: top 0.15s ease-in-out;
}
.skip-to-content:focus {
  top: 8px;
  outline: 3px solid #ffffff;
  outline-offset: 2px;
}

/* =========================================================================
 * (B) #35: スクリーンリーダー専用テキスト
 *   Tailwind の .sr-only と等価。Tailwind未適用箇所でも使えるよう独自に定義。
 *   aria-label を付けにくい箇所で <span class="visually-hidden"> を併用する。
 * ========================================================================= */
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}
/* フォーカス時に表示へ戻す(skip系の補助) */
.visually-hidden-focusable:not(:focus):not(:focus-within) {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* =========================================================================
 * (C) #32: タッチターゲット最小44px(WCAG 2.5.5 / モバイル操作性)
 *   ナビ・フッターのリンク、フォームのボタンなど操作要素に最小高さ/幅を保証。
 *   既存レイアウトの密度を壊さないよう、.tap-target を明示付与する方式を基本にしつつ、
 *   主要な操作要素(submit/button/role=button)には保険のベースも当てる。
 * ========================================================================= */
.tap-target {
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* フォーム送信系ボタンは指で押す前提で最小44pxを確保 */
:where(
  button[type="submit"],
  input[type="submit"],
  input[type="button"],
  button:not([class*="px-"]):not([class*="py-"])
) {
  min-height: 44px;
}

/* テキスト入力・セレクトもモバイルで押しやすい高さに。
   iOS の自動ズーム回避のため 16px 未満にしない。 */
:where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), select, textarea) {
  min-height: 44px;
  font-size: max(16px, 1em);
}

/* チェックボックス/ラジオは見た目を変えず、当たり判定だけ広げるための補助クラス */
.tap-target-choice {
  position: relative;
}
.tap-target-choice::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}

/* =========================================================================
 * (C) #32: レスポンシブ崩れ対策ユーティリティ
 * ========================================================================= */

/* 横長テーブルはモバイルで横スクロールさせ、レイアウト破綻を防ぐ。
   <div class="table-scroll"><table>...</table></div> で包む。 */
.table-scroll {
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.table-scroll > table {
  min-width: max-content;
}

/* 長いURL・英数字の桁あふれを防ぐ(出典URLや金額の羅列など) */
.wrap-anywhere {
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* グリッドの最小幅折り返し(カードが潰れて文字が重ならないように) */
.grid-auto-fit {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1rem;
}

/* ナビが狭幅で溢れたときに横スクロールで救済(リンクを欠落させない) */
.nav-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

/* =========================================================================
 * (B) #35: コントラスト補正
 *   Tailwind の text-slate-400(約 #94a3b8)は白背景でAAを満たさない箇所がある。
 *   フッター等の微細テキストを slate-600 相当へ底上げするための明示クラス。
 *   既存クラスを一括置換しない方針(integration_notes に対象を列挙)で、
 *   ここでは上書き用の安全なクラスのみ提供する。
 * ========================================================================= */
.text-readable-muted {
  color: #475569 !important; /* slate-600 相当: 白背景でAA(4.5:1超)を確保 */
}

/* プレースホルダのコントラスト底上げ(既定はAA未満になりがち) */
::placeholder {
  color: #64748b; /* slate-500 相当 */
  opacity: 1;
}

/* =========================================================================
 * (A) #34: CLS(レイアウトシフト)抑制の保険
 *   img に width/height 属性があってもCSSで上書きされると比率が崩れるため、
 *   属性由来のアスペクト比を尊重させる。lazy画像のプレースホルダ背景も用意。
 * ========================================================================= */
img[width][height] {
  height: auto; /* レスポンシブ縮小時も縦横比を維持(属性で比率は確定済み) */
}

/* 遅延読み込み画像の読み込み前プレースホルダ(チラつき/シフト軽減) */
img.lazy-img {
  background-color: #f1f5f9; /* slate-100 相当 */
}

/* ヒーロー等の主要画像はコンテンツの安定領域として明示(LCP要素のシフト防止) */
.media-stable {
  display: block;
  width: 100%;
  height: auto;
}

/* =========================================================================
 * モーション・コントラスト設定への配慮
 * ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .skip-to-content {
    transition: none;
  }
}

/* Windows ハイコントラスト/強制カラーモードでフォーカスを確実に見せる */
@media (forced-colors: active) {
  :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 3px solid Highlight;
  }
  .skip-to-content {
    border: 1px solid ButtonText;
  }
}
