/*
 * refine.css — デザイン上乗せレイヤー v3「リビングインターフェース」。
 * style.css（およびページ別CSS）の後に読み込む前提で、落ち着いたダーク基調と
 * 青アクセントのアイデンティティは保ったまま、サイト全体を3層の応答で刷新する:
 *   1) 進むと現れる — 既存リビールに 60ms スタガーと見出し罫線のドローイン
 *   2) 触れると光が走る — カード/ボタンの光沢スイープ、統一リフト＋発光
 *   3) 奥に深さがある — オーロラ3層＋ドット格子、ガラスの厚み、発光エレベーション
 *
 * 方針:
 * - 基盤の style.css はトークン参照のみ。上書きはこのファイルに集約する。
 * - CSP 準拠（外部リソース・インライン無し）。テクスチャも全てCSSグラデで生成。
 * - モーションは transform / opacity / box-shadow 遷移のみ。無限アニメは
 *   「ヒーローの超低速ドリフト2層」と「ごく小さな生命感（Clawd の瞬き・
 *   肩書きドットの呼吸・about 現在地の灯）」に限定（いずれも reduced-motion で停止）。
 *   三重ガード:
 *   style.css の 0.001ms キルスイッチ + JS の .reveal 非付与 + 末尾の包括ブロック。
 * - エラーページ(404/403/500)も同じ層を読むため、構造クラスの上書きは互換を保つ。
 * - 紫(--accent-2)は脇役（グラデの端・eyebrow・error-code）に限定し、青を主役に保つ。
 */

/* =====================================================================
   デザイントークン（refine 層専用。基盤トークンは style.css :root）
   ===================================================================== */
:root {
    /* 一次ボタン等の塗り用グラデ（深い青 → 青 → 紫の帯） */
    --grad-accent: linear-gradient(92deg, var(--accent-deep), var(--accent) 52%, var(--accent-2));
    /* (旧 --grad-accent-soft は削除: 消費者ゼロだった) */
    /* テキストグラデ（hero名前/統計数字）とマスク式1pxリング（ナビ/CTA帯）の共通語彙 */
    --grad-text: linear-gradient(120deg, var(--text) 25%, var(--accent-strong) 92%);
    --grad-ring: linear-gradient(100deg, rgba(var(--accent-rgb), 0.35), rgba(255, 255, 255, 0.06) 40%, rgba(var(--accent-2-rgb), 0.28));
    /* ガラス面の上端ハイライト（カード/フォーム/統計タイル等、面グラデの共通語彙） */
    --grad-glass-top: linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent 46%);
    /* ガラス面: ヘアライン枠 + 上端インセットハイライト */
    --glass-border: rgba(255, 255, 255, 0.07);
    --glass-hilite: inset 0 1px 0 var(--edge-light);
    /* ガラスパネルの背景（navbar/目次パネル/モバイルメニュー）。
       backdrop-filter 対応時は -blur を、モバイルメニューは不透明の -strong を使う。
       navbar 裏に画像内テキスト等が透けて見えないよう不透明寄りに保つ
       （旧: -bg=0.82 / -blur=0.62 → 現: -bg=0.92 / -blur=0.85）。 */
    --glass-bg: rgba(var(--bg-rgb), 0.92);
    --glass-bg-blur: rgba(var(--bg-rgb), 0.85);
    --glass-bg-strong: rgba(var(--bg-rgb), 0.97);
    /* 本文の上に浮くガラスパネル(目次パネル/Konamiトースト)共通の影 */
    --glass-shadow-float: var(--glass-hilite), 0 12px 34px rgba(0, 0, 0, 0.4);
    /* 小さめのアクセント発光(スクロール進捗ライン/ナビ現在地の下線) */
    --accent-glow-sm: 0 0 8px rgba(var(--accent-rgb), 0.4);
    /* about「いま」のタイムラインドット: 静止時とnow-pulseアニメの両端で使い、
       ずれ(drift)が起きないよう1箇所にまとめている */
    --timeline-now-glow: 0 0 0 2px var(--accent), 0 0 0 6px var(--accent-soft),
                0 0 18px rgba(var(--accent-rgb), 0.35);

    /* v4: 形状スケールの引き上げ（style.css の既定 12px/8px を上書き）。
       カード・ボタン・入力欄・モーダルがひと回り現代的な丸みになる。
       admin/system（/admin, /system）はrefine.cssを読まないためこの上書きを受けない */
    --radius: 16px;
    --radius-sm: 10px;

    /* v5: 型スケール（display/h1/h2/h3 の4段 + 本文最適幅）。
       「タイトル大 → 章見出し中 → カード小」の遠近感を全ページで統一する。 */
    --fs-h1: clamp(2.4rem, 1.9rem + 2.2vw, 3.3rem);
    --fs-h2: clamp(1.8rem, 1.45rem + 1.5vw, 2.35rem);
    --fs-h3: clamp(1.35rem, 1.27rem + 0.4vw, 1.55rem);
    --measure: 70ch;
}

/* =====================================================================
   A. 背景の奥行き — オーロラ3層 + 上部にだけ浮かぶドット格子
   ===================================================================== */
/* オーロラ3層は html::before の固定レイヤーに描く（body の背景色は style.css が担う）。
   body への background-image + background-attachment: fixed はスクロールごとに背景の
   再ラスタライズを誘発し、iOS Safari では fixed 自体が効かない（scroll 扱いで流れてしまう）。
   position: fixed の擬似要素に閉じればペイント境界が固定に閉じ、iOS でも同一表示。
   body::before（ドット格子）は mask で上部 400px に限定しているため同居できず、
   未使用の html::before を専用層として使う。 */
html::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image:
        radial-gradient(1100px 540px at 50% -10%, rgba(var(--accent-rgb), 0.10), transparent 60%),
        radial-gradient(880px 560px at 100% -4%, rgba(var(--accent-2-rgb), 0.06), transparent 55%),
        radial-gradient(700px 480px at 12% 8%, rgba(var(--accent-rgb), 0.05), transparent 60%);
}

/* 上部 400px にだけ浮かぶドット格子（style.css の body::before グローを置換。
   旧グローの役割は上の background-image が引き継ぐため視覚後退なし）。 */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: none;
    background-image: radial-gradient(rgba(255, 255, 255, 0.028) 1px, transparent 1px);
    background-size: 28px 28px;
    -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 400px);
    mask-image: linear-gradient(180deg, #000 0%, transparent 400px);
}

/* スクロールバーも世界観に合わせて控えめに (Firefox 用)。
   注意: Chrome 121+ は html に scrollbar-color を書くと ::-webkit-scrollbar の
   width 指定を無視して modern 描画モードに切り替わる。そのため Firefox 専用
   feature gate (-moz-appearance) の中に閉じ込め、Chrome/Edge/Safari は下の
   ::-webkit-scrollbar 経路で正確に 8px を効かせる。 */
@supports (-moz-appearance: none) {
    html {
        scrollbar-width: thin;
        scrollbar-color: var(--border-bright) transparent;
    }
}

/* WebKit系: 8px 幅、トラックは透明にして本文の背景に溶かし、
   つまみは透明ボーダー 2px で 4px の細ピルにする。
   （モーダル内の既存定義はより具体的なセレクタで勝つ） */
::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background: var(--border-bright);
    border-radius: var(--radius-pill);
    border: 2px solid transparent;
    background-clip: padding-box;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--dim);
    background-clip: padding-box;
}

/* =====================================================================
   A-2. スクロール進捗ライン — 画面最上端を走る「現在地の光」
   CSS scroll-driven animations（JSゼロ）。対応ブラウザだけの progressive
   enhancement で、非対応環境では何も出ない。右端目次のティックと同じ
   「いまどこ」の語彙を、最上端 2px のグラデラインで補完する。
   スクロールしないページではタイムラインが不活性 → 基底 scaleX(0) のまま不可視。
   reduced-motion（Mブロック）と forced-colors では非表示。
   ===================================================================== */
