/* scenes.css — 各シーンの見た目と演出（--p だけを見る）
 *
 * 子要素のずらしは --i（0,1,2…）と局所進行度 --lp で表す:
 *   --lp = clamp(0, (--p - --i * step) / span, 1)
 * 動かすのは transform / opacity / clip-path のみ。
 */

/* ── 0. Hero ─────────────────────────────────────────────── */
.hero {
  min-height: 100svh;
  display: grid;
  place-items: center;
  text-align: center;
  padding-top: 20vh;
}
.hero__inner {
  /* スクロールで抜けるときは --p（exit）で薄く・小さく */
  opacity: calc(1 - var(--p) * 1.4);
  transform: translate3d(0, calc(var(--p) * -12vh), 0) scale(calc(1 - var(--p) * 0.08));
}
.wordmark {
  /* ロゴは PDF（ベクター原本）から起こした PNG。ダーク背景に載せるため、
     黒い部分だけを白へ置き換えてある（ゴールドはブランド色のまま） */
  width: min(88vw, 46rem);
  margin-inline: auto;
  line-height: 0;
}
.wordmark__img {
  width: 100%;
  height: auto;
  /* 左（マーク）から右（ロゴタイプ）へ順に現れる。
     1枚画像なので、clip-path で見せる範囲を広げるだけで自然な順番になる */
  animation: logo-wipe 1.5s cubic-bezier(0.22, 0.7, 0.2, 1) 0.25s both;
  will-change: clip-path, opacity;
}
@keyframes logo-wipe {
  0%   { clip-path: inset(0 100% 0 0); opacity: 0; }
  15%  { opacity: 1; }
  100% { clip-path: inset(0 0 0 0); opacity: 1; }
}

.hero__sub {
  margin-top: 2rem;
  color: var(--fg-dim);
  letter-spacing: 0.08em;
  font-size: 0.95rem;
  animation: fade-up 0.9s ease-out 0.9s both;
}
.hero__est { font-family: var(--font-mono); color: var(--gold-lit); }
.hero__lead {
  margin-top: 0.75rem;
  color: var(--fg);
  animation: fade-up 0.9s ease-out 1.1s both;
}
@keyframes fade-up {
  from { opacity: 0; transform: translate3d(0, 12px, 0); }
  to   { opacity: 1; transform: none; }
}
.hero__cue {
  position: absolute;
  left: 50%;
  bottom: 2.5rem;
  width: 1px; height: 56px;
  background: var(--line);
  overflow: hidden;
  opacity: calc(1 - var(--p) * 3);
}
.hero__cue span {
  display: block;
  width: 100%; height: 40%;
  background: var(--accent-2);
  animation: cue 1.8s ease-in-out infinite;
}
@keyframes cue { from { transform: translateY(-100%); } to { transform: translateY(260%); } }

/* ── 1. Manifesto ────────────────────────────────────────── */
.manifesto { text-align: center; }
.manifesto__text {
  font-size: clamp(1.8rem, 1rem + 4vw, 4.2rem);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.01em;
}
.manifesto__note {
  margin-top: 1.5rem;
  color: var(--fg-dim);
  font-size: clamp(0.95rem, 0.9rem + 0.4vw, 1.15rem);
}
.line {
  display: block;
  overflow: hidden;
  clip-path: inset(-0.2em 0 -0.25em 0);
  --lp: clamp(0, calc((var(--p) - var(--i) * 0.14) / 0.42), 1);
}
.line__in {
  display: inline-block;
  transform: translate3d(0, calc((1 - var(--lp)) * 110%), 0);
  opacity: var(--lp);
}

