/*
 * UnderSoil 共通スタイル（全ページで読み込む）
 *
 * 従来は index.html にインラインの <style>（184行）があり、その一部
 * （html, body, ::selection, .reveal, .delay-*, .header-glass, .mobile-menu-*）が
 * このファイルにも重複していた。両者を統合し、値は /css/tokens.css の
 * トークンを参照する形に置き換えている。
 *
 * 依存: /css/tokens.css を先に読み込むこと。
 */

/* ==========================================================================
   Base
   ========================================================================== */

/*
 * scroll-behavior: smooth はあえて置いていない。ページ内リンクの滑らかな移動は
 * index.html の scrollTo({ behavior }) が担当しており、そちらは
 * prefers-reduced-motion を見て 'auto' に切り替える。html に指定してしまうと、
 * /#contact のようにフラグメント付きで開いたときにもページ先頭から全ページ分
 * スクロールすることになり、目的のセクションが出るまで余計に待たされる。
 *
 * 以前ここには html { scroll-behavior: smooth } があったが、上のヘッダーコメント
 * 内「.delay-」に続くアスタリスクとスラッシュの並びでコメントが途中終了し、
 * 残りが不正なセレクタとしてこのルールごと飲み込まれて無効化されていた。
 * コメントを直すにあたり、表示上の挙動を変えないようルールの方を取り除いた。
 */

/*
 * palt は約物（句読点・括弧）の前後のアキを詰めるだけの担当にして、字面同士の
 * アキは letter-spacing で明示的に作る。従来の 0.02em は palt が詰めた分を
 * 中途半端に押し返していて、どちらの意図も立っていなかった。値は tokens.css を
 * 参照（--tracking-body）。
 */
body {
  font-feature-settings: "palt";
  letter-spacing: var(--tracking-body);
}

/*
 * 見出しの折り返しを和文向けに整える。2つの指定は役割が違うので両方いる。
 *
 * word-break: auto-phrase … 折り返してよい位置を文節境界に限る。和文には
 *   単語間のスペースが無く、既定では文字単位でどこでも折れるため、
 *   「ソフトウェア開発コンサルティ／ング」「ペ／ージ」のように語の途中で
 *   割れる。ブラウザ内蔵の解析で文節を見つけてくれるので、見出しごとに
 *   <span class="inline-block"> を手で入れる必要がなくなる（＝記事を追加する
 *   たびにタイトルを文節分割する運用にならない）。
 *
 * text-wrap: balance … 折り返す場合の行長を均等に割り振る。最後の1〜2文字
 *   だけが次行に残る「泣き別れ」はこれで防げる。
 *
 * どちらも非対応ブラウザでは宣言ごと無視されるだけで、既定の折り返しに戻る。
 * 意味の切れ目を確実に固定したいところ（ヒーローの h1）は、解析結果に依存
 * しないよう HTML 側で span.inline-block を併用している。
 *
 * 行間はここでは指定しない。Tailwind の text-* スケール側（/tailwind.config.js）が
 * --leading-heading で持っている。このファイルに書いても Play CDN の <style>
 * が後ろに注入されるため、同じ詳細度では負ける。
 *
 * .news-card > p は /news/ の記事カードのタイトル。見出し要素ではないが
 * （リンク全体が <a> で、その中の見出しは文書構造として過剰なため <p> にして
 * ある）役割は見出しと同じで、375px では「…いたしまし／た」と1文字だけが
 * 次行に落ちていた。記事を追加するときは <a> ブロックごとコピーする運用なので、
 * クラスを足す方式ではなく構造で拾っている。
 */
h1, h2, h3, h4, h5, h6,
.news-card > p {
  word-break: auto-phrase;
  text-wrap: balance;
}

::selection {
  background: rgb(var(--c-accent-500) / 0.18);
}

/*
 * キーボード操作時のフォーカス表示（WCAG 2.4.7）。
 *
 * :focus ではなく :focus-visible なので、マウス・タップでの操作では出ない。
 * 色に accent-500 を選んだのは、白地で 3.19:1、フッターの brand-900 地でも
 * 約 4.3:1 と、明るい面・暗い面のどちらでも非テキストコントラストの下限
 * 3:1（WCAG 1.4.11）を満たすから。600 以降は暗すぎてフッター上で沈む。
 *
 * :where() で包んで詳細度を 0 にしてあるので、個別指定（.form-input:focus）
 * が常に勝つ。
 */
