/* ===== Portfolio Gate — CodePen CSS ===== */
/* Gen Interface JP Display（yamatoiizuka / SIL OFL 1.1）
   外部CDN（jsDelivr）に依存せず、fonts/ フォルダに置いた実ファイルを
   相対パスで参照している（同じサーバーからHTML/CSSと一緒に配信され、
   ブラウザに個別キャッシュされる）。このページで使う文字（A-Z a-z 0-9 #）
   だけをカバーする3サブセット×2ウェイト（500/700）の計6ファイル、
   合計約128KB。fonts/ フォルダごとアップロードすること。 */
@font-face{
  font-family:"Gen Interface JP Display";
  font-weight:500;
  font-style:normal;
  font-display:swap;
  unicode-range:U+23;
  src:url("fonts/gen-500-symbol.woff2") format("woff2");
}
@font-face{
  font-family:"Gen Interface JP Display";
  font-weight:500;
  font-style:normal;
  font-display:swap;
  unicode-range:U+4E;
  src:url("fonts/gen-500-n.woff2") format("woff2");
}
@font-face{
  font-family:"Gen Interface JP Display";
  font-weight:500;
  font-style:normal;
  font-display:swap;
  unicode-range:U+30-39,U+41-4D,U+4F-5A,U+61-7A;
  src:url("fonts/gen-500-latin.woff2") format("woff2");
}
@font-face{
  font-family:"Gen Interface JP Display";
  font-weight:700;
  font-style:normal;
  font-display:swap;
  unicode-range:U+23;
  src:url("fonts/gen-700-symbol.woff2") format("woff2");
}
@font-face{
  font-family:"Gen Interface JP Display";
  font-weight:700;
  font-style:normal;
  font-display:swap;
  unicode-range:U+4E;
  src:url("fonts/gen-700-n.woff2") format("woff2");
}
@font-face{
  font-family:"Gen Interface JP Display";
  font-weight:700;
  font-style:normal;
  font-display:swap;
  unicode-range:U+30-39,U+41-4D,U+4F-5A,U+61-7A;
  src:url("fonts/gen-700-latin.woff2") format("woff2");
}

/* ネオンペインティングで漂う「OKUYAMA」「TAIKI」用フォント3種（いずれもGoogle Fonts、
   SIL OFL 1.1、Fontsource経由でA-Zラテン文字をカバーするサブセットのみ取得）。
   文字が生まれるたびにこの中からランダムに1書体を選ぶ。 */
@font-face{
  font-family:"Quicksand";
  font-weight:400;
  font-style:normal;
  font-display:swap;
  src:url("fonts/quicksand-400.woff2") format("woff2");
}
@font-face{
  font-family:"Single Day";
  font-weight:400;
  font-style:normal;
  font-display:swap;
  unicode-range:U+39,U+49,U+4D-4E;
  src:url("fonts/single-day-400-a.woff2") format("woff2");
}
@font-face{
  font-family:"Single Day";
  font-weight:400;
  font-style:normal;
  font-display:swap;
  unicode-range:U+20-22,U+27-2A,U+2C-38,U+3A-3B,U+3F,U+41-47,U+4A-4C,U+4F-5D,U+61-7B,U+7D;
  src:url("fonts/single-day-400-b.woff2") format("woff2");
}
@font-face{
  font-family:"Yuji Hentaigana Akebono";
  font-weight:400;
  font-style:normal;
  font-display:swap;
  unicode-range:U+21-22,U+27-3B,U+3F,U+41-4D,U+4F-5D,U+61-7B,U+7D;
  src:url("fonts/yuji-hentaigana-akebono-400.woff2") format("woff2");
}

/* 「奥山太貴」用フォント2種（いずれもGoogle Fonts、SIL OFL 1.1）。
   奥・山・太・貴の4文字だけをカバーするサブセットを1文字ずつ取得。
   この単語が生まれるときだけ、文字ごとにこの2書体からランダムに選ぶ。 */
