/**
 * assets/css/style.css
 * UnderGround REMATCH 共通スタイルシート
 * header.php の <head> から読み込まれる
 */

/* ==========================================================
 * サイト全体の基準フォントサイズ引き上げ（2026-09-24追加）
 * これまで（2026-09-24の別対応）はTailwindのtext-*ユーティリティクラスの
 * サイズ定義そのものを底上げしていたが、サイト内には明示的なtext-*クラスを
 * 持たない要素が多数あり（例: <body>直下のテキストやTailwindのデフォルトサイズを
 * そのまま使っている箇所）、それらはbodyの既定フォントサイズ(16px)のまま変わらず、
 * 結果として「まだ全体的に小さい」という声につながっていた。
 * font-sizeはCSSの継承プロパティであり、html要素に指定すればページ内の
 * あらゆるテキスト（text-*クラスの有無を問わず）に確実に反映される。また
 * Tailwindのユーティリティ（spacing, sizing, radius等）の大半はrem単位で
 * 定義されているため、html基準サイズを引き上げるとレイアウト全体も比例して
 * 拡大され、依頼にあった「それに合わせたレイアウトの修正」も自動的に満たされる。
 * これに伴い、header.php内にあった旧tailwind.config側のfontSize個別上書きは
 * 二重に拡大されるのを避けるため削除し、Tailwind既定のサイズ比率をそのまま
 * このroot拡大に乗せる形に一本化した。
 * OBS配信オーバーレイ用画面（obs_scoreboard.php／overlay.php）はこの
 * style.cssを読み込んでおらず独立したCSSを持つため、本変更の影響を受けない。 */
html {
    font-size: 112.5%; /* 既定16px→18px相当。Tailwindのrem系ユーティリティに連動して拡大される */
}
/* 2026-10-23（続き83）：スマホ（〜640px）では基準を16pxに戻して文字を小さくする。
   Tailwindのrem系ユーティリティが連動して縮むので、PC表示（18px基準）はそのまま。 */
@media (max-width: 640px) {
    html { font-size: 100%; }
}

body {
    font-family: 'Noto Sans JP', sans-serif;
    background-color: #000;
}

/* ==========================================================
 * アイコン（Material Symbols Rounded。2026-10-24追加）
 * <span class="msi">play_arrow</span> のように名前を文字として書くと、フォントの機能（リガチャ）でアイコンになる。
 * 大きさは周りの文字に合わせる（em）。塗りつぶしは .fill。フォントが読めるまでは隠し、失敗したら出さない。
 * ========================================================== */
.msi {
    font-family: 'Material Symbols Rounded';
    font-weight: normal;
    font-style: normal;
    font-size: 1.2em;
    line-height: 1;
    letter-spacing: normal;
    text-transform: none;
    display: inline-block;
    width: 1em;
    height: 1em;
    overflow: hidden;
    white-space: nowrap;
    direction: ltr;
    vertical-align: -0.2em;
    flex-shrink: 0;
    font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
    font-feature-settings: 'liga';
    -webkit-font-feature-settings: 'liga';
    -webkit-font-smoothing: antialiased;
    user-select: none;
    -webkit-user-select: none;
    visibility: hidden;
}
html.msi-ready .msi { visibility: visible; }
html.msi-fail .msi { display: none; }
.msi.fill { font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24; }

.font-underground {
    font-family: 'Oswald', 'Noto Sans JP', sans-serif;
    letter-spacing: 0.03em;
}

/* ==========================================================
 * 布地・砂紋（枯山水の砂を熊手で描いたような、緩やかに波打つ筋目）のような
 * 質感を出す背景テクスチャ（2026-09-24調整、ユーザー提示の参考画像に合わせて再調整）。
 * 初回はクロスハッチ（格子状の織り目）で試したが、参考画像は格子ではなく、
 * 有機的に緩やかにうねる縞模様（等高線状）だったため、SVGフィルターの構成を
 * 以下の2層に変更した：
 *   1層目：低周波数・低オクターブのfeTurbulenceを、feComponentTransferの
 *          table関数で段階的に区切ることで、なめらかに波打つ等高線状の
 *          縞模様（砂紋の筋目に相当）を作り出している。x方向とy方向で
 *          baseFrequencyの比率を変えることで、渦状ではなく横方向に長く
 *          流れるような筋目になるよう調整した。
 *   2層目：高周波数のfeTurbulenceによる微細な粒立ち（砂の粒子感・布の繊維感）。
 * いずれも黒背景に対してごく低いアルファ値（白 4%/4.5%。当初7%/8%で実装したが、
 * ユーザーから「もう少し黒くてもいい」との声を受けて更に控えめに調整した）に
 * 抑えており、文字とのコントラスト（識字性対応）を損なわない範囲に留めている。
 * ※1層目は当初180px/700px角のタイルを敷き詰める(repeat)方式にしていたが、
 * feTurbulenceのstitchTiles='stitch'だけでは等高線状の縞模様（sharpな
 * feComponentTransferで強調されるため、ごく僅かなタイル境界のズレも
 * くっきりした「継ぎ目」として見えてしまう）が画面上に数本の切れ目として
 * 目立ってしまったため、タイル敷き詰めではなく画面（背景ボックス）全体に
 * 1枚だけ敷く方式（no-repeat + background-size: cover +
 * background-attachment: fixed）に変更し、継ぎ目が原理的に発生しないようにした。
 * 2層目の微細ノイズは粒がランダムで継ぎ目が目立たないため、従来通りタイル
 * 敷き詰め（repeat）のままにしている。 */
.bg-noise {
    background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1920' height='1200'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.0015 0.018' numOctaves='3' seed='11' stitchTiles='stitch'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='table' tableValues='0 1 0 1 0 1'/%3E%3CfeFuncG type='table' tableValues='0 1 0 1 0 1'/%3E%3CfeFuncB type='table' tableValues='0 1 0 1 0 1'/%3E%3CfeFuncA type='table' tableValues='0 1 0 1 0 1'/%3E%3C/feComponentTransfer%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.04 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23w)'/%3E%3C/svg%3E"),
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.045 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    background-repeat: no-repeat, repeat;
    background-size: cover, 180px 180px;
    background-position: center center, top left;
    background-attachment: fixed, scroll;
}

/* ==========================================================
 * マテリアルデザイン寄りのエレベーション（2026-09-25追加）
 * これまで.glow-red／.glow-red-lgや、カード類の shadow-red-950/* ・border-red-950/* は
 * 赤みを帯びた光彩（ネオン風グロー）でカードやボタンの「浮き上がり感」を表現していたが、
 * これはMaterial Designの考え方（色のついた光彩ではなく、ニュートラルな2層シャドウ
 * （近い影＋広がる環境光）で高さ・階層を表現し、色は状態や強調にのみ使う）とは方向性が
 * 異なる。サイトのブランド（黒背景＋赤アクセント・Oswaldフォント）自体は変えずに、
 * 「カードが浮いて見える」表現だけをMaterialの層状シャドウに寄せた。
 * ・.glow-red／.glow-red-lg：クラス名はそのまま（53箇所で使用中のため変更するとPHP側の
 *   一括置換が必要になり影響範囲が大きい）に、中身だけニュートラルな2層シャドウへ変更。
 * ・shadow-red-950/*・border-red-950/*：Tailwindのユーティリティクラスとしてサイト全体で
 *   869箇所使われている（カードのほぼ標準パターン）ため、PHPファイルを1つずつ書き換える
 *   代わりに属性セレクタでクラス名そのものをフックし、CSS側だけで上書きしている
 *   （PHP側のクラス名・マークアップは一切変更していない）。
 * どちらも黒背景に対して淡いグレーの縁取り（白ベースの低不透明度）と、ニュートラルな
 * ドロップシャドウにすることで、赤は引き続きボタンの塗り・テキスト・見出し飾りなど
 * 「意味を持つ強調」にのみ使われる状態にしている。 */
.glow-red {
    box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.6), 0 2px 8px 2px rgba(0, 0, 0, 0.35);
}

.glow-red-lg {
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.65), 0 4px 12px 4px rgba(0, 0, 0, 0.4);
}

/* TailwindのPlay CDNはクラスを検出するたびに<style>を動的に再注入するため、読み込み順に
 * よってはこのstyle.css側の宣言がTailwind側より先に評価されてしまうことがある。属性
 * セレクタ自体の詳細度はTailwindの単一クラスセレクタと同じ（0,1,0）なので、読み込み順に
 * 依存せず確実に上書きされるよう!importantを付けている（このファイル内の:focus-visible
 * ルールと同じ理由・同じ方針）。 */
[class*="shadow-red-950"] {
    box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.6), 0 2px 8px 2px rgba(0, 0, 0, 0.35) !important;
}

[class*="shadow-red-950/30"],
[class*="shadow-red-950/40"] {
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.65), 0 4px 12px 4px rgba(0, 0, 0, 0.4) !important;
}

[class*="border-red-950"] {
    border-color: rgba(255, 255, 255, 0.08) !important;
}

[class*="border-red-950/40"] {
    border-color: rgba(255, 255, 255, 0.05) !important;
}

[class*="border-red-950/80"] {
    border-color: rgba(255, 255, 255, 0.12) !important;
}

/* ==========================================================
 * 押下時の触感フィードバック（2026-09-25追加、マテリアルデザイン対応の第2弾）
 * Material Designのボタン・カード等の「状態レイヤー」表現の一部として、押した瞬間に
 * わずかに縮小させることでクリック/タップへの物理的な手応えを出す。この考え方自体は
 * 実はこのサイトに既にあり、obs_scoreboard.php（OBS操作画面）の.score-bubble:active・
 * .team-name-btn:activeで個別に実装されていた。今回はそれをサイト全体の共有
 * スタイルシートに一般化した。
 * Tailwindの`transition`クラス（このサイトのボタン・リンク412箇所で使用）は既定で
 * transform自体をtransition-propertyに含んでいるため、対象要素は追加設定なしで
 * なめらかにアニメーションする。`:active`はこれまでサイト内で一切使われていなかった
 * （0箇所）ため、既存のスタイルと衝突する心配もない。 */
.transition:active,
button:active:not(:disabled),
[role="button"]:active {
    transform: scale(0.97);
}

/* ==========================================================
 * キーボード操作時のフォーカス表示（2026-09-24追加）
 * サイト内ではTailwindの outline-none クラス（実際にはoutlineを透明にするだけで
 * outline自体は残す仕様だが、見た目上は非表示）がボタン・入力欄・リンク等153箇所で
 * 使われている一方、代わりとなる独自のフォーカス表示が定義されていなかった。その結果、
 * マウスを使わずTabキーだけで操作している人には「今どの項目を選択しているか」が
 * 画面上でまったく分からない状態になっていた。
 * :focus-visible はマウスクリックによるフォーカス（見た目の変化が不要な場面）には
 * 反応せず、キーボード操作でフォーカスが当たった場合にのみ発火する疑似クラスのため、
 * マウス操作時の見た目に影響を与えずに、キーボード操作時だけ視認性の高いリングを
 * 表示できる。色はサイトのブランドカラー（赤）の中でも黒背景で特に視認性が高い
 * red-400相当を使用。outline-none側より必ず優先されるよう!importantを付けている
 * （outline-noneの詳細度は通常これより低いため理屈上は不要だが、要素によって
 * 詳細度の高い個別スタイルが後から追加された場合でも確実に効くようにするための保険）。
 * ========================================================== */
:focus-visible {
    outline: 2px solid #f87171 !important;
    outline-offset: 2px !important;
    box-shadow: 0 0 0 4px rgba(248, 113, 113, 0.25) !important;
}

