@charset "UTF-8";
/* ============================================================================
   ぐんぐんリユース君のおへや

   目次
     1. トークン（★数値を直すのはここだけ）
     2. 土台
     3. ユーティリティ
     4. 背景の空
     5. ヒーロー
     6. カード（共通）
     7. ボタン
     8. 最新動画
     9. ぐんショッピング
    10. カルーセル
    11. フッター
    12. モーション
    13. せまい画面（600px以下 / 400px以下の2段）
    14. 動きを減らす設定

   決めごと
     ・class名は gh- で始める。.card / .btn / .nav のような一般名を避けて、
       あとから別のCSSやウィジェットを足したときに衝突しないようにするため。
     ・値はすべて 1. のカスタムプロパティ経由。ここを直せば全体が揃う。
     ・JSのフックは data-* 側。class名は見た目専用なので自由に変えてよい。
     ・!important は使わない（14. の1箇所だけ例外／理由はそこに記載）。
   ========================================================================== */


/* ============================================================
   1. トークン　★原本受領後に実測値へ差し替えるのはこのブロックだけ
   ============================================================ */
:root{
  /* --- 色 ------------------------------------------------- */
  /* 原本から採取。アクセントは水色1色のみ（原本にそれ以外の差し色がない）。
     ライム（KLDのマーク）はマスコット画像の中にしか出てこないので、
     トークンとしては持たない＝CSSでライムを使う場面を作らない。 */
  --gh-void:      #05060B;  /* 宇宙の地。真っ黒にせず僅かに青を残す */
  --gh-deep:      #0A1020;  /* 星雲の底 */
  --gh-cyan:      #9FDCE9;  /* 原本のタイル／CTAの水色 */
  --gh-cyan-lit:  #C9ECF4;  /* 光が当たった側 */
  --gh-cyan-deep: #79B9C9;  /* 影の側 */
  --gh-ink:       #14161A;  /* カード上の文字は見出しも説明文もこれ1色。理由は .gh-card__lead */
  --gh-paper:     #fff;

  /* ガラスの濃さ。★ここは見た目より可読性で決まっている
     暗い星空の上に重なるので、画面に出る色は指定した薄いグレーではなく
     「指定色 × 不透明度 ＋ 星空 × 残り」の合成色になる。
     .42 だと合成後が #606B6F まで暗くなり、黒文字とのコントラストが
     3.09:1（説明文は2.35:1）しか出ずWCAGの本文基準4.5:1を下回っていた。
     色味は原本どおりニュートラルなグレーのまま変えず、不透明度だけで調整する。
     .76 で合成後は約 #9FA0A1、見出し 6.9:1 / 説明文 4.9:1。
     ★いま .60 を試している（ガラス感を戻すため）。合成後は約 #7F8081 で、
       見出し 4.5:1 / 説明文 3.2:1。説明文が本文基準を下回るので、
       このまま採用するなら文字を黒側へ寄せる必要がある。
     この検算は tools/check.py が毎回やり直すので、値を触ったら必ず実行する。 */
  --gh-glass:     rgba(208, 208, 208, .60);
  --gh-hairline:  rgba(20, 22, 26, .14);

  /* --- 寸法 ----------------------------------------------- */
  --gh-page-max:     702px;  /* 原本の幅。※2倍書き出しの疑いあり→README参照 */
  --gh-gutter:        26px;  /* カードの左右マージン */
  --gh-card-radius:   20px;
  --gh-card-gap:      34px;  /* カード間の縦の間隔 */
  --gh-card-pad:      20px;
  --gh-tile:         152px;  /* カルーセルのタイル1枚 */
  --gh-tile-gap:      11px;
  --gh-stack-gap:     12px;  /* 縦積み型：文言と画像のあいだ */
  --gh-split-gap:     12px;  /* 左テキスト＋右レール型：文言と画像のあいだ */
  --gh-head-col:      28%;   /* 左テキスト＋右レール型の左カラム幅 */
  --gh-nav:           30px;  /* 左右スライドボタン */
  --gh-radius-sm:      8px;
  --gh-radius-md:     14px;

  /* --- 字 ------------------------------------------------- */
  /* 丸ゴシックはmacOS/iOSにしか無いので、Android/Windowsでは普通のゴシックに
     落ちる。タイトルロゴは画像にしたのでもう影響を受けない。ここが効くのは
     タイルに重ねる文字（.gh-tile__label）だけで、短い語なので落ちても許容する */
  --gh-font-display: "Hiragino Maru Gothic ProN", "ヒラギノ丸ゴ ProN W4",
                     "M PLUS Rounded 1c", "Rounded Mplus 1c", sans-serif;
  --gh-font-body:    "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Noto Sans JP",
                     "Yu Gothic Medium", "Meiryo", system-ui, sans-serif;
  /* タイトルロゴの表示幅。★ロゴの大小はこの1行で決める。
     高さは画像の縦横比（244:164）から自動で決まるので触らない。
     画像は2倍(488px)で書き出してあるので、ここを大きくするときは
     tools/make-logo.py の EXPORT_W も上げないとぼやける。 */
  --gh-logo-w:     244px;
  --gh-title-size: 19px;
  --gh-lead-size:  13.5px;  /* 12.5pxは小さすぎたので上げた。原本の実寸確認後に再検討 */

  /* CTAボタン。★せまい画面の収まりを決めているのはこの3つ
     ボタンは折り返さない（2行になると押せる範囲が割れて読みにくい）ので、
     必要な幅は「文字数 × 文字サイズ ＋ 左右の余白」で決まりきってしまう。
     ボタンはカードの細い左カラムに入るため、ここを大きくすると
     せまい画面で左カラムがレールを押しのける。
     tools/check.py が画面幅ごとにこの幅を計算して、
     左カラム・レール・タイルが成立しているかを見ている。 */
  --gh-btn-size:   13px;
  --gh-btn-pad-y:   8px;
  --gh-btn-pad-x:  13px;

  /* --- その他 --------------------------------------------- */
  --gh-ease: cubic-bezier(.2, .75, .25, 1);
  /* ガラスの粒子感。画像を持たずSVGフィルタで描く（リクエスト0・容量ほぼ0） */
  --gh-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23g)'/%3E%3C/svg%3E");
}


