/*
 * ラエル オンライン交流 通話ページ
 *
 * スマホのブラウザと PC ブラウザの両方で同じページを開くため、
 * レイアウトはすべて可変にする。
 *
 * 色と書体はアプリ (lib/ui/theme/app_colors.dart / app_theme.dart) に合わせる。
 * アプリから遷移してきたときに別のサービスに飛ばされたと感じさせないため。
 */

:root {
  /* アプリの AppColors から。左のコメントが Dart 側の名前 */
  --main: #eecd12;        /* newMain    ラエルの黄色 */
  --btn-from: #f8d520;    /* newButton  ボタンのグラデーション始点 */
  --btn-to: #e9a239;      /* newButton  同 終点 */
  --link: #f29a16;        /* newLink    リンク・強調テキスト */
  --text: #444444;        /* newTextBasic */
  --text-strong: #3a3207; /* textDefault  黄色の上に載せる文字 */
  --sub: #8c8c8c;         /* newTextWeak より少し濃い (本文の可読性のため) */
  --line: #dddddd;        /* newLine */
  --bg: #f9f9f9;          /* newBgBasic */
  --card: #ffffff;        /* newWhite */
  --important: #fffced;   /* newBgImportant */
  --danger: #ff4848;      /* newError */
  --disable: #dddddd;     /* newTextDisable */

  /* アプリはライトのみ。夜に開いたときだけ別物に見えるのを避ける */
  color-scheme: light;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  /*
   * 書体はアプリと同じ Noto Sans JP (index.html で読み込む)。
   * 端末のフォントに任せると、環境によっては中国語字形
   * (Noto Sans SC など) で表示されてしまうため、Web フォントを正とし、
   * 読み込めなかったときだけ端末の日本語フォントへ落とす。
   */
  font-family: "Noto Sans JP", "Hiragino Sans", "Hiragino Kaku Gothic ProN",
    "Noto Sans CJK JP", "Yu Gothic", Meiryo, sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.7;
  -webkit-text-size-adjust: 100%;
}

.view {
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.view[hidden] { display: none; }

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;   /* アプリの cardTheme に合わせる */
  padding: 28px 22px;
  width: 100%;
  max-width: 420px;
  text-align: center;
}

.card.wide { max-width: 520px; }

.logo {
  margin: 0 0 20px;
  line-height: 0;
}

.logo img {
  width: 132px;
  height: auto;
}

.title {
  font-size: 19px;
  font-weight: 700;
  margin: 0 0 12px;
  color: var(--text);
}

.lead { font-size: 15px; margin: 0 0 20px; color: var(--text); }
.hint { font-size: 13px; color: var(--sub); margin: 12px 0 0; }
.you { font-size: 14px; color: var(--sub); margin: 16px 0 4px; }

.error {
  color: var(--danger);
  font-size: 14px;
  margin: 12px 0 0;
  font-weight: 700;
}

/* ---- パスコード ---- */

.passcode {
  display: flex;
  gap: 8px;
  justify-content: center;
  margin-bottom: 8px;
}

.passcode input {
  width: 46px;
  height: 56px;
  font-size: 24px;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--card);
  color: var(--text);
  font-family: inherit;
}

.passcode input:focus {
  outline: 2px solid var(--link);
  outline-offset: 1px;
}

/* ---- ボタン ---- */

/* アプリの GradationButton と同じ見た目 (黄→橙のグラデ・白字・角丸4) */
.primary {
  display: block;
  width: 100%;
  margin-top: 20px;
  padding: 14px;
  font-size: 16px;
  font-weight: 700;
  font-family: inherit;
  line-height: 1.4;
  color: #fff;
  background: linear-gradient(to right, var(--btn-from), var(--btn-to));
  border: 0;
  border-radius: 4px;
  cursor: pointer;
}

.primary:hover:not(:disabled) { filter: brightness(1.06); }

.primary:disabled {
  background: var(--disable);
  cursor: not-allowed;
}

