/* 集めたカード＝世界を旅するウリボーのカードを横にめくる画面（2026-10-19 柴山さん「横にスライドして」「明るいほう」）。
   元は Codex のモック design/mocks/stamp-cards-slider.css（T010 その2・明るい地）。画面いっぱいに開く dialog の中だけに効かせる。
   文字は絵にかぶせない（行き先・副題はカードの上、到着した日はカードの下）。絵の上は「◯枚目」の札だけ。動きは transform・opacity だけ */
[hidden] { display: none !important; }
.card-viewer {
  --card-width: min(calc(100vw - 80px), calc((100dvh - 300px) * 1.585185), 360px);
  width: 100%; max-width: 100%; height: 100dvh; max-height: 100dvh; margin: 0; padding: 0 0 max(12px, env(safe-area-inset-bottom));
  border: 0; background: var(--bg); color: var(--ink);
}
.card-viewer[open] { display: flex; flex-direction: column; }
.card-viewer::backdrop { background: var(--bg); }
.card-viewer svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.card-viewer button { font: inherit; color: inherit; background: transparent; border: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.card-viewer button:focus-visible, .card-viewer [tabindex]:focus-visible { outline: 2px solid var(--ink); outline-offset: -3px; }
.card-viewer button:disabled { opacity: .3; cursor: default; }
.card-viewer .viewer-header { display: flex; flex-shrink: 0; justify-content: space-between; align-items: center; height: 56px; padding: 0 12px; padding-top: env(safe-area-inset-top); box-sizing: content-box; gap: 8px; }
.card-viewer .viewer-header h2 { font-size: var(--font-body); margin: 0; font-weight: 700; }
.card-viewer .viewer-close, .card-viewer .viewer-spacer { display: grid; place-items: center; width: 44px; height: 44px; }
.card-viewer .collection-status { margin: 0; padding: 0 16px; text-align: center; font-size: var(--font-min); color: var(--ink-sub); height: 28px; flex-shrink: 0; }
.card-viewer .viewer-scene { flex: 1; min-height: 0; display: flex; flex-direction: column; justify-content: center; }
.card-rail { flex: none; height: calc(var(--card-width) / 1.585185); display: flex; align-items: center; gap: 12px; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; scroll-padding-inline: calc((100% - var(--card-width)) / 2); padding-inline: calc((100% - var(--card-width)) / 2); overscroll-behavior-x: contain; scrollbar-width: none; }
.card-rail::-webkit-scrollbar { display: none; }
.journey-slide { flex: 0 0 var(--card-width); min-width: 0; scroll-snap-align: center; scroll-snap-stop: always; }
.journey-heading { height: 64px; margin-bottom: 16px; text-align: center; }
.journey-heading h3 { font-size: 24px; line-height: 1.3; margin: 0 0 8px; white-space: nowrap; }
.journey-subtitle { font-size: var(--font-min); line-height: 1.6; white-space: nowrap; margin: 0; color: var(--ink-sub); }
.journey-art { position: relative; aspect-ratio: 85.6 / 54; border-radius: var(--radius-l); border: 1px solid var(--closed-bg); overflow: hidden; background: var(--icon-bg); opacity: .55; transform: scale(.94); transition: transform 180ms ease, opacity 180ms ease; }
.journey-art img { display: block; width: 100%; height: 100%; -webkit-user-drag: none; user-select: none; }
.journey-slide.active .journey-art { opacity: 1; transform: scale(1); }
.journey-number { position: absolute; top: 8px; left: 8px; padding: 2px 8px; border-radius: var(--radius-s); color: var(--ink); background: var(--surface); font-size: var(--font-min); font-weight: 700; }
.journey-slide.special .journey-number { color: var(--on-primary); background: var(--primary); }
.journey-art.unknown { display: grid; place-items: center; border-style: dashed; }
.journey-art.unknown.special { border-style: solid; }
.question-mark { font-size: 52px; line-height: 1; color: var(--ink-sub); }
.journey-footer { height: 92px; margin-top: 24px; text-align: center; }
.journey-date, .journey-remaining { font-size: var(--font-sub); line-height: 1.6; margin: 0 0 4px; white-space: nowrap; }
.journey-message { font-size: var(--font-min); line-height: 1.6; color: var(--ink-sub); margin: 0; }
.journey-heading, .journey-footer { opacity: 0; transition: opacity 180ms ease; }
#active-heading .journey-heading, #active-footer .journey-footer { opacity: 1; }
.progress-label { font-size: var(--font-min); margin: 4px 0; color: var(--ink-sub); font-variant-numeric: tabular-nums; }
.card-viewer progress { display: block; appearance: none; width: min(100%, 200px); height: 4px; margin: 0 auto 8px; border: 0; border-radius: var(--radius-s); overflow: hidden; color: var(--ink); background: var(--closed-bg); }
.card-viewer progress::-webkit-progress-bar { background: var(--closed-bg); }
.card-viewer progress::-webkit-progress-value { background: var(--ink); }
.card-viewer progress::-moz-progress-bar { background: var(--ink); }
.slide-controls { display: flex; flex-shrink: 0; align-items: center; justify-content: center; gap: 20px; height: 44px; margin: 0 16px 8px; }
.slide-controls button { width: 44px; height: 44px; display: grid; place-items: center; border: 1px solid var(--closed-bg) !important; border-radius: 50%; }
.slide-controls p { margin: 0; min-width: 96px; text-align: center; font-size: var(--font-min); font-variant-numeric: tabular-nums; }
@media (max-height: 560px) {
  .card-viewer { --card-width: min(calc(100vw - 80px), calc((100dvh - 250px) * 1.585185), 360px); }
  .card-viewer .viewer-header { height: 48px; }
  .card-viewer .collection-status { height: 24px; }
  .journey-heading { height: 48px; margin-bottom: 8px; }
  .journey-heading h3 { font-size: var(--font-heading); margin-bottom: 4px; }
  .journey-footer { height: 72px; margin-top: 12px; }
}
@media (prefers-reduced-motion: reduce) { .journey-art, .journey-heading, .journey-footer { transition: none; } }

/* 集めたカード＝旅先から届いた絵はがき（案D3。2026-10-20 柴山さん「フォントが微妙・ただ文字が書かれてるだけ」→ D3「下はウリボーが書いた旅日記に」「日付はスタンプだけで」）。
   行き先・副題・日記は手書きふうの Klee One（使う文字だけに絞った woff2。OFL-KleeOne.txt）。日付は便せんの右上の消印だけ */
@font-face { font-family: "Klee One"; src: url("/assets/fonts/KleeOne-SemiBold-subset.woff2") format("woff2"); font-weight: 600; font-display: swap; }
.card-viewer { --card-width: min(calc(100vw - 80px), calc((100dvh - 374px) * 1.585185), 360px); }
.journey-heading h3, .journey-subtitle, .journey-footer { font-family: "Klee One", var(--font-family, sans-serif); font-weight: 600; }
.journey-heading h3 { font-size: 28px; letter-spacing: .04em; }
.journey-heading h3 small { margin-left: 4px; font-size: 17px; }
.journey-subtitle { font-size: 15px; }
.journey-slide:not(:has(.unknown)) .journey-art { box-sizing: border-box; border: 6px solid var(--surface); box-shadow: 0 8px 20px rgba(23, 20, 18, .16); }
.journey-slide.active:not(:has(.unknown)) .journey-art { transform: rotate(-1.5deg); }
.journey-footer { height: 136px; margin-top: 52px; }
.letter { position: relative; width: min(calc(100% - 24px), 300px); margin: 0 auto; padding: 6px 16px 8px; box-sizing: border-box; text-align: left; background: #fffdf8; border: 1px solid rgba(23, 20, 18, .15); border-radius: 6px; box-shadow: 0 4px 10px rgba(23, 20, 18, .06); }
.diary { margin: 0; font-size: 16px; line-height: 32px; background: repeating-linear-gradient(transparent 0 31px, rgba(23, 20, 18, .14) 31px 32px); white-space: nowrap; }
.diary-sign { margin: 0; text-align: right; font-size: 14px; line-height: 28px; color: var(--ink-sub); }
/* 日付のスタンプ（案S3）。便せんの上の外に押す＝日記の文字に重ねない。少し傾けて、カードの下の端にかかる */
.postmark { position: absolute; z-index: 3; right: 4px; top: -78px; width: 72px; height: 72px; transform: rotate(12deg); pointer-events: none; }
.postmark svg { display: block; width: 100%; height: 100%; overflow: visible; }
@media (max-height: 560px) {
  .card-viewer { --card-width: min(calc(100vw - 80px), calc((100dvh - 308px) * 1.585185), 360px); }
  .journey-heading { height: 60px; }
  .journey-heading h3 { font-size: 22px; }
  .journey-footer { height: 112px; margin-top: 40px; }
  .diary { line-height: 26px; background: repeating-linear-gradient(transparent 0 25px, rgba(23, 20, 18, .14) 25px 26px); }
  .diary-sign { line-height: 22px; }
  .postmark { width: 60px; height: 60px; top: -64px; }
}

/* カードをもらう流れ（2026-10-20 柴山さん「C2からそのあとC4みたいな」。部品は card-reveal.js）。
   p1＝10個目が押される／p2＝スタンプが真ん中へ集まる／p3＝ポンとカード／p4＝集めたカードへ飛んでしまう。動きは transform・opacity だけ */
.card-reveal { position: fixed; inset: 0; width: 100%; max-width: 100%; height: 100dvh; max-height: 100dvh; margin: 0; padding: 0; border: 0; background: transparent; color: var(--ink); overflow: hidden; }
.card-reveal[open] { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-6); }
.card-reveal::backdrop { background: transparent; }
.card-reveal > * { flex-shrink: 0; }
.rv-bg { position: fixed; inset: 0; background: var(--bg); will-change: opacity; }
.rv-scene { position: relative; width: min(320px, calc(100% - 32px)); aspect-ratio: 85.6 / 54; }

/* スタンプカード（本物の .stamp-grid と同じ丸） */
.rv-sheet { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: center; gap: 10px; padding: 14px 18px; box-sizing: border-box; border: 1.5px solid var(--ink); border-radius: var(--radius-l); background: var(--surface); box-shadow: 0 8px 20px rgba(23, 20, 18, .12); }
.rv-sheet-title { margin: 0; font-size: var(--font-min); font-weight: var(--weight-bold); color: var(--ink-sub); letter-spacing: .08em; }
.rv-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; }
.rv-slot { position: relative; aspect-ratio: 1; border: 1.5px dashed var(--ink-sub); border-radius: 50%; }
.rv-slot.on { border: 1.5px solid var(--ink); background: var(--icon-bg); }
.rv-slot img, .rv-fly img { position: absolute; left: 12%; top: 10%; width: 76%; height: auto; will-change: transform, opacity; backface-visibility: hidden; }
.rv-slot.last img { opacity: 0; transform: scale(2.2) translateY(-18px); }
.p1 .rv-slot.last { border-style: solid; border-color: var(--ink); background: var(--icon-bg); transition: background-color 0s .26s, border-color 0s .26s; }
.p1 .rv-slot.last img { opacity: 1; transform: none; transition: opacity .18s ease-out, transform .34s cubic-bezier(.3, 1.6, .5, 1); }
/* 押した手ごたえは10個目のマスから広がる輪で。スタンプカード全体は縮めない（縮めると文字と縁が一瞬ぼやけて白っぽく光って見えた。2026-10-20 柴山さん） */
.rv-slot.last::after { content: ""; position: absolute; inset: -2px; border: 2px solid var(--ink); border-radius: 50%; opacity: 0; transform: scale(.7); pointer-events: none; }
.p1 .rv-slot.last::after { animation: rv-impact .5s cubic-bezier(.2, .7, .3, 1) .26s both; }
@keyframes rv-impact { 0% { opacity: .55; transform: scale(.9); } 100% { opacity: 0; transform: scale(1.7); } }