/* ============================================================
   2. 土台
   ============================================================ */
*, *::before, *::after{ box-sizing: border-box; }

html{
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body{
  margin: 0;
  min-height: 100vh;
  background: var(--gh-void);
  color: var(--gh-ink);
  font-family: var(--gh-font-body);
  font-feature-settings: "palt" 1;   /* 日本語の字間を詰める。地味だが効く */
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

img, svg{ display: block; max-width: 100%; }
img{ height: auto; }

a{ color: inherit; text-decoration: none; }

button{
  font: inherit;
  color: inherit;
  cursor: pointer;
}

h1, h2, p{ margin: 0; }

ul{ margin: 0; padding: 0; list-style: none; }

/* キーボード操作でどこにいるかが常に見えるようにする */
:focus-visible{
  outline: 2px solid var(--gh-cyan);
  outline-offset: 3px;
}

.gh-page{
  position: relative;
  max-width: var(--gh-page-max);
  margin-inline: auto;
}


/* ============================================================
   3. ユーティリティ
   ============================================================ */
/* 画面には出さず読み上げには残す */
.gh-sr{
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* キーボードで最初に来る「本文へスキップ」。フォーカスされるまで隠れている */
.gh-skip{
  position: fixed;
  top: 8px; left: 8px;
  z-index: 10;
  padding: 10px 16px;
  border-radius: var(--gh-radius-sm);
  background: var(--gh-paper);
  color: var(--gh-ink);
  font-size: 14px;
  font-weight: 700;
  transform: translateY(-160%);
  transition: transform .2s var(--gh-ease);
}
.gh-skip:focus-visible{ transform: none; }


/* ============================================================
   4. 背景の空　遠景と近景を分けて視差で動かす（奥行きの正体）
   ============================================================ */
.gh-sky{
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background: var(--gh-void);
}
.gh-sky > *{
  position: absolute;
  inset: -28%;              /* 視差でずれても端が見えないよう広く取る */
  will-change: transform;
}

/* 星雲。以前はCSSのグラデーションで描いていたが画像に変えた。
   理由: カードは半透明のすりガラスなのに、背後が真っ黒だと不透明度を何%にしても
   「グレーの塗り」に見えるだけでガラスにならない。透ける対象が必要。
   しかも backdrop-filter: blur() は blur半径より小さいものを消すので星は残らず、
   なめらかなグラデーションはぼかしても変化しない＝どちらもガラス感に効かない。
   残るのは「blur半径より大きいムラ」だけなので、そういうムラを持つ画像を敷く。
   色は原本の夜空に合わせて青系1系統のみ。いちばん明るい所でも rgb(40,58,88) 程度。
   小さい画像を拡大しているが、元からぼやけているので粗さは出ない（9KB）。 */
.gh-sky__nebula{
  background:
    url("../img/sky-glow.png") center / cover no-repeat,
    linear-gradient(180deg, var(--gh-deep), var(--gh-void) 62%);
}
/* 遠景：小さく敷いて「遠い」密度をつくる */
.gh-sky__far{
  background: url("../img/sky-far.png") repeat;
  background-size: 620px auto;
  opacity: .85;
}
/* 近景：等倍。こちらがよく動く */
.gh-sky__near{
  background: url("../img/sky-near.png") repeat;
  background-size: 900px auto;
}
/* 瞬く星。数を絞らないと安っぽくなるので16個だけ（app.js側で指定） */
.gh-sky__twinkle > i{
  position: absolute;
  width: 2px; height: 2px;
  border-radius: 50%;
  background: var(--gh-paper);
  opacity: .14;
  animation: gh-twinkle 5.5s ease-in-out infinite;
}


/* ============================================================
   5. ヒーロー
   ============================================================ */
.gh-hero{
  position: relative;
  padding: 56px var(--gh-gutter) 0;
  text-align: center;
}

/* マスコットが放つ光。下のカードにまで落ちる。
   幅は絶対に100%を超えさせない。絶対配置の要素が画面幅を超えると
   ページが横スクロールできる状態になり、全体が中央から外れて見える。
   （ここを 120% にしていてモバイルだけ左寄りになる不具合を出した） */
.gh-hero__glow{
  position: absolute;
  /* 中央寄せに transform も translate も使わない。
     transform はこの要素の立ち上げアニメーション（gh-rise）が使うので取り合いになる。
     単体の translate プロパティは2022年より古いブラウザに無く、効かないと
     この箱が右へ280pxずれて画面幅を超える＝直したはずの横はみ出しが再発する。
     left/right を0にして左右marginをautoにする書き方なら、どこでも中央に来る。 */
  left: 0; right: 0; top: -40px;
  width: min(560px, 100%);
  margin-left: auto; margin-right: auto;
  aspect-ratio: 1 / .72;
  background: radial-gradient(52% 52% at 62% 42%, rgba(159, 220, 233, .30), transparent 70%);
  filter: blur(24px);
  pointer-events: none;
}

.gh-hero__brand{
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 24px;
}

/* タイトルロゴは受領した素材の画像（黒い文字＋白いふち）。文字では組んでいない。
   ここでは大きさだけを決める。影やフィルタは足さない。 */
.gh-logo{
  margin: 0;
  /* 画像の高さは幅から自動で決まる（縦横比はHTMLのwidth/heightが持っている）。
     h1に line-height が付くと画像の下に余白が出るので0にする */
  line-height: 0;
}
.gh-logo img{
  display: block;
  width: var(--gh-logo-w);
  height: auto;
}

.gh-mascot{
  position: relative;
  flex: 0 0 auto;
  width: 92px;
  margin: 0;
}
/* マスコット背後の光は .gh-hero__glow に統合した。
   ここに置くと自分の箱を超える指定（inset:-34%）になり、
   せまい画面で同じ横はみ出しを起こす余地が残るため */
/* 白フチは画像に焼き込んである（tools/make-mascot.py）。
   太さを変えるときはCSSではなくスクリプト側の OUTLINE_RATIO を直す */
.gh-mascot img{
  position: relative;
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 10px 18px rgba(0, 0, 0, .55));
}

.gh-social{ position: relative; }
.gh-social ul{
  display: flex;
  justify-content: center;
  gap: 18px;
  margin-top: 34px;
}
/* 原本は白抜きの透過＝アイコンそのものが白で、下に白い台座は無い。
   箱を60pxのまま残しているのは指で押せる大きさを確保するため（見た目には出ない）。
   マークだけになると小さく見えるので、台座があったときの外形に近い大きさまで
   マークを大きくしている（52px。原本の実寸が判明したら合わせる） */
.gh-social a{
  display: grid;
  place-items: center;
  width: 60px; height: 60px;
  border-radius: 18px;
  transition: transform .2s var(--gh-ease), filter .2s var(--gh-ease);
}
.gh-social a:hover{
  transform: translateY(-3px);
  filter: drop-shadow(0 0 12px rgba(255, 255, 255, .55));
}
/* マークは外部SVG（assets/img/icons/）を <img> で読んでいる。
   <img> で読むと中身にCSSが届かないので、白はSVGファイル側に入れてある。
   色を変えたくなったらCSSではなくSVGを直す（検査もSVGから白を読む） */
.gh-social img{
  display: block;
  width: 52px; height: 52px;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, .55));
}


