/* /s/stay 목업 주입분 — 헤더 미니 플레이어 · 캐치프레이즈 전환. ★ 색·테두리·서체를 전부 템플릿 변수(--tpl-*)에서 가져온다. 값을 박으면 템플릿을 바꿀 때 플레이어만 옛 색으로 남는다. ★ 플레이어는 헤더 **안**이다. 하단 바는 모바일 탭바(fixed bottom:0 · 61px)를 덮었고, 상단 바는 헤더와 두 줄이 됐다. 헤더 안이면 화면에서 차지하는 줄이 늘지 않는다. */ /* ── 헤더에 꽂는 아이콘 세 개 ─────────────────────────────────────── */ #w4d-mini { display: inline-flex; align-items: center; gap: 2px; margin-right: 6px; padding-right: 8px; border-right: 1px solid var(--tpl-border, #bcb49e); } #w4d-mini button { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; padding: 0; color: var(--tpl-text, #1b1a15); background: transparent; border: 0; border-radius: var(--tpl-radius, 0); cursor: pointer; opacity: 0.75; } #w4d-mini button:hover { opacity: 1; background: rgb(27 26 21 / 0.06); } #w4d-mini svg { width: 16px; height: 16px; } /* 지금 나오는 곡명. 좁은 화면에서는 헤더에 자리가 없어 접는다 — 실측(390px): 상호 115px + 오른쪽 묶음 94px 이라 남는 폭이 55px 뿐이다. 그 화면에서는 목록을 열면 재생 중인 줄에 곡명과 시간이 있다. */ #w4d-now { max-width: 150px; overflow: hidden; font-size: 11.5px; font-weight: 700; white-space: nowrap; text-overflow: ellipsis; color: var(--tpl-accent, #bf2f1b); padding-right: 2px; } #w4d-mini[data-playing='0'] #w4d-now { opacity: 0.55; font-weight: 400; } @media (max-width: 860px) { #w4d-now { display: none; } } /* 카세트 — 단추가 아니라 표지다. 이 자리가 무엇인지 한눈에 말해 준다. */ #w4d-tape { display: inline-flex; align-items: center; padding: 0 4px 0 2px; color: var(--tpl-text, #1b1a15); opacity: 0.8; } #w4d-tape svg { width: 20px; height: 20px; } #w4d-mini[data-playing='1'] #w4d-tape { color: var(--tpl-accent, #bf2f1b); opacity: 1; } /* 재생 중에는 릴이 돈다 — 소리가 나고 있다는 것을 글자 없이 말한다. */ #w4d-mini[data-playing='1'] .w4d-reel { transform-box: fill-box; transform-origin: center; animation: w4d-reel 2.6s linear infinite; } @keyframes w4d-reel { to { transform: rotate(360deg); } } @media (prefers-reduced-motion: reduce) { .w4d-reel { animation: none !important; } } /* 재생 중일 때만 강조색 — 헤더에 곡명을 안 두므로 색이 유일한 '지금 나온다' 표시다. */ #w4d-mini button[data-playing='1'] { color: var(--tpl-accent, #bf2f1b); opacity: 1; } @media (max-width: 400px) { #w4d-mini { margin-right: 2px; padding-right: 4px; } #w4d-mini button { width: 27px; height: 27px; } } /* ── 목록 패널 (헤더 아래에 떠 있다) ────────────────────────────── ★ 좁은 화면에서는 좌우 8px 만 남기고 펼친다. 320px 고정이었을 때 390px 화면에서 제목이 두 줄로 접히고 시간이 잘렸다(2026-09-11 사장님: "모바일 대응이 안 되어 있음"). */ #w4d-panel { position: fixed; z-index: 45; /* 사이트 헤더가 z-40 이라 그 위 */ width: 344px; max-width: calc(100vw - 16px); max-height: min(64vh, 520px); display: flex; flex-direction: column; overflow: hidden; font-family: var(--tpl-font-body, serif); color: var(--tpl-text, #1b1a15); background: var(--tpl-card, #efe7d3); border: var(--tpl-border-width, 2px) solid var(--tpl-primary, #1b1a15); box-shadow: var(--tpl-shadow, 4px 4px 0 rgb(27 26 21 / 0.16)); } #w4d-panel[hidden] { display: none; } @media (max-width: 640px) { #w4d-panel { width: auto; } } #w4d-panel .w4d-head { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; padding: 11px 8px 11px 14px; border-bottom: var(--tpl-border-width, 2px) solid var(--tpl-primary, #1b1a15); } .w4d-head-t { font-size: 12px; font-weight: 700; letter-spacing: 0.06em; } .w4d-head-n { flex: 1 1 auto; font-size: 11px; opacity: 0.5; } #w4d-panel .w4d-head button { display: inline-flex; width: 28px; height: 28px; flex: 0 0 auto; align-items: center; justify-content: center; color: inherit; background: transparent; border: 0; cursor: pointer; opacity: 0.6; } #w4d-panel .w4d-head button:hover { opacity: 1; } #w4d-panel .w4d-head svg { width: 14px; height: 14px; } #w4d-panel ol { flex: 1 1 auto; margin: 0; padding: 4px 0; overflow-y: auto; list-style: none; -webkit-overflow-scrolling: touch; } /* 한 줄 = 판 + 제목/가수 + 시간. 48px 아래로 내리지 않는다 — 손가락으로 누르는 자리다. */ .w4d-item { display: flex; width: 100%; min-height: 52px; align-items: center; gap: 11px; padding: 8px 14px; color: inherit; background: transparent; border: 0; font: inherit; text-align: left; cursor: pointer; } .w4d-item + .w4d-item { border-top: 1px dashed var(--tpl-border, #bcb49e); } .w4d-item:hover { background: rgb(27 26 21 / 0.05); } .w4d-item[aria-current='true'] { background: rgb(27 26 21 / 0.06); } .w4d-item[aria-current='true'] .w4d-t { color: var(--tpl-accent, #bf2f1b); } /* 판 자리. 재생 중인 줄에서는 판 대신 막대가 뛴다. */ .w4d-mark { position: relative; flex: 0 0 26px; height: 26px; } .w4d-disc-sm { position: absolute; inset: 0; border-radius: 50%; background: radial-gradient(circle at 50% 50%, var(--w4d-lbl, #bf2f1b) 0 34%, transparent 34%), repeating-radial-gradient(circle at 50% 50%, rgb(255 255 255 / 0.12) 0 1px, transparent 1px 3px), #14110f; } .w4d-disc-sm::after { content: ''; position: absolute; inset: 45%; border-radius: 50%; background: var(--tpl-card, #efe7d3); } .w4d-eq { position: absolute; inset: 0; display: none; align-items: flex-end; justify-content: center; gap: 3px; padding-bottom: 4px; } .w4d-eq i { width: 3px; height: 6px; background: var(--tpl-accent, #bf2f1b); animation: w4d-eq 0.9s ease-in-out infinite; } .w4d-eq i:nth-child(2) { animation-delay: 0.18s; } .w4d-eq i:nth-child(3) { animation-delay: 0.36s; } @keyframes w4d-eq { 0%, 100% { height: 5px; } 50% { height: 17px; } } .w4d-item[data-playing='1'] .w4d-disc-sm { display: none; } .w4d-item[data-playing='1'] .w4d-eq { display: flex; } @media (prefers-reduced-motion: reduce) { .w4d-eq i { animation: none; height: 11px; } } .w4d-info { min-width: 0; flex: 1 1 auto; } .w4d-t { display: block; overflow: hidden; font-size: 13.5px; font-weight: 700; white-space: nowrap; text-overflow: ellipsis; } .w4d-sub { display: block; margin-top: 2px; overflow: hidden; font-size: 11px; white-space: nowrap; text-overflow: ellipsis; opacity: 0.55; } .w4d-time { flex: 0 0 auto; font-size: 11px; opacity: 0.6; font-variant-numeric: tabular-nums; } /* 가사 — 우리 곡만. 종이 위 인쇄물처럼 둔다. */ #w4d-lyrics-box { padding: 10px 12px 14px; border-top: 1px dashed var(--tpl-border, #bcb49e); white-space: pre-line; font-size: 12px; line-height: 1.9; } #w4d-lyrics-box[hidden] { display: none; } /* ★ 이용 정보 맨 아래 가로선을 지운다 (2026-09-10 사장님 지시).
이 아니라 바로 뒤 '예약은 아래로 받습니다' 블록의 border-t 다 — 마지막 항목 밑에 선이 한 줄 더 그어져 빈 칸이 하나 더 있는 것처럼 보인다. 항목 자체는 그대로 둔다. 마크업을 고치면 하이드레이션이 되돌리므로 CSS 로 끈다. */ #root div.border-line.flex.flex-col.gap-3.border-t.pt-6 { border-top-width: 0; } /* 사진 저작자 표시 — 출처 줄과 같은 크기, 한 단 더 옅게. */ .w4d-credit { margin-top: 2px; font-size: 10px; opacity: 0.55; } /* ★ 모바일 헤더에서 전화 단추를 접는다 (2026-09-11 사장님: "저 전화 아이콘은 빼도 되잖아"). 좁은 화면 헤더에 상호 + 플레이어 3개 + 전화 + 메뉴가 다 서서 난잡했다. ★ 전화가 사라지는 게 아니다 — 이 화면 폭에서는 **하단 탭바에 전화가 이미 있다** (실측: NAV fixed bottom:0 · 위치 · 전화 · 네이버 예약). 같은 것이 두 번 서 있던 것이다. ★ 넓은 화면에서는 탭바가 없으므로 그대로 둔다. */ @media (max-width: 860px) { #root header .shell > div:last-child > a[href^="tel:"] { display: none; } } /* 덧붙인 링크 — 본문 글자보다 눈에 띄되 강조색을 남발하지 않는다. */ .w4d-link { color: var(--tpl-accent, #bf2f1b); text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; } /* ── 캐치프레이즈 등장 ──────────────────────────────────────────── ★ 줄 전체를 페이드하지 않고 **단어가 마스크 안에서 올라온다.** 한 줄짜리 문장은 통째로 흐려지면 '바뀌었다'만 보이고 문장이 안 읽힌다 — 왼쪽부터 차례로 서면 눈이 첫 단어에서 읽기를 시작한다. ★ 나갈 때는 반대로 위로 빠지며 흐려진다. 들어오는 방향과 나가는 방향이 같으면 두 문장이 같은 자리에서 겹쳐 보인다. ★ 자리 흔들림: 처음 구워진 줄 높이를 min-height 로 박아 둔다(스크립트가 잰다). 문장 길이가 달라 한 줄↔두 줄이 오갈 때 히어로 아래가 튀는 것을 막는다. */ .w4d-line { display: block; } .w4d-line--out { opacity: 0; transform: translateY(-5px); filter: blur(3px); transition: opacity 0.3s ease, transform 0.3s ease, filter 0.3s ease; } .w4d-line--in { opacity: 1; transform: none; filter: none; transition: opacity 0.3s ease, transform 0.3s ease, filter 0.3s ease; } /* 단어 한 칸 = 마스크. 안쪽 글자가 아래에서 올라온다. */ .w4d-w { display: inline-block; overflow: hidden; vertical-align: bottom; } .w4d-w > span { display: inline-block; transform: translateY(112%); opacity: 0; filter: blur(4px); } .w4d-line--in .w4d-w > span { animation: w4d-rise 0.62s cubic-bezier(0.16, 0.84, 0.28, 1) forwards; animation-delay: var(--w4d-d, 0ms); } @keyframes w4d-rise { from { transform: translateY(112%); opacity: 0; filter: blur(4px); } 60% { filter: blur(0); } to { transform: translateY(0); opacity: 1; filter: blur(0); } } @media (prefers-reduced-motion: reduce) { .w4d-line--out, .w4d-line--in { transition: none; opacity: 1; transform: none; filter: none; } .w4d-w > span { transform: none; opacity: 1; filter: none; animation: none; } } /* 가사 — 우리 곡만. 종이 위 인쇄물처럼 둔다. */ #w4d-lyrics-box { max-width: 1120px; margin: 0 auto; padding: 12px 16px 16px; border-top: 1px dashed var(--tpl-border, #bcb49e); white-space: pre-line; font-size: 13px; line-height: 1.9; max-height: 40vh; overflow-y: auto; } #w4d-lyrics-box[hidden] { display: none; } /* * 일정 정거장 번호 — 제목 글자와 세로 중심을 맞춘다. * * 번호 동그라미는 inline-grid 라 **안에 든 숫자(10px)의 베이스라인**이 제목(14px)의 * 베이스라인에 붙는다. 숫자가 17px 상자 한가운데 있으니 동그라미 중심은 그만큼 아래로 * 내려가고, 렌더러가 얹은 translate-y-px 가 1px 더 내린다. * 실측(1280·390 공통): 동그라미 중심이 제목 줄 중심보다 3.14px 아래. * 2px 올리면 0.14px — 반올림해서 눈에 안 걸리는 자리다. */ #itinerary ol li span.inline-grid.rounded-full { translate: 0 -2px; transform: none; } /* * 날씨 그림 — 움직임만 끈다 (2026-09-11, 사장님: "날씨 애니메이션 지워줘") * 그림 자체는 남는다. `prefers-reduced-motion` 에서 보이는 것과 같은 상태다 * (weather.css 가 "멈춘 상태도 그림으로 성립해야 한다"는 전제로 그려져 있다). * 그림까지 없애려면 아래 두 줄의 주석을 푼다. */ #weather .w4-sky::before, #weather .w4-sky::after { animation: none !important; } /* #weather .w4-sky { display: none; } */