/* スタンプが真ん中に集まる（写しを飛ばす。スタンプカードは消える） */
.rv-fly { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.rv-fly img { left: auto; top: auto; transition: transform .62s cubic-bezier(.55, 0, .75, .1) var(--d), opacity .2s ease calc(var(--d) + .45s); }
.rv-fly.go img { transform: translate(var(--dx), var(--dy)) scale(.35); opacity: 0; }
.p2 .rv-sheet { opacity: 0; transform: scale(.94); transition: opacity .35s ease, transform .35s ease; }

/* 輪が広がって、ポンとカード。光が1回横切る */
.rv-ring { position: absolute; left: 50%; top: 50%; width: 120px; height: 120px; margin: -60px 0 0 -60px; border: 3px solid var(--ink); border-radius: 50%; opacity: 0; transform: scale(.2); will-change: transform, opacity; }
.p3 .rv-ring { animation: rv-ring .7s cubic-bezier(.2, .7, .3, 1) both; }
@keyframes rv-ring { 0% { opacity: .5; transform: scale(.2); } 100% { opacity: 0; transform: scale(3); } }
.rv-card { position: absolute; inset: 0; z-index: 3; border-radius: var(--radius-l); overflow: hidden; border: 1.5px solid var(--ink); background: var(--icon-bg); box-shadow: 0 12px 28px rgba(23, 20, 18, .2); opacity: 0; transform: scale(.2); will-change: transform, opacity; backface-visibility: hidden; }
.rv-card img { display: block; width: 100%; height: 100%; object-fit: cover; }
.p3 .rv-card { opacity: 1; transform: none; transition: opacity .18s ease, transform .75s cubic-bezier(.34, 1.56, .64, 1); }
.rv-shine { position: absolute; top: -10%; bottom: -10%; left: 0; width: 45%; background: linear-gradient(100deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, .55) 50%, rgba(255, 255, 255, 0) 100%); opacity: 0; transform: translateX(-130%) skewX(-12deg); }
.shine .rv-shine { animation: rv-shine .9s cubic-bezier(.4, 0, .2, 1) both; }
@keyframes rv-shine { 0% { opacity: 1; transform: translateX(-130%) skewX(-12deg); } 100% { opacity: 1; transform: translateX(330%) skewX(-12deg); } }

