/* ReGrip — Shared Styles */
:root {
  --primary:#5E86B8; --primary-dark:#2A4A6F; --primary-light:#B9D7EA;
  --bg-app:#F7FBFC; --surface:rgba(255,255,255,0.55); --surface-warm:#EFF6FB;
  --ink:#12263A; --ink-secondary:#3F5A75; --ink-muted:#587693;
  --success:#16A34A; --success-text:#15803D; --warning:#CA8A04; --error:#DC2626;
  --border-radius:1rem;
  --glass-bg:rgba(255,255,255,0.55); --glass-border:rgba(255,255,255,0.65);
  --glass-blur:20px; --glass-shadow:0 8px 32px rgba(42,74,111,0.12);
  --blue-50:#F7FBFC; --blue-100:#D6E6F2; --blue-200:#B9D7EA; --blue-500:#769FCD; --blue-600:#5E86B8; --blue-700:#2A4A6F;

  /* Motion tokens (see animation-systems skill) */
  --dur-fast: 150ms;
  --dur-base: 220ms;
  --dur-slow: 400ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);

  /* Accessibility — root font scale (settings.fontSize → html[data-font-size]) */
  --font-scale: 1;
}

/* Larger-text mode scales the root font-size; rem/em-based sizing follows. */
html[data-font-size="large"]  { --font-scale: 1.15; }
html[data-font-size="xlarge"] { --font-scale: 1.3; }
html { font-size: calc(100% * var(--font-scale)); }

*, *::before, *::after { box-sizing: border-box; }

body {
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  background: linear-gradient(160deg,#F7FBFC,#D6E6F2 45%,#B9D7EA);
  background-attachment: fixed;
  color: var(--ink);
  min-height: 100vh;
}

body::before {
  content: "";
  position: fixed;
  top: -180px; left: -140px;
  width: 620px; height: 620px;
  border-radius: 50%;
  background: rgba(118,159,205,0.16);
  filter: blur(100px);
  pointer-events: none;
  z-index: -1;
}
body::after {
  content: "";
  position: fixed;
  bottom: -200px; right: -160px;
  width: 540px; height: 540px;
  border-radius: 50%;
  background: rgba(94,134,184,0.12);
  filter: blur(100px);
  pointer-events: none;
  z-index: -1;
}

h1, h2, h3, h4, h5, .font-display {
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
}

/* ── Retro shadow utilities ── */
.retro-shadow       { box-shadow: var(--glass-shadow); }
.retro-shadow-sm    { box-shadow: 0 4px 16px rgba(42,74,111,0.10); }
.retro-border       {
  border: 1px solid var(--glass-border);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.5);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.5);
}
.retro-border-thick { border: 1px solid var(--glass-border); }

.retro-shadow:active:not(:disabled),
button.retro-shadow:active:not(:disabled) {
  transform: scale(0.98);
  box-shadow: var(--glass-shadow);
}

/* ── Sidebar Navigation ── */
#nav-sidebar {
  position: fixed;
  top: 16px; left: 16px; bottom: 16px;
  width: 224px;
  height: auto;
  background: var(--glass-bg);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.5);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.5);
  border: 1px solid var(--glass-border);
  border-radius: 24px;
  box-shadow: var(--glass-shadow);
  display: flex;
  flex-direction: column;
  padding: 0;
  z-index: 40;
  overflow-y: auto;
}

#nav-sidebar .nav-logo {
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-size: 22px;
  font-weight: 700;
  color: var(--blue-700);
  letter-spacing: -0.02em;
  padding: 24px 20px 16px;
  border-bottom: 1px solid var(--glass-border);
}

#nav-sidebar .nav-user {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 24px;
  border-bottom: 1px solid var(--glass-border);
}

#nav-sidebar .nav-user img {
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid var(--glass-border);
  object-fit: cover;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(42,74,111,0.12);
}

/* ── Circular icon clipping ── */
.circle-clip {
  overflow: hidden;
  border-radius: 50%;
}
.circle-clip img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

#nav-sidebar .nav-user-name  { font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif; font-weight: 700; font-size: 14px; }
#nav-sidebar .nav-user-sub   { font-size: 11px; color: var(--ink-secondary); letter-spacing: -0.01em; }

#nav-sidebar .nav-start-btn {
  margin: 16px;
  padding: 12px;
  background: linear-gradient(135deg, var(--blue-500), var(--blue-600));
  color: #fff;
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: -0.01em;
  border: none;
  border-radius: 9999px;
  box-shadow: 0 10px 26px rgba(94,134,184,0.42), inset 0 1px 0 rgba(255,255,255,0.35);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: transform 0.1s, filter 0.1s;
  text-decoration: none;
}
#nav-sidebar .nav-start-btn:active { transform: scale(0.98); }