@font-face{
  font-family:"Zen Maru Gothic";
  font-weight:400;
  font-style:normal;
  font-display:swap;
  unicode-range:U+5965;
  src:url("fonts/zen-maru-gothic-400-oku.woff2") format("woff2");
}
@font-face{
  font-family:"Zen Maru Gothic";
  font-weight:400;
  font-style:normal;
  font-display:swap;
  unicode-range:U+8cb4;
  src:url("fonts/zen-maru-gothic-400-ki.woff2") format("woff2");
}
@font-face{
  font-family:"Zen Maru Gothic";
  font-weight:400;
  font-style:normal;
  font-display:swap;
  unicode-range:U+592a;
  src:url("fonts/zen-maru-gothic-400-ta.woff2") format("woff2");
}
@font-face{
  font-family:"Zen Maru Gothic";
  font-weight:400;
  font-style:normal;
  font-display:swap;
  unicode-range:U+5c71;
  src:url("fonts/zen-maru-gothic-400-yama.woff2") format("woff2");
}
@font-face{
  font-family:"Hachi Maru Pop";
  font-weight:400;
  font-style:normal;
  font-display:swap;
  unicode-range:U+5965;
  src:url("fonts/hachi-maru-pop-400-oku.woff2") format("woff2");
}
@font-face{
  font-family:"Hachi Maru Pop";
  font-weight:400;
  font-style:normal;
  font-display:swap;
  unicode-range:U+8cb4;
  src:url("fonts/hachi-maru-pop-400-ki.woff2") format("woff2");
}
@font-face{
  font-family:"Hachi Maru Pop";
  font-weight:400;
  font-style:normal;
  font-display:swap;
  unicode-range:U+592a;
  src:url("fonts/hachi-maru-pop-400-ta.woff2") format("woff2");
}
@font-face{
  font-family:"Hachi Maru Pop";
  font-weight:400;
  font-style:normal;
  font-display:swap;
  unicode-range:U+5c71;
  src:url("fonts/hachi-maru-pop-400-yama.woff2") format("woff2");
}

:root{
  --gate-duration: .36s;                        /* パネル拡縮の時間 */
  --gate-ease: cubic-bezier(.25, .6, .25, 1);   /* 序盤から目に見えて動き、後半で丁寧に収まる */
  --filter-duration: .36s;                      /* 明るさ変化も同じ時間・同じ質感に揃える */
  --gate-pad: clamp(22px, 2.6vw, 40px);         /* パネル内余白 */
}

*, *::before, *::after { box-sizing: border-box; }