:where(a, button, input, textarea, select, [tabindex]):focus-visible {
  outline: 2px solid rgb(var(--c-accent-500));
  outline-offset: 2px;
}

/* ==========================================================================
   Keyframes
   Tailwind の animate-* ユーティリティ（tailwind.config.js の animation）が
   参照する実体。全ページで読み込まれる必要がある。
   ========================================================================== */

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(30px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}

@keyframes lineGrow {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

@keyframes scroll-hint {
  0%, 100% { opacity: 1; transform: translateY(0); }
  50%      { opacity: 0.5; transform: translateY(8px); }
}

/* ヒーロー下端のスクロール手がかり（.hero-scroll-cue）で走らせる光の粒。
   往復ではなく上から下への一方向なので、.scroll-hint と違い ease-in-out は
   使わない（折り返しが無い＝両端を緩める理由が無い）。線の外へ抜けるところ
   まで動かしたいので、終端は 100% を超える 260% まで送る。 */
@keyframes strataFlow {
  0%   { transform: translateY(-100%); opacity: 0; }
  25%  { opacity: 1; }
  75%  { opacity: 1; }
  100% { transform: translateY(260%); opacity: 0; }
}

/* ==========================================================================
   Scroll-triggered reveal

   IntersectionObserver が .active を付けるまで要素を隠す仕掛け。初期非表示を
   無条件に書くと、JSが動かない環境（JS無効・スクリプトの読み込み失敗・
   IntersectionObserver 非対応）でページがほぼ白紙になる。そのため隠す指定は
   <html class="js-reveal"> が付いているときだけ有効にしてある。クラスを付ける
   のは各ページ <head> のインラインスクリプトの責務で、そこで
   IntersectionObserver の有無まで見ている。付かなければ .reveal は素の要素と
   同じで、通常のフローでそのまま表示される。
   ========================================================================== */

.js-reveal .reveal {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity var(--dur-slow) var(--ease-out-expo),
              transform var(--dur-slow) var(--ease-out-expo);
}

.js-reveal .reveal.active {
  opacity: 1;
  transform: translateY(0);
}

/* セクション内の要素を少しずつずらして立ち上げる。 */
.js-reveal .delay-1 { transition-delay: 0.1s; }
.js-reveal .delay-2 { transition-delay: 0.2s; }
.js-reveal .delay-3 { transition-delay: 0.3s; }
.js-reveal .delay-4 { transition-delay: 0.4s; }
.js-reveal .delay-5 { transition-delay: 0.5s; }
.js-reveal .delay-6 { transition-delay: 0.6s; }

/*
 * ずらしを打ち消す。#contact などフラグメント付きで開かれたとき、ジャンプ先は
 * 最初から画面内にあるので、delay-4 なら 0.4s のあいだ transition すら始まらず
 * カードの枠だけがあって中身が空、という状態になってしまう。
 * 付与は各ページの reveal スクリプトが location.hash を見て行う。
 * .delay-* より詳細度が高いので !important は要らない。
 */
.js-reveal .reveal.reveal-now { transition-delay: 0s; }

/* 往復するループなので、片道用の --ease-out-expo ではなく ease-in-out を使う。
   transition 側は全て --ease-out-expo に統一してある。 */
.scroll-hint {
  animation: scroll-hint 2s ease-in-out infinite;
}

/* ==========================================================================
   Skip link
   ========================================================================== */

/*
 * キーボード利用時にヘッダーのナビを読み飛ばして本文へ到達するための導線。
 * <body> 直後に置き、飛び先は <main id="main">。
 *
 * Tailwind の sr-only / focus:not-sr-only ではなく手書きCSSで持っている。
 * Tailwind を CDN 版で読み込んでいた頃は、クラスが実行時に生成されるため、
 * 生成が終わるまでの数フレームだけリンク文言が素のテキストとして画面最上部に
 * 見えてしまう問題があった。現在はビルド済みCSSを配信しておりこの問題は
 * 無いが、実装はそのまま独自CSSで維持している。
 */
.skip-link {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* display:none や visibility:hidden ではなくクリップで隠しているのは、
   それらだとフォーカスを受け取れずリンクごと到達不能になるため。
   枠は上の :focus-visible 既定と同じ考え方だが、白いカードの上に出るので
   accent-600（白地 5.10:1）を使う。 */
.skip-link:focus {
  position: fixed;
  top: 1rem;
  left: 1rem;
  z-index: 100;            /* ヘッダー(z-50)・モバイルメニュー(z-40)より前面 */
  width: auto;
  height: auto;
  overflow: visible;
  clip: auto;
  clip-path: none;
  padding: 0.75rem 1.25rem;
  border-radius: 0.75rem;
  background: #fff;
  color: rgb(var(--c-accent-700));
  font-size: 0.875rem;
  letter-spacing: var(--tracking-ui);
  box-shadow: var(--shadow-lift);
  outline: 2px solid rgb(var(--c-accent-600));
  outline-offset: 2px;
}

/* 飛び先の <main> には tabindex="-1" を併記している（付けないとブラウザに
   よってはフォーカスがヘッダーに残り、次の Tab がまたナビの先頭に戻る）。
   トップページのスムーススクロールも同様に、着地した section へ tabindex="-1"
   を補ってフォーカスを移す。
   いずれも「Tab 順には入らない、飛び先としてだけフォーカスを受ける」要素で、
   どこへ飛んだかはスクロール位置で分かるため枠は出さない。

   要素を main / section に限っているのは、tabindex="-1" を別の目的で使う
   フォーム部品（お問い合わせフォームの _gotcha ハニーポットなど）から
   上の :focus-visible 既定によるフォーカス表示を奪わないため。 */
main[tabindex="-1"]:focus,
section[tabindex="-1"]:focus {
  outline: none;
}

/* ==========================================================================
   Header / Mobile menu
   ========================================================================== */

/*
 * トップページではスクロール時にJSで付与し、下層ページでは常時付与する
 * （下層ページはヘッダー背後に暗いヒーローが無いため）。
 */
.header-glass {
  background: rgb(255 255 255 / 0.8);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: var(--shadow-header);
}

/*
 * 閉じている間は visibility: hidden で「見えない」だけでなく「触れない」
 * 状態にする。transform だけで画面外へ逃がすと、タブ順にも読み上げにも
 * 残ってしまうため（WCAG 2.4.3 / 2.4.7）。
 * JS 側（/js/menu.js）は同じ役割を inert で担う。二重化は inert 非対応
 * 環境への保険。
 *
 * visibility の指定が両者で非対称なのは意図的:
 *
 *   閉じるとき（下の規則）… visibility 0s linear var(--dur-base)
 *     duration 0 で「遅延だけ」を与える。パネルがスライドし切ってから
 *     hidden に落ちるので、消えるアニメーションが途中で切れない。
 *   開くとき（.open）……… transition に visibility を含めない
 *     遷移対象から外して即 visible にする。duration 0 を指定する手も
 *     あるが、それだと prefers-reduced-motion の
 *     「transition-duration: .01ms !important」に引きずられて非ゼロになり、
 *     開いた直後の同期処理の時点ではまだ hidden のままになる。すると
 *     ブラウザが不可視要素へのフォーカスを拒否し、menu.js の
 *     「開いたら先頭リンクへフォーカス」が動きを減らす設定の利用者だけ
 *     黙って効かなくなる。遷移対象から外せば上書きの影響を受けない。
 *
 * visibility 自体を transition させる書き方（transition: visibility .4s）は
 * 両方向とも終端まで値が変わらないので、開くときに同じ問題を起こす。
 */
.mobile-menu-panel {
  transform: translateX(100%);
  visibility: hidden;
  transition: transform var(--dur-base) var(--ease-out-expo),
              visibility 0s linear var(--dur-base);
}

.mobile-menu-panel.open {
  transform: translateX(0);
  visibility: visible;
  transition: transform var(--dur-base) var(--ease-out-expo);
}

/*
 * 開いている間、ハンバーガーボタン（z-50）は白いパネル（z-40）の上に重なる。
 * トップページ最上部ではボタンが text-white なので、閉じるアイコンが
 * 白地に白で描かれ、コントラスト 1:1 で完全に見えなくなる。
 *
 * ID セレクタ（詳細度 1,0,0）で Tailwind の .text-white / .text-brand
 * （0,1,0）を確実に上書きする。index.html のスクロール処理が
 * これらのクラスを付け外ししても影響を受けない。
 * 状態は menu.js が維持する aria-expanded から取る。
 */
#mobile-menu-btn[aria-expanded="true"] {
  color: rgb(var(--c-brand-800));
}

.mobile-menu-overlay {
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease-out-expo);
}