/* ── 2. コード自動タイピング（目玉A） ─────────────────────── */
.typing {
  /* sticky で固定し、この高さぶんのスクロールで 0→1 */
  min-height: 320vh;
  padding-top: 0; padding-bottom: 0;
  max-width: none;
}
.typing__sticky {
  position: sticky;
  top: 0;
  min-height: 100svh;
  display: grid;
  align-content: center;
  gap: 1.5rem;
  padding: 4.5rem var(--gutter) 2.5rem;
  max-width: 72rem;
  margin-inline: auto;
}
.typing .scene__title {
  font-size: clamp(1.4rem, 1.1rem + 1.5vw, 2.1rem);
  margin-bottom: 0;
  --lp: clamp(0, calc(var(--p) / 0.12), 1);
  opacity: var(--lp);
  transform: translate3d(0, calc((1 - var(--lp)) * 20px), 0);
}
.editor {
  --lp: clamp(0, calc((var(--p) - 0.04) / 0.14), 1);
  opacity: var(--lp);
  transform: translate3d(0, calc((1 - var(--lp)) * 32px), 0) scale(calc(0.96 + var(--lp) * 0.04));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.05);
  overflow: hidden;
  max-width: 62rem;
}
.editor__bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--fg-faint);
}
.editor__dot { width: 10px; height: 10px; border-radius: 50%; background: var(--line); }
.editor__tab { margin-left: 0.75rem; color: var(--fg-dim); }
.editor__code, .editor__log {
  padding: 1.1rem 1.25rem;
  font-size: clamp(0.7rem, 0.58rem + 0.42vw, 0.85rem);
  line-height: 1.55;
  overflow-x: auto;
  tab-size: 2;
  white-space: pre;
  /* 等幅フォントの合字（!== が1文字に見える）を切る */
  font-variant-ligatures: none;
}
.editor__code { min-height: 16em; }
.editor__log {
  border-top: 1px solid var(--line);
  color: var(--accent-2);
  background: rgba(0, 0, 0, 0.25);
}
.log__line {
  display: block;
  --lp: clamp(0, calc((var(--p) - 0.80 - var(--i) * 0.045) / 0.04), 1);
  opacity: var(--lp);
  transform: translate3d(calc((1 - var(--lp)) * -8px), 0, 0);
}
.log__line:first-child { color: var(--fg-dim); }

/* トークン（typing.js が生成）。非表示は visibility で幅を保ち、レイアウトを揺らさない */
.tok { visibility: visible; }
.tok.is-hidden { visibility: hidden; }
.tok--cm { color: var(--fg-faint); font-style: italic; }
.tok--kw { color: var(--accent-3); }
.tok--ty { color: var(--accent-2); }
.tok--st { color: #b5f5c8; }
.tok--fn { color: var(--accent); }
.tok--nu { color: #fcd9a0; }
.tok--pn { color: var(--fg-dim); }
.caret {
  display: inline-block;
  width: 0.55em; height: 1.15em;
  vertical-align: text-bottom;
  background: var(--accent-2);
  animation: blink 1s steps(2, start) infinite;
}
@keyframes blink { to { visibility: hidden; } }
.code-line { display: block; }
/* 空行（トークンが1つも無い行）は block だと高さ 0 になるので、行の高さを保つ */
.code-line:empty { height: 1.55em; }
.code-line.line-hl { background: rgba(124, 156, 255, 0.08); }

/* ── 3. 認証フロー（補助） ───────────────────────────────── */
.authflow {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  padding: clamp(0.5rem, 2vw, 1.5rem);
  max-width: 62rem;
}
.authflow__svg { width: 100%; height: auto; font-family: var(--font-sans); }
.authflow__wire { stroke: var(--line); stroke-width: 2; fill: none; }
.authflow__beam {
  stroke: url(#beam);
  stroke-width: 3;
  fill: none;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - var(--lp));
  filter: drop-shadow(0 0 6px rgba(124, 156, 255, 0.8));
}
.authflow__beam--1 { --lp: clamp(0, calc((var(--p) - 0.25) / 0.25), 1); }
.authflow__beam--2 { --lp: clamp(0, calc((var(--p) - 0.55) / 0.25), 1); }
.authflow__pulse {
  fill: #fff;
  filter: drop-shadow(0 0 8px var(--accent-2));
  offset-rotate: 0deg;
  offset-distance: calc(var(--lp) * 100%);
  opacity: calc(var(--lp) * (1 - var(--lp)) * 4);
}
.authflow__pulse--1 { offset-path: path("M170 130 H370"); --lp: clamp(0, calc((var(--p) - 0.25) / 0.25), 1); }
.authflow__pulse--2 { offset-path: path("M530 130 H730"); --lp: clamp(0, calc((var(--p) - 0.55) / 0.25), 1); }
.authflow__node {
  --lp: clamp(0, calc((var(--p) - var(--i) * 0.3) / 0.2), 1);
  opacity: calc(0.35 + var(--lp) * 0.65);
  transform: translate3d(0, calc((1 - var(--lp)) * 10px), 0);
}
.authflow__node rect {
  fill: rgba(11, 15, 26, 0.9);
  stroke: var(--line);
  stroke-width: 1.5;
}
.authflow__node text { fill: var(--fg); font-size: 20px; font-weight: 600; }
.authflow__node .authflow__small { fill: var(--fg-dim); font-size: 13px; font-weight: 400; }
.authflow__node.is-lit rect { stroke: var(--accent); filter: drop-shadow(0 0 10px rgba(124, 156, 255, 0.5)); }
.authflow__lock {
  --lp: clamp(0, calc((var(--p) - 0.86) / 0.12), 1);
  opacity: calc(0.4 + var(--lp) * 0.6);
}
.authflow__body { fill: rgba(124, 156, 255, 0.25); stroke: var(--accent); stroke-width: 1.5; }
.authflow__hole { fill: var(--accent-2); }
.authflow__shackle {
  fill: none; stroke: var(--accent-2); stroke-width: 3; stroke-linecap: round;
  transform-box: fill-box;
  transform-origin: 100% 100%;
  transform: translateY(calc(var(--lp) * -6px)) rotate(calc(var(--lp) * -35deg));
}
.authflow__caption { fill: var(--fg-faint); font-size: 12px; }
.authflow__status {
  margin-top: 0.75rem;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--fg-dim);
}
.authflow__status.is-done { color: var(--accent-2); }

/* ── 4. Products ─────────────────────────────────────────── */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.25rem;
  perspective: 1200px;
}
.card {
  --lp: clamp(0, calc((var(--p) - var(--i) * 0.12) / 0.5), 1);
  opacity: var(--lp);
  transform: translate3d(0, calc((1 - var(--lp)) * (48px + var(--i) * 36px)), 0);
}
.card__link {
  display: grid;
  gap: 0.5rem;
  height: 100%;
  padding: 1.6rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 0.25s ease-out, border-color 0.25s;
  will-change: transform;
}
.card__link:hover { border-color: rgba(124, 156, 255, 0.5); }
.card__tag { font-size: 0.75rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); }
.card__title { font-size: 1.5rem; font-weight: 700; }
.card__desc { color: var(--fg-dim); font-size: 0.95rem; }
.card__url { font-family: var(--font-mono); font-size: 0.8rem; color: var(--accent-2); margin-top: auto; padding-top: 0.5rem; }