/* ============================================================
   6. カード　半透明グレー＋blur を本物のガラスとして扱う
      上端に反射、下端に内影、面に粒子、背後をぼかす
   ============================================================ */
.gh-card{
  position: relative;
  margin: var(--gh-card-gap) var(--gh-gutter) 0;
  padding: var(--gh-card-pad);
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: var(--gh-card-radius);
  background: var(--gh-glass);
  /* blur は 16px から下げた。半径を大きくすると背後のムラまで平らになり、
     せっかく半透明にしても「透けている」ことが見えなくなる。
     8px は星の点は消し（ちらつき防止）ムラは残る、という境目 */
  -webkit-backdrop-filter: blur(8px) saturate(118%);
  backdrop-filter: blur(8px) saturate(118%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .55),       /* 上端の反射 */
    inset 0 -18px 26px -20px rgba(0, 0, 0, .34),  /* 下端の内影 */
    0 22px 44px -22px rgba(0, 0, 0, .72);         /* 落ち影 */
  overflow: hidden;   /* 中身は必ずこの内側に収める */
}
/* ガラスの粒子感 */
.gh-card::after{
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--gh-grain);
  opacity: .04;   /* ガラスを明るくした分、粒子は薄くしないと文字がざらつく */
  mix-blend-mode: overlay;
  pointer-events: none;
}
/* カード自体はリンクではないので、hoverで浮かせない（押せると誤解させる） */