::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: #09090b;
}

::-webkit-scrollbar-thumb {
    background: #7f1d1d;
    border-radius: 4px;
}

.toast-enter {
    animation: toastIn 0.35s ease-out;
}

@keyframes toastIn {
    from {
        opacity: 0;
        transform: translateY(-12px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* ==========================================================
 * サイト共通レイアウト幅
 * PC画面で余白を持て余さないよう、最大幅を広めに確保する
 * ========================================================== */
.site-container {
    max-width: 1600px;
}

/* ==========================================================
 * アンビエント背景演出（固定・低輝度で揺らめく光の輪）
 * すべてのページの最背面に配置し、地下鉄の暗がりに滲む光のような
 * 動きのある背景を演出する。コンテンツの操作を妨げないよう
 * pointer-events は無効化し、position:fixed で固定表示する。
 * ========================================================== */
#ambient-bg {
    position: fixed;
    inset: 0;
    z-index: -1;
    overflow: hidden;
    pointer-events: none;
}

#ambient-bg span {
    position: absolute;
    border-radius: 9999px;
    opacity: 0.28;
    /* 中心から縁にかけて自然にフェードするグラデーションだけで柔らかさを表現し、
       描画コストの大きい filter: blur() は使わない（transform/opacityのみをアニメーションさせ、
       コンポジタ層に任せて軽量化する）。 */
    background: radial-gradient(circle, rgba(185, 28, 28, 0.45) 0%, rgba(185, 28, 28, 0) 65%);
    animation: ambientDrift 26s ease-in-out infinite;
    will-change: transform, opacity;
}

#ambient-bg span.orb-1 { width: 480px; height: 480px; top: -120px; left: -100px; }
#ambient-bg span.orb-2 { width: 380px; height: 380px; top: 40%; right: -140px; animation-delay: -10s; }

@keyframes ambientDrift {
    0%, 100% { transform: translate(0, 0) scale(1); opacity: 0.22; }
    50% { transform: translate(30px, -25px) scale(1.15); opacity: 0.32; }
}

/* スマホ・小さいウィンドウでは端末負荷を優先し、装飾のアンビエント背景を非表示にする */
@media (max-width: 640px) {
    #ambient-bg {
        display: none;
    }
}

/* ==========================================================
 * ヒーローセクション背景スライドショー（2026-09-29追加）
 * ユーザーから提供・使用許可済みのゲーム「REMATCH」実機スクリーンショット4枚
 * （スタジアム／トンネル／宇宙ステーションのピッチ／海中遺跡のピッチ）を、
 * 「さあ、地下へ来い。」ヒーローセクションの背景として純CSSのクロスフェード
 * スライドショーで敷き、「豪華にしてほしい」という要望に応えている。
 * 4枚を5秒ずつ、20秒周期で入れ替える（animation-delayを5秒ずつずらした
 * 同一keyframeを4枚に適用）。文字の可読性は既存の黒グラデーション
 * オーバーレイ（コンテンツラッパー側の bg-gradient-to-b from-black/20
 * via-black/45 to-black/80）と、直後に重なる紅いradial-gradient・
 * ripple-ringsがそのまま担うため、このレイヤー自体には追加の暗化を
 * 加えていない。DOM順で一番手前（＝視覚的には一番奥）に置くことで、
 * 既存の演出レイヤーより背面に自然に収まる。
 * prefers-reduced-motion: reduce の環境ではアニメーションを止め、
 * 1枚目（スタジアム）を静止表示に切り替える。 */
.hero-bg-slideshow {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
}

.hero-bg-slide {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    opacity: 0;
    animation: heroBgFade 20s infinite;
}

.hero-bg-slide-1 { background-image: url('../../img/landing_about_hero.jpg'); animation-delay: 0s; }
.hero-bg-slide-2 { background-image: url('../../img/landing_hero_bg_tunnel.jpg'); animation-delay: 5s; }
.hero-bg-slide-3 { background-image: url('../../img/landing_hero_bg_space.jpg'); animation-delay: 10s; }
.hero-bg-slide-4 { background-image: url('../../img/landing_hero_bg_underwater.jpg'); animation-delay: 15s; }

@keyframes heroBgFade {
    0%   { opacity: 0; }
    4%   { opacity: 1; }
    21%  { opacity: 1; }
    25%  { opacity: 0; }
    100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .hero-bg-slide { animation: none; opacity: 0; }
    .hero-bg-slide-1 { opacity: 1; }
}

/* ===== 波紋（同心円）の装飾アニメーション：主にヒーローセクションで使用 ===== */
.ripple-rings {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    pointer-events: none;
}

.ripple-rings span {
    position: absolute;
    width: 60px;
    height: 60px;
    border-radius: 9999px;
    border: 1px solid rgba(248, 113, 113, 0.5);
    animation: rippleOut 4.5s cubic-bezier(0.2, 0.6, 0.4, 1) infinite;
    will-change: transform, opacity;
}

.ripple-rings span:nth-child(2) { animation-delay: 1.1s; }
.ripple-rings span:nth-child(3) { animation-delay: 2.2s; }
.ripple-rings span:nth-child(4) { animation-delay: 3.3s; }

/* transform/opacity のみをアニメーションさせる（border-colorの補間は再描画コストが大きいため避ける） */
@keyframes rippleOut {
    0% { transform: scale(0.3); opacity: 0.7; }
    100% { transform: scale(9); opacity: 0; }
}

/* 狭い画面では非表示にして端末負荷を抑える */
@media (max-width: 640px) {
    .ripple-rings {
        display: none;
    }
}

/* ==========================================================
 * スクロールリビール（フェードイン）
 * main内の section 要素に自動付与され、画面内に入った時に
 * ふわっと浮かび上がるように表示する（assets/js/motion.js が制御）。
 * ========================================================== */
.reveal {
    opacity: 0;
    transform: translateY(22px);
    transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1), transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}

.reveal.is-visible {
    opacity: 1;
    transform: translateY(0);
}

/* ページ読み込み時のフェードイン */
main.page-fade-in {
    animation: pageFadeIn 0.55s ease-out;
}

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

/* ==========================================================
 * クリック波紋エフェクト（Material風リップル）
 * assets/js/motion.js がクリックされた要素に .ripple-host を付与し、
 * クリック位置を起点にした波紋（span.ripple-dot）を生成する。
 * ========================================================== */
.ripple-host {
    position: relative;
    overflow: hidden;
}

.ripple-dot {
    position: absolute;
    border-radius: 9999px;
    background: rgba(255, 255, 255, 0.35);
    transform: scale(0);
    animation: rippleDot 0.6s ease-out;
    pointer-events: none;
}

@keyframes rippleDot {
    to {
        transform: scale(2.6);
        opacity: 0;
    }
}

/* ==========================================================
 * ハンバーガーメニュー
 * ========================================================== */
.hamburger-btn {
    position: relative;
    width: 40px;
    height: 40px;
    flex-shrink: 0;
}

.hamburger-btn span {
    position: absolute;
    left: 8px;
    right: 8px;
    height: 2px;
    background: currentColor;
    border-radius: 2px;
    transition: transform 0.3s ease, opacity 0.3s ease, top 0.3s ease;
}

.hamburger-btn span:nth-child(1) { top: 13px; }
.hamburger-btn span:nth-child(2) { top: 19px; }
.hamburger-btn span:nth-child(3) { top: 25px; }

.hamburger-btn.is-open span:nth-child(1) { top: 19px; transform: rotate(45deg); }
.hamburger-btn.is-open span:nth-child(2) { opacity: 0; }
.hamburger-btn.is-open span:nth-child(3) { top: 19px; transform: rotate(-45deg); }

#nav-drawer-backdrop {
    position: fixed;
    inset: 0;
    /* backdrop-filter (ぼかし) は端末によっては描画コストが大きいため、
       濃さのある単色の半透明背景だけで暗転させる */
    background: rgba(0, 0, 0, 0.75);
    z-index: 49;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
}

#nav-drawer-backdrop.is-open {
    opacity: 1;
    pointer-events: auto;
}

#nav-drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(360px, 88vw);
    background: #0a0a0c;
    border-left: 1px solid rgba(127, 29, 29, 0.6);
    box-shadow: -20px 0 60px rgba(0, 0, 0, 0.6);
    z-index: 50;
    transform: translateX(100%);
    transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
    overflow-y: auto;
}

#nav-drawer.is-open {
    transform: translateX(0);
}

body.nav-drawer-locked {
    overflow: hidden;
}

/* ==========================================================
 * 見出しの「駅番号」キッカー
 * セクション見出しの先頭に、地下鉄の駅ナンバリング標識のような
 * 小さな番号バッジを添えて情報の階層を演出する。
 * ========================================================== */
.section-kicker {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.85rem;
    height: 1.85rem;
    padding: 0 0.45rem;
    border: 1px solid rgba(185, 28, 28, 0.6);
    border-radius: 0.375rem;
    background: rgba(127, 29, 29, 0.18);
    color: #f87171;
    font-family: 'Oswald', 'Noto Sans JP', sans-serif;
    font-size: 0.7625rem; /* 2026-09-24：全体的な文字サイズ+1px調整の一環（元0.7rem） */
    letter-spacing: 0.04em;
}

/* 見出しテキストにグラデーションをかけ、赤〜黒へ沈み込むような奥行きを出す */
.text-gradient-red {
    background: linear-gradient(135deg, #fecaca 0%, #ef4444 45%, #7f1d1d 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}

/* ==========================================================
 * 路線図風の区切り線（セクション間の装飾ディバイダー）
 * 点線のレールに駅（ドット）が並ぶイメージ。アニメーションはさせず
 * 静的なCSSのみで構成するため描画コストはほぼゼロ。
 * ========================================================== */
.subway-divider {
    position: relative;
    height: 22px;
    /* width: 100% を明示しないと、flexboxの子要素（guide.phpの flex flex-col gap-12 内）
       として置かれたとき、margin: 0 auto の auto マージンが優先されて幅が
       fit-content（中身の点5個ぶんの最小幅）に縮んでしまい、点が中央に小さく
       固まって見える不具合が実際に発生した。width: 100% を指定して基準幅を
       確保したうえで max-width で上限を掛けることで、通常のブロック要素の並び
       （index.php等）でもflexboxの子要素（guide.php等）でも同じ見た目になる。 */
    width: 100%;
    max-width: 480px;
    /* 縦方向のmarginは持たせない。設置先が通常のブロック要素の並び（index.php等）なら
       呼び出し側でmy-*ユーティリティを付与し、flexboxのgapで間隔を作っている箇所
       （guide.phpの flex flex-col gap-12 等）ではgapとmarginが二重に加算されて
       余白が異常に広がってしまう（実際に発生した不具合）ため、それを避ける設計にしている。 */
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.subway-divider::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: 1px;
    transform: translateY(-50%);
    background-image: repeating-linear-gradient(to right, rgba(185, 28, 28, 0.55) 0 6px, transparent 6px 14px);
}

.subway-divider .station-dot {
    position: relative;
    z-index: 1;
    width: 7px;
    height: 7px;
    border-radius: 9999px;
    background: #7f1d1d;
    box-shadow: 0 0 6px rgba(185, 28, 28, 0.5);
}

/* 1駅だけ「現在地」を示すシグナルカラー（黄）を差し色として使う */
.subway-divider .station-dot.is-current {
    width: 10px;
    height: 10px;
    background: #f5b400;
    box-shadow: 0 0 10px rgba(245, 180, 0, 0.65);
}

/* ==========================================================
 * カードのホバー演出（マイクロインタラクション）
 * ホバー時のみ transform / box-shadow / border-color を遷移させる。
 * 常時アニメーションではなく操作時のみの描画のため負荷は軽微。
 * ========================================================== */
.hover-glow-card {
    transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.hover-glow-card:hover {
    transform: translateY(-3px);
    border-color: rgba(220, 38, 38, 0.75);
    box-shadow: 0 14px 32px rgba(185, 28, 28, 0.28);
}

/* ==========================================================
 * ページツアー（ヘッダー「？」ボタンの操作説明オーバーレイ）
 * assets/js/page-tour.js が生成する #page-tour-overlay 用のスタイル。
 * ========================================================== */
#page-tour-overlay {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 300;
}

#page-tour-overlay.is-open {
    display: block;
}

#page-tour-spotlight {
    position: fixed;
    border-radius: 10px;
    /* 巨大なbox-shadowで対象要素の「外側」だけを暗くする定番のスポットライト表現。
       対象要素自体には触れないため、既存のz-index構成やflipカードの3D transformと衝突しない。 */
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.76), 0 0 0 2px rgba(220, 38, 38, 0.9), 0 0 26px rgba(220, 38, 38, 0.55);
    transition: top 0.25s ease, left 0.25s ease, width 0.25s ease, height 0.25s ease;
    pointer-events: none;
}

