/* ワークショップの動画 (video-embed.js) — shared by /, /lp and /progress. Colours fall back to stamp119's tokens.
   The player is YouTube's own frame in a 16:9 box; until it paints, the box shows YouTube's thumbnail. */

/* ---------- the player (made on the tap) ---------- */
.yt-live{position:relative;aspect-ratio:16/9;overflow:hidden;border-radius:inherit;background:#0c1210 var(--yt-thumb,none) center/cover no-repeat}
.yt-live iframe{position:absolute;inset:0;display:block;width:100%;height:100%;border:0}
/* ✕: same look as the picture viewer's (swipe.css .sv-close), 44px, over the player's top-right corner */
.yt-close{position:absolute;z-index:2;top:6px;right:6px;display:grid;place-items:center;width:44px;height:44px;padding:0;border:0;border-radius:50%;cursor:pointer;
  color:var(--ink,#17201d);background:rgb(255 255 255 / .9);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  box-shadow:0 1px 2px rgb(0 0 0 / .08),0 6px 18px rgb(0 0 0 / .22),inset 0 0 0 1px rgb(16 48 40 / .08);
  transition:transform 240ms cubic-bezier(.23,1,.32,1);-webkit-tap-highlight-color:transparent;touch-action:manipulation}
/* ✕ and 🔈 are lucide's own SVGs (video-embed.js LUCIDE), drawn with the bottom menu's line: 24px, 2.4 (富村「アイコンは線太く少し大きく」) */
.vr-ico{display:block;flex:none;width:24px;height:24px;stroke-width:2.4}
/* the app's one press (app.css --press): down in 90ms, back in 240ms */
.yt-close:active{transform:scale(var(--press,.96));transition-duration:90ms}
.yt-close:focus-visible{outline:2px solid var(--focus-ring,#07614f);outline-offset:2px}

/* ---------- the cover on /lp and /progress: YouTube's thumbnail and a play button, the same size as the player ---------- */
.yt{position:relative;aspect-ratio:16/9;overflow:hidden;border-radius:var(--yt-radius,18px);background:#0c1210;isolation:isolate}
.yt>.yt-live{position:absolute;inset:0}
.yt-cover{position:absolute;inset:0;display:block;width:100%;height:100%;margin:0;padding:0;border:0;background:none;color:inherit;font:inherit;cursor:pointer;
  -webkit-tap-highlight-color:transparent;touch-action:manipulation}
.yt-cover img{display:block;width:100%;height:100%;object-fit:cover;transition:transform 420ms cubic-bezier(.23,1,.32,1)}
.yt-cover::after{content:"";position:absolute;inset:0;background:radial-gradient(circle at 50% 50%,rgb(0 0 0 / .18),rgb(0 0 0 / 0) 42%);pointer-events:none}
.yt-play{position:absolute;z-index:1;left:50%;top:50%;display:grid;place-items:center;width:72px;height:72px;margin:-36px 0 0 -36px;border-radius:50%;
  background:rgb(255 255 255 / .94);box-shadow:0 10px 30px rgb(0 0 0 / .3),0 0 0 6px rgb(255 255 255 / .22);transition:transform 240ms cubic-bezier(.23,1,.32,1)}
.yt-play::before{content:"";margin-left:6px;border-left:22px solid var(--ink,#17201d);border-block:13px solid transparent}
.yt-cover:focus-visible{outline:none}
.yt-cover:focus-visible .yt-play{outline:2px solid var(--focus-ring,#07614f);outline-offset:4px}
@media (hover:hover) and (pointer:fine){.yt-cover:hover img{transform:scale(1.025)}.yt-cover:hover .yt-play{transform:scale(1.05)}}
/* the press (app.css --press: down in 90ms, back in 240ms), after the hover so a mouse press shows it too */
.yt-cover:active .yt-play{transform:scale(var(--press,.96));transition-duration:90ms}
@media (max-width:420px){.yt-play{width:60px;height:60px;margin:-30px 0 0 -30px}.yt-play::before{margin-left:5px;border-left-width:18px;border-block-width:11px}}
/* where the video comes from: small, under the video */
.yt-source{margin:8px 2px 0;font-size:12px;font-weight:600;line-height:1.5;color:var(--muted,#66706c)}
/* 「視差効果を減らす」でも動きは同じ。止めるのは揺れと小さな点滅だけ（app.css 末尾の1か所） */

/* ---------- an article's video (/blog/<slug>, /ideas — written by the server, lib/content.mjs videoFigure) ---------- */
.post-video{margin:24px auto;max-width:640px}
.blog-article .post-video .yt-cover img{height:100%;border-radius:0}
.blog-article .post-video .yt-source{text-align:left}
.idea-card .post-video{margin:6px 0 2px;max-width:none}
.idea-card .post-video .yt{--yt-radius:14px}
.idea-card .post-video .yt-play{width:54px;height:54px;margin:-27px 0 0 -27px}
.idea-card .post-video .yt-play::before{margin-left:4px;border-left-width:16px;border-block-width:10px}
.idea-card .post-video .yt-source{margin-top:6px}

/* ---------- the swipe rail (video-rail.js): square (the first video's shape) cards, the middle one plays ----------
   On the top it takes the whole photo step (app.css .wstep.is-video) and reaches the screen's edges, so the side cards
   peek from the edges (phones: the card is 80% of the width and the cards 8px apart, so 22–32px of each neighbour shows;
   富村 2026-09-27). The card is as big as the spot allows after the ✕ row, the title and the dots, at most 84% of the
   screen width and 720px (iPad / PC): it always fits without scrolling. On /lp and /progress (.vr-inline) it sits in the
   page and takes its size from its own box. The thumbnail stays until the first frame is on screen. */
.vr{--vr-close:44px;--vr-meta:30px;--vr-lift:16px;--vr-pad-top:8px;--vr-pad-bottom:28px;--vr-max:min(84vw,720px);
  --vr-h:min(100cqh - var(--vr-close) - var(--vr-meta) - var(--vr-pad-top) - var(--vr-pad-bottom) - 8px,var(--vr-max) / var(--vr-a,1));
  --vr-w:calc(var(--vr-h) * var(--vr-a,1));
  position:absolute;top:0;bottom:0;left:calc(50% - 50vw);right:calc(50% - 50vw);display:flex;flex-direction:column;justify-content:center;min-width:0}
/* the row above the card, as wide as it: 🔈 at its left end (our own files only), ✕ at its right end — nothing on the
   video itself, so the CMs' own words (their bottom band) are never covered */
.vr-top{flex:none;display:flex;align-items:center;width:var(--vr-w);height:var(--vr-close);margin:0 auto}
.vr-close.yt-close{position:relative;top:auto;right:auto;flex:none;margin:0 -4px 0 auto}
.vr-track.cf{--cf-item:var(--vr-w);--cf-gap:14px;flex:none;align-items:center;padding-block:var(--vr-pad-top) var(--vr-pad-bottom);
  height:calc(var(--vr-h) + var(--vr-pad-top) + var(--vr-pad-bottom));box-sizing:border-box}
/* phones: the card is 80% of the width and the cards 7px apart, so 22–28px of each neighbour shows (the sign that it swipes;
   320px wide: 22.5px — with 8px it was 21.6) */
@media (max-width:499px){.vr{--vr-max:80vw}.vr-track.cf{--cf-gap:7px}}
/* Everywhere else the same 28px (富村: 22–32px): the track shows a window — the middle card, the gaps and 28px of each
   neighbour — instead of 190–390px of the next card on an iPad on its side, a PC or a phone on its side (UI review r3).
   swipe.js coverflow (the rails' min .8, k 1.35) sets a neighbour at rest .9372 of a step out and scales it .8518, so its
   inner edge is .5113 × the card + .9372 × the gap from the middle. Where the neighbours show 28px or less anyway (phones)
   max() is 0: nothing is cut. (-24px above and below: it never cuts across the cards.) Where it cuts (wider than a phone held
   upright, or on its side), the last 12px fade out — the neighbour melts into the page instead of ending on a straight
   line in the air (the phones' neighbours end at the screen's edge: no mask there). */
.vr-track.cf{--vr-cut:max(0px,calc(50% - var(--vr-w) * .5113 - var(--cf-gap) * .9372 - 28px));clip-path:inset(-24px var(--vr-cut))}
@media (min-width:431px),(orientation:landscape){
  .vr-track.cf{--vr-fade:min(12px,var(--vr-cut));
    -webkit-mask-image:linear-gradient(90deg,transparent var(--vr-cut),#000 calc(var(--vr-cut) + var(--vr-fade)),#000 calc(100% - var(--vr-cut) - var(--vr-fade)),transparent calc(100% - var(--vr-cut)));
    mask-image:linear-gradient(90deg,transparent var(--vr-cut),#000 calc(var(--vr-cut) + var(--vr-fade)),#000 calc(100% - var(--vr-cut) - var(--vr-fade)),transparent calc(100% - var(--vr-cut)))}
}
.vr-item{position:relative;height:var(--vr-h);border-radius:24px;overflow:hidden;background:#0c1210;isolation:isolate;touch-action:pan-x pinch-zoom;
  box-shadow:0 1px 2px rgb(0 0 0 / .1),0 12px 24px -8px rgb(12 30 24 / .3)}
/* a video file without a cover: a soft tint until its own first frame (video-rail.js frameCover) is there — never black */
.vr-item.no-cover{background:linear-gradient(160deg,#e4ece9,#c2d3cd)}
/* One flick = one video (a fast flick does not skip past the next one). */
.vr-track>.vr-item{scroll-snap-stop:always}
.vr-item:has(.vr-hit:focus-visible){outline:2px solid var(--focus-ring,#07614f);outline-offset:3px}
.vr-poster,.vr-media,.vr-frame{position:absolute;inset:0;display:block;width:100%;height:100%;border:0}
.vr-media{z-index:0;object-fit:contain;background:transparent}
.vr-poster{z-index:1;object-fit:cover;transition:opacity 160ms cubic-bezier(.23,1,.32,1)}
.vr-item.has-frame .vr-poster{opacity:0}
.vr-frame{z-index:3;transition:opacity 220ms cubic-bezier(.23,1,.32,1)}
.vr-frame.is-loading{opacity:0}
.vr-hit{position:absolute;inset:0;z-index:2;margin:0;padding:0;border:0;border-radius:inherit;background:transparent;color:inherit;cursor:pointer;
  -webkit-tap-highlight-color:transparent;touch-action:pan-x pinch-zoom}
.vr-hit:focus{outline:none}
.vr-item.has-frame-live .vr-hit{pointer-events:none}
/* ▶ only when the viewer paused it (or the last one ended), and on /lp and /progress before the first tap (.is-cued):
   it never flickers in while the next one is on its way */
.vr-play{position:absolute;z-index:4;left:50%;top:50%;display:grid;place-items:center;width:68px;height:68px;margin:-34px 0 0 -34px;border-radius:50%;
  background:rgb(255 255 255 / .9);-webkit-backdrop-filter:blur(14px) saturate(160%);backdrop-filter:blur(14px) saturate(160%);
  box-shadow:0 10px 28px rgb(0 0 0 / .28),0 0 0 6px rgb(255 255 255 / .18);opacity:0;scale:.94;pointer-events:none;
  transition:opacity 200ms cubic-bezier(.23,1,.32,1),scale 200ms cubic-bezier(.23,1,.32,1)}
.vr-play::before{content:"";margin-left:5px;border-left:21px solid var(--ink,#17201d);border-block:12.5px solid transparent}
.vr-item.is-paused .vr-play{opacity:1;scale:1}
.vr.is-cued .vr-item.is-center .vr-play{opacity:1;scale:1}
/* how far the playing video has got: a thin line inside the card's rounded corners (14px in, 10px up), over a faint
   track, under the CMs' words */
.vr-line{position:absolute;z-index:4;left:14px;right:14px;bottom:10px;height:3px;border-radius:2px;overflow:hidden;background:rgb(255 255 255 / .28);opacity:0;
  transition:opacity 200ms cubic-bezier(.23,1,.32,1);pointer-events:none}
.vr-bar{position:absolute;inset:0;background:rgb(255 255 255 / .92);transform:scaleX(0);transform-origin:0 50%}
.vr-item.is-playing .vr-line,.vr-item.is-paused .vr-line{opacity:1}
.vr-item::after{content:"";position:absolute;z-index:3;inset:auto 0 0;height:26%;background:linear-gradient(rgb(0 0 0 / 0),rgb(0 0 0 / .3));opacity:0;
  transition:opacity 200ms cubic-bezier(.23,1,.32,1);pointer-events:none}
.vr-item.is-playing::after,.vr-item.is-paused::after{opacity:1}
/* 🔈 (lucide volume-2 / volume-x): mute / unmute. One button, in the row above the card, the same frosted 44px circle as ✕ */
.vr-sound{position:relative;z-index:5;display:grid;place-items:center;flex:none;width:44px;height:44px;margin:0 0 0 -4px;padding:0;border:0;border-radius:50%;
  color:var(--ink,#17201d);background:rgb(255 255 255 / .9);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);cursor:pointer;
  box-shadow:0 1px 2px rgb(0 0 0 / .08),0 6px 18px rgb(0 0 0 / .22),inset 0 0 0 1px rgb(16 48 40 / .08);-webkit-tap-highlight-color:transparent;touch-action:manipulation;
  transition:transform 240ms cubic-bezier(.23,1,.32,1)}
.vr-sound:active{transform:scale(var(--press,.96));transition-duration:90ms}
.vr-sound:focus{outline:none}
.vr-sound:focus-visible{outline:2px solid var(--focus-ring,#07614f);outline-offset:2px}
.vr-ico-volume-x,.vr.is-muted .vr-ico-volume-2{display:none}
.vr.is-muted .vr-ico-volume-x{display:block}
/* title of the middle video (it changes once the rail rests; while a finger holds another card in the middle it dims),
   where it comes from (YouTube only), dots. The title sits 14px under the card (closer to it than to anything else). */
.vr-meta{flex:none;display:grid;justify-items:center;align-content:start;gap:4px;min-width:0;min-height:calc(var(--vr-meta) + var(--vr-lift));
  margin-top:calc(0px - var(--vr-lift));padding:2px 16px 0;box-sizing:border-box}
.vr-title{max-width:100%;margin:0;overflow:hidden;font-size:15px;font-weight:700;line-height:1.45;letter-spacing:.01em;color:var(--ink,#17201d);
  text-align:center;text-overflow:ellipsis;white-space:nowrap}
.vr-title,.vr-source{transition:opacity 140ms cubic-bezier(.23,1,.32,1)}
.vr-meta.is-stale>:is(.vr-title,.vr-source){opacity:.35}
.vr-source{margin:-2px 0 0;font-size:11.5px;font-weight:600;line-height:1.4;color:var(--muted,#66706c)}
.vr-source[hidden]{display:none}
.vr.has-yt{--vr-meta:46px}
.vr-dots{margin:2px 0 0}
.vr-status{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* keys get no motion (video-rail.js keyed): opened with Enter / Space, or moved or paused with a key, the rail changes at once */
.vr-instant,.vr-instant *,.vr-instant *::before,.vr-instant *::after{transition:none!important}
@container stage (min-width:500px){.vr{--vr-meta:38px}.vr.has-yt{--vr-meta:56px}.vr-title{font-size:17px}.vr-dots i{width:8px;height:8px}}
@container stage (max-height:300px){.vr{--vr-meta:24px;--vr-lift:0px;--vr-pad-bottom:12px}.vr.has-yt{--vr-meta:44px}.vr-dots{display:none}.vr-play{width:56px;height:56px;margin:-28px 0 0 -28px}}
/* /lp and /progress: the rail in the page. The box is the size: the card is 80% of its width (at most 480px and 60% of
   the screen's height), and it waits for a tap (▶) — the page never starts a video by itself. */
.vr-host{position:relative;container:vrhost/inline-size}
.vr.vr-inline{position:relative;top:auto;bottom:auto;left:auto;right:auto;--vr-pad-top:6px;--vr-fill:80cqw;
  --vr-h:min(var(--vr-fill) / var(--vr-a,1),480px / var(--vr-a,1),60svh)}
/* an SE (a box under 300px): 74% of it, so the neighbours show 22px or more there too (80%: 17.8px) */
@container vrhost (max-width:300px){.vr.vr-inline{--vr-fill:74cqw}}
/* 🔈 at the card's left end, the same place as on the top (it used to take the right end here: nothing to close) */
.vr-inline .vr-sound{margin:0 auto 0 -4px}
.vr-inline .vr-meta{padding-inline:8px}
@container vrhost (min-width:500px){.vr-inline{--vr-meta:38px}.vr-inline .vr-title{font-size:17px}.vr-inline .vr-dots i{width:8px;height:8px}}
/* /lp (style.css .video-section): on phones the rail runs to the section's inner edges, like its other rails */
.video-section .vr-host{margin-block:2px 0}
.video-section:has(.vr-host) .video-copy h2{word-break:keep-all;overflow-wrap:anywhere;text-wrap:balance}
@media (max-width:760px){.video-section .vr-host{margin-inline:-18px}}
/* iPad・PC (two columns): the rail runs to the section's right border and is cut by its rounded frame (overflow:clip), not
   by an invisible line 28px inside it (UI review r3) */
@media (min-width:761px){.video-section:has(.vr-host){overflow:clip}.video-section .vr-host{margin-inline-end:-28px}}
/* While /lp's setting is on the way (video-embed.js: data-yt-pending) the section keeps its room, invisible, as tall as
   the CMs' rail will be, so nothing under it jumps when it comes (UI review r3: 590–670px in one frame). The rail's box is
   the figure plus the section's padding it runs into (36px on a phone, 28px on iPad・PC); its card is 80% of that (74%
   under 300px), at most 480px and 60% of the screen; around it the 🔈 row, the pads, the title and the 2px above: 110px
   (118px from a 500px box, whose title is 38px tall). The description and the source line are not there on the rail. */
[data-yt-section][data-yt-pending]{visibility:hidden}
[data-yt-section][data-yt-pending] :is([data-yt-text=desc],.yt-source){display:none}
.video-section[data-yt-pending] .video-figure{container:ytfig/inline-size}
.video-section[data-yt-pending] .yt[data-yt]{aspect-ratio:auto;height:calc(min((100cqw + 28px) * .8,480px,60svh) + 110px)}
@container ytfig (min-width:472px){.video-section[data-yt-pending] .yt[data-yt]{height:calc(min((100cqw + 28px) * .8,480px,60svh) + 118px)}}
@media (max-width:760px){
  .video-section[data-yt-pending] .yt[data-yt]{height:calc(min((100cqw + 36px) * .8,480px,60svh) + 110px)}
  @container ytfig (max-width:263px){.video-section[data-yt-pending] .yt[data-yt]{height:calc(min((100cqw + 36px) * .74,480px,60svh) + 110px)}}
  @container ytfig (min-width:464px){.video-section[data-yt-pending] .yt[data-yt]{height:calc(min((100cqw + 36px) * .8,480px,60svh) + 118px)}}
}
/* a phone on its side (the top only): the card gets the screen's height (app.css hides the header and the bottom menu
   while the rail is out); ✕ and 🔈 sit in the screen's top-right corner, one above the other — where a full-screen player
   keeps them, outside the card (and its 28px neighbour), so nothing covers the CMs' own words (the r3 corner inside the
   card hid 「！？」 of 第3話). The dots stay, beside the title. (.photo-stage is a container: absolute, not fixed.) */
@media (orientation:landscape) and (max-height:500px){
  .vr:not(.vr-inline){--vr-close:0px;--vr-meta:24px;--vr-lift:0px;--vr-pad-top:6px;--vr-pad-bottom:10px}
  .vr:not(.vr-inline) .vr-top{position:absolute;z-index:6;top:max(8px,env(safe-area-inset-top));right:max(12px,env(safe-area-inset-right));
    width:auto;height:auto;margin:0;flex-direction:column;gap:8px}
  .vr:not(.vr-inline) .vr-close.yt-close{order:-1;margin:0}
  .vr:not(.vr-inline) .vr-sound{margin:0}
  .vr:not(.vr-inline) .vr-meta{grid-auto-flow:column;justify-content:center;align-items:center;gap:10px}
  .vr:not(.vr-inline) .vr-dots{display:flex;margin:0}
}
/* 200% text (a 195px-wide page): the title takes two lines instead of 「第1話 沖縄のおばーLIN…」 (WCAG 1.4.4) */
@media (max-width:260px){.vr-title{white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;text-overflow:clip}}
/* iPhone 「透明度を下げる」: the frosted buttons are solid (app.css does the same for the header, the capsule and 「▶ 動画」) */
@media (prefers-reduced-transparency:reduce){.vr-sound,.yt-close,.vr-play{background:#fff;-webkit-backdrop-filter:none;backdrop-filter:none}}
/* Windows のハイコントラスト (forced-colors): ▶ is a border triangle, and the forced colours painted its transparent top and
   bottom too — a square, 「停止」's ■ (UI review r3). It keeps its own borders; the point takes the text colour. (Written
   with a space after the colon: test/video-embed.test.mjs reads that word glued to a colon as a press.) */
@media (forced-colors: active){.vr-play::before,.yt-play::before{forced-color-adjust:none;border-left-color:CanvasText}}
/* ⛶ sits right after 🔈, the same circle */
.vr-expand{margin:0 0 0 8px}
.vr-inline .vr-sound{margin:0 0 0 -4px}
.vr-inline .vr-expand{margin:0 auto 0 8px}
@media (orientation:landscape) and (max-height:500px){.vr:not(.vr-inline) .vr-expand{margin:0}}
/* ⛶ the same 44px frosted circle and press as 🔈 */
.vr-expand{position:relative;z-index:5;display:grid;place-items:center;flex:none;width:44px;height:44px;padding:0;border:0;border-radius:50%;
  color:var(--ink,#17201d);background:rgb(255 255 255 / .9);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);cursor:pointer;
  box-shadow:0 1px 2px rgb(0 0 0 / .08),0 6px 18px rgb(0 0 0 / .22),inset 0 0 0 1px rgb(16 48 40 / .08);-webkit-tap-highlight-color:transparent;touch-action:manipulation;
  transition:transform 240ms cubic-bezier(.23,1,.32,1)}
.vr-expand:active{transform:scale(var(--press,.96));transition-duration:90ms}
.vr-expand:focus{outline:none}
.vr-expand:focus-visible{outline:2px solid var(--focus-ring,#07614f);outline-offset:2px}
@media (prefers-reduced-transparency:reduce){.vr-expand{background:#fff;-webkit-backdrop-filter:none;backdrop-filter:none}}