/* iframe の固定高さに追従するため 100vh は使わず height:100% 基準 */
html, body{
  margin: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

body{
  font-family: "Gen Interface JP Display", Helvetica, Arial, sans-serif;
  background: #000;
  color: #fff;
  -webkit-tap-highlight-color: transparent;
}

.visually-hidden{
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

/* ---------------- Gate ---------------- */

.portfolio-gate{
  position: relative;
  display: flex;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #000;
}

/* ネオンペインティング用canvas。両パネルにまたがる1枚。
   video(暗黙のz-index)より上、.gate-panel__inner(z-index:2)より下に置き、
   線がタイトル・タグの上に被って読みにくくならないようにする。
   pointer-events:none でクリック・ホバーは常に下のパネルへ通す。 */
#neon-paint{
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* PCに加えてタッチ環境でも動作する。reduced-motionでは初期化自体を
   JS側でスキップするが、念のため万一表示されても隠す */
@media (prefers-reduced-motion: reduce){
  #neon-paint{ display: none; }
}

.gate-panel{
  position: relative;
  display: block;
  height: 100%;
  flex: 0 0 50%;
  min-width: 0;
  overflow: hidden;
  background: #08080c;           /* 動画・poster 読み込み前のフォールバック */
  color: #fff;
  text-decoration: none;
  outline: none;
  user-select: none;
  -webkit-user-select: none;
  transition: flex-basis var(--gate-duration) var(--gate-ease);
}

.gate-panel__video{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;             /* 幅変化時は中央基準でトリミング */
  pointer-events: none;
  filter: brightness(.72) contrast(1.05);   /* 通常時：黒オーバーレイではなく filter で少し暗く */
  transition: filter var(--filter-duration) var(--gate-ease);
}

.gate-panel__inner{
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  max-width: 100%;
  padding: var(--gate-pad);
  pointer-events: none;
}

.gate-panel__title{
  margin: 0;
  font-size: clamp(28px, 3vw, 46px);
  font-weight: 700;
  letter-spacing: .04em;
  line-height: 1;
  text-shadow: 0 2px 18px rgba(0, 0, 0, .45);
}

/* タイトルの1文字ずつデコード演出（JS側で <span class="char"> に分解して駆動） */
.gate-panel__title .char{
  display: inline-block;
  /* 幅は JS 側で最終文字の実測幅を固定して渡す（プロポーショナルフォントで
     ランダム文字を入れ替えると文字ごとに幅が違いガタつくため、確定文字の
     幅で先に固定してグリフだけが入れ替わるようにしている） */
}

.gate-panel__title .char.decoding{
  opacity: .5;
}

.gate-panel__title .char.settled{
  animation: char-settle .34s cubic-bezier(.2, .8, .3, 1);
}

/* ネオン管が1本ずつ灯るように、確定した瞬間だけ一瞬強く発光してから馴染む */
@keyframes char-settle{
  0%   { opacity: .5;  transform: scale(1.08); text-shadow: 0 0 18px rgba(255, 255, 255, .9); }
  55%  { opacity: 1;   transform: scale(1);    text-shadow: 0 0 10px rgba(255, 255, 255, .5); }
  100% { opacity: 1;   transform: scale(1);    text-shadow: 0 2px 18px rgba(0, 0, 0, .45); }
}

.gate-panel__tags{
  margin: 14px 0 0;
  font-size: clamp(10px, .82vw, 12px);
  font-weight: 500;
  letter-spacing: .03em;
  line-height: 1.4;
  opacity: .95;
  text-shadow: 0 2px 18px rgba(0, 0, 0, .45);
}

.gate-panel__tags span{ display: block; }

/* ハッシュタグの入場演出（タイトルのデコードが終わった直後に、1行ずつ
   下からふっと立ち上がる。JS側で各 span に transition-delay を振り、
   .revealed クラスで一斉にトリガーする） */
@media (prefers-reduced-motion: no-preference){
  .gate-panel__tags span{
    opacity: 0;
    transform: translateY(7px);
    transition: opacity .38s ease, transform .38s cubic-bezier(.22, .8, .28, 1);
  }
  .gate-panel__tags.revealed span{
    opacity: 1;
    transform: translateY(0);
  }
}

/* ---------------- Hover（PC・マウス環境のみ） ---------------- */

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference){
  .portfolio-gate:hover .gate-panel{ flex-basis: 30%; }
  .portfolio-gate .gate-panel:hover{ flex-basis: 70%; }

  .gate-panel:hover .gate-panel__video{
    filter: brightness(1) contrast(1.08) saturate(1.05);
  }

  /* 縮んだ側は filter のみで沈める（参考画像準拠・黒オーバーレイ不使用） */
  .portfolio-gate:hover .gate-panel:not(:hover) .gate-panel__video{
    filter: brightness(.45) contrast(1.02) saturate(.85);
  }
}

/* キーボードフォーカス時もホバー同等に開く（:has 非対応ブラウザでは無視される） */
@media (prefers-reduced-motion: no-preference){
  .portfolio-gate:has(.gate-panel:focus-visible) .gate-panel{ flex-basis: 30%; }
  .portfolio-gate .gate-panel:focus-visible{ flex-basis: 70%; }
  .gate-panel:focus-visible .gate-panel__video{
    filter: brightness(1) contrast(1.08) saturate(1.05);
  }
}

.gate-panel:focus-visible::after{
  content: "";
  position: absolute;
  inset: 10px;
  z-index: 3;
  border: 1px solid rgba(255, 255, 255, .55);
  pointer-events: none;
}

/* ---------------- スマホ：上下2分割・サイズ変化なし ---------------- */

@media (max-width: 768px){
  .portfolio-gate{ flex-direction: column; }

  .gate-panel{
    width: 100%;
    flex-basis: 50%;
  }

  .portfolio-gate:hover .gate-panel,
  .portfolio-gate .gate-panel:hover{ flex-basis: 50%; }
}

/* :has を含むため別ブロック（非対応ブラウザで上のルールまで無効化されないように） */
@media (max-width: 768px){
  .portfolio-gate:has(.gate-panel:focus-visible) .gate-panel,
  .portfolio-gate .gate-panel:focus-visible{ flex-basis: 50%; }
}

/* ---------------- ローディング（毎回表示） ---------------- */

.loader{
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
  transition: opacity .6s ease;
}

.loader.is-hidden{
  opacity: 0;
  pointer-events: none;
}

/* ---------------- 遷移時のホワイトアウト ---------------- */

.gate-transition-veil{
  position: fixed;
  inset: 0;
  z-index: 200;              /* ローダー(z-index:100)より前面 */
  background: #fff;
  opacity: 0;
  pointer-events: none;
  transition: opacity .26s ease;
}

.gate-transition-veil.is-active{
  opacity: 1;
  pointer-events: all;       /* 遷移中は下の操作を受け付けない */
}

@media (prefers-reduced-motion: reduce){
  .gate-transition-veil{ transition: none; }
}

.loader__logo{
  width: min(300px, 56vw);
  height: auto;
  animation:
    neon-ignite 1.35s linear both,
    neon-idle 2.8s ease-in-out 1.35s infinite;
}

/* 暗い → 一瞬強く光る → 落ちる → 不安定に揺れる → 安定 */
@keyframes neon-ignite{
  0%   { opacity: .05; filter: brightness(.55) drop-shadow(0 0 0 rgba(255,255,255,0)); }
  5%   { opacity: .05; filter: brightness(.55) drop-shadow(0 0 0 rgba(255,255,255,0)); }
  11%  { opacity: 1;   filter: brightness(1.8)  drop-shadow(0 0 30px rgba(255,255,255,.85)); }
  16%  { opacity: .2;  filter: brightness(.75)  drop-shadow(0 0 3px  rgba(255,255,255,.12)); }
  22%  { opacity: .85; filter: brightness(1.15) drop-shadow(0 0 12px rgba(255,255,255,.4)); }
  27%  { opacity: .3;  filter: brightness(.8)   drop-shadow(0 0 4px  rgba(255,255,255,.12)); }
  33%  { opacity: 1;   filter: brightness(1.4)  drop-shadow(0 0 20px rgba(255,255,255,.6)); }
  41%  { opacity: .55; filter: brightness(.9)   drop-shadow(0 0 8px  rgba(255,255,255,.25)); }
  49%  { opacity: .95; filter: brightness(1.2)  drop-shadow(0 0 16px rgba(255,255,255,.5)); }
  57%  { opacity: .72; filter: brightness(1)    drop-shadow(0 0 10px rgba(255,255,255,.3)); }
  68%  { opacity: 1;   filter: brightness(1.18) drop-shadow(0 0 16px rgba(255,255,255,.45)); }
  82%  { opacity: .93; filter: brightness(1.08) drop-shadow(0 0 13px rgba(255,255,255,.38)); }
  100% { opacity: 1;   filter: brightness(1.06) drop-shadow(0 0 14px rgba(255,255,255,.35)); }
}

/* 安定後のごく弱い呼吸 */
@keyframes neon-idle{
  0%, 100% { filter: brightness(1.06) drop-shadow(0 0 14px rgba(255,255,255,.35)); }
  50%      { filter: brightness(1.14) drop-shadow(0 0 18px rgba(255,255,255,.48)); }
}

/* ---------------- prefers-reduced-motion ---------------- */

@media (prefers-reduced-motion: reduce){
  .gate-panel,
  .gate-panel__video,
  .loader{ transition: none; }

  .loader__logo{
    animation: none;
    opacity: 1;
    filter: brightness(1.06) drop-shadow(0 0 14px rgba(255,255,255,.35));
  }
}