#nav-sidebar .nav-links {
  flex: 1;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

#nav-sidebar .nav-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  border-radius: 16px;
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-secondary);
  text-decoration: none;
  transition: background 0.15s, color 0.15s, box-shadow 0.15s;
  border: 1px solid transparent;
}
#nav-sidebar .nav-item:hover {
  background: rgba(255,255,255,0.5);
  color: var(--blue-700);
  transform: none;
}
#nav-sidebar .nav-item.active {
  background: rgba(255,255,255,0.9);
  color: var(--blue-700);
  border-color: transparent;
  box-shadow: 0 6px 18px rgba(42,74,111,0.16);
}
#nav-sidebar .nav-item .material-symbols-outlined { font-size: 22px; }

#nav-sidebar .nav-sensor-btn {
  margin: 12px 16px 20px;
  padding: 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: #DCFCE7;
  border: 1px solid var(--glass-border);
  border-radius: var(--border-radius);
  box-shadow: 0 2px 8px rgba(42,74,111,0.10);
  cursor: pointer;
  font-size: 12px;
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
  gap: 8px;
}
#nav-sidebar .nav-sensor-btn:hover { filter: brightness(0.97); }

/* ── Bottom Nav Bar (mobile) — floating glass pill bar ── */
#nav-bottom {
  display: none;
  position: fixed;
  left: 12px; right: 12px; bottom: 12px;
  height: 68px;
  background: var(--glass-bg);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.5);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.5);
  border: 1px solid var(--glass-border);
  border-radius: 9999px;
  box-shadow: var(--glass-shadow);
  z-index: 50;
  justify-content: space-around;
  align-items: center;
  padding: 0 8px;
}
#nav-bottom .nav-bottom-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 6px 12px;
  text-decoration: none;
  color: var(--ink-secondary);
  border-radius: 16px;
  border: 1px solid transparent;
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: -0.01em;
  transition: background 0.15s, color 0.15s;
  min-width: 56px;
  text-align: center;
}
#nav-bottom .nav-bottom-item.active {
  color: var(--blue-700);
  background: rgba(255,255,255,0.9);
  border-color: transparent;
  box-shadow: 0 4px 14px rgba(42,74,111,0.16);
}
#nav-bottom .nav-bottom-item .material-symbols-outlined { font-size: 22px; }

/* ── Responsive layout ── */
.app-shell {
  display: flex;
  min-height: 100vh;
}

.app-main {
  flex: 1;
  padding-bottom: 0;
}

@media (min-width: 768px) {
  .app-main { margin-left: 256px; }
  #nav-bottom { display: none !important; }
  #nav-sidebar { display: flex !important; }
}
@media (max-width: 767px) {
  #nav-sidebar { display: none !important; }
  #nav-bottom  { display: flex !important; }
  .app-main    { margin-left: 0; padding-bottom: 96px; }
}

/* ── Feedback Modal Overlay ── */
#feedback-modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(18,38,58,0.4);
  align-items: center;
  justify-content: center;
  padding: 24px;
}
#feedback-modal.open { display: flex; }

#feedback-modal .modal-card {
  background: var(--glass-bg);
  backdrop-filter: blur(24px) saturate(1.5);
  -webkit-backdrop-filter: blur(24px) saturate(1.5);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
  border-radius: 24px;
  width: 100%;
  max-width: 520px;
  overflow: hidden;
}

#feedback-modal .modal-banner {
  background: rgba(254,226,226,0.6);
  border-bottom: 1px solid var(--glass-border);
  padding: 14px 20px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: -0.01em;
}

#feedback-modal .modal-body {
  padding: 32px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 16px;
}

#feedback-modal .modal-icon {
  width: 80px; height: 80px;
  border-radius: 50%;
  background: #FEE2E2;
  border: 1px solid var(--glass-border);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
#feedback-modal .modal-icon .material-symbols-outlined { font-size: 40px; color: var(--primary); }
#feedback-modal .modal-icon .modal-badge {
  position: absolute; bottom: -4px; right: -4px;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  border: 1px solid rgba(255,255,255,0.6);
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-weight: 700;
  font-size: 14px;
  display: flex; align-items: center; justify-content: center;
}

#feedback-modal h2 {
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-size: 22px; font-weight: 700;
}

#feedback-modal p { color: var(--ink-secondary); font-size: 16px; line-height: 1.6; }