#page-tour-tooltip {
    position: fixed;
    width: 90vw;
    max-width: 340px;
    z-index: 1;
    top: -9999px;
    left: -9999px;
}

body.page-tour-locked {
    overflow: hidden;
}

/* ヘッダーの「？」ボタン */
.page-tour-btn {
    width: 30px;
    height: 30px;
    border-radius: 9999px;
    border: 1px solid rgba(185, 28, 28, 0.6);
    color: #d4d4d8;
    font-family: var(--font-underground, inherit);
    font-weight: 700;
    font-size: 14px; /* 2026-09-24：全体的な文字サイズ+1px調整の一環（元13px） */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
    flex-shrink: 0;
}

.page-tour-btn:hover {
    color: #f87171;
    border-color: rgba(220, 38, 38, 0.9);
    box-shadow: 0 0 12px rgba(220, 38, 38, 0.35);
}

/* ボタン内矢印のホバー移動（マイクロインタラクション） */
.btn-arrow {
    display: inline-block;
    transition: transform 0.25s ease;
}

.group:hover .btn-arrow {
    transform: translateX(4px);
}

/* ==========================================================
 * カードめくりアニメーション（フリップリビール）
 * トレーディングカード風タイル（選手カード・チームカード）や既存の
 * カードグリッドに .flip-card クラスを付け、親要素に .flip-card-grid を
 * 付けることで、画面内に入ったタイミングで1枚ずつ「めくれて」現れる。
 * 実装は rotateY + opacity の遷移のみ（画像の差し替え等は行わない簡易版）。
 * 各カードの遷移開始タイミング（transition-delay）はJS側
 * （assets/js/motion.js の initFlipCards()）が並び順から計算して付与する。
 * ========================================================== */
.flip-card-grid {
    perspective: 1400px;
}

.flip-card {
    transform: rotateY(-92deg);
    opacity: 0;
    transform-origin: center center;
    backface-visibility: hidden;
    transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.4s ease;
    /* will-changeは常時指定せず、motion.jsのinitFlipCards()側でアニメーション中のみ
       付与し完了後に解除する（2026-09-13改修：カード枚数が多いページでのモバイル描画不良対策）。 */
}

.flip-card.is-flipped {
    transform: rotateY(0deg);
    opacity: 1;
}

/* ==========================================================
 * ランディングページ（landing.php）専用：1セクションずつの
 * スクロールスナップ ＋ 上下にめくれるページフリップ演出（2026-09-29追加）
 * 「ランディングページを1セクション毎にスクロールさせる仕組みにしてほしい。
 * 上下にめくるようなアニメーションも足してほしい」との要望を受けて追加。
 *
 * 仕組みは上の .flip-card（rotateY＝左右にめくれるトレーディングカード風演出）と
 * 対になっている：親に perspective、対象自体を rotateX で倒しておき、JS側
 * （assets/js/motion.js の initPageFlip()）のIntersectionObserverが画面内へ
 * 入ったタイミングで .is-flipped を付けて起こす。.flip-card との違いは、
 * 上下（rotateX）にめくれる点と、一度めくれたら固定ではなく画面外に出るたびに
 * リセットして何度でもめくれる点（ページを行き来する体験の演出のため）。
 *
 * scroll-snap-type はランディングページ以外に影響しないよう、bodyへ直接ではなく
 * body.landing-scroll-snap にスコープしている（header.phpの<body>クラスは
 * 全ページ共通のため、ここに直接書くと site全体のスクロール挙動が変わってしまう）。
 * このクラスの付け外し自体もJS側（initPageFlip()）が、.page-section-flip要素の
 * 有無で自動的に行う（pjaxナビゲーションでは<body>要素自体は使い回されるため、
 * ランディングページから他ページへ移動した際に外し忘れないようにするため）。
 * 「1セクション毎にスクロール」を確実にするためmandatory（＝スナップ位置以外では
 * 止まらない）を使用。各セクション自体は画面より縦長なことが多いため、mandatoryでも
 * セクション「内」の通常スクロールは妨げられず、セクションの境界をまたいだ瞬間だけ
 * 次（前）のセクションの先頭にスナップする（TOCのアンカージャンプも着地点が
 * そのままスナップ対象になるだけなので干渉しない）。
 * ========================================================== */
body.landing-scroll-snap {
    scroll-snap-type: y mandatory;
}

.page-flip-group {
    perspective: 1800px;
}

.landing-snap-section {
    scroll-snap-align: start;
    scroll-margin-top: 88px;
}

.page-section-flip {
    transform: rotateX(-14deg) translateY(22px);
    opacity: 0;
    transform-origin: top center;
    transition: transform 0.8s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.6s ease;
    /* will-changeは.flip-cardと同様、常時ではなくJS側でアニメーション中のみ付与する。 */
}

.page-section-flip.is-flipped {
    transform: rotateX(0deg) translateY(0);
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    body.landing-scroll-snap {
        scroll-snap-type: none;
    }
    .page-section-flip {
        transition: none;
        transform: none;
        opacity: 1;
    }
}

/* ==========================================================
 * 選手トレーディングカード（team_detail.php の「PLAYER CARDS」タイル）
 * 遊戯王カードのような、金〜赤のグラデーション枠を持つ縦長カード。
 * ========================================================== */
.player-tcg-card {
    display: block;
    text-decoration: none;
    height: 100%;
}