@supports (animation-timeline: scroll()) {
    body::after {
        content: "";
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        height: 2px;
        z-index: 1002;
        pointer-events: none;
        background: var(--grad-accent);
        box-shadow: var(--accent-glow-sm);
        transform-origin: 0 50%;
        transform: scaleX(0);
        animation: scroll-progress linear both;
        animation-timeline: scroll(root);
    }

    @keyframes scroll-progress {
        from {
            transform: scaleX(0);
        }

        to {
            transform: scaleX(1);
        }
    }
}

/* =====================================================================
   B. ナビ / フッター — v4: 浮遊するガラスのピルナビ
   上端密着バーをやめ、余白＋角丸＋グラデーションリングの浮遊ナビへ。
   --header-height(68px) は本文の逃げ量として維持し、ピル本体は
   top:10px + height:58px = 下端ちょうど 68px に収める（既存レイアウト不変）。
   transform は使わない（モバイルの position:fixed メニューを狂わせないため）。
   ===================================================================== */
.navbar {
    top: 10px;
    left: 0;
    right: 0;
    margin-inline: auto;
    width: min(var(--container-wide), calc(100% - 24px));
    height: calc(var(--header-height) - 10px);
    border: 1px solid var(--glass-border);
    border-bottom: 1px solid var(--glass-border);
    border-radius: var(--radius-pill);
    background: var(--glass-bg);
    box-shadow: var(--glass-hilite), 0 10px 32px rgba(0, 0, 0, 0.38), 0 0 0 1px rgba(var(--accent-rgb), 0.04);
}

@supports ((backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px))) {
    .navbar {
        background: var(--glass-bg-blur);
        -webkit-backdrop-filter: blur(18px) saturate(160%);
        backdrop-filter: blur(18px) saturate(160%);
    }
}

/* ピルの縁を一周する淡いグラデーションリング（マスクで枠線1pxだけ残す） */
.navbar::after {
    content: "";
    position: absolute;
    inset: -1px;
    padding: 1px;
    border-radius: inherit;
    pointer-events: none;
    background: var(--grad-ring);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
}

/* スキップリンクはピルナビより前面に（フォーカス時に隠れない） */
.skip-link {
    z-index: 1001;
}

/* モバイルのドロップダウンもピルに合わせた浮遊ガラスパネルに */
@media (max-width: 768px) {
    .nav-menu {
        top: calc(var(--header-height) + 8px);
        left: 12px;
        right: 12px;
        border: 1px solid var(--glass-border);
        border-bottom: 1px solid var(--glass-border);
        border-radius: var(--radius);
        background: var(--glass-bg-strong);
        box-shadow: var(--shadow-lg);
        overflow: hidden;
    }
}

/* ナビ下線: 左から伸びるグラデ + 現在地のみ淡い発光（全項目同一装飾 = 統一感の維持） */
.nav-menu li a::after {
    background: linear-gradient(90deg, var(--accent), var(--accent-strong));
    transform-origin: left;
    transition: transform var(--dur) var(--ease-out), opacity var(--dur) var(--ease-out);
}

.nav-menu li a.is-active::after,
.nav-menu li a[aria-current]::after {
    box-shadow: var(--accent-glow-sm);
}

/* フッター: 上端の発光ヘアライン + 淡い照り返し */
.site-footer {
    position: relative;
    border-top-color: transparent;
}

.site-footer::before {
    content: "";
    position: absolute;
    top: -1px;
    left: 0;
    right: 0;
    height: 1px;
    pointer-events: none;
    background: linear-gradient(90deg, transparent, rgba(var(--accent-rgb), 0.35) 40%, rgba(var(--accent-2-rgb), 0.25) 60%, transparent);
}

.site-footer::after {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: min(900px, 100%);
    height: 160px;
    pointer-events: none;
    background: radial-gradient(900px 160px at 50% 0, rgba(var(--accent-rgb), 0.09), transparent 70%);
}

/* v5: 3カラムの「締めの面」— 左=ワードマーク+ソーシャル / 中=サイトマップ /
   右=補助リンク。最下段はヘアラインで copyright / 最終更新を振り分け。 */
.footer-container {
    align-items: stretch;
    text-align: left;
    gap: 0;
    padding: 3rem 1.8rem 1.6rem;
}

/* v6: 2カラムに整理（左=ワードマーク+ソーシャル / 右=全ページへのサイトマップ）。
   以前は「サイトマップ」「補助リンク」の2列に分かれ、項目数が7:3で非対称に
   間延びして見えたため、1本の一覧に統合して .footer-sitemap 内部の
   2カラム(column-count)で自動的に釣り合わせる。 */
.footer-grid {
    display: grid;
    grid-template-columns: 1.1fr 1fr;
    gap: 32px;
    padding-bottom: 28px;
}

.footer-logo {
    display: inline-block;
    font-size: 1.35rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    text-decoration: none;
    color: var(--text);
}

/* グラデ文字は他のグラデ文字（hero名前等）と同じ @supports 防御に揃える */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
    .footer-logo {
        background: var(--grad-heading);
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
    }
}

.footer-social {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 14px;
}

.footer-social a {
    /* --brand は各 <a class="x|github|..."> で個別に上書き。未設定なら muted。 */
    --brand: var(--muted);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-pill);
    background: var(--surface);
    color: var(--brand);
    box-shadow: var(--glass-hilite);
    transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out),
                transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}

/* 各ソーシャルのブランド色。--brand-* は style.css で定義済み。
   sponsor は accent (heart) で通す。X は --brand-glow で hover 時だけ Twitter blue に。 */
.footer-social a.x       { --brand: var(--brand-x);       --brand-glow: var(--brand-x-hover); }
.footer-social a.github  { --brand: var(--brand-github); }
.footer-social a.yt      { --brand: var(--brand-yt); }
.footer-social a.discord { --brand: var(--brand-discord); }
.footer-social a.keybase { --brand: var(--brand-keybase); }
.footer-social a.sponsor { --brand: var(--accent); }

.footer-social a:hover,
.footer-social a:focus-visible {
    border-color: color-mix(in srgb, var(--brand-glow, var(--brand)) 55%, transparent);
    transform: translateY(var(--lift-sm));
    box-shadow: var(--glass-hilite), 0 0 0 3px color-mix(in srgb, var(--brand-glow, var(--brand)) 18%, transparent);
}

.footer-social .fa-icon {
    width: 1.05em;
    height: 1.05em;
}

/* タッチ端末はサイト規約どおり 44px のタップ標的に */
@media (pointer: coarse) {
    .footer-social a {
        width: 44px;
        height: 44px;
    }
}

/* 全ページへのリンクを1本のnavにまとめ、明示的な CSS Grid で2列×5行に
   決定的に配置する（1列目を上から詰めてから2列目へ。10リンク前提。
   件数が変わったら grid-template-rows の行数も合わせて調整する）。
   newspaper 型の `columns` は自動バランスに依存し見た目の予測が難しいため
   採用しない。狭い幅では1カラムに戻す。 */
.footer-sitemap {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: repeat(5, auto);
    grid-auto-flow: column;
    column-gap: 28px;
    margin: 0;
}

.footer-sitemap a {
    display: block;
    font-size: 0.88rem;
    color: var(--muted);
    text-decoration: none;
    padding: 6px 0;
    transition: color var(--dur) var(--ease-out);
}

.footer-sitemap a:hover,
.footer-sitemap a:focus-visible {
    color: var(--accent-strong);
}

/* BP 規約 (380/600/768/860) に整合させ 480px → 600px へ。600-480 帯は 2 列 → 1 列に
   変わるが、footer リンク 10 件の可読性はむしろ向上する。 */
@media (max-width: 600px) {
    .footer-sitemap {
        grid-template-columns: 1fr;
        grid-template-rows: none;
        grid-auto-flow: row;
    }
}

.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    gap: 6px 16px;
    padding-top: 18px;
    border-top: 1px solid var(--border);
}

@media (max-width: 768px) {
    .footer-grid {
        grid-template-columns: 1fr;
        gap: 24px;
    }

    .footer-bottom {
        flex-direction: column;
        align-items: flex-start;
    }
}

/* =====================================================================
   C. 見出しとセクションの骨格 — グラデ下線のドローインと消え入る境界線
   ===================================================================== */