.mobile-menu-overlay.open {
  opacity: 1;
  pointer-events: auto;
}

/* ==========================================================================
   Components
   ========================================================================== */

/* --- Primary button --- */
.btn-primary {
  position: relative;
  overflow: hidden;
  transition: all var(--dur-fast) var(--ease-out-expo);
}

.btn-primary::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, rgb(255 255 255 / 0.1), rgb(255 255 255 / 0));
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out-expo);
}

.btn-primary:hover::after {
  opacity: 1;
}

.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-cta);
}

/* --- ヒーローCTAのフォーカスリング ---
   ヒーローのCTAは明度の変わる地（.strata-surface）の上に載るため、UA既定の
   フォーカスリングが地の色に埋もれて見えないことがある。キーボード操作でも
   現在位置が分かるよう、暗い縁と白のリングを二重に置いて、地の明暗どちらでも
   輪郭が残るようにしている。白背景の上に置かれる他の .btn-primary（フォームの送信ボタン等）は
   既定のままで十分見えるので、#hero 内に限定する。 */
#hero a:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgb(var(--c-brand-900) / 0.9),
              0 0 0 4px rgb(255 255 255 / 0.9);
}

/* --- Service card (トップページ) --- */
.service-card {
  transition: transform var(--dur-base) var(--ease-out-expo),
              box-shadow var(--dur-base) var(--ease-out-expo);
}