.tcg-card-frame {
    position: relative;
    aspect-ratio: 2 / 3;
    height: 100%;
    border-radius: 14px;
    padding: 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    background-image:
        linear-gradient(160deg, #1a0505 0%, #0a0a0a 55%, #1a0505 100%),
        linear-gradient(135deg, #f5b400 0%, #7f1d1d 45%, #f5b400 100%);
    background-origin: border-box;
    background-clip: padding-box, border-box;
    border: 2px solid transparent;
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.55), inset 0 0 18px rgba(245, 180, 0, 0.06);
    transition: box-shadow 0.25s ease, transform 0.25s ease;
    overflow: hidden;
}

.player-tcg-card:hover .tcg-card-frame {
    transform: translateY(-4px);
    box-shadow: 0 14px 30px rgba(245, 180, 0, 0.22), 0 8px 22px rgba(0, 0, 0, 0.6);
}

.tcg-card-header {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0;
    gap: 3px;
}

/* PLAYER CARDS（team_detail.php）のヘッダー左側：ポジション表記＋称号（バッジ）アイコン
   （最大3つ）をひとまとめにするラッパー。キャプテンマーク「C」（ヘッダー右側）と合わせて
   justify-content: space-betweenの2要素構成を保つため、ポジション表記と称号アイコン列を
   1つの子要素としてまとめている。min-width:0とoverflow:hiddenで、カード幅が狭い場合でも
   このラッパー自体がカードの外にはみ出さないようにする（2026-09-15追加）。 */
.tcg-header-left {
    display: flex;
    align-items: center;
    gap: 3px;
    min-width: 0;
    overflow: hidden;
}

/* 称号（バッジ）アイコン列。最大3件（表示件数の制限はteam_detail.php側でarray_sliceにより
   実施）。アイコン自体は幅を持ったまま縮まないようにし、カードに収まりきらない場合は
   .tcg-header-left側のoverflow:hiddenで自然に切れる（表示上カードをはみ出すことはない）。 */
.tcg-badge-row {
    display: flex;
    align-items: center;
    gap: 2px;
    flex-shrink: 0;
}

.tcg-badge-icon {
    /* 2026-09-24：全体的な文字サイズ+1px調整の一環（元 width/height:15px, font-size:8px）。
       overflow:hiddenで囲われた小さな丸バッジのため、文字だけでなく箱自体も少し広げて
       アイコンが枠からはみ出て切れてしまわないようにしている。 */
    width: 17px;
    height: 17px;
    border-radius: 9999px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 9px;
    line-height: 1;
    font-weight: 700;
    flex-shrink: 0;
    overflow: hidden;
}

.tcg-avatar-frame {
    position: relative;
    width: 100%;
    flex: 1 1 auto;
    min-height: 0;
    border-radius: 8px;
    border: 1px solid rgba(245, 180, 0, 0.35);
    background: radial-gradient(circle at 50% 30%, rgba(127, 29, 29, 0.4), rgba(0, 0, 0, 0.7));
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.tcg-avatar-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* 選手カード（players.php の .player-meishi-card）の左上にはみ出す形で表示するバッジ群
   （NEW FACEタグ・BGM設定済み音符バッジ）をまとめる横並びラッパー。2026-09-13追加：
   従来はBGMバッジ単体が直接カード左上（-8px/-8px）に絶対配置されていたが、NEW FACEタグも
   同じ左上（アイコンの真上）に表示してほしいという要望を受け、位置指定をこのラッパー側に
   一本化し、中の各バッジはラッパー内でflexの横並び要素として並べる方式に変更した。これにより
   「新規登録かつBGM設定済み」の選手でも両バッジが重ならずに並んで表示される。
   親要素は.player-meishi-card（position:relativeが必要）。

   2026-09-25改修：年俸ランキングTOP3の「豪華」演出（.rank-luxury）をカードに付けると、
   overflow:hiddenの影響でカード角からはみ出す形（-8px/-8px）で配置していたこのバッジが
   切り取られて消えてしまう不具合が発生した（ユーザー報告：「音楽マークとお気に入りマークが
   カードから飛び越えて消えてしまってる」）。専用の装飾レイヤーで回避する方式を一度試したが
   複雑になりすぎたため、そもそもバッジをカードの外にはみ出させず、カード内側（top/left:7px）に
   収める方式に変更した。これによりoverflow:hiddenの影響を受けなくなり、TOP3以外の通常カードの
   見た目もよりすっきりする。 */
.meishi-top-left-badges {
    position: absolute;
    top: 7px;
    left: 7px;
    display: flex;
    align-items: center;
    gap: 0.3rem;
    z-index: 10;
}

/* NEW FACEタグ本体。直近登録された選手（db.phpのNEW_FACE_WINDOW_DAYS日数以内）を示す
   ピル型バッジ。2026-09-13追加、同日中に選手名行→カード左上（.meishi-top-left-badges内）へ
   移動。 */
.meishi-new-face-badge {
    display: inline-flex;
    align-items: center;
    /* 2026-09-29（続き12）：ユーザー指示「NEW FACE・☆・♪の所が全体的に小さいのでもう少し
       大きくして（5pxくらい）」を受け、拡大。ピル型（可変幅）のためfont-sizeとpaddingを
       両方引き上げ、見た目の高さが約16px→約21px（+5px）になるようにした
       （font-size 10→13px、padding上下 3→4px, 8→10pxで 13+4*2=21px）。 */
    padding: 4px 10px;
    border-radius: 9999px;
    background: rgba(0, 0, 0, 0.85);
    border: 1px solid rgba(16, 185, 129, 0.7);
    color: #6ee7b7;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.05em;
    line-height: 1;
    white-space: nowrap;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
}

/* BGM設定済みの選手カードに表示する音符バッジ。2026-09-10追加、2026-09-10改修：当初は
   アバター右上（.tcg-bgm-badge）に配置していたが、目立ちにくいとの指摘を受けカード自体の
   左上に変更。2026-09-13改修：単体での絶対配置をやめ、.meishi-top-left-badges内のflex子要素
   として並ぶ方式に変更（NEW FACEタグとの同時表示に対応するため）。 */
.meishi-bgm-badge {
    /* 2026-09-29（続き12）：ユーザー指示「NEW FACE・☆・♪の所が全体的に小さいのでもう少し
       大きくして（5pxくらい）」を受け、直径を23px→28px（+5px）に拡大。font-sizeも円の
       拡大比率（約1.22倍）に合わせて12→15pxに引き上げている（元 width/height:22px,
       font-size:11px）。 */
    width: 28px;
    height: 28px;
    border-radius: 9999px;
    background: rgba(0, 0, 0, 0.85);
    border: 1px solid rgba(245, 180, 0, 0.7);
    color: #fbbf24;
    font-size: 15px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
    flex-shrink: 0;
}

/* お気に入り登録ボタン（players.php の .player-meishi-card 右上に表示。.meishi-bgm-badge と
   対になる位置。2026-09-13追加）。未登録時はグレー、登録済みは金色。
   .flip-card内の<a>タグの外側（兄弟要素）に配置しているため、クリックしても選手詳細ページへの
   遷移とは独立して動作する（イベント伝播の抑制は不要）。
   2026-09-25改修：.meishi-top-left-badgesと同じ理由（TOP3の豪華演出のoverflow:hiddenによる
   クリップ回避）で、カード角からのはみ出し（-8px/-8px）をやめ、カード内側（top:7px/right:7px）に
   収める位置に変更した。 */
.meishi-favorite-badge {
    position: absolute;
    top: 7px;
    right: 7px;
    /* 2026-09-29（続き12）：ユーザー指示「NEW FACE・☆・♪の所が全体的に小さいのでもう少し
       大きくして（5pxくらい）」を受け、直径を27px→32px（+5px）に拡大。font-sizeも円の
       拡大比率に合わせて14→17pxに引き上げている（元 width/height:26px, font-size:13px）。 */
    width: 32px;
    height: 32px;
    border-radius: 9999px;
    background: rgba(0, 0, 0, 0.85);
    border: 1px solid rgba(161, 161, 170, 0.5);
    color: #71717a;
    font-size: 17px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
    cursor: pointer;
    transition: color 0.2s ease, border-color 0.2s ease, transform 0.15s ease;
    z-index: 10;
}

.meishi-favorite-badge:hover {
    transform: scale(1.12);
    border-color: rgba(245, 180, 0, 0.7);
}

.meishi-favorite-badge.is-favorited {
    color: #fbbf24;
    border-color: rgba(245, 180, 0, 0.9);
}

.tcg-name {
    width: 100%;
    text-align: center;
    font-size: 0.7825rem; /* 2026-09-24：全体的な文字サイズ+1px調整の一環（元0.72rem）。
       text-overflow:ellipsisで自然に省略されるため箱側の調整は不要。 */
    font-weight: 700;
    color: #fef3c7;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex-shrink: 0;
}

.tcg-radar {
    width: 78%;
    aspect-ratio: 1 / 1;
    flex-shrink: 0;
}

.tcg-footer {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 0.6825rem; /* 2026-09-24：全体的な文字サイズ+1px調整の一環（元0.62rem） */
    color: #a1a1aa;
    border-top: 1px solid rgba(245, 180, 0, 0.2);
    padding-top: 3px;
    flex-shrink: 0;
}

.tcg-footer .tcg-salary-value {
    color: #f87171;
    font-weight: 700;
}

/* ==========================================================
 * 選手一覧（players.php）の横長カード（名刺風）
 * team_detail.phpの縦長トレーディングカード（.tcg-*）とは別デザイン。
 * 固定のaspect-ratioを持たせず、内容量に応じて高さが伸びる自然な高さのカードにすることで、
 * 文字が枠からはみ出して見切れる問題を避けている（2026-09-10改修：縦長カードで発生していた
 * 文字切れの修正を兼ねる）。
 * ========================================================== */
.meishi-avatar-frame {
    position: relative;
    border-radius: 8px;
    border: 1px solid rgba(245, 180, 0, 0.35);
    background: radial-gradient(circle at 50% 30%, rgba(127, 29, 29, 0.4), rgba(0, 0, 0, 0.7));
    overflow: hidden;
}

.meishi-avatar-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* 選手一覧の名刺カード：アバター写真右下に重ねるチームロゴバッジ（2026-09-28追加）。
 * 上の`.meishi-avatar-frame img`ルール（無指定のimg全てを100%サイズにする）は、この
 * ロゴバッジにも効いてしまい元のサイズ指定を打ち消すため、専用クラスで明示的に上書きする
 * （セレクタの詳細度を上げるため`.meishi-avatar-frame img.meishi-team-logo-badge`にしている）。 */
.meishi-avatar-frame img.meishi-team-logo-badge {
    width: 2.3rem;
    height: 2.3rem;
    object-fit: cover;
}

/* 選手一覧（players.php）の称号（バッジ）表示行。2026-09-13改修：それまで選手名と同じ行に
   詰め込まれていた称号チップを、アイコン・レーダーチャート行の下に独立した行として配置し、
   カード幅いっぱいを使って折り返せるようにした（スマホでの窮屈さ・見づらさの解消が目的）。
   称号が1つも無い選手のカードにはこの行自体が出力されないため、余白の無駄も発生しない。 */
.meishi-badge-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.375rem;
    /* padding: 5px; */
    /* background: #000000; */
}

/* ==========================================================
 * 選手一覧（players.php）の名刺カード刷新（2026-09-29追加）
 * ユーザーから提示されたレイアウト画像を基にした変更。カード上下に紺×金の波形バナーを追加し、
 * アイコン写真を全幅の大きな1枚に、チーム名・選手名・基本年俸・契約年俸を独立した「バー」表示に、
 * レーダーチャート（JRL・UGRMステータス）をより大きな枠に、チームロゴをカード下部バナーに
 * 重ねる円形バッジに、それぞれ変更した。
 * - 波形バナーの紺×金という配色は、ユーザーから「装飾グラフィックの部分（紺金の波形バナー）は
 *   なるべく再現し、それ以外はサイトの既存デザインを参照」との指示を受けて採用したもので、
 *   サイト全体のUNDERGROUND REMATCH配色（zinc×red）とは別に、この名刺カード専用の装飾として
 *   導入している。金色自体は既存の.rank-luxury-1やBGMバッジ等で使われている金トーン
 *   （#fbbf24 / rgba(245,180,0,...)系統）に寄せることで、サイト全体との統一感を保っている。
 * - チーム名・選手名・年俸2種の「バー」表示、称号（.meishi-badge-row、変更なし）、
 *   投げ銭・オファーボタンは、いずれもユーザー確認の上でサイトの既存ダーク×レッド配色を
 *   踏襲している（画像の赤・ピンク・黒はあくまでワイヤーフレームの配色）。
 * - JRL・UGRMステータスの六角形部分は、ユーザー確認の上で既存の五角形レーダーチャート
 *   （stat_radar_svg()）をこの大きめの枠（.meishi-radar-frame-lg）に配置するだけでよいことにした
 *   （六角形の外枠自体を新規に作る必要はない）。
 * - 波形の実体（<symbol id="meishi-wave-shape">）はplayers.php側で1度だけ定義し、各カードは
 *   <use>で参照する（選手数が多い一覧ページでSVGパスを人数分複製してページを重くしないため）。
 *   下部バナーは同じsymbolを.meishi-wave-svg-flipで上下反転して使い回している。
 *
 * 2026-09-29（続き）：ユーザーからレイアウト画像の各パーツについて追加の指摘を受け、以下の通り
 * 修正した（画像内の色分けの意味：グレー＝アイコン写真、赤＝チーム名/選手名、ピンク＝年俸、
 * 黒六角形＝レーダーチャート設置枠、黒背景エリア＝称号タグの設置エリア、という対応関係を
 * ユーザーに確認済み）。
 * - チーム名・選手名・基本年俸・契約年俸・レーダーチャートは、アイコン写真の「下」に別枠で
 *   並べるのではなく、アイコン写真の「上」に重ねて表示する（.meishi-photo-overlay）。写真は
 *   position:absoluteの背景として敷き、その上に下端寄せのグラデーションスクリムを重ね、
 *   さらにその上にバー群とレーダー枠を配置することで、画像上部は写真がそのまま見える余白として
 *   残しつつ、下寄りに文字情報を読みやすく重ねる構成にしている。
 * - 称号（バッジ）は黒背景のエリアに並べる指定を受け、.meishi-badge-rowを黒背景の帯
 *   （.meishi-lower-panel）でラップし、カード端まで塗り足す形にした。
 * - 投げ銭・オファーボタンは「右下固定」の指定を受け、通常のフロー内の下寄せ配置から、下部の
 *   波形バナー右端に重ねる絶対配置（.meishi-band-actions。左端のチームロゴと左右対称）に変更した。
 * ========================================================== */
/* 2026-09-29（続き2）：当初はSVGの波形パス（<symbol id="meishi-wave-shape">を<use>で参照）を
   帯の中身にしていたが、ユーザーから「波線が少しダサいのでもう少しカチッとしたデザインに」との
   指摘を受け、一旦は::beforeの二重linear-gradient（ハードストップ）による斜めストライプ意匠に
   差し替えていた。
   2026-09-29（続き3）：その後ユーザーから紺×金の波形フレーム画像（透過PNG、既製の意匠）が
   提示され「これ使える？」との相談を受けたため、この画像の上端・下端の波形部分のみを切り出して
   img/meishi_wave_band_top.png・img/meishi_wave_band_bottom.png として取り込み、帯の背景画像に
   採用した（ストライプ案は結果的に不採用）。
   2026-09-29（続き4）：取り込み当初は画像の透過部分の裏に紺グラデーションを敷いていたが、
   ユーザーから「カードの上下が紺色の背景になってしまっていて、せっかくの透過画像がうまく
   生きていない。カード自体の背景（灰黒）に合わせよう」との指摘を受け、この紺グラデーション
   レイヤーを廃止した。.meishi-wave-band-top/-bottomはカード本体（.player-meishi-card、
   Tailwindの`bg-zinc-900/90`）の子要素であるため、背景色を明示指定しなければ透過部分から
   親であるカード自体の灰黒背景がそのまま透けて見える（＝画像が「紺色の四角の中」ではなく
   「カードの上に直接乗っている」ように見える）。これによりカード上下端が紺色にならず、
   画像の切り抜き形状そのものが活きる見た目になる。 */
.meishi-wave-band {
    position: relative;
    height: 40px;
    overflow: hidden;
    flex-shrink: 0;
}

.meishi-wave-band-top {
    border-top-left-radius: 11px;
    border-top-right-radius: 11px;
    background-image: url('../../img/meishi_wave_band_top.png');
    background-size: 100% 100%;
    background-repeat: no-repeat;
}

.meishi-wave-band-bottom {
    border-bottom-left-radius: 11px;
    border-bottom-right-radius: 11px;
    margin-top: .25rem;
    background-image: url('../../img/meishi_wave_band_bottom.png');
    background-size: 100% 100%;
    background-repeat: no-repeat;
}

/* 称号の黒背景帯（.meishi-lower-panel）が直前にある場合は、帯自体がすでにカード端まで黒で
   塗り足されているため、下部バナーとの間に隙間を作らない（2026-09-29追加）。 */
.meishi-lower-panel + .meishi-wave-band-bottom {
    margin-top: 0;
}

/* 2026-09-29（続き13）：チームロゴは.meishi-photo-team-logo-badge（写真左上、ポジション
   バッジの直下）へ移設したため、下部バナー左端に重ねていた旧.meishi-band-logo-badgeは
   ここでは廃止した。 */

/* 投げ銭・オファーボタン：2026-09-29追加。ユーザー指示「投げ銭・オファーは右下固定」を受け、
   カード本体側の通常フロー（下寄せ）から、下部波形バナーの右端に重ねる絶対配置に変更した。
   Tailwindの任意値クラス（text-[10px]等）に頼らず専用クラスとして書き起こしているのは、
   カードの主要な見た目をTailwind CDNの読み込み成否に依存させないための方針
   （.meishi-radar-frame-lg等と同じ理由）による。 */
.meishi-band-actions {
    position: absolute;
    right: 10px;
    bottom: 7px;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    z-index: 5;
}

.meishi-band-action-btn {
    box-sizing: border-box;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.03em;
    white-space: nowrap;
    padding: 0.4rem 0.65rem;
    border-radius: 6px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.55);
    transition: filter 0.15s ease, transform 0.15s ease;
}

