/* ============================================================
   UI riêng của bản live (spec v2.1): chấm trạng thái mạng, dòng cue "sắp lên LED",
   toast "đang trên LED", nút admin 30s, vòng đếm ngược quanh nút tim, triện hiệu ứng,
   băng rôn "đang cầm sân khấu". Không đụng app-stage.css / app-wish.css đã duyệt.
   ============================================================ */
.s4-net{position:absolute;right:14px;top:max(14px,calc(env(safe-area-inset-top) + 8px));z-index:7;width:8px;height:8px;border-radius:50%;
  background:#7de0a0;box-shadow:0 0 8px #7de0a0;opacity:0;transition:opacity .3s,background .3s}
#sc2.net-connecting .s4-net,#sc2.net-reconnecting .s4-net{opacity:1;background:#e0a97d;box-shadow:0 0 8px #e0a97d}
#sc2.net-offline .s4-net{opacity:1;background:#e07d7d;box-shadow:0 0 8px #e07d7d}

.s4-cue{position:absolute;left:14px;right:14px;bottom:calc(var(--s4-btn) + var(--s4-pad) + 16px + env(safe-area-inset-bottom));z-index:11;
  text-align:center;pointer-events:none;font:500 11px 'Be Vietnam Pro',system-ui,sans-serif;letter-spacing:.18em;text-transform:uppercase;
  color:#f3dea3;text-shadow:0 2px 10px rgba(0,0,0,.95);opacity:0;transform:translateY(6px);transition:opacity .3s,transform .3s}
.s4-cue.on{opacity:1;transform:none}
.s4-cue b{font-weight:600;color:#fff}

.s4-toast{position:absolute;left:50%;top:18%;transform:translate(-50%,-8px);z-index:12;pointer-events:none;white-space:nowrap;
  padding:9px 16px;border-radius:999px;background:rgba(9,7,12,.78);border:1px solid rgba(243,222,163,.6);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  font:500 12px 'Be Vietnam Pro',system-ui,sans-serif;letter-spacing:.12em;text-transform:uppercase;color:#f3dea3;
  opacity:0;transition:opacity .3s,transform .3s}
.s4-toast.on{opacity:1;transform:translate(-50%,0)}

/* Nút đưa lời chúc lên LED — icon tròn ngồi cuối dòng ký tên của thẻ lời chúc.
   Bản trước là viên thuốc chữ to nằm đè ngang giữa câu chúc, che mất chỗ đang đọc.
   Nút KHÔNG nằm trong .mywish: thẻ đó cứ vài giây lại mượn để đọc lời chúc khách khác và làm mờ cả
   dòng ký tên, nút nằm trong là chớp tắt theo. z-12 để nổi trên lớp tim (.jp-layer z-11). */
#sc2 .s4-led{position:absolute;right:14px;z-index:12;width:38px;height:38px;border-radius:50%;padding:0;
  bottom:calc(var(--s4-btn) + var(--s4-pad) + 5px + env(safe-area-inset-bottom));
  display:grid;place-items:center;cursor:pointer;pointer-events:auto;
  border:1px solid rgba(243,222,163,.55);background:rgba(11,10,13,.5);color:var(--gold2);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  box-shadow:0 10px 22px -12px rgba(0,0,0,.9);transition:transform .12s,opacity .3s,border-color .3s,box-shadow .3s}
/* Icon là chính logo F đính kim cương của FANOS (fanos-logo.webp, nền trong).
   20px là cỡ lớn nhất còn chừa được vành tối quanh logo trong khung tròn 38px. */
#sc2 .s4-led .mark{width:20px;height:auto;display:block;user-select:none;-webkit-user-drag:none}
#sc2 .s4-led:active{transform:scale(.92)}
/* Bấm được thì phải mời gọi: viền vàng sáng thở nhẹ, đủ để mắt tìm ra nút mà không nhảy múa. */
#sc2 .s4-led:not([disabled]){animation:s4ledcall 2.8s ease-in-out infinite}
@keyframes s4ledcall{0%,100%{box-shadow:0 10px 22px -12px rgba(0,0,0,.9),0 0 0 0 rgba(243,222,163,0)}
  55%{box-shadow:0 10px 22px -12px rgba(0,0,0,.9),0 0 14px -2px rgba(243,222,163,.55)}}
#sc2 .s4-led[disabled]{cursor:default;animation:none}
#sc2 .s4-led.sending{opacity:.55}
/* Màn đang chiếu lời chúc của người khác: nút xám lại, huy hiệu đếm ngược giây còn lại. */
#sc2 .s4-led.busy{opacity:.5;border-color:rgba(243,222,163,.25)}
#sc2 .s4-led.busy .mark{filter:grayscale(1) brightness(.8)}
#sc2 .s4-led .cd{position:absolute;right:-3px;bottom:-3px;min-width:17px;height:17px;padding:0 3px;border-radius:9px;
  display:grid;place-items:center;background:rgba(9,7,12,.92);border:1px solid rgba(243,222,163,.45);
  font:600 9px 'Be Vietnam Pro',system-ui,sans-serif;color:#f3dea3;line-height:1}
#sc2 .s4-led .cd:empty{display:none}
#sc2.onstage .s4-led{display:none}

/* đang cầm sân khấu: vòng vàng vơi dần quanh nút tim đúng 30s (--stagems do JS đặt), triện sáng lên và ghi "→ LED" */
#sc2.onstage .jp-heartbtn::after{opacity:1;inset:-5px;border:0;
  background:conic-gradient(#f3dea3 var(--p,100%),rgba(255,255,255,.1) 0);
  -webkit-mask:radial-gradient(circle,transparent 70%,#000 72%);mask:radial-gradient(circle,transparent 70%,#000 72%);
  animation:s4stage var(--stagems,30000ms) linear forwards}
@keyframes s4stage{from{--p:100%}to{--p:0%}}
#sc2.onstage .s4-seal{border-color:rgba(243,222,163,.95);box-shadow:0 0 18px -4px rgba(243,222,163,.8)}
#sc2.onstage .s4-seal .lb::after{content:'→ LED';display:block;font-size:6.5px;letter-spacing:.14em;margin-top:2px;color:#fff}
.s4-seal.fire{display:none}
#sc2.onstage .s4-seal.fire{display:grid}
.s4-banner{position:absolute;left:50%;top:max(98px,13cqh,calc(env(safe-area-inset-top) + 84px));z-index:13;
  transform:translate(-50%,-4px);width:max-content;max-width:calc(100vw - 56px);display:flex;flex-direction:column;align-items:center;gap:3px;
  padding:8px 13px 9px;border-radius:999px;border:1px solid rgba(243,222,163,.46);
  background:rgba(8,6,11,.66);box-shadow:0 16px 36px -22px rgba(0,0,0,.95),inset 0 1px 0 rgba(255,255,255,.1);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  text-align:center;pointer-events:none;color:#f3dea3;text-shadow:0 2px 8px rgba(0,0,0,.95);opacity:0;transition:opacity .3s,transform .3s}
.s4-banner b{display:block;font:600 10px/1.1 'Be Vietnam Pro',system-ui,sans-serif;letter-spacing:.14em;text-transform:uppercase;color:#fff7dd}
.s4-banner span{display:block;font:500 9px/1.1 'Be Vietnam Pro',system-ui,sans-serif;letter-spacing:.08em;text-transform:uppercase;color:#f3dea3}
#sc2.onstage .s4-banner{opacity:1}

/* ============================================================
   v3 — phần viết: ảnh khách + consent lưu kỷ niệm.
   ============================================================ */
.s1-extra{display:block;margin-top:18px}
/* Ô «Thêm ảnh» — mẫu anh Trí 24/09: huy hiệu tròn 88px trồi ra góc trên phải tấm viết
   (trồi 0,37 d lên trên mép, lấn ra phải 5px), nền tối đặc để che mép tấm, viền nét đứt vàng,
   icon máy ảnh + chữ. Neo theo .sheet (position:absolute) chứ không nằm trong luồng form.
   Có ảnh: ảnh phủ kín vòng, viền thành vành kem + chỉ vàng — đúng huy hiệu ảnh khách trên
   thẻ LED/sân khấu, khách thấy trước ảnh mình sẽ lên màn trông ra sao. */
.s1-photo{--ph:88px;position:absolute;z-index:2;top:calc(var(--ph) * -.37);right:-5px;width:var(--ph);height:var(--ph);
  margin:0;padding:0;border-radius:50%;display:grid;place-items:center;cursor:pointer;
  border:2px dashed rgba(222,196,138,.82);background:#141215;color:#e8cf95;
  box-shadow:0 12px 26px -10px rgba(0,0,0,.85);transition:transform .12s}
.s1-photo:active{transform:scale(.96)}
.s1-photo-preview{position:absolute;inset:0;border-radius:50%;overflow:hidden;pointer-events:none}
.s1-photo-preview img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.s1-photo-preview b{position:absolute;left:50%;top:calc(50% - 8px);transform:translate(-50%,-50%);display:block;width:26px;height:26px}
.s1-photo-preview b svg{display:block;width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linejoin:round}
.s1-photo-copy{position:absolute;left:0;right:0;top:calc(50% + 9px);text-align:center;pointer-events:none;line-height:1}
.s1-photo-copy b{font:700 9.5px/1 'Be Vietnam Pro',system-ui,sans-serif;letter-spacing:.1em;text-transform:uppercase;color:#ecd59e;white-space:nowrap}
/* đã có ảnh: ảnh che icon, chữ ẩn, viền nét đứt đổi thành vành kem */
.s1-photo:has(#photoPreview:not([hidden])){border:0;
  box-shadow:0 0 0 4px #f6eedf,0 0 0 5px rgba(214,184,120,.75),0 12px 26px -10px rgba(0,0,0,.85)}
.s1-photo:has(#photoPreview:not([hidden])) .s1-photo-copy{display:none}
@media (max-width:360px){.s1-photo{--ph:80px}.s1-photo-copy b{font-size:8.5px;letter-spacing:.08em}}
.s4-login{position:fixed;inset:0;z-index:300;display:grid;place-items:center;padding:20px;background:rgba(8,6,10,.72);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.s4-login-box{width:min(320px,calc(100vw - 40px));border-radius:16px;border:1px solid rgba(243,222,163,.35);
  background:rgba(17,13,20,.95);padding:18px;box-shadow:0 24px 60px rgba(0,0,0,.45)}
.s4-login-box b{display:block;text-align:center;font:500 20px/1.2 'Cormorant Garamond',serif;color:#f4efe6}
.s4-login-box p{margin:8px 0 14px;text-align:center;font:400 13px/1.45 'Be Vietnam Pro',system-ui,sans-serif;color:rgba(244,239,230,.72)}
.s4-login-box button{width:100%;min-height:48px;margin-top:8px;border:0;border-radius:12px;cursor:pointer;
  font:600 11px 'Be Vietnam Pro',system-ui,sans-serif;letter-spacing:.14em;text-transform:uppercase}
#keepPrimary{color:#1b1407;background:linear-gradient(135deg,#f3dea3,#d6b878)}
#keepClose{color:#f3dea3;background:rgba(255,255,255,.08);border:1px solid rgba(243,222,163,.28)}

/* ============================================================
   v3 — ảnh khách + khung trên thẻ lời chúc (spec §8.2).
   App khách chưa dựng mấy element này nên phần dưới không đổi gì bên đó.
   ============================================================ */
/* Ảnh khách trên thẻ lời chúc chính — chốt 24/09, docs/superpowers/specs/2026-09-24-guest-avatar.html (A2 · B1).
   Huy hiệu tròn sát phải, trồi NỬA ảnh lên trên mép trên tấm mờ (tấm là .mw-in::before,
   lùi lên --mw-pt so với .mw-in). Tấm, chữ nghiêng, dòng ký tên dưới chân giữ nguyên.
   --mw-av: đường kính; --mw-av-r: cách mép phải .mw-in. Số dưới là của app khách: 72pt,
   cách mép màn 14pt (.mw-in đã lùi 2cqw — .mywish app rộng đúng bằng màn nên 2cqw ở đây
   bằng 2cqw của màn). Màn LED ghi đè bằng cqh trong led.html.
   Không có ảnh: app-wishphoto.js ẩn .mw-photo và bỏ has-photo — không vòng trống, không chữ cái đầu. */
.mywish{--mw-av:72px;--mw-av-r:calc(14px - 2cqw)}
.mywish .mw-photo{position:absolute;z-index:2;right:var(--mw-av-r);top:calc(var(--mw-pt) * -1 - var(--mw-av) / 2);
  width:var(--mw-av);height:var(--mw-av);border-radius:50%;overflow:hidden;background:#1b1407;
  box-shadow:0 0 0 max(2px,calc(var(--mw-av) * .045)) #f6eedf,
    0 0 0 calc(max(2px,calc(var(--mw-av) * .045)) + 1px) rgba(214,184,120,.75),
    0 calc(var(--mw-av) * .12) calc(var(--mw-av) * .32) rgba(0,0,0,.62);
  opacity:0;transition:opacity .35s}
.mywish .mw-photo.ld{opacity:1}
.mywish .mw-photo[hidden]{display:none}
.mywish .mw-photo img{width:100%;height:100%;object-fit:cover;display:block}
/* dòng đầu lời chúc tự lùi vào, né phần ảnh thò xuống tấm */
.mywish.has-photo .mw-msg::before{content:'';float:right;
  width:calc(var(--mw-av) + var(--mw-av-r) + 8px);
  height:max(0px,calc(var(--mw-av) / 2 - var(--mw-pt) + 4px))}
/* avatar nhỏ trên thẻ phụ */
.jp-chip .av{width:3cqw;height:3cqw;border-radius:50%;object-fit:cover;float:left;margin:0 .8cqw .2cqw 0}
.led-wall .jp-chip .av{width:3.2vh;height:3.2vh}
/* Thẻ bay của app khách (.jp-sub) — chốt 24/09 (A3): ảnh 36pt (9,6cqw ở màn 375) trồi ra
   góc trên phải thẻ: trồi 0,36 d, lấn phải 0,17 d. Không có ảnh thì không vòng, không chừa.
   Chỉ đụng .jp-sub: tường thẻ .led-wall của layout=center giữ kiểu cũ ở trên. */
.jp-sub .jp-chip{max-width:34cqw}
.jp-sub .jp-chip b{font-size:2.55cqw}
.jp-sub .jp-chip p{font-size:3.75cqw;line-height:1.25}
.jp-sub .jp-chip p.en{font-size:2.8cqw;line-height:1.35}   /* bản Anh = .75 lời chúc gốc, như thẻ phụ LED */
.jp-sub .jp-chip .av{position:absolute;float:none;margin:0;top:-3.46cqw;right:-1.63cqw;width:9.6cqw;height:9.6cqw;
  border-radius:50%;object-fit:cover;background:#1b1407;
  box-shadow:0 0 0 .45cqw #f6eedf,0 0 0 .6cqw rgba(214,184,120,.75),0 1.15cqw 3cqw rgba(0,0,0,.62)}
.jp-sub .jp-chip.has-av b{padding-right:6.2cqw}