.section-title {
    font-size: var(--fs-h2);
    letter-spacing: -0.015em;
    /* 和文が2行に折り返した時の窮屈さを緩和（1行で収まる見た目はほぼ変わらない） */
    line-height: 1.3;
    text-wrap: balance;
}

/* ページタイトル(h1)は章見出し(h2)から一段引き上げ、開いた瞬間の遠近感を作る */
h1.section-title {
    font-size: var(--fs-h1);
    letter-spacing: -0.02em;
}

main.left .section-title::after {
    width: 72px;
    background: var(--grad-rule);
    box-shadow: 0 0 16px rgba(var(--accent-rgb), 0.45);
}

/* カードグリッドの呼吸を広げる（v4） */
.cards {
    gap: 24px;
}

/* 見出し罫線のドローイン: リビール発火に同期して左から引かれる。
   非JS / reduced-motion では .reveal が付かないため常に表示（既存ガード再利用）。 */
body.js .reveal .section-title::after {
    transform: scaleX(0);
    transform-origin: left;
}

body.js .reveal.is-revealed .section-title::after {
    transform: scaleX(1);
    transition: transform 0.6s var(--ease-out) 0.1s;
}

/* 小見出し4種のサイズ統一（マークアップ・文言不変）+ グラデ縦ノッチ。
   h1 の --grad-rule と同じグラデ語彙を縦棒4pxで反復し、リズムアンカーにする。 */
.ai-subheading,
.contact-faq-title,
.community-subtitle {
    font-size: var(--fs-h3);
    position: relative;
    padding-left: 16px;
}

/* 見出しの行間と折返しバランス + 和文約物の詰め（halt はサブセット収録済み） */
.card-title,
.value-title,
.stack-card-name,
.ai-subheading,
.contact-faq-title,
.community-subtitle,
.work-modal-body h3 {
    line-height: 1.4;
    text-wrap: balance;
}

.section-title,
.card-title,
.ai-subheading,
.contact-faq-title,
.community-subtitle,
.work-modal-body h3 {
    font-feature-settings: "halt" 1;
}

/* 本文は段落末尾の孤立行を防ぐ（非対応環境では無害な no-op） */
p,
.card-text {
    text-wrap: pretty;
}

/* リード系段落の行長を全ページで統一（余白のデザイン） */
.contact-lead,
.ai-sub-lead {
    max-width: var(--measure);
}

.cta-band-lead {
    max-width: var(--measure);
    margin-inline: auto;
}

/* メタ情報の数字は等幅（today も将来のマークアップも一括で規律化） */
time,
.card-meta-item,
.community-note,
.community-breakdown {
    font-variant-numeric: tabular-nums;
}

.ai-subheading::before,
.contact-faq-title::before,
.community-subtitle::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.18em;
    width: 4px;
    height: 0.9em;
    border-radius: 2px;
    background: var(--grad-rule);
    box-shadow: 0 0 10px rgba(var(--accent-rgb), 0.35);
}

/* セクション境界の消え入る罫線（縦の間延び対策を兼ねる） */
main.left .section + .section {
    border-top: 1px solid transparent;
    border-image: linear-gradient(90deg, transparent, rgba(var(--accent-rgb), 0.16), transparent) 1;
}

/* 境界罫線の直下に「天井光」の radial ブルーム（site-footer::after と同語彙）。
   各セクションが罫線の光を受けて始まる。CTA帯はパネル化するため除外。 */
main.left .section + .section:not(.cta-band) {
    position: relative;
}

main.left .section + .section:not(.cta-band)::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: min(760px, 92%);
    height: 140px;
    pointer-events: none;
    background: radial-gradient(60% 100% at 50% 0, rgba(var(--accent-rgb), 0.07), transparent 70%);
}

/* セクションの縦リズムを広げ、余白で「格」を出す（モバイルは style.css の値を維持） */
@media (min-width: 769px) {
    .section {
        padding-top: 88px;
        padding-bottom: 88px;
    }
}

/* 目次が先行する最初のセクションは初画面を引き上げる
   （skills.css / privacy.css の個別ルールをここへ昇格して全サブページ統一） */
main.left .page-toc ~ .section:first-of-type {
    padding-top: 24px;
}

/* =====================================================================
   D. カード — ガラスの厚み + 常時灯る上端ライン + 光沢スイープ
   （.card 基底の全種 / projects の .stack-card / community の .timeline-content）
   ===================================================================== */
.card,
.stack-card,
.timeline-content {
    background-image: var(--grad-glass-top);
    border-color: var(--glass-border);
    box-shadow: var(--glass-hilite);
}

/* 上端のアクセントライン: 常時 28% で灯し、ホバーで満点灯＋発光 */
.card::before {
    height: 2px;
    background: var(--grad-rule);
    transform: none;
    opacity: 0.28;
    transition: opacity 0.3s ease, box-shadow 0.3s ease;
}

/* 静的カード（クリック不可）は縁を点灯させるだけに留める。
   リフト・発光・光沢スイープは押せるカード専用（下の強い演出）に集中させる。 */
.card:hover {
    border-color: rgba(var(--accent-rgb), 0.35);
    transform: none;
}

.card:hover::before {
    opacity: 1;
    box-shadow: 0 0 12px rgba(var(--accent-rgb), 0.4);
}

/* クリック可能カードだけの強い演出（-4px リフト＋発光）。
   is-pending / is-strip（準備中カード）は対象外のまま。 */
:is(.work-card:not(.is-pending), .timeline-content, .tool-card):hover {
    transform: translateY(var(--lift));
    box-shadow:
        var(--glass-hilite),
        var(--shadow-lg),
        0 0 0 1px rgba(var(--accent-rgb), 0.16),
        var(--glow);
}

/* about-timeline はクリック不可（about.css で既に無効化済み）。強い演出から除外し、
   従来どおり発光のみ（リフトなし）を維持する。 */
.about-timeline .timeline-content:hover {
    transform: none;
    box-shadow: var(--glass-hilite), var(--shadow), var(--glow);
}

/* stack-card / timeline を共通のカード言語に合流 */
.stack-card,
.timeline-content {
    transition: transform var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}

.stack-card:hover {
    border-color: rgba(var(--accent-rgb), 0.35);
    box-shadow: var(--glass-hilite), var(--shadow), var(--glow);
}

@media (hover: hover) {
    .stack-card:hover {
        transform: translateY(var(--lift));
    }
}

/* 光沢スイープ: ホバーで光の帯がひと拭き。transition を hover 側にだけ書くことで
   ホバー解除時は瞬時に左へ戻り、二重発火しない。押せるカードだけに限定
   （静的カードは上の弱いホバーのみ／about-timeline は下の抑制ルールで除外）。 */
@media (hover: hover) {
    :is(.work-card:not(.is-pending), .timeline-content, .tool-card)::after,
    .stack-card::after {
        content: "";
        position: absolute;
        inset: 0;
        z-index: 3;
        pointer-events: none;
        border-radius: inherit;
        background: linear-gradient(105deg, transparent 42%, rgba(255, 255, 255, 0.055) 50%, transparent 58%);
        transform: translateX(-130%);
    }

    .stack-card,
    .timeline-content {
        position: relative;
        overflow: hidden;
    }

    :is(.work-card:not(.is-pending), .timeline-content, .tool-card):hover::after,
    .stack-card:hover::after {
        transform: translateX(130%);
        transition: transform 0.7s ease;
    }
}

/* about-timeline はクリック不可のため光沢スイープを出さない（is-pending と同じ抑制手法）。 */
.about-timeline .timeline-content::after {
    content: none;
}

/* サムネイル: 下部ビネットで本文との繋がりを滑らかに。ズームは既存、イージングだけ統一 */
.card-thumb::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(var(--shade-rgb), 0) 58%, rgba(var(--shade-rgb), 0.38));
}

.card-thumb img {
    transition: transform 0.5s var(--ease-out);
}

.work-card:hover .card-thumb img {
    filter: saturate(1.08);
}

/* 準備中/読込失敗サムネ: 斜めストライプの「仕込み中の面」+ 砂時計のガラスタイル化。
   カードホバーの砂時計180度フリップ（O-2）はタイルごとひっくり返る。 */