.meishi-band-action-btn:hover {
    filter: brightness(1.15);
    transform: translateY(-1px);
}

.meishi-band-action-btn.is-tip {
    background: rgba(0, 0, 0, 0.6);
    border: 1px solid rgba(248, 113, 113, 0.6);
    color: #fca5a5;
}

.meishi-band-action-btn.is-offer {
    background: rgba(127, 29, 29, 0.85);
    border: 1px solid rgba(248, 113, 113, 0.6);
    color: #fef2f2;
}

/* アイコン画像（プロフィール写真）を大きな背景として敷き、その上にチーム名・選手名・基本年俸・
   契約年俸のバーとレーダーチャート枠を重ねるオーバーレイ。2026-09-29改修：当初は写真を単独の
   枠（.meishi-icon-photo-frame）として表示し、その「下」に各バー・レーダー枠を個別に並べる
   構成にしていたが、ユーザーから「チーム名・選手名・基本年俸・契約年俸・レーダーチャートは
   アイコン画像の上に重ねる配置」との指摘を受け、写真を背景に敷いた上に重ねるオーバーレイ方式に
   作り直した。
   高さは中身（バー4本＋レーダー枠）を重ねてもなお上部に写真の見える余白が残るよう、内包する
   .meishi-radar-frame-lgの高さ（7rem/9rem/10rem）に合わせてブレークポイントごとに明示指定
   している（子要素が全てposition:absoluteのため、親に高さの指定が無いと潰れてしまう）。 */
.meishi-photo-overlay {
    box-sizing: border-box;
    position: relative;
    width: 100%;
    height: 15rem;
    border-radius: 8px;
    border: 1px solid rgba(245, 180, 0, 0.35);
    background: radial-gradient(circle at 50% 30%, rgba(127, 29, 29, 0.4), rgba(0, 0, 0, 0.7));
    overflow: hidden;
    flex-shrink: 0;
}

@media (min-width: 640px) {
    .meishi-photo-overlay {
        height: 17rem;
    }
}

@media (min-width: 1024px) {
    .meishi-photo-overlay {
        height: 18.5rem;
    }
}

.meishi-photo-overlay-link {
    position: absolute;
    inset: 0;
    display: block;
    z-index: 0;
}

.meishi-photo-bg {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* 写真の下部にかけての半透明スクリム。重ねるバー・レーダー枠自体にも背景色は付けているが、
   スクリムを一枚挟むことで写真の柄や明るさに関わらず文字情報を読みやすくしている。 */
.meishi-photo-overlay::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.78) 0%, rgba(0, 0, 0, 0.4) 42%, rgba(0, 0, 0, 0) 68%);
    z-index: 1;
    pointer-events: none;
}

/* ポジション表示バッジ（FW/MF/DF/GK等）とチームロゴを縦に並べる、写真左上のスタック。
   2026-09-29（続き13）：ユーザー指示「ポジションの下にチームアイコンを置く形にしよう」を
   受けて新設。従来ポジションバッジ単体に付けていた絶対配置（top:6px/left:6px）と
   z-indexをこのラッパー側に移し、中の2要素はflexで縦積みにするだけのシンプルな配置に
   した。 */
.meishi-photo-topleft-stack {
    position: absolute;
    top: 6px;
    left: 6px;
    z-index: 3;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.3rem;
}

/* ポジション表示バッジ（FW/MF/DF/GK等）。以前は写真枠内にTailwindの絶対配置クラス
   （absolute top-1.5 left-1.5）で直接置いていたが、他の主要パーツと同じ理由でTailwindに
   依存しない専用クラスに書き起こした。position_color_class()が返す枠線・文字色のクラスは
   従来通りTailwindユーティリティ（border/text系）を使い続けている。
   2026-09-29（続き13）：ユーザー指示「DFとかのポジションも5pxくらい大きくしよう」を受け、
   NEW FACEバッジと同じ考え方で拡大（font-size 10→13px、padding上下 2→3px, 左右 6→8pxで
   高さが約14px→19px、+5pxになるようline-height:1を明示）。絶対配置は親の
   .meishi-photo-topleft-stackへ移したためここでは指定しない。 */
.meishi-photo-position-badge {
    box-sizing: border-box;
    font-size: 13px;
    line-height: 1;
    padding: 0.1875rem 0.5rem;
    border-radius: 9999px;
    flex-shrink: 0;
}

/* チームロゴ（登録があれば）をポジションバッジの直下に並べる円形バッジ。
   2026-09-29（続き13）：従来は下部バナー左端（.meishi-band-logo-badge）に重ねていたが、
   ユーザー指示「ポジションの下にチームアイコンを置く形にしよう」を受けてこちらへ移設した
   （旧.meishi-band-logo-badgeは未使用になったため削除）。
   2026-09-29（続き14）：ユーザー指示「チームアイコンだけど55px×55pxにしてください」を受け、
   20px→55pxに拡大。 */
.meishi-photo-team-logo-badge {
    box-sizing: border-box;
    width: 55px;
    height: 55px;
    border-radius: 9999px;
    border: 2px solid rgba(245, 180, 0, 0.7);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
    object-fit: cover;
    background: #09090b;
    flex-shrink: 0;
}

.meishi-photo-overlay-content {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 0.6rem;
    pointer-events: none;
}

.meishi-photo-overlay-row {
    display: flex;
    align-items: flex-end;
    gap: 0.6rem;
    /* 2026-09-29（続き11）：ユーザー指摘「カードのリンクの部分が、上に乗せた都合上反応しない
       ところが出てきてる」への対応。このrowだけpointer-events:autoにしていたため、チーム名・
       選手名・基本年俸・契約年俸のバー列やレーダーチャート（.meishi-radar-frame-lg）を
       クリックしても、その下にある.meishi-photo-overlay-link（選手詳細ページへのリンク、
       z-index:0）まで届かずクリックが無効になっていた。auto→noneに変更し、このrow自体は
       クリックを透過させることで、写真だけでなくこの中身（SVGレーダーチャート含む）を
       クリックしても選手詳細へ飛べるようにした。称号（.meishi-badge-row）は
       .meishi-photo-overlayの外側（.meishi-lower-panel、別要素）にあるため、この変更の
       影響を受けず従来通り選手詳細へは飛ばない（称号自体のクリックは絞り込みリンクのまま）。
       なお、この変更によりレーダー枠のtitle属性（JRL/UGRM説明）やFA（受取不可）表示の
       title属性（cursor-help）はpointer-events:noneが継承されホバーでは出なくなるため、
       レーダー枠のtitleは代わりに.meishi-photo-overlay-link側（db.php）に付け替えている。 */
    pointer-events: none;
}