.service-card:hover {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lift);
}

.service-card .card-icon {
  transition: transform var(--dur-base) var(--ease-out-expo);
}

.service-card:hover .card-icon {
  transform: scale(1.1);
}

/* --- リスト状カードの浮き上がり ---
   /news/ の記事カードと /404.html の導線カードで挙動を共有する。
   同じ見た目を別名で複製すると片方だけ値がずれても気づけないため、
   セレクタを並記して1つの定義にまとめている。 */
.news-card,
.nav-card {
  transition: transform var(--dur-base) var(--ease-out-expo),
              box-shadow var(--dur-base) var(--ease-out-expo);
}

.news-card:hover,
.nav-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
}

/* --- Breadcrumb（/news/ 一覧・記事ページ） ---
   区切り記号は擬似要素で描く。マークアップ側に <li aria-hidden="true">/</li> を
   置く書き方もあるが、それだと <ol> の項目数が階層の倍近くになり、スクリーン
   リーダーが「リスト、5項目」と読み上げてしまう（実際の階層は3）。装飾は CSS に
   寄せ、<ol> には階層そのものだけを残す。
   文字サイズと色は用途ごとに変わるのでマークアップ側のユーティリティに任せ、
   ここではレイアウトと区切り記号だけを持つ。 */
.breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.breadcrumb li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.breadcrumb li + li::before {
  content: '/';
  color: rgb(var(--c-brand-300));
}

/* --- Form --- */
.form-input {
  transition: all var(--dur-fast) var(--ease-out-expo);
}

.form-input:focus {
  outline: none;
  border-color: rgb(var(--c-accent-600));
  box-shadow: 0 0 0 4px rgb(var(--c-accent-600) / 0.1);
}

/*
 * エラー時の見た目は aria-invalid を単一の情報源にしている。
 * 別途 .is-error のようなクラスを足すと「支援技術向けの状態」と
 * 「目に見える状態」が二重管理になり、片方だけ外れる事故が起きる。
 */
.form-input[aria-invalid="true"] {
  border-color: rgb(var(--c-danger-600));
}

.form-input[aria-invalid="true"]:focus {
  border-color: rgb(var(--c-danger-600));
  box-shadow: 0 0 0 4px rgb(var(--c-danger-600) / 0.12);
}