#feedback-modal .modal-actions {
  display: flex;
  gap: 12px;
  width: 100%;
  flex-wrap: wrap;
}
#feedback-modal .modal-actions button {
  flex: 1;
  padding: 12px 16px;
  border: 1px solid var(--glass-border);
  border-radius: 9999px;
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: -0.01em;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  box-shadow: 0 4px 16px rgba(42,74,111,0.10);
  transition: transform 0.1s, box-shadow 0.1s;
  white-space: nowrap;
}
#feedback-modal .modal-actions button:active { transform: scale(0.98); box-shadow: 0 2px 8px rgba(42,74,111,0.10); }
#feedback-modal .modal-actions .btn-primary { background: var(--primary); color: #fff; }
#feedback-modal .modal-actions .btn-secondary { background: #E0F2FE; color: var(--ink); }

#feedback-modal .modal-hint {
  width: 100%;
  background: var(--surface-warm);
  border-top: 1px solid var(--glass-border);
  padding: 14px 20px;
  display: flex;
  gap: 10px;
  text-align: left;
  font-size: 14px;
  color: var(--ink-secondary);
  line-height: 1.5;
}

/* ═══════════════════════════════════════════════════════════════════════════
   ADDITIONS — retro buttons, states, a11y, motion (v2 shared base)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Retro buttons ── */
.btn-retro,
.btn-retro-primary,
.btn-retro-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 12px 22px;
  border: 1px solid var(--glass-border);
  border-radius: 9999px;
  box-shadow: var(--glass-shadow);
  background: var(--glass-bg);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.5);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.5);
  color: var(--ink);
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-weight: 600;
  font-size: 14px;
  letter-spacing: -0.01em;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out),
              filter var(--dur-fast) var(--ease-out);
}
.btn-retro:hover,
.btn-retro-primary:hover,
.btn-retro-danger:hover { filter: brightness(1.02); transform: translateY(-1px); }
.btn-retro:active:not(:disabled),
.btn-retro-primary:active:not(:disabled),
.btn-retro-danger:active:not(:disabled) {
  transform: scale(0.98);
}
.btn-retro-primary {
  background: linear-gradient(135deg, var(--blue-500), var(--blue-600));
  color: #fff;
  border-color: transparent;
  box-shadow: 0 10px 26px rgba(94,134,184,0.42), inset 0 1px 0 rgba(255,255,255,0.35);
}
.btn-retro-danger  {
  background: var(--error);
  color: #fff;
  border-color: transparent;
}
.btn-retro:disabled,
.btn-retro-primary:disabled,
.btn-retro-danger:disabled { opacity: 0.5; cursor: not-allowed; box-shadow: none; }

/* ── Empty state ── */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
  padding: 40px 24px;
  background: var(--glass-bg);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.5);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.5);
  border: 1px solid var(--glass-border);
  border-radius: 24px;
}
.empty-state-icon {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: rgba(255,255,255,0.5);
  border: 1px solid var(--glass-border);
  box-shadow: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
.empty-state-icon .material-symbols-outlined { font-size: 36px; color: var(--primary); }
.empty-state-title { font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif; font-size: 18px; font-weight: 700; color: var(--ink); }
.empty-state-desc  { color: var(--ink-secondary); font-size: 14px; line-height: 1.6; max-width: 42ch; }
.empty-state-actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; margin-top: 4px; }

/* ── Skeleton loader (soft pastel pulse) ── */
.skeleton {
  background: linear-gradient(90deg, rgba(214,230,242,0.5), rgba(185,215,234,0.5), rgba(214,230,242,0.5));
  border: 1px solid var(--glass-border);
  border-radius: var(--border-radius);
  animation: skeletonPulse 1.4s ease-in-out infinite;
}
@keyframes skeletonPulse {
  0%, 100% { opacity: 0.6; }
  50%      { opacity: 1; }
}

/* ── Numeric alignment ── */
.tabular { font-variant-numeric: tabular-nums; }

/* ── Retro toast (bottom-right) ── */
.retro-toast {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 300;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  background: var(--glass-bg);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.5);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.5);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
  border-radius: 9999px;
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-weight: 700;
  font-size: 14px;
  color: var(--ink);
  animation: toastSlideUp var(--dur-base) var(--ease-out);
}
@keyframes toastSlideUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Confirm modal (retro replacement for native confirm) ── */
.confirm-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 250;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(18,38,58,0.4);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
.confirm-modal-overlay.open { opacity: 1; }
.confirm-modal-card {
  width: 100%;
  max-width: 420px;
  background: var(--glass-bg);
  backdrop-filter: blur(24px) saturate(1.5);
  -webkit-backdrop-filter: blur(24px) saturate(1.5);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
  border-radius: 24px;
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  transform: translateY(8px) scale(0.98);
  transition: transform var(--dur-base) var(--ease-out);
}
.confirm-modal-overlay.open .confirm-modal-card { transform: translateY(0) scale(1); }
.confirm-modal-title { font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif; font-size: 20px; font-weight: 700; color: var(--ink); }
.confirm-modal-body  { color: var(--ink-secondary); font-size: 15px; line-height: 1.6; }
.confirm-modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 6px; }