.meishi-photo-overlay-fields {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

/* 2026-09-29（続き6）：ユーザー指摘「4カラム表示の際、チーム名・選手名・基本年俸・契約年俸が
   見切れている」への対応。4カラムに切り替わる1536px以上では、カード自体の幅は狭いままレーダー
   チャート枠のサイズだけは10rem（lg基準のまま、2xl専用の拡大は無い）を維持しているため、
   バー列に残る横幅が151px程度まで狭まり、年俸などの数値が省略記号で見切れてしまっていた。
   横に並べたまま文字を縮めるのではなく、この幅だけ「バー列を上・レーダーを下」に縦積みへ
   切り替えることで、バー列がカード幅いっぱいを使えるようにし、見切れを根本的に解消した
   （#players-grid.flip-card-gridが4列になるブレークポイントと同じ1536pxを使うことで、
   実際にカードが狭くなるタイミングとレイアウト切り替えのタイミングを一致させている）。
   縦積みになる分コンテンツの縦幅が増えるため、.meishi-photo-overlayの高さも合わせて
   拡張し、写真が見える余白を確保している。 */
@media (min-width: 1536px) {
    .meishi-photo-overlay {
        height: 23rem;
    }

    .meishi-photo-overlay-row {
        flex-direction: column;
        /* 2026-09-29（続き9）：ユーザー指示「チャートグラフを右に寄せたい」を受け、centerから
           flex-endに変更。この列（縦積み）方向ではalign-itemsが横方向の揃え位置になる。
           バー列側は元々width:100%のためこの値による見た目の変化は無く、幅が固定
           （.meishi-radar-frame-lgのwidth指定分）のレーダーチャートだけが右端に寄る。 */
        align-items: flex-end;
    }

    .meishi-photo-overlay-fields {
        flex: 0 0 auto;
        width: 100%;
        /* 2026-09-29追加：ユーザー指示「選手一覧のチャートとチーム名とかの表示を上下逆にしよう」
           を受け、この2xl幅（4カラム表示）でのみ縦積みになるバー列・レーダー枠の上下順を
           入れ替えた。HTML側の出力順（バー列→レーダー枠）は他の幅（横並び時：バー列が左、
           レーダーが右）に影響するため変更せず、この中でだけflexのorderで見た目の順序を
           操作している（bar列をorder:2で後ろ＝下に、レーダー枠をorder:1で先＝上に）。
           2026-09-29（続き8）：ユーザーから届いた調整版に合わせ、この2xl幅でのバー列と
           レーダー枠の上下バランス（高さ・余白）を微調整。レーダー枠が先頭（order:1）に来る分、
           直後のバー列との間隔が詰まって見えたため、バー列側に上マージンを足して呼吸感を出し、
           パネル自体の高さ（24rem→23rem）も若干詰めてガタつきを抑えた。 */
        order: 2;
        margin-top: 0.5rem;
    }

    .meishi-radar-frame-lg {
        order: 1;
    }
}

/* チーム名・選手名・基本年俸・契約年俸を独立した「バー」として縦に並べる表示
   （ユーザー提示のレイアウト画像の左カラムに相当。配色は画像そのままではなくサイトの
   既存ダーク×レッド／ゴールドに合わせている）。2026-09-29改修：アイコン写真の「上」に
   重ねる配置になったため、写真が透けて見えないよう背景の不透明度をやや上げている。 */
.meishi-field-bar {
    box-sizing: border-box;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    min-width: 0;
    background: rgba(9, 9, 11, 0.72);
    border: 1px solid rgba(63, 63, 70, 0.7);
    border-left: 3px solid rgba(185, 28, 28, 0.85);
    border-radius: 6px;
    padding: 0.35rem 0.6rem;
    backdrop-filter: blur(2px);
}

.meishi-field-bar.is-salary {
    border-left-color: rgba(245, 180, 0, 0.85);
}

.meishi-field-bar .meishi-field-label {
    font-size: 0.65rem;
    color: #a1a1aa;
    flex-shrink: 0;
    white-space: nowrap;
}

.meishi-field-bar .meishi-field-value {
    font-size: 0.85rem;
    font-weight: 700;
    color: #f4f4f5;
    text-align: right;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* JRL・UGRMステータス（レーダーチャート）を収める大きめの枠。中身は既存のstat_radar_svg()を
   そのまま使い、枠だけを新設した。2026-09-29改修：アイコン写真の「上」に重ねる配置になった
   ため、背景の不透明度をやや上げて写真の柄に埋もれないようにしている。
   2026-09-29追記：サイズ（幅・高さ）は当初db.php側でTailwindのサイズクラス
   （w-28/sm:w-36/lg:w-40。従来のアバター・レーダー枠と同じ、既に実績のある値）を
   付与するだけにしていたが、Tailwind（Play CDN）の読み込みに問題が起きた場合にこの枠が
   カード全幅まで広がってしまう（display:flexのみでwidth未指定のため）と表示が大きく崩れて
   見えてしまうため、同じサイズ値をこちらのCSS側にも直接持たせ、Tailwindが使えない状況でも
   最低限このサイズで表示されるようにした（Tailwind側のクラスは残しているが、詳細度が同じ
   場合は後から読み込まれる側が勝つため、通常はTailwind側の値がそのまま使われる）。 */
.meishi-radar-frame-lg {
    box-sizing: border-box;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    align-self: center;
    border-radius: 8px;
    border: 1px solid rgba(245, 180, 0, 0.45);
    /* 2026-09-29（続き5）：ユーザー指示「5角形チャートはもう少し透過させて後ろのアイコンを
       見やすくしてほしい」を受け、背景の不透明度を大幅に下げた（0.96/0.92→0.42/0.36）。
       完全な透明にはせず、チャート自体の視認性（赤い線・文字ラベル）を保つための最低限の
       濃さは残している。backdrop-filterも足し、写真の柄が強い場合でも線がにじんで見えにくく
       ならないようにした。 */
    background: radial-gradient(circle at 50% 40%, rgba(24, 24, 27, 0.42), rgba(0, 0, 0, 0.36));
    backdrop-filter: blur(1.5px);
    padding: 0.5rem;
    width: 7rem;
    height: 7rem;
}

@media (min-width: 640px) {
    .meishi-radar-frame-lg {
        width: 9rem;
        height: 9rem;
    }
}

@media (min-width: 1024px) {
    .meishi-radar-frame-lg {
        width: 10rem;
        height: 10rem;
    }
}

/* 称号（バッジ）タグの黒背景帯。2026-09-29追加：ユーザー指示「タグは黒背景の所に並べていく
   イメージ」を受け、.meishi-badge-row（配置ロジックは変更なし）を黒背景の帯でラップし、
   装飾帯と同じ要領でカード左右のpaddingを負のマージンで打ち消してカード端まで塗り足した。
   2026-09-29（続き）：ユーザー指示「称号タグエリアは一旦3行分くらいの高さで揃えてできる限り
   カードの高さを合わせてください」を受け、高さを称号3行分の固定値にし、称号が0件の選手にも
   この帯自体は出力する方式に変更した（db.php側も参照）。これにより、同じグリッド行に並ぶ
   カード同士の高さが（称号が3行に収まる範囲では）揃うようになる。overflow:hiddenにしているため、
   3行を超える多数の称号を持つ選手は一旦あふれた分が見切れる（今回は「一旦」の対応としてこの形に
   し、恒常的な対応が必要なら改めて検討する）。

   2026-09-29（続き8）：ユーザーから届いた調整版で、background・paddingの明示指定が
   コメントアウトされていた（帯の黒背景・左右余白を無くす方向の調整）。意図を汲み、そのまま
   反映した。高さ（7rem）自体は変更なし。 */
.meishi-lower-panel {
    box-sizing: border-box;
    /* background: #050505; */
    /* margin: auto; */
    /* width: 100%; */
    height: 7rem;
    overflow: hidden;
}

@media (min-width: 640px) {
    .meishi-lower-panel {
        padding: 0.6rem 1.25rem 0.7rem;
    }
}

/* 選手一覧グリッド（players.php の #players-grid）の列数。2026-09-29追記：グリッド自体
   （display:grid・grid-cols-*）もTailwindクラスに任せきりだと、上と同じ理由でTailwindが
   使えない場合に1カラム崩れ（実質ただの縦並び）になってしまうため、同じ列数の内訳を
   ここにも直接持たせておく。 */
#players-grid.flip-card-grid {
    display: grid;
    grid-template-columns: repeat(1, minmax(0, 1fr));
    gap: 1rem;
}

@media (min-width: 640px) {
    #players-grid.flip-card-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1024px) {
    #players-grid.flip-card-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (min-width: 1536px) {
    #players-grid.flip-card-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* ==========================================================
 * BGM再生中ビジュアライザー（player_detail.php プロフィールカード背景、2026-09-10追加）
 * 音楽再生アプリによくある「びょんびょん伸縮する縦棒イコライザー」風の装飾アニメーション。
 * 再生中のみ表示・アニメーションさせ、一時停止中は非表示にする（#bgm-toggle-btnのJSから
 * is-playingクラスをカード側に付け外しする）。カードは position:relative にした上で、
 * このビジュアライザーはその背景いっぱいに絶対配置し、実際のコンテンツ（.bgm-card-content）
 * 側に z-10 を与えて常に手前に表示させる。
 * ========================================================== */
.bgm-visualizer {
    position: absolute;
    inset: 0;
    z-index: 0;
    display: flex;
    align-items: flex-end;
    justify-content: space-evenly;
    gap: 3px;
    padding: 0 3%;
    overflow: hidden;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.6s ease;
    contain: strict;
}

.bgm-visualizer.is-playing {
    opacity: 1;
}

.bgm-visualizer span {
    display: block;
    width: 3px;
    flex-shrink: 0;
    border-radius: 2px 2px 0 0;
    background: linear-gradient(to top, rgba(239, 68, 68, 0.55), rgba(239, 68, 68, 0.05));
    /* 【2026-10-10高速化】以前は height をアニメーションしていたため、32本の棒が毎フレーム
       レイアウト再計算＋再描画を起こし、再生中のNobtyfyが重くなる原因だった。高さは固定にし、
       transform: scaleY() だけを動かす（GPU合成のみで済み、レイアウトが走らない）。 */
    height: 88%;
    transform-origin: bottom center;
    transform: scaleY(0.09);
    will-change: transform;
    animation: bgm-bar-bounce 1.2s ease-in-out infinite;
    animation-play-state: paused;
}

.bgm-visualizer.is-playing span {
    animation-play-state: running;
}

.bgm-visualizer span:nth-child(4n+1) { animation-duration: 1.35s; animation-delay: -0.15s; }
.bgm-visualizer span:nth-child(4n+2) { animation-duration: 0.85s; animation-delay: -0.65s; }
.bgm-visualizer span:nth-child(4n+3) { animation-duration: 1.55s; animation-delay: -0.95s; }
.bgm-visualizer span:nth-child(4n)   { animation-duration: 1.05s; animation-delay: -0.35s; }

@keyframes bgm-bar-bounce {
    0%, 100% { transform: scaleY(0.09); }
    50% { transform: scaleY(1); }
}

/* ==========================================================
 * カレンダー式日付ピッカー（assets/js/date-picker.js）
 * `.ugr-date-input`クラスを持つ<input type="text">をクリックすると表示されるポップアップカレンダー。
 * Bootstrap等は導入せず、既存のダークレッド地下鉄テーマに合わせた自前実装。
 * ========================================================== */
.ugr-date-input {
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2371717a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.6rem center;
    padding-right: 2.1rem !important;
}

.ugr-datepicker-pop {
    position: absolute;
    z-index: 500;
    width: 240px;
    background: rgba(9, 9, 11, 0.98);
    border: 1px solid rgba(127, 29, 29, 0.7);
    border-radius: 10px;
    box-shadow: 0 16px 36px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(0, 0, 0, 0.4);
    padding: 0.6rem;
    font-family: inherit;
}

.ugr-datepicker-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.5rem;
}

.ugr-datepicker-label {
    font-size: 0.8125rem; /* 2026-09-24：全体的な文字サイズ+1px調整の一環（元0.75rem） */
    letter-spacing: 0.05em;
    color: #e4e4e7;
    font-weight: 700;
}

.ugr-datepicker-nav {
    /* 2026-09-24：全体的な文字サイズ+1px調整の一環（元 width/height:26px, font-size:0.9rem） */
    width: 27px;
    height: 27px;
    border-radius: 6px;
    border: 1px solid #3f3f46;
    background: transparent;
    color: #a1a1aa;
    font-size: 0.9625rem;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.ugr-datepicker-nav:hover {
    background: rgba(127, 29, 29, 0.35);
    border-color: rgba(185, 28, 28, 0.6);
    color: #fca5a5;
}

.ugr-datepicker-weekdays {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    text-align: center;
    font-size: 0.7125rem; /* 2026-09-24：全体的な文字サイズ+1px調整の一環（元0.65rem） */
    color: #71717a;
    margin-bottom: 0.25rem;
}

.ugr-datepicker-weekdays .is-sun { color: #f87171; }
.ugr-datepicker-weekdays .is-sat { color: #7dd3fc; }

.ugr-datepicker-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
}

.ugr-datepicker-day {
    aspect-ratio: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7625rem; /* 2026-09-24：全体的な文字サイズ+1px調整の一環（元0.7rem） */
    color: #d4d4d8;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 6px;
    cursor: pointer;
    transition: background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

.ugr-datepicker-day.is-blank {
    cursor: default;
    pointer-events: none;
}

.ugr-datepicker-day.is-sun { color: #fca5a5; }
.ugr-datepicker-day.is-sat { color: #7dd3fc; }

.ugr-datepicker-day:not(.is-blank):hover {
    background: rgba(127, 29, 29, 0.35);
    border-color: rgba(185, 28, 28, 0.5);
}

.ugr-datepicker-day.is-today {
    border-color: rgba(220, 38, 38, 0.7);
    font-weight: 700;
}

.ugr-datepicker-day.is-selected {
    background: #b91c1c;
    border-color: #b91c1c;
    color: #ffffff;
    font-weight: 700;
}

.ugr-datepicker-day.is-disabled,
.ugr-datepicker-day:disabled {
    color: #3f3f46;
    cursor: not-allowed;
    pointer-events: none;
}

.ugr-datepicker-footer {
    display: flex;
    justify-content: center;
    gap: 0.75rem;
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px solid #27272a;
}

.ugr-datepicker-footer-btn {
    background: transparent;
    border: none;
    font-size: 0.7625rem; /* 2026-09-24：全体的な文字サイズ+1px調整の一環（元0.7rem） */
    color: #f87171;
    cursor: pointer;
    padding: 0.15rem 0.3rem;
}

.ugr-datepicker-footer-btn:hover {
    color: #fca5a5;
    text-decoration: underline;
}

.ugr-datepicker-footer-btn.is-muted {
    color: #71717a;
}

.ugr-datepicker-footer-btn.is-muted:hover {
    color: #a1a1aa;
}

.ugr-datepicker-footer-btn:disabled {
    color: #52525b;
    cursor: not-allowed;
    pointer-events: none;
}

/* ==========================================================
 * 画像の切り取り・拡大縮小モーダル（assets/js/image-cropper.js）
 * チームアイコン等、画像アップロード後に「切り取り・拡大して好きな場所を使う」ための
 * 汎用モーダル。date-picker.jsと同様にJS側で動的にDOM生成するため、対応するクラスを
 * ここで自前定義する（Tailwind Play CDNは動的追加要素を確実にスキャンする保証が無いため）。
 * 2026-09-28追加。
 * ========================================================== */
body.ugr-cropper-open {
    overflow: hidden;
}

.ugr-cropper-overlay {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background: rgba(0, 0, 0, 0.82);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.25rem;
}

.ugr-cropper-modal {
    width: 100%;
    max-width: 420px;
    background: rgba(9, 9, 11, 0.98);
    border: 1px solid rgba(127, 29, 29, 0.7);
    border-radius: 14px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.65), 0 0 0 1px rgba(0, 0, 0, 0.4);
    padding: 1.25rem;
    font-family: inherit;
}

.ugr-cropper-title {
    font-family: 'Oswald', 'Noto Sans JP', sans-serif;
    font-weight: 700;
    letter-spacing: 0.05em;
    font-size: 0.9rem;
    color: #f4f4f5;
    margin-bottom: 0.35rem;
}

.ugr-cropper-hint {
    font-size: 0.7rem;
    color: #a1a1aa;
    line-height: 1.5;
    margin-bottom: 1rem;
}

.ugr-cropper-viewport {
    position: relative;
    width: min(300px, 72vw);
    height: min(300px, 72vw);
    margin: 0 auto 1.1rem;
    overflow: hidden;
    background: repeating-conic-gradient(#18181b 0% 25%, #0a0a0a 0% 50%) 50% / 20px 20px;
    border: 2px solid rgba(185, 28, 28, 0.6);
    cursor: grab;
    touch-action: none;
    user-select: none;
}

.ugr-cropper-viewport:active {
    cursor: grabbing;
}

.ugr-cropper-viewport.is-circle {
    border-radius: 50%;
}

.ugr-cropper-img {
    position: absolute;
    left: 0;
    top: 0;
    max-width: none;
    pointer-events: none;
    -webkit-user-drag: none;
}

.ugr-cropper-controls {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 1.1rem;
}

.ugr-cropper-zoom-label {
    font-size: 0.85rem;
    color: #71717a;
    flex-shrink: 0;
    width: 1rem;
    text-align: center;
}

.ugr-cropper-slider {
    flex: 1;
    accent-color: #dc2626;
}

.ugr-cropper-buttons {
    display: flex;
    justify-content: flex-end;
    gap: 0.6rem;
}

.ugr-cropper-btn {
    font-family: 'Oswald', 'Noto Sans JP', sans-serif;
    letter-spacing: 0.05em;
    font-size: 0.75rem;
    padding: 0.55rem 1.1rem;
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.ugr-cropper-btn-secondary {
    background: transparent;
    border: 1px solid #3f3f46;
    color: #d4d4d8;
}

.ugr-cropper-btn-secondary:hover {
    border-color: rgba(185, 28, 28, 0.6);
    color: #fca5a5;
}

.ugr-cropper-btn-primary {
    background: linear-gradient(to right, #450a0a, #18181b);
    border: 1px solid rgba(185, 28, 28, 0.7);
    color: #f4f4f5;
}

.ugr-cropper-btn-primary:hover {
    background: linear-gradient(to right, #7f1d1d, #27272a);
}

/* ==========================================================
 * 通知バッジ（assets/js/notifications.js）
 * 新着お知らせ／チーム宛ての対応待ち／自分の申請結果／管理者向け承認待ちの未読件数を表示する
 * ==========================================================
 * .notif-badge          : ヘッダーのベルアイコン用（アイコンの右上に重ねる、position:absolute）
 * .notif-badge-inline    : ハンバーガーメニュー内の各リンク用（行の右端に並べる、インライン表示）
 */
.notif-badge {
    /* 2026-09-24：全体的な文字サイズ+1px調整の一環（元 min-width/height/line-height:15px,
       font-size:10px）。line-heightを箱の高さと一致させて数字を縦中央に揃える方式のため、
       高さ・line-heightも文字サイズと合わせて調整している。 */
    position: absolute;
    top: -4px;
    right: -6px;
    min-width: 16px;
    height: 16px;
    padding: 0 3px;
    border-radius: 9999px;
    background: #dc2626;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
    box-shadow: 0 0 0 2px rgba(9, 9, 11, 0.95);
}

.notif-badge-inline {
    /* 2026-09-24：全体的な文字サイズ+1px調整の一環（元 min-width/height/line-height:18px,
       font-size:10px） */
    display: inline-block;
    min-width: 19px;
    height: 19px;
    padding: 0 5px;
    border-radius: 9999px;
    background: #dc2626;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    line-height: 19px;
    text-align: center;
    flex-shrink: 0;
}

/* .notif-badge-inlineの display:inline-block はJSが付け外しする[hidden]属性より詳細度で
   上回ってしまう（UAスタイルシートの[hidden]{display:none}は詳細度に関わらず author CSSより
   優先度が低いため）。明示的に上書きしておく。 */
.notif-badge[hidden],
.notif-badge-inline[hidden] {
    display: none;
}

/* 2026-09-28追加：上と全く同じ原因（Tailwindのflex等のdisplayユーティリティがJSの[hidden]
   属性より優先されてしまう）で、称号付与の選手検索・称号絞り込みの一覧行が「絞り込んでも
   表示が切り替わらない」不具合が発生していたため、同じパターンで明示的に上書きする。
   併せて、同じ理由で同様に壊れていたチーム一覧検索（team-row）・DB管理タブ検索
   （table-tab-btn）も一緒に修正した（いずれも行要素自体にflex系クラスが付いているため、
   [hidden]を付けてもflexの方が優先されて非表示にならなかった）。
   2026-09-28追加：対戦結果入力の「現在の記録一覧」（match-result-submission-list）も
   flex flex-colクラスを持つため、同じ理由で[hidden]が効かなくなる不具合を予防的に修正。 */
.badge-assign-player-row[hidden],
.badge-assign-badge-row[hidden],
.team-row[hidden],
.table-tab-btn[hidden],
.match-result-submission-list[hidden] {
    display: none;
}

/* ==========================================================
 * music.php：「Nobtyfy」ブランディング（Spotify的な音楽アプリの雰囲気を
 * 出しつつ、実在ブランドのロゴ・マークそのものは模倣しない独自デザイン）
 * ========================================================== */
.nobtyfy-badge {
    display: inline-flex;
    flex-shrink: 0;
    filter: drop-shadow(0 2px 6px rgba(16, 122, 71, 0.45));
}

.nobtyfy-wordmark {
    background: linear-gradient(90deg, #3ee08c, #0a8a4d);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}

.nobtyfy-dot {
    -webkit-text-fill-color: #ef4444;
    color: #ef4444;
}

/* ==========================================================
 * 年俸ランキング TOP3 豪華演出（金・銀・銅のグラデーション枠 + グロー + 光沢アニメーション）
 * salary_ranking.php の ranking_luxury_class() でカードに .rank-luxury / .rank-luxury-1〜3 を付与する。
 * 実装メモ：
 * - グラデーション枠は「二重背景」テクニック（background-clip: padding-box, border-box）で実現。
 *   1枚目（padding-box）はカード本来の zinc-900 系の背景色を塗り直し、2枚目（border-box）に
 *   金/銀/銅のグラデーションを敷いて border-color: transparent の border 部分にだけ見せている。
 *   Tailwind の bg-* は background-color のみを設定するため、この background-image 指定と競合しない。
 * - border-color と box-shadow は、既存の Material Design 用の属性セレクタ上書き
 *   （[class*="border-red-950..."] / [class*="shadow-red-950..."]、いずれも !important）と
 *   詳細度が同じ（0,1,0）なので、このブロックをファイル内でそれより後ろに置くことで確実に勝たせている。
 * - 光沢アニメーションは ::after の斜めグラデーション帯をカード上を横切らせるだけで、
 *   レイアウトに影響しないよう position: absolute + overflow: hidden（カード側）で完結させている。
 * ========================================================== */
.rank-luxury {
    position: relative;
    overflow: hidden;
    border-width: 1px;
    border-style: solid;
    border-color: transparent !important;
    background-image:
        linear-gradient(180deg, rgba(24, 24, 27, 0.95), rgba(24, 24, 27, 0.95)),
        var(--rank-luxury-gradient);
    background-origin: border-box;
    background-clip: padding-box, border-box;
}

.rank-luxury-1 {
    --rank-luxury-gradient: linear-gradient(135deg, #fde68a 0%, #b45309 35%, #fde68a 65%, #fffbeb 100%);
    box-shadow:
        0 0 0 1px rgba(251, 191, 36, 0.25),
        0 4px 16px 2px rgba(251, 191, 36, 0.25),
        0 2px 4px 0 rgba(0, 0, 0, 0.6) !important;
}

.rank-luxury-2 {
    --rank-luxury-gradient: linear-gradient(135deg, #e4e4e7 0%, #71717a 35%, #e4e4e7 65%, #fafafa 100%);
    box-shadow:
        0 0 0 1px rgba(212, 212, 216, 0.22),
        0 4px 16px 2px rgba(212, 212, 216, 0.18),
        0 2px 4px 0 rgba(0, 0, 0, 0.6) !important;
}

.rank-luxury-3 {
    --rank-luxury-gradient: linear-gradient(135deg, #fdba74 0%, #7c2d12 35%, #fdba74 65%, #ffedd5 100%);
    box-shadow:
        0 0 0 1px rgba(251, 146, 60, 0.22),
        0 4px 16px 2px rgba(194, 101, 45, 0.2),
        0 2px 4px 0 rgba(0, 0, 0, 0.6) !important;
}

.rank-luxury::after {
    content: "";
    position: absolute;
    top: 0;
    left: -150%;
    width: 55%;
    height: 100%;
    background: linear-gradient(115deg, transparent, rgba(255, 255, 255, 0.35), transparent);
    transform: skewX(-20deg);
    animation: rank-luxury-shine 4.5s ease-in-out infinite;
    pointer-events: none;
}

.rank-luxury-2::after {
    animation-delay: 0.35s;
}

.rank-luxury-3::after {
    animation-delay: 0.7s;
}

@keyframes rank-luxury-shine {
    0% {
        left: -150%;
    }
    35% {
        left: 150%;
    }
    100% {
        left: 150%;
    }
}

/* ==========================================================
 * 称号（バッジ）の「特別演出」カード（鱗パターン背景＋グラデーション枠。2026-09-26追加）
 * db.php の special_badge_theme_class() で、badge_types.special_theme フラグが立っている称号を
 * 持つ選手のカード（.player-meishi-card）に .badge-special-theme-crimson を付与する。
 * 最初のきっかけは称号「孤高の漢」だが、名前をハードコードせず汎用の仕組みにしてあるので、
 * 管理画面（称号カタログ管理）でチェックを入れた称号なら何にでもこの演出が付く。
 * 実装メモ：
 * - グラデーション枠は .rank-luxury と同じ「二重背景」テクニック（background-clip: padding-box
 *   ×3層＋border-box×1層）。手前から順に「鱗パターン2枚（半タイルずらして重ね、互い違いの
 *   鱗模様を作る）」→「鱗の下地となるほぼ黒のグラデーション」→「枠線用の紅蓮グラデーション」。
 *   .rank-luxuryと同じ要素には併用できない（背景レイヤーが競合して崩れるため、db.php側で
 *   称号の特別演出を優先し排他にしている。special_badge_theme_class()のコメント参照）。
 * - 鱗パターンはradial-gradient(circle at 50% 0%, ...)による半円を敷き詰め、2枚目を横に
 *   半タイル（17px/34pxの半分）・縦に半タイル（15px/30pxの半分）ずらして重ねることで、
 *   隙間なく連続する鱗模様になる（一般的なCSS鱗柄の手法）。
 * - border-color・box-shadowは.rank-luxuryと同じ理由（既存の属性セレクタ上書きと同じ詳細度
 *   のため、ファイル内でそれより後ろに置くことで確実に勝たせている）で!importantを付けている。
 * ========================================================== */
.badge-special-theme-crimson {
    position: relative;
    overflow: hidden;
    border-width: 1px;
    border-style: solid;
    border-color: transparent !important;
    background-image:
        radial-gradient(circle at 50% 0%, transparent 45%, rgba(239, 68, 68, 0.30) 46%, rgba(239, 68, 68, 0.30) 58%, transparent 59%),
        radial-gradient(circle at 50% 0%, transparent 45%, rgba(239, 68, 68, 0.30) 46%, rgba(239, 68, 68, 0.30) 58%, transparent 59%),
        linear-gradient(180deg, #0a0505 0%, #1c0e0e 100%),
        linear-gradient(160deg, #fca5a5 0%, #7f1d1d 35%, #1c0a0a 60%, #ef4444 100%);
    background-size: 34px 30px, 34px 30px, 100% 100%, 100% 100%;
    background-position: 0 0, 17px 15px, 0 0, 0 0;
    background-origin: border-box, border-box, border-box, border-box;
    background-clip: padding-box, padding-box, padding-box, border-box;
    box-shadow:
        0 0 0 1px rgba(239, 68, 68, 0.4),
        0 0 34px 3px rgba(220, 38, 38, 0.3),
        0 2px 4px 0 rgba(0, 0, 0, 0.6) !important;
}

/* ==========================================================
 * アクセシビリティ配慮：動きを抑えたい環境ではアニメーションを最小化
 * ========================================================== */
@media (prefers-reduced-motion: reduce) {
    .rank-luxury::after {
        animation: none !important;
        display: none !important;
    }
    #ambient-bg span,
    .ripple-rings span,
    main.page-fade-in,
    .reveal {
        animation: none !important;
        transition: none !important;
        opacity: 1 !important;
        transform: none !important;
    }
    .bgm-visualizer span {
        animation: none !important;
    }
    .bgm-visualizer.is-playing {
        opacity: 0.35 !important;
    }
    .hover-glow-card:hover {
        transform: none !important;
    }
    .flip-card {
        transition: none !important;
        transform: none !important;
        opacity: 1 !important;
    }
    .player-tcg-card:hover .tcg-card-frame {
        transform: none !important;
    }
}

/* ==========================================================
   スマホ用：表を「カード表示」に切り替える（2026-10-16追加）
   対象：表に class="m-card-table" を付けたもの（シーズン精算 season_payroll.php／チーム管理の清算・年俸調整）。
   ・幅767px以下で、1行=1枚のカード、各セルは「項目名（data-label）＋値」の縦並びになる（横スクロール不要）。
   ・入力欄は文字サイズ16px以上（iPhoneで入力時に画面が勝手に拡大されるのを防ぐ）、タップしやすい高さ44px。
   ・td の class: m-title＝カードの見出し（項目名なし）／m-stack＝項目名の下に値を全幅で表示（入力欄など）。
   ========================================================== */
@media (max-width: 767px) {
    .m-card-table, .m-card-table tbody { display: block; width: 100% !important; min-width: 0 !important; }
    .m-card-table thead { display: none; }
    .m-card-table tbody tr {
        display: block;
        margin: 0 0 12px;
        padding: 10px 14px 12px;
        border: 1px solid rgba(127, 29, 29, 0.55) !important;
        border-radius: 12px;
        background: rgba(0, 0, 0, 0.35);
    }
    .m-card-table tbody tr:last-child { margin-bottom: 0; }
    .m-card-table tbody td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        width: 100%;
        padding: 6px 0 !important;
        text-align: right !important;
        border: 0 !important;
        min-width: 0 !important;
    }
    .m-card-table tbody td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-size: 11px;
        font-weight: 400;
        letter-spacing: 0.04em;
        color: #a1a1aa;
        text-align: left;
    }
    .m-card-table tbody td.m-title {
        display: block;
        text-align: left !important;
        font-size: 15px;
        font-weight: 700;
        padding: 2px 0 8px !important;
        margin-bottom: 4px;
        border-bottom: 1px solid rgba(63, 63, 70, 0.7) !important;
    }
    .m-card-table tbody td.m-stack { display: block; text-align: left !important; }
    .m-card-table tbody td.m-stack[data-label]::before { display: block; margin-bottom: 6px; }
    .m-card-table input[type="text"], .m-card-table input[type="url"], .m-card-table input[type="number"], .m-card-table select {
        font-size: 16px !important;
        min-height: 44px;
        padding-left: 10px !important;
        padding-right: 10px !important;
    }
    .m-card-table .m-row { display: flex; flex-wrap: wrap; gap: 8px; width: 100%; min-width: 0 !important; }
    .m-card-table .m-row input { flex: 1 1 100%; width: 100% !important; min-width: 0; }
    .m-card-table .m-row button, .m-card-table .m-row a { flex: 1 1 0; min-height: 44px; font-size: 14px !important; display: inline-flex; align-items: center; justify-content: center; }
    .m-card-table button.m-big { min-height: 44px; font-size: 14px !important; padding-left: 16px !important; padding-right: 16px !important; }
}

/* ===== 選手ティアリスト（tierlist_edit.php）のドラッグ＆ドロップ（2026-10-19追加） ===== */
.tl-chip { position: relative; width: 3.75rem; flex-shrink: 0; display: flex; flex-direction: column; align-items: center; padding: 2px 0; cursor: grab; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; touch-action: pan-y; }
@media (min-width: 640px) { .tl-chip { width: 4.25rem; } }
.tl-chip img { pointer-events: none; -webkit-user-drag: none; }
.tl-chip.tl-chip-src { display: none; }
.tl-chip.tl-selected img { outline: 3px solid #f59e0b; outline-offset: 2px; }
.tl-ghost { position: fixed; z-index: 80; pointer-events: none; opacity: .95; transform: translate(-50%, -50%) scale(1.12); filter: drop-shadow(0 8px 14px rgba(0, 0, 0, .65)); }
.tl-ph { width: 3.75rem; height: 4.6rem; flex-shrink: 0; border: 2px dashed #ef4444; border-radius: .75rem; background: rgba(239, 68, 68, .08); }
@media (min-width: 640px) { .tl-ph { width: 4.25rem; } }
.tl-zone { flex: 1; min-width: 0; min-height: 5.25rem; display: flex; flex-wrap: wrap; gap: .5rem; align-items: flex-start; align-content: flex-start; padding: .5rem; transition: background .15s; }
.tl-zone.tl-over { background: rgba(239, 68, 68, .12) !important; outline: 2px dashed rgba(239, 68, 68, .65); outline-offset: -2px; }
.tl-zone[data-empty="1"]::before { content: attr(data-hint); color: #52525b; font-size: .75rem; align-self: center; padding: 0 .35rem; }
.tl-label { cursor: pointer; border: 0; }
.tl-label:hover { filter: brightness(1.08); }
body.tl-dragging { cursor: grabbing; user-select: none; -webkit-user-select: none; }
body.tl-dragging * { cursor: grabbing !important; }

/* ===== Nobtyfy 歌詞（2026-10-23）：時間同期表示 ===== */
.ugr-ly-view { position: relative; }
.ugr-ly-plain { white-space: pre-wrap; word-break: break-word; line-height: 1.7; }
.ugr-ly-line { padding: 0.18em 0.4em; line-height: 1.55; color: rgba(212,212,216,0.55); border-radius: 6px; transition: color .25s, background-color .25s, transform .25s; word-break: break-word; }
.ugr-ly-line.is-timed { cursor: pointer; }
.ugr-ly-line.is-timed:hover { color: rgba(244,244,245,0.85); }
.ugr-ly-line.is-active { color: #fff; font-weight: 700; background-color: rgba(185,28,28,0.28); transform: scale(1.02); }

/* ==========================================================
 * 折り返し・1行表示ルール（2026-10-23 続き83）
 * - 本文：日本語を文節単位で折る（word-break:auto-phrase。Chrome/Edge系。未対応ブラウザは
 *   禁則処理つきの通常折り返し）。長い英数字やURLだけは溢れないよう最終手段で折る。
 * - ボタン・タブ・バッジ・見出し：途中で折らず1行に収める（収まらなければ省略記号）。
 *   複数行が必要な箇所は class="wrap-ok"（または whitespace-normal）を付ければ折り返せる。
 * ========================================================== */
body {
    line-break: strict;
    overflow-wrap: break-word;
}
@supports (word-break: auto-phrase) {
    body { word-break: auto-phrase; }
}
p, li, dd, td, label, figcaption, blockquote { text-wrap: pretty; }
button, [role="tab"], summary,
.btn, .tab, .badge,
a[class*="rounded-full"], span[class*="rounded-full"], span[class*="rounded-md"], span[class*="rounded-sm"],
span[class*="rounded border"], span[class*="border-red"][class*="px-"], span[class*="border-amber"][class*="px-"],
span[class*="border-zinc"][class*="px-"], span[class*="bg-"][class*="px-"][class*="py-"] {
    white-space: nowrap;
}
button:not(.wrap-ok):not(.whitespace-normal), [role="tab"] {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* ボタン・バッジ・タブで収まらないものは fit-oneline.js が文字を最大0.78倍まで縮める */
h1, h2, h3, h4 { text-wrap: balance; }
/* 見出しは fit-oneline.js が「1行に収まる大きさまで縮めれば収まる」場合だけ .ugr-oneline を付ける。
   縮めても収まらない長い見出しは、文節単位の折り返しのままにする（省略記号で欠けさせない）。 */
.ugr-oneline { white-space: nowrap; min-width: 0; max-width: 100%; overflow: hidden; }
.wrap-ok, .wrap-ok.ugr-oneline { white-space: normal; overflow: visible; text-overflow: clip; }
/* 2026-10-25：ベルの赤いバッジ（アイコンの右上にはみ出して重ねる）が、上の button の overflow:hidden で
   切れていたため、バッジを重ねるボタンだけは overflow を戻す。 */
#notif-bell-btn, .hamburger-btn { overflow: visible; }