/*
 * エラー文言。赤という色だけが手がかりだと色覚特性によっては伝わらないため、
 * マークアップ側で警告アイコンを添える（WCAG 1.4.1 色の使用）。
 * display は .form-error 側で持つ。Tailwind の flex ユーティリティを併記すると
 * [hidden] との詰まり順を気にする必要が出るので、ここで完結させている。
 */
.form-error {
  display: flex;
  align-items: flex-start;
  gap: 0.375rem;
  margin-top: 0.5rem;
  font-size: 0.75rem;
  line-height: 1.6;
  color: rgb(var(--c-danger-600));
}

.form-error[hidden] {
  display: none;
}

.form-error svg {
  width: 0.875rem;
  height: 0.875rem;
  flex-shrink: 0;
  margin-top: 0.15em;
}

/* --- Company info row --- */
.info-row {
  transition: background-color var(--dur-fast) var(--ease-out-expo);
}

.info-row:hover {
  background-color: rgb(var(--c-accent-600) / 0.02);
}

/* --- Eyebrow（SERVICES / NAVIGATION 等の英大文字ラベル） ---
   書体・字間・字送りが常にセットで効くよう、ユーティリティの並記ではなく
   1つのクラスにまとめている。色と文字サイズは用途ごとに変わるのでここでは
   指定しない。 */