/* ── Bottom-nav touch target + label size ── */
#nav-bottom .nav-bottom-item { min-height: 56px; font-size: 11px; }

/* ── Focus ring (a11y, keyboard nav) ── */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 2px;
}

/* ── Reduced motion — media query AND [data-reduced-motion] root attribute ──
   The universal `*` selector also neutralizes page-defined infinite animations
   (e.g. cloudDrift) by forcing a single, near-instant iteration. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
[data-reduced-motion] *,
[data-reduced-motion] *::before,
[data-reduced-motion] *::after {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
  scroll-behavior: auto !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
   ADDITIONS — auth / login screen + server-connection card
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Login screen shell ── */
.auth-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: transparent;
}
.auth-card {
  width: 100%;
  max-width: 440px;
  background: var(--glass-bg);
  backdrop-filter: blur(24px) saturate(1.5);
  -webkit-backdrop-filter: blur(24px) saturate(1.5);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
  border-radius: 28px;
  padding: 40px 32px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.auth-logo {
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-size: 32px;
  font-weight: 700;
  color: var(--blue-700);
  letter-spacing: -0.02em;
  text-align: center;
}
.auth-sub {
  text-align: center;
  color: var(--ink-secondary);
  font-size: 14px;
  margin-top: -10px;
}

/* ── Tabs (login / signup) — pill segment ── */
.auth-tabs {
  display: flex;
  gap: 4px;
  padding: 4px;
  border-radius: 9999px;
  background: rgba(255,255,255,0.4);
  border: 1px solid var(--glass-border);
}
.auth-tab {
  flex: 1;
  min-height: 40px;
  padding: 10px 0;
  border: none;
  border-radius: 9999px;
  background: transparent;
  color: var(--ink-secondary);
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-weight: 600;
  font-size: 14px;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, box-shadow 0.15s;
}
.auth-tab.active { background: #fff; color: var(--blue-700); box-shadow: 0 4px 14px rgba(42,74,111,0.16); }

/* ── Fields ── */
.auth-field { display: flex; flex-direction: column; }
.auth-label {
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink-secondary);
  margin-bottom: 6px;
}
/* .auth-card 한정자: Tailwind forms 플러그인이 런타임 주입하는 [type=...] 규칙(1px #6B7280)이
   동일 특이도로 뒤에 와서 이기므로, 특이도를 올려 글라스 보더를 보장한다. */
.auth-card .auth-input {
  width: 100%;
  min-height: 48px;
  border: 1px solid var(--glass-border);
  border-radius: 16px;
  padding: 12px 16px;
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-size: 15px;
  background: rgba(255,255,255,0.5);
  color: var(--ink);
  outline: none;
  transition: box-shadow 0.15s, border-color 0.15s, background 0.15s;
}
.auth-card .auth-input:focus {
  box-shadow: 0 0 0 3px rgba(118,159,205,0.35);
  border-color: var(--blue-500);
  background: rgba(255,255,255,0.75);
}

/* ── Consent rows ── */
.auth-consent {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-secondary);
  cursor: pointer;
}
.auth-consent input[type="checkbox"] {
  width: 22px; height: 22px;
  min-width: 22px;
  margin-top: 1px;
  accent-color: var(--primary);
  cursor: pointer;
}

/* ── Notice / error ── */
.auth-note {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  background: rgba(255,255,255,0.4);
  border: 1px solid var(--glass-border);
  border-radius: 12px;
  padding: 10px 12px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-secondary);
}
.auth-note .material-symbols-outlined { font-size: 18px; color: var(--primary); flex-shrink: 0; }
.auth-error {
  display: none;
  background: #FEE2E2;
  border: 1px solid var(--error);
  border-radius: 8px;
  padding: 10px 12px;
  color: #991B1B;
  font-size: 13.5px;
  line-height: 1.5;
}
.auth-error.show { display: block; }
.auth-alt {
  text-align: center;
  font-size: 13px;
  color: var(--ink-secondary);
}
.auth-alt a { color: var(--primary); font-weight: 700; text-decoration: underline; }