/* 行き先の名前（文字は少なく） */
.rv-name { position: relative; display: flex; flex-direction: column; align-items: center; gap: var(--space-1); min-height: 64px; text-align: center; opacity: 0; transition: opacity .4s ease .35s; }
.p3 .rv-name { opacity: 1; }
.rv-name strong { font-size: var(--font-heading); }
.rv-name span { font-size: var(--font-sub); color: var(--ink-sub); }

/* しまう：背景が消えて画面が見え、カードが束（ホームは下の「出勤の記録」）へ飛ぶ */
.p4 .rv-bg, .p4-away .rv-bg { opacity: 0; transition: opacity .35s ease .1s; }
.p4 .rv-name, .p4-away .rv-name { opacity: 0; transition: opacity .2s ease; }
.p4 .rv-card { transform: translate(var(--fx), var(--fy)) scale(var(--fs)) rotate(-2deg); transition: transform .7s cubic-bezier(.55, 0, .2, 1); }
.p4-away .rv-card { opacity: 0; transform: scale(.6); transition: opacity .4s ease, transform .5s ease; }

/* 動きを減らす設定・絵が読めないとき：止まった絵だけ */
.still *, .still { transition: none !important; animation: none !important; }
.still .rv-sheet, .still .rv-ring { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .card-reveal * { transition: none !important; animation: none !important; } }