/* ── 5. 沿革 ─────────────────────────────────────────────── */
.timeline {
  position: relative;
  padding-left: 2rem;
  display: grid;
  gap: 2.5rem;
  max-width: 44rem;
}
.timeline::before {
  content: "";
  position: absolute;
  left: 7px; top: 0; bottom: 0;
  width: 2px;
  background: linear-gradient(to bottom, var(--gold-lit), var(--accent));
  transform-origin: top;
  transform: scaleY(var(--p));
}
.timeline__item {
  position: relative;
  --lp: clamp(0, calc((var(--p) - 0.08 - var(--i) * 0.2) / 0.28), 1);
  opacity: var(--lp);
  transform: translate3d(calc((1 - var(--lp)) * 16px), 0, 0);
}
.timeline__item::before {
  content: "";
  position: absolute;
  left: -2rem; top: 0.55em;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--bg);
  border: 2px solid var(--gold-lit);
  transform: scale(var(--lp));
}
.timeline__date { font-family: var(--font-mono); font-size: 0.85rem; color: var(--gold-lit); }
.timeline__title { font-size: 1.25rem; font-weight: 700; margin-top: 0.2rem; }
.timeline__desc { color: var(--fg-dim); font-size: 0.95rem; }
.timeline__item--next .timeline__date { color: var(--fg-faint); }

/* ── 6. 招待制 ───────────────────────────────────────────── */
.invite {
  min-height: 70vh;
  display: grid;
  place-items: center;
  text-align: center;
  contain-intrinsic-size: auto 70vh;
}
.invite__text {
  font-size: clamp(1.3rem, 0.9rem + 2.4vw, 2.6rem);
  font-weight: 600;
  letter-spacing: calc((1 - var(--p)) * 0.3em);
  opacity: var(--p);
  filter: blur(calc((1 - var(--p)) * 6px));
}

/* ── 小画面 ──────────────────────────────────────────────── */
@media (max-width: 767px) {
  /* 「九州工業大学 非公認学生団体 / est. 2026.08.29」が中途半端に折り返すので、
     区切りの「/」を消して 2 行に組み直す */
  .hero__sep { display: none; }
  .hero__est { display: block; margin-top: 0.35rem; }

  .typing { min-height: 260vh; }
  /* 狭い画面ではエディタに幅を回す（コードは横スクロールで読める） */
  .typing__sticky { padding-left: 0.75rem; padding-right: 0.75rem; }
  .editor__code { min-height: 14em; }
  .hero__cue { display: none; }
}
@media (hover: none) {
  .card__link { transform: none; }
}