.gh-card__title{
  font-size: var(--gh-title-size);
  font-weight: 600;
  letter-spacing: .03em;
  line-height: 1.5;
  /* ページ内リンクの着地点。見出しを画面のいちばん上ぴったりに寄せると
     カードの上フチと余白が画面外に出て、飛んだ先が切れて見える。
     カードの内側の余白ぶんだけ手前で止める（ヘッダーは固定していないので
     どけるための値は要らない）。 */
  scroll-margin-top: calc(var(--gh-card-pad) + 12px);
}
/* 説明文の色は指定しない（body の --gh-ink をそのまま継ぐ）。
   ガラスが .60 だとカード面はいちばん暗い位置で #7E7F81 になり、
   ここで 4.5:1 を満たせる最も薄い灰色は #15181C＝見出しと見分けが付かない。
   つまり「見出しは黒、説明文は灰色」は成立しない不透明度。
   灰色で弱めるのをやめ、**大きさと太さだけで階層をつける**。
   （ガラスを .70 以上に戻すなら灰色の説明文も選べる。tools/check.py が下限を出す） */
.gh-card__lead{
  margin-top: 7px;
  font-size: var(--gh-lead-size);
  font-weight: 400;
  line-height: 1.75;
}

/* 縦積み型：最新動画 / ぐんショッピング
   文言と画像は「同じ話をしている一組」なので近づける。離すと別の塊に見える */
.gh-card--stack > * + *{ margin-top: var(--gh-stack-gap); }
.gh-card--stack .gh-card__lead{ margin-top: 7px; }

/* 左テキスト＋右レール型：公式グッズ / SUZURI / LINEスタンプ / GAME

   左カラムの幅を「--gh-head-col か、中身が必要とする幅か、大きいほう」にしている。
   割合だけで固定していたときは、せまい画面でCTAボタンが左カラムを越えて
   カードの外へ出ていた（カードは overflow:hidden なので切れて見える）。
   ボタンは折り返さないので必要な幅が端末のフォント次第で変わり
   （ヒラギノとAndroidの標準ゴシックで字幅が違う）、
   こちらで実測できない値に対して割合を固定すると必ずどこかで溢れる。
   minmax(min-content, X%) なら、入るときは X% を守り、
   入らないときだけ必要な分だけ広がる＝**構造としてはみ出しが起きない**。
   広がった分はレールが狭くなるだけで、タイルは必ずカードの内側に収まる。
   （狭くなりすぎていないかは tools/check.py が画面幅ごとに検算する）

   右は 1fr ではなく minmax(0,1fr)。1fr だけだとレールの中身の幅で
   右カラムが膨らんで崩れる。 */