.card-thumb.is-placeholder,
.card-thumb.is-failed {
    background-image:
        repeating-linear-gradient(-45deg, rgba(255, 255, 255, 0.02) 0 10px, transparent 10px 22px),
        radial-gradient(120% 100% at 50% 0%, rgba(var(--accent-rgb), 0.08), transparent 62%);
    color: var(--accent-strong);
}

.card-thumb.is-placeholder .fa-icon,
.card-thumb.is-failed .fa-icon {
    box-sizing: content-box;
    padding: 13px;
    border-radius: var(--radius-sm);
    background: linear-gradient(135deg, rgba(var(--accent-rgb), 0.14), rgba(var(--accent-2-rgb), 0.10));
    border: 1px solid rgba(var(--accent-rgb), 0.22);
    box-shadow: var(--glass-hilite);
}

/* 準備中カードは「意図されたプレースホルダー」に降格: 点線・ガラス撤去・
   上端ライン消灯・浮上/発光/光沢スイープなし。主役カードとの三段差を作る。 */
.work-card.is-pending {
    border: 1px dashed var(--border-bright);
    background: rgba(255, 255, 255, 0.015);
    background-image: none;
    box-shadow: none;
}

.work-card.is-pending::after {
    content: none;
}

.work-card.is-pending::before,
.work-card.is-pending:hover::before {
    opacity: 0;
}

.work-card.is-pending:hover {
    transform: none;
    border-color: var(--border-bright);
    box-shadow: none;
}

.work-card.is-pending .card-thumb.is-placeholder {
    aspect-ratio: 21 / 9;
    border-bottom: 1px dashed var(--border);
}

.work-card.is-pending .card-title {
    font-size: 1.05rem;
}

/* 技術タグ: ガラスチップに揃える */
.tech-tags li {
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0) 60%), rgba(255, 255, 255, 0.03);
    border-color: var(--glass-border);
}

/* =====================================================================
   E. ボタン体系 — 素の .btn はセカンダリ、primary はグラデ＋光沢スイープ
   （.btn を先、.btn-primary を後: 同詳細度のため順序が生命線）
   ===================================================================== */
.btn {
    position: relative;
    overflow: hidden;
    border-color: var(--border-bright);
    transition: background var(--dur) var(--ease-out), transform 0.18s var(--ease-spring),
                box-shadow var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out),
                color var(--dur) var(--ease-out);
}

.btn:hover {
    transform: translateY(var(--lift-sm));
    border-color: rgba(var(--accent-rgb), 0.45);
    color: var(--accent-strong);
    box-shadow: var(--glow);
}

.btn:active {
    transform: translateY(0) scale(0.985);
    transition-duration: 0.06s;
}

.btn-primary {
    background: var(--grad-accent);
    border-color: transparent;
    color: var(--on-accent);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 6px 18px rgba(var(--accent-deep-rgb), 0.26);
}

.btn-primary:hover {
    background: linear-gradient(92deg, var(--accent), var(--accent-strong) 52%, var(--accent-2));
    color: var(--on-accent);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 10px 30px rgba(var(--accent-rgb), 0.4),
                0 0 0 1px rgba(var(--accent-rgb), 0.35);
}

@media (hover: hover) {
    .btn-primary::after {
        content: "";
        position: absolute;
        inset: 0;
        pointer-events: none;
        background: linear-gradient(105deg, transparent 40%, rgba(255, 255, 255, 0.14) 50%, transparent 60%);
        transform: translateX(-130%);
    }

    .btn-primary:hover::after {
        transform: translateX(130%);
        transition: transform 0.6s ease;
    }
}

/* リンク / ソーシャルの微動作 */
.card-link .fa-icon {
    transition: transform var(--dur-fast) var(--ease-out);
}

.card-link:hover .fa-icon {
    transform: translateX(2px);
}

.social-btn {
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0) 55%), var(--surface);
    /* rest 状態で border と halo に各ブランド色を薄く敷く。--brand-glow は X だけ
       Twitter blue に切替、他は fallback で --brand (github/yt/discord/keybase の色)。
       hover で下の 3 層 glow が上書きしてさらに強く光る 2 段階。 */
    border-color: color-mix(in srgb, var(--brand-glow, var(--brand)) 32%, var(--glass-border));
    box-shadow: var(--glass-hilite), 0 0 14px color-mix(in srgb, var(--brand-glow, var(--brand)) 18%, transparent);
}

.social-btn .fa-icon {
    /* transform は spring 曲線でわずかに跳ねる（過剰にならない範囲）。
       filter は常時薄いブランド色 halo を出して「光ってる」感を出す。 */
    transition: color var(--dur) ease,
                transform 260ms cubic-bezier(0.34, 1.56, 0.64, 1),
                filter var(--dur) ease;
}

@supports (color: color-mix(in srgb, red, blue)) {
    /* 常時: アイコンにブランド色の subtle drop-shadow を敷いて「光っている」ように見せる。
       6px blur × 30% で控えめ、視認性は落とさない範囲。halo 色は --brand-glow (未指定
       なら --brand fallback)。X は --brand-glow = Twitter blue なので常時青く光る。 */
    .social-btn .fa-icon {
        filter: drop-shadow(0 0 6px color-mix(in srgb, var(--brand-glow, var(--brand)) 30%, transparent));
    }

    /* ホバー/フォーカス: 3 層の box-shadow で「浮上 + 発光リング + halo」を重ねる。
       各層の役割:
       1) drop-shadow 風 (下方向の柔らかい影)
       2) 3px の halo リング (輪郭を強調)
       3) 24px の soft glow (全周ぼんやり)
       glow 色は --brand-glow (未指定なら --brand fallback)。X だけ style.css で
       --brand-glow を Twitter blue に上書きして「アイコン白 / hover は青」を実現。 */
    .social-btn:hover,
    .social-btn:focus-visible {
        box-shadow:
            var(--glass-hilite),
            0 8px 22px -6px color-mix(in srgb, var(--brand-glow, var(--brand)) 40%, transparent),
            0 0 0 3px color-mix(in srgb, var(--brand-glow, var(--brand)) 18%, transparent),
            0 0 24px color-mix(in srgb, var(--brand-glow, var(--brand)) 35%, transparent);
    }

    /* ホバー時のアイコン: halo を強めに (12px blur × 55%) して「光量が増した」感 */
    .social-btn:hover .fa-icon,
    .social-btn:focus-visible .fa-icon {
        filter: drop-shadow(0 0 12px color-mix(in srgb, var(--brand) 55%, transparent));
    }
}

/* =====================================================================
   F. チップ / バッジ — 2様式に統一し、「発光リング」を現在地の共通語彙に
   ===================================================================== */

/* F-1. 統一目次（render_page_toc）: 左スパイン付きの縦レール（"on this page"）。
   about/projects/ai/privacy の目次はすべて .page-toc + .page-toc-list に統一済み。
   チップ列をやめ、線＋見出し名の素直な目次に。現在地は発光ドットで示す。 */

/* 目次は「広い hover 環境の右端フローティング版」だけを見せ、それ未満（狭幅・
   タブレット・タッチ）では出さない。本文冒頭に縦レールが挟まって読みにくくなる
   のを防ぐ（ページ間移動はナビ＝ハンバーガー、節間はスクロールに任せる）。
   下の F-1b（min-width:1160 + hover）でフローティング表示に上書きする。
   forced-colors 時はフローティングが外れるため、アクセシビリティ確保として
   インラインのレールを残す。 */
.page-toc {
    display: none;
}

@media (forced-colors: active) {
    .page-toc {
        display: block;
    }
}

/* エラーページ / contact の導線リンク。目次レールと同じトランジション語彙を
   共有しているため元は目次ブロックの中に置かれていたが、目次専用ではないので
   デスクトップ限定の refine-toc.css には移さず、ここに残す。 */
.error-nav a,
.contact-welcome li {
    transition: color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out),
                background var(--dur) var(--ease-out), transform var(--dur) var(--ease-out),
                box-shadow var(--dur) var(--ease-out);
}

.error-nav a:hover, .error-nav a:focus-visible {
    color: var(--text);
    border-color: var(--border-bright);
    background: var(--surface-2);
    transform: translateY(var(--lift-sm));
}