.as-button { text-decoration: none; text-align: center; }

/* アプリの CustomOutlineButton と同じ見た目。副次的な導線に使う */
.secondary {
  display: block;
  width: 100%;
  margin-top: 10px;
  padding: 14px;
  font-size: 15px;
  font-weight: 700;
  font-family: inherit;
  color: var(--link);
  background: var(--card);
  border: 1px solid var(--link);
  border-radius: 4px;
  cursor: pointer;
}

.controls {
  display: flex;
  gap: 8px;
  justify-content: center;
  margin: 14px 0;
}

/* アプリの CustomOutlineButton と同じ見た目 (白地・橙の枠と文字) */
.toggle {
  flex: 1;
  padding: 10px;
  font-size: 14px;
  font-family: inherit;
  font-weight: 700;
  color: var(--link);
  background: var(--card);
  border: 1px solid var(--link);
  border-radius: 4px;
  cursor: pointer;
}

/* オフはひと目で分かる必要があるので、枠線ではなく塗りで示す */
.toggle[aria-pressed="false"] {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}

/* ---- 前室 ---- */

.preview-wrap { position: relative; }

/*
 * 映像の入れ物。中の video は Agora の SDK が作って差し込む。
 * 自分の映像の鏡像化と、はみ出した分の切り取りも SDK 側が行うので、
 * ここでは大きさと角丸だけを決める。
 */
.video-box {
  position: relative;
  background: #3a3207;
  border-radius: 10px;
  overflow: hidden;
}

#preview {
  width: 100%;
  aspect-ratio: 4 / 3;
}

.notice {
  position: absolute;
  left: 50%;
  bottom: 10px;
  transform: translateX(-50%);
  margin: 0;
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 700;
  color: var(--text-strong);
  background: var(--main);
  border-radius: 999px;
  white-space: nowrap;
}

/* 前室も通話中と同じ。塗りつぶさないと直前の映像が透けて残る */
.preview-off {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: 0;
  background: #2b2b2b;
  color: #fff;
  font-size: 14px;
}

.preview-off p { margin: 0; }

.preview-off svg {
  width: 40px;
  height: 40px;
  fill: rgba(255, 255, 255, 0.75);
}

/* display を指定した要素は、そのままだと hidden 属性が効かない
   (作者スタイルが UA の display:none を上書きするため)。
   ボタン類は「その画面で意味のあるものだけ出す」作りなので、
   ここが漏れると押す意味のないボタンが並ぶ */
.preview-off[hidden],
.notice[hidden],
.primary[hidden],
.secondary[hidden] {
  display: none;
}

.field { text-align: left; margin-top: 14px; }

.field label,
.field .label {
  display: block;
  font-size: 13px;
  font-weight: 700;
  margin-bottom: 6px;
  color: var(--text);
}

.field select {
  width: 100%;
  padding: 10px;
  font-size: 14px;
  font-family: inherit;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--card);
  color: var(--text);
}

/* ---- 背景の選択 ---- */

.bg-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}

.bg-tile {
  padding: 0;
  background: none;
  border: 0;
  font-family: inherit;
  cursor: pointer;
  text-align: center;
}

.bg-tile[hidden] { display: none; }

.bg-thumb {
  display: block;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--line);
  border-radius: 6px;
  background-color: var(--card);
  background-size: cover;
  background-position: center;
}