.gh-card--split{
  display: grid;
  grid-template-columns: minmax(min-content, var(--gh-head-col)) minmax(0, 1fr);
  gap: var(--gh-split-gap);
  align-items: center;
}
.gh-card--split > .gh-card__head{ align-self: start; }


/* ============================================================
   7. ボタン
   ============================================================ */
/* すきまと矢印は px ではなく em で持つ。文字サイズを下げたときに
   px のままだと余白と矢印の比率だけが上がり、字を小さくした分が
   幅に返ってこない（＝せまい画面で縮めた意味がなくなる）。 */
.gh-btn{
  display: inline-flex;
  align-items: center;
  gap: .38em;
  margin-top: 13px;
  padding: var(--gh-btn-pad-y) var(--gh-btn-pad-x);
  border: 1px solid rgba(0, 0, 0, .14);
  border-radius: var(--gh-radius-sm);
  background: linear-gradient(180deg, var(--gh-cyan-lit), var(--gh-cyan));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7), 0 3px 8px -3px rgba(0, 0, 0, .4);
  font-size: var(--gh-btn-size);
  font-weight: 700;
  letter-spacing: .02em;
  /* 折り返さない。2行になると押せる範囲が割れて、ボタンに見えなくなる。
     そのぶん幅は中身で決まりきるので、収まりは .gh-card--split 側で受ける */
  white-space: nowrap;
  transition: transform .18s var(--gh-ease), box-shadow .18s var(--gh-ease),
              filter .18s var(--gh-ease);
}
.gh-btn::after{
  content: "▶";
  font-size: .7em;
  translate: 0 .5px;
}
.gh-btn:hover{
  transform: translateY(-1px);
  filter: brightness(1.04);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .8), 0 8px 16px -6px rgba(0, 0, 0, .5);
}
.gh-btn:active{ transform: translateY(0); }


/* ============================================================
   8. 最新動画
   ============================================================ */
/* 埋め込みの枠。中身は次のどちらかで、どちらでも大きさはこの枠が決める。
     ・YouTubeでコピーした <iframe>（本番）
     ・仮のサムネイル <a class="gh-video">（素材待ちのあいだ）
   枠を別に立ててあるのは、担当者が貼り替えるのが「中身」だけになるようにするため。 */
.gh-embed{
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 12px;
  background: var(--gh-void);
  box-shadow: 0 10px 24px -14px rgba(0, 0, 0, .7), inset 0 0 0 1px rgba(0, 0, 0, .08);
}
/* YouTubeがコピーするコードには width="560" height="315" が付いてくる。
   担当者に数字を直させないため、ここで枠いっぱいに上書きする。
   角丸をiframe自身にも掛けるのは、Safariが親の overflow で中の枠を切り抜けないため。 */
.gh-embed > iframe{
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  border: 0;                    /* frameborder="0" が付いていない形で貼られても枠が出ない */
  border-radius: inherit;
}
.gh-video{                      /* 素材待ちのあいだの仮のサムネイル */
  position: absolute;
  inset: 0;
  display: block;
}
.gh-video img{
  width: 100%; height: 100%;
  object-fit: cover;
}
/* ごく浅い周辺減光。写真の締まりが出る */
.gh-video::after{
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 100% at 50% 40%, transparent 52%, rgba(0, 0, 0, .24));
  pointer-events: none;
}
.gh-video__play{
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 74px; height: 74px;
  margin: auto;
  border-radius: 50%;
  background: rgba(8, 10, 14, .84);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .22), 0 16px 30px -12px rgba(0, 0, 0, .7);
  transition: transform .25s var(--gh-ease), box-shadow .25s var(--gh-ease);
}
.gh-video__play::before{      /* ▶ を三角形で描く（フォント依存にしない） */
  content: "";
  width: 0; height: 0;
  margin-left: 6px;
  border-style: solid;
  border-width: 13px 0 13px 21px;
  border-color: transparent transparent transparent var(--gh-paper);
}
.gh-video:hover .gh-video__play{
  transform: scale(1.07);
  box-shadow:
    0 0 0 2px var(--gh-cyan),
    0 0 30px -2px rgba(159, 220, 233, .55),
    0 18px 34px -12px rgba(0, 0, 0, .75);
}