.eyebrow {
  font-family: var(--font-brand);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

/* --- 和文の小見出し ---
   .eyebrow と同じ位置（ブロックの上に置く小さな見出し）に使うが、和文には
   0.25em の字送りが広すぎて語のまとまりが崩れる。UIラベルと同じ 0.05em に
   とどめ、和文には効かず英字だけが変形する text-transform も持たせない。
   書体も欧文用の Archivo ではなく見出し用の Zen Kaku Gothic New を使う。 */
.subhead {
  font-family: "Zen Kaku Gothic New", sans-serif;
  font-weight: 500;
  letter-spacing: var(--tracking-ui);
}

/* --- Decorative --- */

/* ヒーローの地層背景。
   ロゴは地層の断面である。上から3層が土、最下層のアクセント色が帯水層——
   土の下を流れる地下水脈を指す。この面はその断面を全面に引き伸ばしたもので、
   ページを開いた人はロゴの内側、土の中に立っていることになる。

   置き換えの経緯:
   以前ここには Unsplash のグラデーション画像（hero-bg.jpg）を敷き、そこに
   含まれるピンクとマゼンタが新アクセントの色相と競合するため saturate(0.3)
   で彩度を落としていた。ただし saturate は明度を変えない。写真の明るい部分
   （#6E7774 前後）はそのまま残り、白文字とのコントラストは eyebrow で
   2.76:1、価値提案で 4.16:1 と AA を割っていた。地をブランドの色相そのもので
   作れば、落とすべき彩度も、明度を奪う元画像も最初から存在しない。

   マークの実寸との対応（undersoil-mark.svg / viewBox 54×54）:
     帯幅は 47 / 37 / 27 / 17 で、54に対する比は 87% / 68% / 50% / 31%。
     下の帯ほど短くなるこの階段がマークの署名なので、線は左寄せ（マークと同じ）で
     引き、幅にはこの比をそのまま使う。

   土の層の線を3本やめて、下の2本だけにした経緯:
     以前は上部（10% / 12.5% / 15%）に白の細線を3本引き、その下の 94% に
     帯水層の線を置いていた。これは次の2つの理由で機能していなかった。

     1. 比率が保てない。マークの階段は縦横およそ 2:1 のなかで成立している。
        1440×900 に引き伸ばすと線の間隔は 22px のまま長さだけが 1252px に
        なり、およそ 50:1 の平たい線になる。この比では、何本並べても
        「下ほど短くなる階段」としては読めない。
     2. 濃度が中途半端だった。白10%〜17%の1pxは地に対して 1.31〜1.55:1。
        これは「意図した線に見える」には足りず、「見えない」には足りている
        ——最も悪い位置で、しかも 10% は固定ヘッダー（h-20）のすぐ下に来る
        ため、幅87%で唐突に途切れる横線が描画の継ぎ目のように見えていた。
        濃くしても 1. は解決しないので、上げるのではなく外した。

     残したのは階段の下2段（50% / 31%）で、位置も下端の静かな帯へ寄せてある。
     ここは中身（CTAの下端）から100px以上空いており、線が文字と干渉しない。
     2本にすると水位線が「1本の罫」ではなく層の境界として読め、土と水の境を
     示すという元の意図はむしろ通る。色を白ではなくアクセントにしたのは、
     この2本が土の層ではなく帯水層側の面だからである。

   線で描き、面の明度差にしなかった理由:
     トークンは OKLCH の明度軸で生成されているため、brand-900 (#252E31) と
     accent-900 (#003D49) はほぼ同じ明度で、重ねても色相しか変わらない。
     段差を出すには地全体を明るくするしかないが、そうすると accent-600 の
     主CTAが地に埋もれ、従CTAの白40%の枠も 3:1 を割る（計測値 2.86:1）。
     線であれば地の明度を上げずに局所的な輪郭だけを作れる。

   記述順は重なり順（先頭が最前面）:
     1.   帯水層の上面。階段の3段目（50%）を 88% の高さに置く。
     2.   帯水層の水位線。階段の4段目（31%）を 94% の高さに置く。
          位置を動かすときは、中身の下端より下（＝下端から12%以内）を保つこと。
     3.   帯水層の光。芯を画面下端の外に置き、光だけが層の間から上がってくる。
          彩度を持つ領域を画面内でここだけにすると、CTAとアクセントドットが
          地と競合しない。下端が最も明るいのは、次のセクション（bg-surface）
          が明るいためで、スクロールの継ぎ目を段差にしない狙いもある。
     4.   土の柱。下へ行くほど帯水層の色を含む。177deg は真下（180deg）から
          3°傾けた角度で、堆積層は水平ではなく僅かに傾くという事実に沿う。
          真水平だと地層ではなくブラインドに見える。

   background-repeat: no-repeat は必須。境界の2枚は高さ1pxの帯なので、
   繰り返しを許すと縦方向に敷き詰められて面全体が縞になる。 */
.strata-surface {
  background-color: rgb(var(--c-brand-900));
  background-repeat: no-repeat;

  background-image:
    linear-gradient(90deg, rgb(var(--c-accent-300) / 0.30), rgb(var(--c-accent-300) / 0)),
    linear-gradient(90deg, rgb(var(--c-accent-300) / 0.55), rgb(var(--c-accent-300) / 0)),
    radial-gradient(140% 40% at 50% 108%,
      rgb(var(--c-accent-400) / 0.45) 0%,
      rgb(var(--c-accent-500) / 0.24) 40%,
      transparent 74%),
    linear-gradient(177deg,
      rgb(var(--c-accent-900) / 0)    0%,
      rgb(var(--c-accent-900) / 0.18) 28%,
      rgb(var(--c-accent-900) / 0.38) 56%,
      rgb(var(--c-accent-800) / 0.62) 84%,
      rgb(var(--c-accent-800) / 0.82) 100%);

  background-size:
    50% 1px,
    31% 1px,
    100% 100%,
    100% 100%;

  background-position:
    0 88%,
    0 94%,
    0 0,
    0 0;
}

/* ヒーローの見出し。
   行間だけを --leading-display（1.25）に差し替える。text-3xl 〜 text-6xl は
   tailwind.config.js 側で行間 --leading-heading（1.4）を抱えており、
   ブレークポイント付きの lg:text-6xl はメディアクエリ内に出力されるため
   HTML に leading-* を並べても勝てない。site.css は読み込み順が最後なので、
   同じ詳細度でもこちらが後に来て上書きできる。この1点のためだけのクラス。

   1.4 のままだと 60px の見出しの行間が 84px になり、2行が別々の帯に見える。
   ヒーローの h1 は「1つの塊」として読ませたいので、ここだけ詰める。
   折り返し（word-break: auto-phrase / text-wrap: balance）はこのファイル
   冒頭で h1〜h6 に一括で当たっているので、ここでは行間だけを扱う。 */
.hero-title {
  line-height: var(--leading-display);
}

/* ヒーロー下端のスクロール手がかり。

   なぜ要るか:
     ヒーローは min-h-screen で、中身は justify-center で中央に置かれる。
     中身の高さは画面より低いので下端に必ず余白が残る（1440×900 で実測
     130px 前後、縦長のウィンドウではさらに開く）。ここが空のままだと
     「下に続きがある」ことを示すものが画面内に何も無い。

   なぜリンクにしないか:
     従CTA「事業内容を見る」が既に #services への導線を持っている。ここを
     もう1つのリンクにすると、同じ行き先のターゲットがヒーローに2つ並ぶ。
     これは選択肢ではなく手がかりなので、aria-hidden の装飾に留めて
     支援技術からは隠す。

   見た目:
     地の .strata-surface は「土の断面」で、下端の光は帯水層を表している。
     この線を光の粒が上から下へ抜けていくのは、その水脈へ降りていく動き。
     線そのもの（下へ向かって明るくなるグラデーション）は静止画でも成立
     するので、prefers-reduced-motion で粒が止まっても手がかりは残る。 */
.hero-scroll-cue {
  position: absolute;
  bottom: 2rem;
  left: 50%;
  transform: translateX(-50%);
  width: 1px;
  height: 3.5rem;
  overflow: hidden;
  background: linear-gradient(to bottom,
    rgb(255 255 255 / 0),
    rgb(255 255 255 / 0.28));
}

.hero-scroll-cue::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 45%;
  background: linear-gradient(to bottom,
    rgb(var(--c-accent-300) / 0),
    rgb(var(--c-accent-300) / 0.95));
  animation: strataFlow 2.6s linear infinite;
}