/* =====================================================================
   G. アイコンタイル — グラデ格上げ + 親カードに反応する多層ホバー
   ===================================================================== */
.ai-card-icon,
.stat-icon,
.role-icon,
.stack-card-icon,
.tool-card-icon,
.ai-flow-icon {
    background: linear-gradient(135deg, rgba(var(--accent-rgb), 0.16), rgba(var(--accent-2-rgb), 0.10));
    border: 1px solid rgba(var(--accent-rgb), 0.22);
    box-shadow: var(--glass-hilite);
    transition: transform var(--dur) var(--ease-spring), box-shadow var(--dur) var(--ease-out);
}

.stack-card-icon,
.tool-card-icon {
    border-radius: var(--radius-sm);
}

@media (hover: hover) {
    /* タイル自身のホバーで反応（カード全体ホバーで一斉に動かない） */
    :is(.ai-card-icon, .stat-icon, .role-icon, .tool-card-icon, .ai-flow-icon, .stack-card-icon):hover {
        transform: scale(1.08) rotate(-3deg);
        box-shadow: var(--glass-hilite), 0 0 14px rgba(var(--accent-rgb), 0.18);
    }
}

/* =====================================================================
   L. スタガーリビール（JS追加ゼロ）— カード群が 60ms 刻みで立ち上がる
   transition ではなく animation + backwards フィルで実装し、表示後の
   ホバー遷移（transform/box-shadow）を一切汚さない。
   非JS / reduced-motion では .reveal 自体が付かないため一切隠れない。
   ===================================================================== */
/* 対象コンテナ11種は :is() で集約（引数は単一クラスのみ＝従来の平坦セレクタと
   詳細度・順序が同値。見た目は不変で、重複70行超を圧縮）。 */
body.js .reveal :is(.cards, .about-cards, .tool-cards, .stack-grid, .community-stats, .community-roles, .skills-grid, .ai-grid, .ai-split, .value-list, .article-index) > * {
    opacity: 0;
}

body.js .reveal.is-revealed :is(.cards, .about-cards, .tool-cards, .stack-grid, .community-stats, .community-roles, .skills-grid, .ai-grid, .ai-split, .value-list, .article-index) > * {
    opacity: 1;
    animation: stagger-in var(--dur-slow) var(--ease-out) backwards;
}

@keyframes stagger-in {
    from {
        opacity: 0;
        transform: translateY(14px);
    }
}

/* 60ms 刻み + 7要素目以降の上限キャップ（多要素グリッドの間延び防止） */
body.js .reveal.is-revealed :is(.cards, .about-cards, .tool-cards, .stack-grid, .community-stats, .community-roles, .skills-grid, .ai-grid, .ai-split, .value-list, .article-index) > :nth-child(2) {
    animation-delay: 0.06s;
}

body.js .reveal.is-revealed :is(.cards, .about-cards, .tool-cards, .stack-grid, .community-stats, .community-roles, .skills-grid, .ai-grid, .ai-split, .value-list, .article-index) > :nth-child(3) {
    animation-delay: 0.12s;
}

body.js .reveal.is-revealed :is(.cards, .about-cards, .tool-cards, .stack-grid, .community-stats, .community-roles, .skills-grid, .ai-grid, .ai-split, .value-list, .article-index) > :nth-child(4) {
    animation-delay: 0.18s;
}

body.js .reveal.is-revealed :is(.cards, .about-cards, .tool-cards, .stack-grid, .community-stats, .community-roles, .skills-grid, .ai-grid, .ai-split, .value-list, .article-index) > :nth-child(5) {
    animation-delay: 0.24s;
}

body.js .reveal.is-revealed :is(.cards, .about-cards, .tool-cards, .stack-grid, .community-stats, .community-roles, .skills-grid, .ai-grid, .ai-split, .value-list, .article-index) > :nth-child(6) {
    animation-delay: 0.3s;
}

body.js .reveal.is-revealed :is(.cards, .about-cards, .tool-cards, .stack-grid, .community-stats, .community-roles, .skills-grid, .ai-grid, .ai-split, .value-list, .article-index) > :nth-child(n + 7) {
    animation-delay: 0.36s;
}

/* =====================================================================
   ページ別の底上げ — community / ai / privacy
   ===================================================================== */

/* Claude スパーク（✳）: ホバー中、Claude が生成中に見せる「考えている」風の
   鼓動を再現する。実物は回転ではなく「ぎゅっと縮んで、ふっと膨らむ」を不規則な
   間合いで繰り返す動き。キーフレームを不均等に刻み、縮み方も毎回変える。
   reduced-motion は既存キルスイッチ（0.001ms・1回）で静止する。 */
:is(a, button, .skill, li, .ai-card-icon, .ai-flow-icon, .stack-card-icon):hover .fa-claude {
    animation: claude-thinking 2s ease-in-out infinite;
}

@keyframes claude-thinking {
    0% {
        transform: scale(1);
    }

    /* ぎゅっと縮む → ぽんっと戻る */
    9% {
        transform: scale(0.55);
    }

    18% {
        transform: scale(1.12);
    }

    24% {
        transform: scale(1);
    }

    /* ひと呼吸おいて、浅めの収縮 */
    46% {
        transform: scale(0.78);
    }

    55% {
        transform: scale(1.06);
    }

    61% {
        transform: scale(1);
    }

    /* 間合いを変えてもう一度深く */
    82% {
        transform: scale(0.6);
    }

    91% {
        transform: scale(1.1);
    }

    100% {
        transform: scale(1);
    }
}

/* ai: 「向き合い方」ノートにClaudeオレンジのアクセント罫（brand-claude の脇役起用） */
.ai-note {
    border-left: 3px solid var(--brand-claude);
    background: linear-gradient(90deg, rgba(var(--brand-claude-rgb), 0.08), transparent 60%), var(--surface);
    box-shadow: var(--glass-hilite);
}

/* CTA帯（projects/skills/community 末尾の締め導線）
   v5: ピルナビと同語彙の「発光グラデーションリング付きガラスパネル」。
   下端中央から立ち上る青の光だまり + 左上に紫の脇役グロー。 */
.cta-band .section-container {
    position: relative;
    max-width: 880px;
    padding: 56px 32px;
    border: 1px solid var(--glass-border);
    border-radius: calc(var(--radius) + 8px);
    background:
        radial-gradient(640px 300px at 50% 118%, rgba(var(--accent-rgb), 0.14), transparent 70%),
        radial-gradient(420px 220px at 10% -12%, rgba(var(--accent-2-rgb), 0.10), transparent 70%),
        linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent 45%),
        var(--surface);
    box-shadow: var(--glass-hilite), var(--shadow-sm);
    text-align: center;
}

/* ピルナビ .navbar::after と同じマスク式1pxグラデリング（語彙の再利用） */
.cta-band .section-container::before {
    content: "";
    position: absolute;
    inset: -1px;
    padding: 1px;
    border-radius: inherit;
    pointer-events: none;
    background: var(--grad-ring);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
}

/* パネル化に伴い直上の消え入り罫線は切る（二重装飾防止） */
main.left .section.cta-band {
    border-image: none;
    border-top-color: transparent;
}

.cta-band .btn-group {
    justify-content: center;
}

.cta-band-lead {
    margin: 0 0 24px;
    color: var(--text);
    font-weight: 700;
    letter-spacing: -0.01em;
    font-size: clamp(1.15rem, 1rem + 0.9vw, 1.45rem);
}

@media (max-width: 768px) {
    .cta-band .section-container {
        padding: 40px 20px;
    }
}

/* back-to-top: ホバーで発光を足す */
.back-to-top:hover,
.back-to-top:focus-visible {
    box-shadow: var(--shadow), var(--glow);
}

/* フッターが画面下半分に入ったら退く（script.js の IntersectionObserver が付与）。
   フッター最下段の「最終更新」表記に重なって浮く事故を防ぐ。既存の
   transition（opacity/transform）をそのまま使うためここでは再定義しない。 */
.back-to-top.is-near-footer {
    opacity: 0;
    pointer-events: none;
}