/* ============================================================
   9. ぐんショッピング
   ============================================================ */
.gh-goods{
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gh-tile-gap);
}
.gh-goods a{
  display: block;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  border-radius: var(--gh-radius-sm);
  background: var(--gh-paper);
  /* ガラスを明るくしたので、白い商品枠は輪郭線が無いとカードに溶ける */
  box-shadow: inset 0 0 0 1px var(--gh-hairline), 0 6px 14px -10px rgba(0, 0, 0, .6);
  transition: transform .22s var(--gh-ease), box-shadow .22s var(--gh-ease);
}
.gh-goods img{
  width: 100%; height: 100%;
  object-fit: contain;
  transition: transform .35s var(--gh-ease);
}
.gh-goods a:hover{
  transform: translateY(-4px);
  box-shadow: inset 0 0 0 1px var(--gh-hairline), 0 14px 22px -12px rgba(0, 0, 0, .7);
}
.gh-goods a:hover img{ transform: scale(1.05); }


/* ============================================================
  10. カルーセル
      ・タイルはカードの内側に必ず収める（はみ出させない）
      ・指のスワイプはCSSのscroll-snapだけで動く。JSは不要
      ・左右ボタンはレールの下に置く。タイルに重ねるとリンクを覆うため
   ============================================================ */
.gh-carousel{
  position: relative;
  min-width: 0;     /* grid内で中身の幅に押し広げられないための保険 */
}

.gh-rail{
  display: flex;
  gap: var(--gh-tile-gap);
  overflow-x: auto;
  overscroll-behavior-x: contain;   /* 端まで来てもページごと動かない */
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.gh-rail::-webkit-scrollbar{ display: none; }
.gh-rail > li{
  flex: 0 0 var(--gh-tile);
  scroll-snap-align: start;
}

.gh-tile{
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  border-radius: var(--gh-radius-md);
  /* 平らな面ではなく、左上から光が当たった物として塗る */
  background: radial-gradient(118% 118% at 22% 12%,
              var(--gh-cyan-lit) 0%, var(--gh-cyan) 48%, var(--gh-cyan-deep) 100%);
  box-shadow:
    inset 0 0 0 1px var(--gh-hairline),          /* 明るいカードとの境目 */
    inset 0 1px 0 rgba(255, 255, 255, .55),
    0 8px 18px -12px rgba(0, 0, 0, .7);
  transition: transform .22s var(--gh-ease), box-shadow .22s var(--gh-ease);
}
.gh-tile img{
  width: 100%; height: 100%;
  object-fit: contain;
}
.gh-tile:hover{
  transform: translateY(-4px);
  box-shadow:
    inset 0 0 0 1px var(--gh-hairline),
    inset 0 1px 0 rgba(255, 255, 255, .65),
    0 16px 26px -12px rgba(0, 0, 0, .75);
}
.gh-tile__label{
  position: absolute;
  inset: auto 0 13%;
  text-align: center;
  color: #111418;
  font-family: var(--gh-font-display);
  font-size: 23px;
  font-weight: 800;
  letter-spacing: .05em;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .4);
}

/* 10-a. 操作列：スクロール位置の目安＋左右ボタン */
.gh-carousel__ctrl{
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 13px;
}
/* 操作列はカードの上に乗る。カードを明るくしたので、
   ここを白系にすると背景と同化して「操作できる物」に見えない。
   白＝1.0 対 カード面≒#A1A2A5 は 2.6:1 で、UI部品の下限3:1を下回る。
   ぶら下げる色を黒側へ振って 4.5:1 以上を確保した。 */