.hero-shape {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  opacity: 0.3;
}

/* ==========================================================================
   Article typography (/news/ 記事本文)
   ========================================================================== */

.article-prose p {
  margin-bottom: 1.5em;
  line-height: 1.9;
}

.article-prose p:last-child {
  margin-bottom: 0;
}

/*
 * 記事末尾の前後ナビ。
 *
 * 「次の記事」に grid-column を明示しているのが要点。最古の記事には「前の記事」が
 * 無いため、指定しないと「次の記事」が左端に寄る。記事を順に読んでいく利用者から
 * 見ると、記事ごとに新しい方が左右どちらに来るか変わることになり、毎回どちらが
 * 新しい方か読み直す羽目になる。片方しか無い記事でも位置は動かさない。
 */
.article-nav {
  display: grid;
  gap: 0.75rem;
}

@media (min-width: 640px) {
  .article-nav {
    grid-template-columns: 1fr 1fr;
  }

  .article-nav > .article-nav-next {
    grid-column: 2;
    text-align: right;
  }
}

/* ==========================================================================
   Reduced motion

   OS/ブラウザで「視差効果を減らす」を有効にしている利用者には動きを見せない。
   前庭障害・光過敏への配慮であり、WCAG 2.3.3 Animation from Interactions /
   2.2.2 Pause, Stop, Hide に対応する。他の指定を確実に上書きするため、この
   ブロックはファイル末尾に置くこと。
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {

  /*
   * reveal は「動きを止める」のではなく「最初から見えている」状態にする。
   * transition を消すだけだと opacity: 0 のまま JS の発火待ちになり、動きを
   * 減らしたい利用者ほど長く白紙を見ることになって逆効果になる。
   */
  .js-reveal .reveal {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  /*
   * 残りの動き（ヒーローの fade-in / fade-up / line-grow、ロゴの float、
   * スクロールヒント、ホバーの浮き上がり、モバイルメニューの開閉）をまとめて潰す。
   *
   * animation-delay を 0 にするのが要点。ヒーローの各ブロックは HTML 側に
   * style="animation-delay: 0.5s; animation-fill-mode: both" を持っており、
   * fill-mode: both は待ち時間中も開始キーフレーム（opacity: 0）を保つ。
   * duration だけ潰しても delay の分は消えたままになってしまう。インライン
   * style を上回る必要があるので !important を付ける。
   *
   * scroll-behavior もここで面倒を見る（html を含むすべてのスクロール要素が
   * 対象になる）。ただし JS が scrollTo({ behavior: 'smooth' }) と明示した場合は
   * CSS では止められないので、index.html 側でも同じ設定を見ている。
   */
  *,
  *::before,
  *::after {
    animation-delay: 0s !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-delay: 0s !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