/* しまったときに束（・下の「出勤の記録」）が少し弾む */
.rv-bump { animation: rv-bump .4s cubic-bezier(.3, 1.6, .5, 1) both; }
@keyframes rv-bump { 0% { transform: scale(1); } 40% { transform: scale(1.1); } 100% { transform: scale(1); } }
.collection-stack > .rv-pending { opacity: 0; }

/* 集めたカードの入口＝カードの絵を重ねた束（案B1。2026-10-20）。いちばん上が最新。0枚のときは「？」のカード1枚 */
.collection-stack-row { display: flex; align-items: center; gap: var(--space-4); width: 100%; margin: var(--space-3) 0 0; padding: var(--space-3) var(--space-1) 0; border: 0; border-top: 1px dashed var(--ink-sub); background: none; color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.collection-stack { position: relative; flex: none; width: 128px; height: 92px; }
.collection-stack > * { position: absolute; width: 112px; aspect-ratio: 85.6 / 54; border-radius: 6px; border: 1.5px solid var(--ink); box-shadow: 0 3px 8px rgba(23, 20, 18, .14); }
.collection-stack img { display: block; height: auto; object-fit: cover; background: var(--icon-bg); }
.collection-stack .stack-q { display: grid; place-items: center; border-style: dashed; border-color: var(--ink-sub); background: var(--bg); color: var(--ink-sub); font-size: var(--font-heading); font-weight: var(--weight-bold); box-shadow: none; }
.collection-stack > :nth-child(1) { left: 0; top: 14px; transform: rotate(-6deg); }
.collection-stack > :nth-child(2) { left: 14px; top: 8px; transform: rotate(3deg); }
.collection-stack > :nth-child(3) { left: 8px; top: 2px; transform: rotate(-1deg); }
.collection-stack > :only-child { left: 8px; top: 12px; transform: rotate(-2deg); }
.collection-stack-row .grow { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.collection-stack-row .stack-title { font-size: var(--font-body); font-weight: var(--weight-bold); }
.collection-stack-row .collection-count { max-width: none; text-align: left; font-size: var(--font-sub); }
.collection-stack-row .collection-count b { font-size: var(--font-number); font-weight: var(--weight-number); letter-spacing: var(--tracking-number); line-height: 1; margin-right: 2px; }
.collection-stack-row .stack-hint { font-size: var(--font-min); color: var(--ink-sub); }
.collection-stack-row + .sub-text { margin-top: var(--space-3); }

/* 国がわかるマスキングテープ（案E2-c。2026-10-20 柴山さん「3色だけだと分かりにくい」→ 色のしま＋国名）。カードの右上の角に斜めに貼る。
   端は手で切ったようなギザギザ。テープがカードの外にはみ出せるよう、絵の角丸は絵の側で付ける */
.journey-art.has-tape { overflow: visible; }
.journey-art.has-tape > img { border-radius: 10px; }
.journey-tape { position: absolute; z-index: 2; right: -10px; top: 30px; width: 98px; height: 20px; transform: rotate(38deg); opacity: .94; pointer-events: none; }
.journey-tape svg { display: block; width: 100%; height: 100%; clip-path: polygon(3% 0, 97% 0, 100% 18%, 97.5% 36%, 100% 55%, 97% 75%, 100% 100%, 3% 100%, 0 82%, 2.5% 63%, 0 45%, 3% 25%, 0 8%); }
/* 狭い画面（幅320など）では束を少し小さくして、「まだありません」「10日の出勤で1枚目」を1行に収める。
   折り返すと行の高さが変わり、読み込み中の枠（staff.css の h-stamp）とずれて画面が動く（2026-10-20 レビュー ALL-41） */
.collection-stack-row .collection-count, .collection-stack-row .stack-hint { white-space: nowrap; }
@media (max-width: 359px) {
  .collection-stack-row { gap: var(--space-2); }
  .collection-stack { width: 100px; }
  .collection-stack > * { width: 86px; }
}