.gh-carousel__bar{
  position: relative;
  flex: 1 1 auto;
  height: 3px;
  border-radius: 2px;
  background: var(--gh-hairline);
  cursor: pointer;                     /* 押すとその位置へ飛ぶ */
  touch-action: manipulation;          /* 二度押しの拡大を待たずに反応する */
}
/* 押せる範囲を上下に広げる。見た目は3pxのまま、当たり判定だけ25px。
   指で押せる最小は24px前後で、3pxのままだと狙って押せない。
   ここを広げるために親の overflow: hidden を外してあるので、
   つまみが端からはみ出さないよう app.js 側で 0〜1 に丸めている。 */
.gh-carousel__bar::before{
  content: "";
  position: absolute;
  inset: -11px 0;
}
.gh-carousel__bar > span{
  position: absolute;
  inset: 0 auto 0 0;
  width: 100%;
  border-radius: 2px;
  background: rgba(20, 22, 26, .75);   /* カード面に対して 4.5:1 */
  pointer-events: none;                /* つまみを押しても親が受ける */
}

.gh-nav{
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: var(--gh-nav); height: var(--gh-nav);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--gh-ink);           /* カード面に対して 7.4:1 */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .18),
    0 4px 10px -3px rgba(0, 0, 0, .45);
  transition: opacity .2s var(--gh-ease), transform .16s var(--gh-ease),
              background .16s var(--gh-ease);
}
.gh-nav::before{             /* 矢印。フォントに頼らず罫線で描く */
  content: "";
  width: 7px; height: 7px;
  border-top: 2px solid var(--gh-paper);
  border-right: 2px solid var(--gh-paper);
}
.gh-nav--prev::before{ transform: translateX(1px) rotate(-135deg); }
.gh-nav--next::before{ transform: translateX(-1px) rotate(45deg); }
.gh-nav:hover:not([disabled]){ background: #33383F; }
.gh-nav:active:not([disabled]){ transform: scale(.92); }
/* 端まで来たボタンは消さずに薄くする（消すと列の幅が動いてちらつく） */
.gh-nav[disabled]{
  opacity: .34;
  cursor: default;
}

/* タイルが全部見えていて横スクロールが要らないときは操作列を出さない */
.gh-carousel.is-static .gh-carousel__ctrl{ display: none; }
/* JSが無い環境ではボタンが動かないので出さない（スワイプだけで使える） */
html:not(.js) .gh-carousel__ctrl{ display: none; }


/* ============================================================
  11. フッター
   ============================================================ */
.gh-foot{
  margin-top: 56px;
  padding: 0 var(--gh-gutter) 40px;
  /* .38/11px は暗い背景に対して 3.5:1 しか出ておらず本文基準を下回っていた */
  color: rgba(255, 255, 255, .62);
  font-size: 12px;
  letter-spacing: .06em;
  text-align: center;
}


/* ============================================================
  12. モーション
      読み込み時に一度だけ順番に立ち上げ、以降はスクロールで静かに現れる。
      派手さは「無重力に漂うマスコット」の1点に集中させ、他は動かさない。
   ============================================================ */
@keyframes gh-rise{
  from{ opacity: 0; transform: translateY(18px); }
  to  { opacity: 1; transform: none; }
}
@keyframes gh-drift-in{
  from{ opacity: 0; transform: translateY(26px) scale(.9) rotate(-8deg); }
  to  { opacity: 1; transform: translateY(0) scale(1) rotate(-2deg); }
}
@keyframes gh-float{
  0%  { transform: translateY(0) rotate(-2deg); }
  50% { transform: translateY(-10px) rotate(2.5deg); }
  100%{ transform: translateY(0) rotate(-2deg); }
}
@keyframes gh-twinkle{
  0%, 100%{ opacity: .12; transform: scale(1); }
  50%     { opacity: .90; transform: scale(1.7); }
}

/* JSが無い環境では何も隠さない（= そのまま全部見える） */
/* ロゴが文字だったころは3行を .10 / .20 / .30s とずらして立ち上げていた。
   画像は1枚なのでまとめて上げる。3行ばらばらに動かすには画像を3枚に切る
   必要があり、素材の差し替えのたびに切り直しが発生するのでやらない */
.js .gh-logo{ animation: gh-rise .8s var(--gh-ease) .10s both; }
.js .gh-hero__glow{ animation: gh-rise 1.6s ease-out .2s both; }
.js .gh-mascot{ animation: gh-drift-in 1s var(--gh-ease) .38s both; }
.js .gh-mascot img{ animation: gh-float 7s ease-in-out 1.4s infinite; }
.js .gh-social li{ animation: gh-rise .7s var(--gh-ease) both; }
.js .gh-social li:nth-child(1){ animation-delay: .62s; }
.js .gh-social li:nth-child(2){ animation-delay: .70s; }
.js .gh-social li:nth-child(3){ animation-delay: .78s; }

.js .gh-reveal{
  opacity: 0;
  transform: translateY(20px);
  transition: opacity .75s var(--gh-ease), transform .75s var(--gh-ease);
}
.js .gh-reveal.is-visible{
  opacity: 1;
  transform: none;
}


/* ============================================================
  13. せまい画面　値だけ差し替える（レイアウトの形は変えない）
      2段ある。
        13-a  600px以下 … タブレット縦〜大きめのスマホ。余白だけ詰める
        13-b  400px以下 … iPhone SE 前後。文字も下げる
   ============================================================ */
/* 13-a */
@media (max-width: 600px){
  :root{
    --gh-gutter:      16px;
    --gh-card-gap:    26px;
    --gh-card-pad:    16px;
    --gh-card-radius: 17px;
    --gh-logo-w:     189px;
    --gh-title-size:  17px;
    --gh-tile:       124px;
    --gh-head-col:    33%;
    --gh-nav:         26px;
    /* 本文サイズはここで下げない。せまい画面ほど読みづらくなるので、
       文字は据え置いて余白だけ詰める */
  }
  .gh-hero{ padding-top: 38px; }
  .gh-hero__brand{ gap: 15px; }
  .gh-mascot{ width: 70px; }
  .gh-social ul{ margin-top: 26px; gap: 15px; }
  .gh-social a{ width: 53px; height: 53px; border-radius: 16px; }
  .gh-social img{ width: 46px; height: 46px; }
  .gh-tile__label{ font-size: 19px; }
}

/* 13-b  iPhone SE 前後（375px）以下。
   ここだけ**文字サイズも下げる**段にしている。13-a では余白しか詰めていないが、
   この幅ではカードの内側が 270〜320px しかなく、左右2カラムに割ると
   左カラムが 100〜120px になる。そこに次の2つが入らなくなる。
     ・見出し「今週のぐんショッピングのアイテム」は16文字。
       17pxだと272px要るので、320px端末では1行に収まらない
     ・折り返さないCTAボタン（「ショップを見る▶」）
   下げるのは**短くて幅を決めている要素＝見出しとボタン**だけ。
   説明文（--gh-lead-size）は読む文章なので下げない。
   せまい画面ほど読みづらくなるので、ここを削るのは順序が逆。 */
@media (max-width: 400px){
  :root{
    --gh-gutter:      13px;
    --gh-card-pad:    14px;
    --gh-title-size:  16px;
    --gh-btn-size:    12px;
    --gh-btn-pad-y:    7px;
    --gh-btn-pad-x:   10px;
    --gh-tile:       104px;
    --gh-tile-gap:     9px;
    --gh-head-col:    38%;   /* 割合は上げる。左カラムが必要幅で押し広がる前に、
                                最初から必要な分を渡しておくほうがレールが読める */
    --gh-split-gap:   10px;
  }
  .gh-btn{ margin-top: 10px; }
  /* タイルが124→104pxに小さくなるので、重ねる文字も同じ比率で下げる */
  .gh-tile__label{ font-size: 17px; }
}


/* ============================================================
  14. 動きを減らす設定を尊重する
      OS側で「視差効果を減らす」を選んでいる人には演出を止める。
      止めたときに .gh-reveal が透明のまま残ると本文が読めなくなるので、
      表示状態を確実に上書きする必要がある。ここだけ !important を使う。
   ============================================================ */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto; }

  .gh-sky__twinkle{ display: none; }

  .js .gh-logo,
  .js .gh-hero__glow,
  .js .gh-mascot,
  .js .gh-mascot img,
  .js .gh-social li{
    animation: none;
  }

  .js .gh-reveal{
    opacity: 1 !important;
    transform: none !important;
    transition: none;
  }

  .gh-btn, .gh-nav, .gh-tile, .gh-goods a, .gh-goods img,
  .gh-social a, .gh-video__play, .gh-skip{
    transition: none;
  }
}