/* =====================================================================
   右クリックメニュー（script.js の initContextMenu が生成）
   ガラスパネルの語彙（glass-bg / glass-border / shadow-lg）で統一。
   リンク・入力・画像上や選択中はネイティブメニューが出る（JS側で制御）。
   ===================================================================== */
.ctx-menu {
    position: fixed;
    z-index: 1200; /* ピルナビ(1000)・skip-link(1001)より前面 */
    /* 極端に狭いウィンドウでは画面内に収める（タッチでは元々出ないため保険） */
    min-width: min(220px, calc(100vw - 16px));
    max-width: 280px;
    padding: 6px;
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-sm);
    /* 本文の真上に浮くメニューなので透け過ぎ防止でほぼ不透明に（目次パネルと同基準） */
    background: var(--glass-bg-strong);
    box-shadow: var(--glass-hilite), var(--shadow-lg);
    animation: ctx-in 0.12s var(--ease-out);
}

@supports ((backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px))) {
    .ctx-menu {
        /* -blur(0.62)だと背景の本文が透けて項目と混同するため、目次パネルと
           同じほぼ不透明の -strong(0.97)。ぼかしは質感として残す。 */
        background: var(--glass-bg-strong);
        -webkit-backdrop-filter: blur(16px) saturate(150%);
        backdrop-filter: blur(16px) saturate(150%);
    }
}

@keyframes ctx-in {
    from {
        opacity: 0;
        transform: scale(0.97) translateY(-2px);
    }
}

.ctx-menu:focus {
    outline: none; /* コンテナ自体のフォーカスは視覚不要（項目側にリングが出る） */
}

.ctx-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 12px;
    border: 0;
    border-radius: var(--radius-xs);
    background: none;
    color: var(--muted);
    font: inherit;
    font-size: 0.88rem;
    width: 1em;
    height: 1em;
    flex: none;
    color: var(--accent);
}

.ctx-icon-back {
    transform: rotate(180deg);
}

.ctx-item:hover,
.ctx-item:focus-visible {
    background: rgba(255, 255, 255, 0.06);
    color: var(--text);
}

.ctx-item:focus-visible {
    outline: 2px solid rgba(var(--accent-rgb), 0.6);
    outline-offset: -2px;
}

.ctx-item.is-done .fa-icon {
    color: var(--success-icon);
}

.ctx-sep {
    height: 1px;
    margin: 6px 4px;
    background: var(--border);
}

/* 目次フライアウト: 「目次」項目をホバー/展開すると横に開くサブメニュー。
   セクション数が増えてもメインメニューの縦幅が伸びないよう畳んでおく
   （OSの右クリックメニューのサブメニューと同じ作法）。 */
.ctx-item-wrap {
    position: relative;
}

/* 折り畳み状態でも「開く」ことが伝わるよう、キャレットを右端に寄せる */
.ctx-caret {
    display: inline-flex;
    flex: none;
    margin-left: auto; /* 先頭アイコン+ラベルは他項目と同じ詰め、キャレットだけ右端へ */
}

.ctx-caret .fa-icon {
    color: var(--dim);
}

.ctx-submenu {
    display: none;
    position: absolute;
    top: -6px;
    left: calc(100% + 4px);
    z-index: 1;
    min-width: min(200px, calc(100vw - 16px));
    max-width: 260px;
    max-height: min(60vh, 360px);
    overflow-y: auto;
    padding: 6px;
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-sm);
    /* 親メニューと同じく透け過ぎ防止でほぼ不透明に */
    background: var(--glass-bg-strong);
    box-shadow: var(--glass-hilite), var(--shadow-lg);
}

.ctx-submenu:not([hidden]) {
    display: flex;
    flex-direction: column;
}

/* 右端に収まらない場合は左側に開く（script.js が実測して付与） */
.ctx-submenu.ctx-submenu-left {
    left: auto;
    right: calc(100% + 4px);
}

@supports ((backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px))) {
    .ctx-submenu {
        /* 親メニューと同じく、透け過ぎ防止でほぼ不透明の -strong に */
        background: var(--glass-bg-strong);
        -webkit-backdrop-filter: blur(16px) saturate(150%);
        backdrop-filter: blur(16px) saturate(150%);
    }
}

/* =====================================================================
   コナミコマンド easter egg（script.js の initKonamiCode が生成）。
   ↑↑↓↓←→←→BA を入力すると、どのページでも Clawd が画面下端を歩いて
   横切る。既存の clawd-sprite.png / steps(47) 駒送り（clawd-live、
   ai.php の .clawd-anim と共有）に、横断用の translateX を別プロパティ
   として重ねる（background-position と transform は独立なので同時に
   走らせられる）。見つけた人へのご褒美のみで、常設のギミックではない。
   ===================================================================== */
.konami-clawd {
    position: fixed;
    left: 0;
    bottom: max(24px, env(safe-area-inset-bottom));
    width: 77px;
    height: 58px;
    z-index: 2000;
    pointer-events: none;
    background: url("../img/clawd-sprite.png") no-repeat 0 0;
    image-rendering: pixelated;
    animation: clawd-live 3.13s steps(47) infinite,
               konami-walk-across 6s linear forwards;
}

@keyframes konami-walk-across {
    from {
        transform: translateX(-100px);
    }

    to {
        transform: translateX(calc(100vw + 100px));
    }
}

.konami-toast {
    position: fixed;
    left: 50%;
    bottom: 90px;
    z-index: 2001;
    padding: 10px 18px;
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-pill);
    background: var(--glass-bg);
    box-shadow: var(--glass-shadow-float);
    color: var(--text);
    font-size: 0.9rem;
    font-weight: 600;
    opacity: 0;
    pointer-events: none;
    transform: translateX(-50%) translateY(8px);
    transition: opacity 0.25s var(--ease-out), transform 0.25s var(--ease-out);
}

@supports ((backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px))) {
    .konami-toast {
        background: var(--glass-bg-blur);
        -webkit-backdrop-filter: blur(16px) saturate(150%);
        backdrop-filter: blur(16px) saturate(150%);
    }
}

.konami-toast.is-visible {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

/* =====================================================================
   N. フォーカスリング強化（a11y 前進のみ: アウトラインに発光を重ねる）
   ---------------------------------------------------------------------
   V15: box-shadow 15% alpha 単体では WCAG 2.4.11 (フォーカス指示の 3:1
   コントラスト) が満たせない可能性が高く、また box-shadow は
   forced-colors: active で無効化されるためハイコントラストモードで
   フォーカス完全喪失。outline (システム色を尊重できる) を主役に据え、
   glow (box-shadow) を装飾層として重ねる二層構造に。
   ===================================================================== */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    box-shadow: 0 0 0 4px rgba(var(--accent-rgb), 0.28);
}

/* forced-colors (Windows ハイコントラスト等) では accent 色ではなく
   ユーザー設定の Highlight を使う。box-shadow は仕様上無効化されるが
   outline は必ず system Highlight で描画される。 */
@media (forced-colors: active) {
    :focus-visible {
        outline-color: Highlight;
    }
}

/* =====================================================================
   ページ間トランジション（View Transitions API / クロスドキュメント）
   対応ブラウザで同一オリジン遷移に、本文だけがふわっと差し替わる控えめな
   クロスフェード＋上方向 14px（リビール初動と同じ動き）を足す。
   ===================================================================== */
@view-transition {
    navigation: auto;
}

::view-transition-old(root) {
    animation: page-leave 220ms ease both;
}

::view-transition-new(root) {
    animation: page-enter 460ms var(--ease-out) both;
}

@keyframes page-leave {
    to {
        opacity: 0;
    }
}