/* 画像を持たない選択肢は、見た目でそれと分かるようにしておく */
.bg-thumb.none {
  background-image: linear-gradient(135deg, #fff 48%, var(--line) 48%,
    var(--line) 52%, #fff 52%);
}

.bg-thumb.blur-soft {
  background-image: radial-gradient(120% 120% at 30% 25%, #fdfdfe, #e6e9ef);
}

.bg-thumb.blur-strong {
  background-image: radial-gradient(120% 120% at 30% 25%, #f2f4f8, #c8cdd7);
}

.bg-tile.active .bg-thumb {
  border: 3px solid var(--main);
}

.bg-name {
  display: block;
  margin-top: 3px;
  font-size: 10px;
  line-height: 1.4;
  color: var(--sub);
}

.bg-tile.active .bg-name {
  color: var(--text);
  font-weight: 700;
}

.bg-more {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 100%;
  margin-top: 10px;
  padding: 6px;
  font-size: 12px;
  font-family: inherit;
  font-weight: 700;
  color: var(--link);
  background: none;
  border: 0;
  cursor: pointer;
}

.bg-more[hidden] { display: none; }

.bg-more .chevron {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid currentColor;
  transition: transform .15s;
}

.bg-more[aria-expanded="true"] .chevron { transform: rotate(180deg); }

.countdown {
  font-size: 14px;
  font-weight: 700;
  color: var(--link);
  margin: 14px 0 0;
}

/* 参加ボタンは常に見えるようにする。カード下端に貼り付ける */
.prejoin-actions {
  position: sticky;
  bottom: 0;
  z-index: 1;
  margin: 8px -22px -28px;
  padding: 10px 22px 20px;
  background: var(--card);
  box-shadow: 0 -10px 14px -10px rgba(0, 0, 0, .18);
}

.prejoin-actions .primary { margin-top: 10px; }
.prejoin-actions .countdown { margin-top: 0; }

.help {
  margin-top: 18px;
  padding: 12px 14px;
  text-align: left;
  font-size: 13px;
  color: var(--text);
  background: var(--important);
  border-radius: 10px;
}

.help summary { cursor: pointer; font-weight: 700; }
.help p { margin: 8px 0 0; }

/* ---- 通話中 ---- */

/*
 * 通話画面は画面いっぱいに広げる。
 * 高さを祖先から継がせようとすると、どこか 1 つで途切れただけで
 * 映像が潰れる。ビューポートに直接貼り付けて切り離す。
 */
.view.call {
  position: fixed;
  inset: 0;
  height: auto;
  min-height: 0;
  padding: 0;
  flex-direction: column;
  align-items: stretch;
  overflow: hidden;
}

.banner {
  padding: 8px 14px;
  font-size: 14px;
  font-weight: 700;
  text-align: center;
  background: var(--main);
  color: var(--text-strong);
}

.banner.warn { background: var(--btn-to); color: #fff; }
.banner.danger { background: var(--danger); color: #fff; }
.banner[hidden] { display: none; }

/* 相手を画面いっぱいに、自分を右上に小さく (アプリの通話画面と同じ配置) */
.stage {
  position: relative;
  flex: 1;
  min-height: 0;
  background: #000;
}

/*
 * 入っている人のぶんだけ枠を並べる。
 * 1 人なら画面いっぱい、増えたら自動で分かれる。狭い画面では
 * 横に並べず縦に積む (顔が小さくなりすぎるため)
 */
.remote-grid {
  position: absolute;
  inset: 0;
  display: grid;
  gap: 2px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  background: #000;
}

.remote-tile {
  position: relative;
  min-width: 0;
  min-height: 0;
  background: #000;
}

.remote-video { width: 100%; height: 100%; }

/*
 * 相手がカメラを切っているのか、映像が来ていないのかを区別する。
 *
 * カメラを切ると、その瞬間の映像が止まったまま残る。透ける作りにすると
 * 「固まっているだけ」に見えてしまうので、必ず塗りつぶして隠す。
 */
.remote-camoff {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: 0;
  background: #2b2b2b;
  color: #fff;
  font-size: 14px;
}

.remote-camoff p { margin: 0; }

.remote-camoff svg {
  width: 40px;
  height: 40px;
  fill: rgba(255, 255, 255, 0.75);
}

.remote-camoff[hidden] { display: none; }

/* いま何台つながっているか。常に見えている必要がある */
.call-status {
  position: absolute;
  top: 12px;
  left: 12px;
  margin: 0;
  padding: 4px 12px;
  font-size: 12px;
  font-weight: 700;
  color: #fff;
  background: rgba(0, 0, 0, .55);
  border-radius: 999px;
}

.remote-waiting {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  color: #fff;
  font-size: 15px;
}

.remote-waiting[hidden] { display: none; }

.local-wrap {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 22%;
  max-width: 180px;
  min-width: 96px;
  aspect-ratio: 4 / 3;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .4);
  border-radius: 10px;
}

#local-video { width: 100%; height: 100%; }

/* 自分の枠も同じ。止まった映像が残らないよう塗りつぶす */
.local-off {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin: 0;
  border-radius: 10px;
  background: #2b2b2b;
  color: #fff;
  font-size: 12px;
  line-height: 1.3;
  text-align: center;
}

.local-off p { margin: 0; }

.local-off svg {
  width: 24px;
  height: 24px;
  fill: rgba(255, 255, 255, 0.75);
}

.local-off[hidden] { display: none; }

/*
 * 通話中の操作。アプリの通話画面と同じ、映像に重ねた丸いアイコンにする。
 * 同じ機能なのに端末で見た目が違うと、電話中に迷うことになる。
 */
.call-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(20px + env(safe-area-inset-bottom));
  display: flex;
  gap: 16px;
  justify-content: center;
  flex-wrap: wrap;
}

.call-btn {
  width: 52px;
  height: 52px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  background: rgba(0, 0, 0, .54);
  border: 0;
  border-radius: 50%;
  cursor: pointer;
}

.call-btn svg { width: 26px; height: 26px; fill: currentColor; }

.call-btn[hidden] { display: none; }

/*
 * オフはひと目で分かる必要があるので塗りで示す。
 * 赤くするのはマイクとカメラだけ。画面共有は「していない」が既定なので、
 * 同じ扱いにすると常に赤いボタンが並ぶことになる。
 */
#call-mic[aria-pressed="false"],
#call-cam[aria-pressed="false"],
.call-btn.danger {
  background: var(--danger);
}

/* 共有中であることを分かるようにする */
#call-share[aria-pressed="true"] {
  background: var(--link);
}

/*
 * 背景の選び直し。アプリと同じく、下から映像に重ねて開く。
 * 開いている間は操作バーが隠れるので、シート側に「閉じる」を置いてある。
 */
.call-sheet {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  background: var(--card);
  border-radius: 12px 12px 0 0;
  max-height: 70%;
  overflow-y: auto;
}

.call-sheet[hidden] { display: none; }

.call-sheet-inner {
  max-width: 640px;
  margin: 0 auto;
  padding: 14px 16px calc(14px + env(safe-area-inset-bottom));
}

.call-sheet .label { display: block; font-size: 13px; font-weight: 700; margin: 0 0 8px; }
.call-sheet .secondary { margin-top: 14px; }

/* 画面の幅に応じて列を増やす。通話中は映像の場所を空けたいので、
   前室のように 4 列固定にすると 1 枚が大きくなりすぎる */
.call-sheet .bg-grid {
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
}

.call-notice {
  position: absolute;
  left: 50%;
  bottom: 88px;
  z-index: 1;
  transform: translateX(-50%);
  margin: 0;
  padding: 6px 14px;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-strong);
  background: var(--main);
  border-radius: 999px;
  white-space: nowrap;
}

.call-notice[hidden] { display: none; }

/* 人数が合わないことの警告。見逃されては意味が無いので目立たせる */
.call-warning {
  position: absolute;
  left: 12px;
  right: 12px;
  top: 44px;
  z-index: 1;
  margin: 0;
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 700;
  text-align: center;
  color: #fff;
  background: var(--danger);
  border-radius: 8px;
}

.call-warning[hidden] { display: none; }

/* ---- 読み込み中 ---- */

.spinner {
  width: 32px;
  height: 32px;
  margin: 0 auto 16px;
  border: 3px solid var(--line);
  border-top-color: var(--main);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 3s; }
}