/* ── Server-connection card status pill (settings) ── */
.server-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border: 1px solid var(--glass-border);
  border-radius: 9999px;
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: -0.01em;
}
.server-status.local  { background: #F1F5F9; color: var(--ink-secondary); }
.server-status.remote { background: #DCFCE7; color: var(--success-text); }
.server-status .dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; }

/* ═══════════════════════════════════════════════════════════════════════════
   GAME SHELL — ready / countdown / pause overlays (retro neo-vernacular)
   ═══════════════════════════════════════════════════════════════════════════ */

/* 좁은 화면에서 게임 헤더의 조작법 힌트 칩을 숨긴다 — 준비 오버레이가 같은 정보를
   전달하므로 중복이고, 390px급에서 시뮬레이션 배지가 어색하게 줄바꿈되는 원인. */
@media (max-width: 520px) {
  .game-hud-hint { display: none; }
}

/* Shared overlay scaffold (ready + pause + rotate). Sits below the confirm modal (z 250). */
.game-ready-overlay,
.game-pause-overlay,
.game-rotate-overlay {
  position: fixed;
  inset: 0;
  z-index: 240;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(18,38,58,0.4);
}
.game-pause-overlay { z-index: 245; }
/* 회전 안내는 일시정지 오버레이(245) 위에 온다 — 가로로 돌리면 둘이 함께 뜨는데,
   사용자가 먼저 읽어야 하는 쪽은 "왜 멈췄는가"이기 때문이다.
   확인 모달(250)보다는 아래로 둬서 기존 레이어 계약을 그대로 지킨다. */
.game-rotate-overlay { z-index: 248; }

.game-ready-card,
.game-pause-card,
.game-rotate-card {
  width: 100%;
  max-width: 460px;
  background: var(--glass-bg);
  backdrop-filter: blur(24px) saturate(1.5);
  -webkit-backdrop-filter: blur(24px) saturate(1.5);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
  border-radius: 24px;
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  animation: gameOverlayIn var(--dur-base) var(--ease-out);
}

@keyframes gameOverlayIn {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.game-ready-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.game-ready-title {
  font-size: 24px;
  font-weight: 700;
  color: var(--ink);
}

/* Difficulty chip — retro pill in the brand color. */
.game-difficulty-chip {
  display: inline-flex;
  align-items: center;
  padding: 5px 14px;
  background: var(--primary);
  color: #fff;
  border: none;
  border-radius: 9999px;
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: -0.01em;
  flex-shrink: 0;
}

.game-ready-status {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 16px;
  background: rgba(255,255,255,0.4);
  border: 1px solid var(--glass-border);
  border-radius: 12px;
}
.game-ready-line {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--ink-secondary);
  line-height: 1.5;
}
.game-ready-line .material-symbols-outlined { font-size: 20px; color: var(--primary); flex-shrink: 0; }
.game-ready-line a { color: var(--primary); font-weight: 700; text-decoration: underline; }

.game-ready-howto {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.game-ready-howto li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  color: var(--ink);
  line-height: 1.5;
}
.game-ready-howto li .material-symbols-outlined {
  font-size: 22px;
  color: var(--primary);
  flex-shrink: 0;
  padding: 6px;
  background: rgba(255,255,255,0.4);
  border: 1px solid var(--glass-border);
  border-radius: 10px;
}

.game-ready-actions,
.game-pause-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.game-ready-actions .btn-retro,
.game-ready-actions .btn-retro-primary,
.game-pause-actions .btn-retro,
.game-pause-actions .btn-retro-primary { flex: 1 1 auto; }

.game-pause-card,
.game-rotate-card { max-width: 380px; text-align: center; }
.game-pause-card h2,
.game-rotate-card h2 { font-size: 22px; font-weight: 700; color: var(--ink); }

/* ── 회전 안내 오버레이 (세로 전용) ──
   스캐폴드·유리 카드·제목은 위 규칙을 선택자에 얹어 그대로 공유한다. 새 색/그림자/radius 없음.
   아래 두 규칙만 회전 카드 고유이고, 값은 전부 기존 것을 그대로 가져왔다:
   아이콘 색은 .game-ready-line 아이콘과 같은 var(--primary),
   본문은 .game-ready-line 과 같은 14px / var(--ink-secondary) / 1.5. */
.game-rotate-icon {
  font-size: 44px;
  color: var(--primary);
  animation: gameRotateHint 2.6s var(--ease-out) infinite;
}
.game-rotate-desc {
  font-size: 14px;
  color: var(--ink-secondary);
  line-height: 1.5;
}
@keyframes gameRotateHint {
  0%, 55%, 100% { transform: rotate(0deg); }
  25%, 40%      { transform: rotate(-22deg); }
}

/* Countdown 3-2-1 — large numeral, brand color, hard-edged pop. */
.game-countdown-num {
  font-family: 'Pretendard Variable', 'Noto Sans KR', sans-serif;
  font-size: clamp(96px, 22vw, 180px);
  font-weight: 700;
  line-height: 1;
  color: var(--blue-700);
  text-align: center;
  -webkit-text-stroke: 0;
  text-shadow: 0 4px 24px rgba(42,74,111,0.25);
}
.game-countdown-num.countdown-pop { animation: countdownPop 0.6s var(--ease-out); }
@keyframes countdownPop {
  0%   { transform: scale(0.4); opacity: 0; }
  40%  { transform: scale(1.15); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* Reduced motion — neutralize overlay entrance + countdown pop (mirrors the shared block:
   media query AND [data-reduced-motion] root attribute). */
@media (prefers-reduced-motion: reduce) {
  .game-ready-card,
  .game-pause-card,
  .game-rotate-card,
  .game-rotate-icon,
  .game-countdown-num.countdown-pop { animation: none !important; }
}
[data-reduced-motion] .game-ready-card,
[data-reduced-motion] .game-pause-card,
[data-reduced-motion] .game-rotate-card,
[data-reduced-motion] .game-rotate-icon,
[data-reduced-motion] .game-countdown-num.countdown-pop { animation: none !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE — 게임 셸 반응형 (≤767px) + 하단탭 6칸 대응
   앱 셸과 동일한 767px 경계를 쓴다(위 "Responsive layout" 구역 참조).
   여기 있는 규칙은 전부 max-width 미디어 쿼리 안에 있거나(=데스크톱 미적용),
   기존 값과 동일한 결과를 내는 순수 추가다. 색/그림자/블러/radius/폰트는 건드리지 않는다.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 게임 화면 높이 — 모바일 브라우저 주소창 때문에 100vh는 화면 밖으로 넘친다.
   dvh 미지원 브라우저를 위해 100vh 폴백을 먼저 선언한다.
   데스크톱에는 동적으로 접히는 UA 툴바가 없어 100dvh == 100vh 이므로 렌더링이 같다.
   (#game-screen 은 게임 4종에만 존재하고, Tailwind .min-h-screen 과 같은 100vh 를 준다) */
#game-screen {
  min-height: 100vh;
  min-height: 100dvh;
}

@media (max-width: 767px) {
  /* 헤더 — 게임 시작 후 GameShell 이 일시정지 버튼을 끼워 넣어 요소가 4개가 되면서
     390px 이하에서 센서 배지가 두 줄로 접히고 로고와 겹친다. 여백·글자 크기만 줄여
     한 줄을 유지한다(색·그림자·블러는 그대로). */
  #game-screen > header { padding-left: 12px; padding-right: 12px; gap: 8px; }
  #game-screen > header > div:first-child { flex-shrink: 0; }
  #game-screen > header > div:last-child  { gap: 8px; min-width: 0; }
  #game-screen > header #sensor-badge {
    flex-shrink: 0;
    white-space: nowrap;
    font-size: 10px;
    padding: 4px 8px;
  }
  /* 일시정지·종료는 게임 중 유일한 이탈 컨트롤이다. 글자·좌우 여백은 줄여 헤더 한 줄을
     유지하되, 터치 타깃은 48×48 이상을 보장한다(WCAG 2.5.5 44×44 상회).
     min-height/width 를 여기서 책임지므로 shared.js 는 인라인으로 크기를 주지 않는다.
     이 블록은 max-width:767px 안이라 데스크톱 렌더링은 그대로다. */
  #game-screen > header #game-pause-btn,
  #game-screen > header #exit-btn {
    flex-shrink: 0;
    white-space: nowrap;
    font-size: 12px;
    padding: 6px 10px;
    min-width: 48px;
    min-height: 48px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* 3열(좌 HUD · 스테이지 · 우 게이지) → 세로 3단 */
  .game-layout { flex-direction: column; }

  /* 좌측 세로 패널 → 상단 가로 스트립. 넘치면 가로 스크롤. */
  .game-layout > .game-hud-left {
    flex: 0 0 auto;
    width: auto;
    flex-direction: row;
    align-items: stretch;
    gap: 8px;
    padding: 8px 10px;
    overflow-x: auto;
    overflow-y: hidden;
  }
  .game-hud-left > div {
    flex: 0 0 auto;
    min-width: 0;
    margin-top: 0;   /* .mt-auto 무력화 (가로 스트립에서는 의미 없음) */
  }
  .game-hud-left > .rounded-xl,
  .game-hud-left > .rounded-lg { padding: 8px 10px; }
  /* 수치 글자 축소 — 스트립 높이를 낮춰 플레이 영역을 확보하기 위한 것 */
  .game-hud-left .text-5xl { font-size: 26px; line-height: 1.1; }
  .game-hud-left .text-3xl { font-size: 22px; line-height: 1.1; }
  .game-hud-left .text-2xl { font-size: 18px; line-height: 1.1; }
  .game-hud-left .text-lg  { font-size: 15px; line-height: 1.1; }
  .game-hud-left .mb-1 { margin-bottom: 0; }
  .game-hud-left .mb-2 { margin-bottom: 2px; }

  /* 긴 설명·정적 눈금 라벨은 숨긴다 — 준비 오버레이(.game-ready-howto)가 같은 내용을
     보여주고, 타이머·점수·콤보 같은 실시간 지표는 그대로 남는다. */
  .game-hud-left .game-hud-verbose,
  .game-hud-right .game-hud-verbose { display: none; }

  /* 플레이 영역 — 남는 공간 전부 + 화면 절반 이상 확보 */
  .game-layout > .game-stage {
    flex: 1 1 auto;
    min-height: 55vh;
    min-height: 55dvh;
  }

  /* 우측 세로 게이지 → 하단 가로 바.
     게이지 자체는 세로축을 유지한 채 축소한다 — 각 게임 JS가 #gauge-fill / 타깃 밴드를
     height·bottom 퍼센트로 제어하므로 세로축을 뒤집으면 값이 어긋난다. */
  .game-layout > .game-hud-right {
    flex: 0 0 auto;
    width: auto;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 8px 12px;
  }
  .game-hud-right > div {
    flex: 0 0 auto;
    margin: 0;
    width: auto;
    flex-direction: row;   /* 리듬 게임 범례(쥐기/풀기)를 한 줄로 */
  }
  /* 게이지는 이 제품의 핵심 피드백 채널이다. 너무 낮추면 1%당 1px 미만이 되어
     '목표 구간 유지' 메커니즘이 판독 불가능해진다. 76px = 1%당 0.76px,
     목표 밴드(±8%)가 12px 이상으로 눈에 잡힌다. */
  .game-hud-right #gauge-track {
    flex: 0 0 auto;
    width: 32px;
    height: 76px;
  }
  /* 채움의 상단선이 사용자가 맞춰야 할 판독선이다. 데스크톱의 rounded-full(9999px)은
     짧은 트랙에서 채움 박스 전체를 원으로 만들어 상단선을 곡선으로 만든다 → 평평하게.
     아래쪽만 트랙 곡률에 맞춰 남긴다(트랙이 overflow:hidden 이라 실제로는 클리핑됨). */
  .game-hud-right #gauge-fill { border-radius: 0 0 10px 10px; }
  .game-hud-right .text-2xl { font-size: 20px; }
  /* 크레인 목표선 라벨은 게이지 왼쪽 바깥(right:100%)에 절대배치돼 가로 바에서 겹친다.
     목표선(#target-line) 자체는 게이지에 그대로 남는다. */
  .game-hud-right #target-line-label { display: none; }
}

/* 320px급 초소형 화면 — 헤더에 4개가 다 들어가지 않으므로 게임 중 기능이 없는
   ReGrip 로고만 감춘다(센서 배지·일시정지·종료는 유지). */
@media (max-width: 359px) {
  #game-screen > header { justify-content: flex-end; }
  #game-screen > header > div:first-child { display: none; }
}

/* 320×568 세로 — 게이지 하단이 화면 밖(fold 아래)으로 나가던 문제.
   실측 박스 합계: 헤더 73 + 상단 HUD 스트립 120 + 스테이지 312.39(=55dvh 하한이 구속)
   + 하단 게이지 바 92 = 597 → 뷰포트 568 대비 29px 오버플로, #gauge-track 하단이 589.4.
   잘리는 구간이 하필 저출력(반복 시작) 구간이라 판독이 안 되면 곤란하다.

   게이지(76px)는 이 제품의 핵심 해상도라 줄이지 않고, 스테이지 min-height:55dvh 도 유지한다.
   따라서 회수 대상은 상단 HUD 스트립뿐이다. 예산: 568 − 73(헤더) − 92(게이지 바)
   − 312.4(55dvh) = 90.6px 가 스트립 상한 → 120px 에서 ~30px 를 줄여야 한다.
   패딩·여백·도넛 아이콘 지름만 건드리고, 타이머·점수·콤보 수치는 22px 이상으로 남겨
   읽을 수 있게 한다(라벨 12px 도 그대로). 색·그림자·radius·폰트는 손대지 않는다.
   경계는 359px — 360px 은 국내 안드로이드 최다 실기기 폭이라 영향을 주면 안 된다. */
@media (max-width: 359px) {
  .game-layout > .game-hud-left { padding: 4px 8px; }
  .game-hud-left > .rounded-xl,
  .game-hud-left > .rounded-lg { padding: 4px 8px; }
  /* 수치는 여전히 크게 읽힌다(26px → 22px). */
  .game-hud-left .text-5xl { font-size: 22px; }
  /* 크레인 44px / 열기구 40px 유지 도넛 — 옆의 숫자 블록(≈32.5px)이 행 높이를 결정하는
     지점까지만 줄인다. 더 줄여도 행은 낮아지지 않는다. */
  .game-hud-left svg { width: 28px; height: 28px; }
  /* 크레인 '집게 열림/닫힘' 상태줄의 mt-2(8px) — 카드 안 마지막 줄이라 여백이 그대로 높이다. */
  .game-hud-left .mt-2 { margin-top: 2px; }
}

/* 가로 모드 휴대폰 — 세로 전용 제품이므로 여기서 게임을 하지는 않는다(GameShell 이
   (orientation: landscape) and (max-height: 500px) 에서 회전 안내를 띄우고 일시정지한다).
   남은 규칙은 안내 뒤에 비치는 레이아웃이 스크롤을 만들지 않게 하는 방어선이다.

   .game-stage { min-height: 30dvh } 클램프는 제거했다: 가로에서는 스테이지가
   flex:1 1 auto 로 남는 공간을 어차피 다 가져가는데, 30dvh 하한이 남는 공간보다 크면
   스테이지를 억지로 늘려 세로 스크롤을 만들었다(568×320 실측 +27px). 가로에서 플레이하지
   않게 된 지금은 얻는 것 없이 잘라내는 부작용만 남는다.

   게이지 42px 규칙은 남긴다 — min-height 와 달리 콘텐츠를 잘라내지 않고(#gauge-fill 은
   퍼센트 기반이라 짧아져도 값은 그대로 읽힌다), 회전 안내가 뜨지 못한 상황에서 세로 스크롤을
   줄여 주는 안전망이기 때문이다.

   min-height:0 은 위 세로 블록의 .game-stage { min-height: 55dvh } 를 가로에서 무효화한다.
   30dvh 클램프만 지웠을 때는 이 55dvh 가 그대로 남아 스테이지를 뷰포트의 55% 로 강제해
   세로 스크롤이 계속 생겼다(실측 740×360 +61px / 568×320 +107px / 667×375 +55px).
   가로에서는 플레이하지 않으므로 스테이지에 하한을 둘 이유가 없다 — flex:1 1 auto 로
   남는 공간만 차지하게 두면 안내 뒤 레이아웃이 스크롤을 만들지 않는다.
   선택자 특이도는 세로 규칙과 같은 (0,2,0) 이고 파일에서 뒤에 오므로 이긴다. */
@media (max-width: 767px) and (orientation: landscape) {
  .game-layout > .game-stage { min-height: 0; }
  .game-hud-right #gauge-track { height: 42px; }
}

/* ── 하단 탭바 — 항목 6개(홈·훈련·기록·업적·설정·프로필) 대응 ──
   고정 min-width:56px 6칸은 360px 폭에서 넘친다. 오버플로를 실제로 푸는 건
   균등 분배(flex:1 1 0 + min-width:0)와 좌우 패딩 축소이지 글자 축소가 아니다.
   주 사용자가 고령자·저시력자이므로 라벨 11px / 아이콘 22px 기본값을 그대로 쓴다.
   터치 타깃 최소 높이 56px(≥48px)도 그대로 유지한다.
   #nav-bottom 은 ≥768px 에서 display:none 이므로 데스크톱에는 영향이 없다. */
@media (max-width: 767px) {
  #nav-bottom { padding: 0 4px; }
  #nav-bottom .nav-bottom-item {
    flex: 1 1 0;
    min-width: 0;
    padding: 6px 2px;
    white-space: nowrap;
    justify-content: center;
  }
}
/* 320px급 초소형 화면 — 4px 좌우 패딩까지 있으면 한 칸이 47.7px 로 48px 에 미달한다.
   패딩을 없애 칸 폭을 확보한다(글자는 줄이지 않는다). 경계는 게임 헤더 로고 숨김과
   동일한 359px 로 맞춘다 — 360px 은 국내 안드로이드 최다 실기기 폭이라 "초소형"이 아니다. */
@media (max-width: 359px) {
  #nav-bottom { padding: 0; }
}