@keyframes page-enter {
    from {
        opacity: 0;
        transform: translateY(14px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* 固定ヘッダーとフッターは遷移中も“居続ける”ので、本文だけが入れ替わる印象に */
.navbar {
    view-transition-name: site-header;
}

.site-footer {
    view-transition-name: site-footer;
}

/* ナビ/フッターの層は本文(460ms)より先に 140ms で「定まる」二層のリズム。
   中身は前後ページでほぼ同一なので、UA既定のクロスフェード(plus-lighter,
   同一ピクセルなら見た目不変)と位置モーフの duration を短縮するだけにする。
   独自キーフレームで opacity を振ると同一内容でも合成輝度が揺れて
   ちらつくため、既定アニメの時間上書きに留めるのが安全。 */
::view-transition-group(site-header),
::view-transition-group(site-footer),
::view-transition-old(site-header),
::view-transition-old(site-footer),
::view-transition-new(site-header),
::view-transition-new(site-footer) {
    animation-duration: 140ms;
}

/* =====================================================================
   O. マイクロインタラクション — Claude スパークの仲間たち
   アイコンごとに「らしい」小さな動きを与える。原則:
   - 全て transform / opacity のみ（レイアウトを動かさない）
   - ホバー起点は単発再生（infinite は O-3 のごく小さな生命感のみ）
   - reduced-motion は style.css キルスイッチ + 末尾Mブロックで静止
   ===================================================================== */

/* ---- O-0. 共通キーフレーム ---- */

/* ぴょこん（小さくジャンプして着地） */
@keyframes icon-hop {

    0%,
    100% {
        transform: none;
    }

    40% {
        transform: translateY(-4px);
    }

    70% {
        transform: translateY(1px);
    }
}

/* ひと振り（左右にひと揺れして戻る） */
@keyframes icon-swing {

    0%,
    100% {
        transform: none;
    }

    30% {
        transform: rotate(-12deg);
    }

    65% {
        transform: rotate(8deg);
    }
}

/* ポン（太鼓判のひと押し） */
@keyframes icon-pop {

    0%,
    100% {
        transform: none;
    }

    45% {
        transform: scale(1.3);
    }
}

/* ぶるっ（横シェイク） */
@keyframes icon-shake {

    0%,
    100% {
        transform: none;
    }

    20% {
        transform: translateX(-3px);
    }

    45% {
        transform: translateX(3px);
    }

    70% {
        transform: translateX(-2px);
    }
}

/* 見得（盾がぐっと構える） */
@keyframes icon-guard {

    0%,
    100% {
        transform: none;
    }

    35% {
        transform: scale(1.18) rotate(-8deg);
    }

    70% {
        transform: scale(1.06) rotate(4deg);
    }
}

/* ---- O-1. ホバー連動（transform 遷移: 出て戻るまで滑らか） ---- */

/* 行内アイコンの下地遷移（.card-link / .social-btn は既存遷移を尊重して除外） */
:is(.btn, .error-nav a) .fa-icon {
    transition: transform var(--dur-fast) var(--ease-out);
}

/* 外部リンクの矢印: 右上へ「飛び出す」 */
:is(.card-link, .btn, .error-nav a):is(:hover, :focus-visible) .fa-arrow-up-right-from-square {
    transform: translate(2px, -2px);
}

/* シェブロン: 一歩前へ（汎用の 2px より強く） */
:is(.card-link, .error-nav a):is(:hover, :focus-visible) .fa-chevron-right {
    transform: translateX(4px);
}

/* 紙飛行機: 機首を上げて離陸（ボタンでもカードでもリストでも、どの器に居ても飛ぶ） */
.fa-paper-plane {
    transition: transform 0.3s var(--ease-spring);
}

:is(.btn, .error-nav a):is(:hover, :focus-visible) .fa-paper-plane,
:is(li, .role-icon):hover .fa-paper-plane {
    transform: translate(2px, -2px) rotate(-14deg);
}

/* 砂時計: ひっくり返して計り直す（projects の準備中サムネ / contact の返信メモ項目） */
.fa-hourglass-half {
    transition: transform 0.5s var(--ease-spring);
}

:is(.card-thumb, li):hover .fa-hourglass-half {
    transform: rotate(180deg);
}

/* 技術チップ自体もわずかに浮く（中のアイコンの跳ねと合わせて器ごと生きる） */
.tech-tags li {
    transition: transform var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}

.tech-tags li:hover {
    transform: translateY(-2px);
    border-color: rgba(var(--accent-rgb), 0.35);
}

/* モーダルの閉じる ×: くるっと構える */
.work-modal-close .fa-xmark {
    transition: transform 0.3s var(--ease-spring);
}

.work-modal-close:is(:hover, :focus-visible) .fa-xmark {
    transform: rotate(90deg);
}

/* ソーシャル: 既存の拡大に、わずかな傾きを足す（focus にも同じ反応）。
   1.15/-8deg → 1.2/-10deg に少し盛って「豪華」寄せ。spring 曲線 (line 823) と
   組み合わせて、ふわっと跳ね上がる印象になる。 */
.social-btn:is(:hover, :focus-visible) .fa-icon {
    transform: scale(1.2) rotate(-10deg);
}

/* ---- O-2. ホバー単発再生（アイコンの性格づけ） ----
   各アイコンは「それを直接抱える要素」のホバーで動く。トリガーはリンク・ボタン・
   リスト項目(li)・注記の段落(p)・summary・メタ span(.card-meta-item / .timeline-date)・
   サムネ(.card-thumb)・アイコンタイル(.ai-card-icon 等)。
   カード全体（.card / .stack-card / .timeline-content）はトリガーにしない
   ＝ カードを撫でても中のアイコンが一斉に動かない。
   social-btn は O-1 の拡大＋傾きが担当（a:not(.social-btn) で除外）。 */

/* カレンダー: めくる前のひと振り（作品メタ / タイムライン日付） */
:is(.card-meta-item, .timeline-date):hover .fa-calendar {
    animation: icon-swing 0.5s var(--ease-out);
}

/* チェック: 太鼓判のポン */
:is(a:not(.social-btn), button):is(:hover, :focus-visible) .fa-circle-check,
:is(li, p, .ai-card-icon, .ai-flow-icon):hover .fa-circle-check {
    animation: icon-pop 0.4s var(--ease-out);
}

/* 注意アイコン: 「なになに？」のひと揺れ */
:is(summary, li, p):hover .fa-circle-exclamation {
    animation: icon-swing 0.5s var(--ease-out);
}

/* 盾: ぐっと構える見得 */
:is(a:not(.social-btn), button):is(:hover, :focus-visible) .fa-shield-halved,
:is(li, p, .ai-card-icon, .ai-flow-icon, .role-icon):hover .fa-shield-halved {
    animation: icon-guard 0.5s var(--ease-out);
}

/* git: ブランチの枝振り */
:is(a:not(.social-btn), button):is(:hover, :focus-visible) .fa-git-alt,
:is(li, .ai-flow-icon, .stack-card-icon):hover .fa-git-alt {
    animation: icon-swing 0.5s var(--ease-out);
}

/* 王冠: 誇らしげにひと構え（community の創設スタッツ） */
:is(li, .stat-icon):hover .fa-crown {
    animation: icon-guard 0.5s var(--ease-out);
}

/* 握手: ぶんぶんと固い握手 */
:is(li, .stat-icon):hover .fa-handshake {
    animation: icon-shake 0.45s ease;
}

/* 画像プレースホルダー: ポン（サムネ自身のホバー） */
.card-thumb:hover .fa-image {
    animation: icon-pop 0.4s var(--ease-out);
}

/* ブランド/人・モノ系はアイコンの器ホバーでぴょこん（Claude はスパーク鼓動が担当するので除外） */
:is(a:not(.social-btn), button):is(:hover, :focus-visible) :is(.fa-php, .fa-js, .fa-css3-alt, .fa-python, .fa-discord, .fa-github, .fa-x-twitter, .fa-robot, .fa-user, .fa-users),
:is(li, p, .card-meta-item, .stat-icon, .role-icon, .ai-card-icon, .ai-flow-icon, .stack-card-icon, .skill):hover :is(.fa-php, .fa-js, .fa-css3-alt, .fa-python, .fa-discord, .fa-github, .fa-x-twitter, .fa-robot, .fa-user, .fa-users) {
    animation: icon-hop 0.45s var(--ease-out);
}

/* back-to-top: 矢印が「上だよ」とぴょこん */
.back-to-top:is(:hover, :focus-visible) .fa-arrow-up {
    animation: icon-hop 0.5s var(--ease-out);
}

/* ---- O-3. 登場アニメ（1回だけ）と、ごく小さな生命感（常時） ---- */

/* 送信結果バナー: 成功のチェックはポップイン、エラーの ! はぶるっ */
.form-alert-success .fa-icon {
    animation: icon-pop-in 0.45s var(--ease-spring) 0.12s backwards;
}

.form-alert-error .fa-icon {
    animation: icon-shake 0.4s ease 0.15s;
}

@keyframes icon-pop-in {
    from {
        transform: scale(0);
    }

    60% {
        transform: scale(1.25);
    }

    to {
        transform: none;
    }
}

/* フィールドエラー: すっと現れる（PRG 直後も JS の blur 検証追加時も同じ動き） */
.field-error {
    animation: alert-in 0.25s var(--ease-out) both;
}

/* FAQ: 開いた瞬間、回答がふわっと立ち上がる */
.faq-item[open] > p {
    animation: alert-in 0.3s var(--ease-out);
}

/* about「いま」のタイムラインドット: 現在地の灯が静かに脈打つ */
.about-timeline .timeline-item.is-current::before {
    animation: now-pulse 3.2s ease-in-out infinite;
}

@keyframes now-pulse {

    0%,
    100% {
        box-shadow: var(--timeline-now-glow);
    }

    50% {
        box-shadow: 0 0 0 2px var(--accent), 0 0 0 10px rgba(var(--accent-rgb), 0.08),
                    0 0 26px rgba(var(--accent-rgb), 0.55);
    }
}

/* =====================================================================
   M. reduced-motion 包括ブロック（三重ガードの最終層 — 必ずファイル最末尾）
   静止してもグラデ・発光・レイアウトは全て残す（消すのは動く帯だけ）。
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {

    /* .card::after はこの一覧から除外: console.css で右下コーナーブラケット
       (構造的な装飾、モーションではない) に転用されているため、モーション
       抑制の対象にすると全カードのブラケットが片側だけ消えて非対称になる。 */
    .stack-card::after,
    .timeline-content::after,
    .btn-primary::after,
    body.js .skills-graph.in-view .skill-level::after {
        display: none;
    }

    /* スクロール進捗ライン（scroll-driven）は出さない */
    body::after {
        content: none;
    }

    /* ヒーローの視差（scroll-driven）は killswitch が効かないため明示停止 */
    main .hero .hero-right {
        animation: none;
    }

    /* ホーム各節下端のヘアライン（純装飾）も出さない */
    main.left .section:not(#contact)::after {
        display: none;
    }

    /* コナミコマンド: JS側で既に生成を止めているが、保険として二重に無効化 */
    .konami-clawd {
        display: none;
    }

    .hero::before,
    .hero::after {
        animation: none;
    }

    body.js .reveal :is(.cards, .about-cards, .tool-cards, .stack-grid, .community-stats, .community-roles, .skills-grid, .ai-grid, .ai-split, .value-list, .article-index) > * {
        opacity: 1;
        animation: none;
    }

    .card:hover,
    .stack-card:hover,
    :is(.work-card:not(.is-pending), .timeline-content, .tool-card):hover,
    .btn:hover,
    .page-toc a:hover,
    .error-nav a:hover,
    :is(.ai-card-icon, .stat-icon, .role-icon, .tool-card-icon, .ai-flow-icon, .stack-card-icon):hover,
    .skill:hover .skill-icon,
    .footer-social a:is(:hover, :focus-visible),
    .card-link:hover .fa-icon,
    .social-btn:is(:hover, :focus-visible) .fa-icon,
    :is(.card-link, .btn, .error-nav a):is(:hover, :focus-visible) :is(.fa-arrow-up-right-from-square, .fa-chevron-right, .fa-paper-plane),
    :is(li, .role-icon, .card-thumb):hover :is(.fa-paper-plane, .fa-hourglass-half),
    .tech-tags li:hover,
    .work-modal-close:is(:hover, :focus-visible) .fa-xmark {
        transform: none;
    }

    /* O. マイクロインタラクション: 単発再生と常時の呼吸をすべて静止
       （ホバー単発は「アイコンを抱える要素」ごと包括指定で殺す。Clawd は静止SVGに切替済み） */
    .about-timeline .timeline-item.is-current::before,
    .form-alert .fa-icon,
    .field-error,
    .faq-item[open] > p,
    .back-to-top:is(:hover, :focus-visible) .fa-arrow-up,
    :is(a, button, summary):is(:hover, :focus-visible) .fa-icon,
    :is(li, p, .card-meta-item, .timeline-date, .card-thumb, .skill, .ai-card-icon, .ai-flow-icon, .stat-icon, .role-icon, .stack-card-icon, .tool-card-icon):hover .fa-icon {
        animation: none;
    }

    ::view-transition-old(root),
    ::view-transition-new(root),
    ::view-transition-group(site-header),
    ::view-transition-group(site-footer),
    ::view-transition-old(site-header),
    ::view-transition-old(site-footer),
    ::view-transition-new(site-header),
    ::view-transition-new(site-footer) {
        animation: none;
    }

    .ctx-menu {
        animation: none;
    }
}

/* タッチ端末: 新設リフトの貼り付き防止（style.css の既存 (hover:none) を拡張） */
@media (hover: none) {

    .btn:hover,
    .page-toc a:hover,
    .error-nav a:hover,
    .stack-card:hover,
    :is(.work-card:not(.is-pending), .timeline-content, .tool-card):hover {
        transform: none;
    }

    /* タップ後の sticky hover でアイコン変形・チップの浮きが貼り付かないように */
    :is(.card-link, .btn, .error-nav a):hover :is(.fa-arrow-up-right-from-square, .fa-chevron-right, .fa-paper-plane),
    :is(li, .role-icon, .card-thumb):hover :is(.fa-paper-plane, .fa-hourglass-half),
    .tech-tags li:hover,
    :is(.ai-card-icon, .stat-icon, .role-icon, .tool-card-icon, .ai-flow-icon, .stack-card-icon):hover,
    .skill:hover .skill-icon,
    .footer-social a:hover,
    .social-btn:hover .fa-icon {
        transform: none;
    }
}

/* =====================================================================
   forced-colors（Windows ハイコントラスト等）— 装飾はシステムの無効化
   （背景画像・box-shadow の強制除去）に任せ、意味を持つ要素だけ明示する
   ===================================================================== */
@media (forced-colors: active) {

    /* グラデ文字を実線のシステム文字色へ戻す（透明文字の事故を構造的に防ぐ） */
    #typewriter,
    .hero-name,
    .stat-value,
    .error-code {
        background: none;
        -webkit-background-clip: border-box;
        background-clip: border-box;
        color: CanvasText;
        filter: none;
    }

    /* スクロール進捗ライン: 強制配色ではグラデが潰れるため出さない */
    body::after {
        display: none;
    }

    /* ホーム各節下端のヘアラインも同様（グラデ装飾のため） */
    main.left .section:not(#contact)::after {
        display: none;
    }

    /* スキルバー: 背景が無効化されても水位が読めるようシステム色で明示 */
    .skill-bar {
        border: 1px solid CanvasText;
    }

    /* ハンバーガーの3本線は背景色で描いているため、強制配色でも見えるように */
    .nav-toggle-btn span {
        background: ButtonText;
    }

    /* フッターのグラデ文字ロゴをシステム色で明示 */
    .footer-logo {
        background: none;
        -webkit-background-clip: border-box;
        background-clip: border-box;
        color: LinkText;
    }

    .skill-level {
        background: Highlight;
        forced-color-adjust: none;
    }

    /* 光沢スイープ帯は情報を持たない純装飾なので出さない。.card::after は
       ここでも除外 (上の reduced-motion ブロックと同じ理由: 右下コーナー
       ブラケットは構造的な装飾で、forced-colors 側は下の専用ブロックで
       CanvasText の罫線として明示的に描画している)。 */
    .stack-card::after,
    .timeline-content::after,
    .btn-primary::after,
    body.js .skills-graph.in-view .skill-level::after {
        display: none;
    }

    /* Clawd: スプライトの背景画像は強制配色で消えるため、SVG 静止版に戻す */
    .clawd-anim {
        display: none;
    }

    .ai-card .clawd {
        display: block;
    }
}
