/* K-MAGIC — 무료 마술 웹앱.
 *
 * 빌드도 의존성도 없다. HTML 세 장 + 이 파일이 전부다. 서버·DB·가입이 없어서
 * 운영비가 0원이다(대표 요구). 외부 폰트도 안 받는다 — 부스 와이파이가 나빠도
 * 글자가 늦게 뜨면 안 되고, 그게 곧 비용 0원이기도 하다.
 */
:root {
  --bg: #000000;
  --tile: #0C0D10;
  --line: #1D1F25;
  --ink: #F2F3F5;
  --ink-dim: #7C818B;
  --accent: #E7B765;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  background: var(--bg);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo",
    "Noto Sans KR", "Malgun Gothic", sans-serif;
  -webkit-font-smoothing: antialiased;
  /* 공연 중 손이 스치면 글자가 잡히거나 화면이 튀면 안 된다. */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  overscroll-behavior: none;
  /* 🔴 더블탭 확대만 끈다. 두 손가락 확대(핀치)는 «살려 둔다» — 눈이 불편한
     분에게 그건 유일한 확대 수단이고, 그것까지 막으면 접근성을 끊는 것이다.
     더블탭은 마술 도중 손이 두 번 스치면 화면이 튀어서 흐름이 깨진다. */
  touch-action: manipulation;
}

body {
  min-height: 100dvh;
  /* 위는 상단바(로고·햄버거)가 차지한다. 그 아래에서 본문이 시작한다. */
  padding: calc(max(14px, env(safe-area-inset-top)) + 46px) 20px
           max(28px, env(safe-area-inset-bottom));
}

a { color: inherit; text-decoration: none; }

.wrap { max-width: 560px; margin: 0 auto; }

/* ── 머리 ── */
.brand {
  display: block;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .34em;
  text-indent: .34em;
}
.brand-sub {
  margin-top: 7px;
  font-size: 12px;
  color: var(--ink-dim);
}

/* ── 격자 ── */
.grid {
  margin-top: 26px;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
@media (min-width: 520px) { .grid { grid-template-columns: repeat(3, 1fr); } }

.tile {
  position: relative;   /* .tile-go::after 가 칸을 덮는 기준점 */
  aspect-ratio: 1;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--tile);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px;
  text-align: center;
  /* 🔴 한글은 «낱말 가운데»가 잘리면 안 된다. 없으면 브라우저가 글자 단위로
   *    끊어서 「만납니 / 다」처럼 갈라진다 (대표 화면 2026-09-09). */
  word-break: keep-all;
}
.tile-name { font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
.tile-note { font-size: 11px; color: var(--ink-dim); }

/* ── 칸 안의 «설명서 · 설정» (대표 2026-09-09) ──────────────────────────
 *
 * 🔴 전에는 설명서가 «햄버거 메뉴»에 마술 수만큼 줄로 서 있었다. 마술이 하나
 *    늘 때마다 메뉴도 한 줄씩 길어져서 대표님이 「쭉 늘어나지 않게 정리하고
 *    각 앱 버튼에 설명서 버튼 같이 넣어놔줘 공간이 그래야 살듯」이라 하셨다.
 *    이제 설명서는 «그 마술 칸 안»에 있다 — 마술이 늘어도 메뉴는 그대로다.
 *
 * 🔴 칸 «전체»가 여전히 마술 시작이다. .tile-go 가 ::after 로 칸을 통째로 덮고
 *    버튼만 그 위에 선다. <a> 안에 <a> 를 넣을 수 없어서 이렇게 한다 —
 *    넣으면 브라우저가 조용히 구조를 바꿔서 칸이 통째로 안 눌린다.
 *    ⚠️ .tile-acts 의 z-index 를 빼지 말 것. 빼면 설명서를 눌러도 마술이 열린다.
 */
.tile-go {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
}
.tile-go::after { content: ""; position: absolute; inset: 0; border-radius: 14px; }
/* 🔴 칸 하나에 버튼이 최대 셋(시작·설명서·설정)이라 좁은 폰에서 넘친다.
 *    줄바꿈을 허용하고 가운데로 모은다 — 넘쳐서 잘리면 「설정이 없는 마술」로 읽힌다. */
.tile-acts { position: relative; z-index: 2; display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; }
.tile-act {
  font-size: 11px;
  line-height: 1.2;
  color: var(--ink-dim);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px 10px;
  white-space: nowrap;
}
.tile-act:active { color: var(--ink); border-color: #33363E; }

/* 열린 칸 — 지금 쓸 수 있는 것. 색은 하나만 쓴다. */
.tile.open { border-color: #33363E; }

/* ── 「다음 마술」 자리 (대표 2026-09-10) ──────────────────────────────
 * 🔴 «비어 보이되 고장 나 보이지는 않게» 가 전부다. 그 둘을 가르는 건 셋이다:
 *    ① 점선 테두리 — 「아직 안 채워진 자리」라는 뜻이고, 실선이면 그냥 어두운 칸이다
 *    ② 손가락을 아예 안 받는다 — 눌리는데 반응이 없으면 «고장»으로 읽힌다
 *    ③ 배지 색을 금색에서 뺀다 — 금색은 이 판에서 「지금 할 수 있는 것」의 색이다
 * ⚠️ `:active`·`:hover` 를 «주지 말 것». 반응이 있는 순간 기대가 아니라 기다림이 된다. */
.tile-soon {
  border-style: dashed;
  background: transparent;
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
}
.tile-soon .tile-name { color: var(--ink-dim); font-weight: 500; }
.tile-soon .tile-note { color: #4A4E56; }
/* 🔴 `.pill.pill-soon` 으로 «두 번» 적는다. `.pill` 이 이 파일에서 «아래»에 있어서
   같은 세기면 그쪽이 이긴다 — 실제로 배지가 금색으로 남아 있었다(실측 rgb(231,183,101)).
   순서를 바꾸는 대신 세기를 올린다. 순서에 기대면 다음에 누가 옮길 때 또 깨진다. */
.pill.pill-soon {
  color: var(--ink-dim);
  border-color: var(--line);
  letter-spacing: .1em;
}
.pill {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  color: var(--accent);
  border: 1px solid rgba(231, 183, 101, .4);
  border-radius: 999px;
  padding: 3px 8px;
}

/* 잠긴 칸 */
.tile.locked .tile-name { color: #9AA0A9; }
.tile svg { stroke: #4A4E56; }
.tile.soon { opacity: .45; }

/* ── 마술계 소식 ── 피카님 시안(2026-09-01) 그대로. 새 색은 안 만들었다 — 기존 토큰만.
   배치의 답: **왼쪽=장소 / 오른쪽=시간.** 목록을 왼쪽 세로줄만 훑으면
   서울·부산·부산·해외가 그대로 읽혀서, 「내가 갈 수 있나」가 카드를 열지 않고 끝난다. */
.news-head { display: flex; align-items: baseline; justify-content: space-between; margin-top: 26px; }
.news-title { font-size: 11px; font-weight: 700; letter-spacing: .1em; color: var(--ink-dim); }
/* 여백으로 손가락 자리를 만든다 — 글자만 두면 폰에서 「보이는데 안 눌린다」. */
.news-all { font-size: 11px; color: var(--accent); padding: 8px 0 8px 12px; margin: -8px 0; }
.news-list { margin-top: 10px; display: flex; flex-direction: column; gap: 10px; }

.news-card {
  display: block;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--tile);
  padding: 13px 15px;
}
.news-top { display: flex; align-items: center; gap: 8px; }
/* 라벨은 «금색 하나»를 채움·테두리·회색 셋으로 나눠 쓴다(피카님 확정 2026-09-01).
   넷에 다른 색을 주면 카드 다섯 장만 쌓여도 알록달록해지고 아무것도 안 튄다.

   🔴 위계를 «규칙이 아니라 형태»가 지킨다 — 덩어리(채움)가 테두리를 «언제나»
      이긴다. 나중에 누가 값을 만져도 「서리아트가 모집보다 세면 안 된다」가
      저절로 지켜진다. 지켜야 하는 규칙을 안 지켜도 되는 구조로 바꾼 것이다.

   D-N 의 금색과 안 헷갈린다 — 자리와 형태가 다르다:
      채운 칩 = 돈(일거리)  /  테두리 칩 = 우리 것  /  오른쪽 금색 글자 = 임박 */
.news-kind {
  font-size: 10px; font-weight: 700; letter-spacing: .08em; color: var(--ink-dim);
  border: 1px solid var(--line); border-radius: 5px; padding: 3px 6px; flex: none;
}
/* 「모집」 = 마술사에게 «일거리». 놓치면 그 기회가 영영 사라져서 제일 세다. */
.news-kind.job { color: #0A0B0D; background: var(--accent); border-color: var(--accent); }
/* 「서리아트」 = 우리 것. 숨기지 않되 «모집보다 약하게» — 테두리와 글자만 금색이다.
   ⚠️ 테두리만 금색으로 두고 글자를 회색으로 남기면 안 된다. 금색 상자 안에 회색
      글자가 앉아서 «꺼진 칸»처럼 읽힌다(피카님이 뽑아 보고 뺀 안이다). */
.news-kind.ours { border-color: rgba(231, 183, 101, .55); color: var(--accent); }
/* 지역은 흐리게 두지 않는다. 마술사가 제일 먼저 판단하는 게 「갈 수 있나」다. */
.news-region {
  font-size: 12px; font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.news-when {
  margin-left: auto; flex: none;
  font-size: 13px; font-weight: 700; letter-spacing: -.01em; white-space: nowrap;
}
/* 「시작 / 폐막 / 마감」. 이 두 글자가 없으면 D-N 이 거짓말을 한다. */
.news-when i { font-style: normal; font-weight: 600; font-size: 10px; color: var(--ink-dim); margin-right: 4px; }
.news-when.near { color: var(--accent); }                  /* 금색은 D-7 이내에만 */
.news-when.far { font-weight: 600; color: var(--ink-dim); } /* D-60 초과 — 달로 적는다 */
/* 🔴 display:block 을 빼지 말 것. <a> 안의 <span> 이라 빼면 제목과 설명이
   «한 문장으로 이어져 붙는다»(피카님 1차 렌더에서 실제로 그랬다). */
.news-name { display: block; margin-top: 9px; font-size: 14px; font-weight: 600; line-height: 1.35; }
.news-line { display: block; margin-top: 4px; font-size: 11px; color: var(--ink-dim); line-height: 1.5; }
/* 「누르면 주최 측 원문으로 간다」는 말. 금색은 안 쓴다 — 임박 D-N 이 이미 쓰고
   있어서 뜻이 겹치고, 그러면 급한 것과 안 급한 것이 같은 무게로 보인다. */
.news-src { display: block; margin-top: 6px; font-size: 10px; color: var(--ink-dim); }

/* 대체 화면. 높이를 소식 카드와 맞춰 뒀다 — 자리가 바뀔 때 아래가 안 튄다. */
.rec {
  display: flex; align-items: center; gap: 15px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--tile); padding: 14px 15px;
}
.rec-body { flex: 1; min-width: 0; }
.rec-name { display: block; font-size: 14px; font-weight: 600; }
.rec-line { display: block; margin-top: 4px; font-size: 11px; color: var(--ink-dim); line-height: 1.5; }
.rec-go { flex: none; font-size: 11px; font-weight: 600; color: var(--accent); }
.rec-mark {
  flex: none; width: 38px; height: 38px;
  border: 1px solid var(--line); border-radius: 10px;
  display: flex; align-items: center; justify-content: center; background: #101216;
}
/* 🔴 이모지가 아니라 SVG 다(피카님). 이모지는 폰마다 그림이 달라서 아이폰과
   갤럭시가 다르게 보인다 — 워드마크·카드 숫자를 SVG 로 통일한 것과 같은 이유다.
   색은 여기서 준다(파일엔 currentColor 만 있다). 면으로 칠하지 않는다. */
.rec-mark svg { width: 20px; height: 20px; stroke: var(--accent); fill: none; }

/* 돌아가는 소식의 «어디까지 왔나» + 손으로 넘기는 자리.
   🔴 점이 아니라 화살표와 숫자다(대표 2026-09-09). 점은 소식 갯수만큼 늘어나
      20건이면 화면을 먹지만, 「3 / 20」은 몇 건이든 «자리가 같다».
   🔴 「움직임 줄이기」를 켠 사람에게는 이게 «유일한» 넘김 수단이라 장식이 아니라
      조작 장치다 — 그래서 손가락이 확실히 닿는 44px 를 준다(애플 권장 최소치). */
.news-nav { display: flex; align-items: center; justify-content: center; margin-top: 6px; }
.news-arrow {
  width: 44px; height: 44px; padding: 0; border: 0; background: none;
  color: var(--ink-dim); font-size: 20px; line-height: 1; font-family: inherit;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.news-arrow:active { color: var(--ink); }
/* 🔴 tabular-nums 가 없으면 3/20 → 4/20 으로 갈 때 숫자 폭이 달라 화살표가
      덜컹거린다. 5초마다 덜컹이는 화면은 그 자체로 고장으로 읽힌다. */
.news-count {
  min-width: 56px; text-align: center;
  font-size: 11px; color: var(--ink-dim); font-variant-numeric: tabular-nums;
}

/* 목록 화면(/news) */
.news-lead { margin-top: 10px; font-size: 12px; line-height: 1.8; color: var(--ink-dim); }
/* 마지막 갱신 — 「매주 갱신합니다」라는 약속 대신 두는 증거다(잡스님 2026-09-07).
   🔴 오래됐을 때 «회색으로 내리는» 첫 안은 폐기됐다(피카님 §18, 2026-09-08).
      --ink-dim 은 이 화면에서 부제·카드 설명줄·먼 날짜가 «이미 쓰는» 색이라,
      오래된 줄을 회색으로 만들면 드러내는 게 아니라 «덮는» 장치가 된다 —
      정직하려고 넣은 줄이 오래될수록 안 보이게 된다.
      그래서 색을 새로 만들지 않고 «말을 하나 늘린다». 오래됐을 때만 또렷해진다. */
.news-updated { margin-top: 16px; font-size: 11px; color: var(--ink-dim); }
.news-updated .old { color: var(--ink); font-weight: 600; }
.news-updated:empty { display: none; }

/* 제보 — 목록 «아래»에 온다. 마술사가 보러 온 것은 소식이고, 이건 그다음이다.
   🔴 「바로 안 올라갑니다」를 폼 위에 먼저 적는다. 기대와 다르게 굴면
      「올렸는데 왜 안 보이냐」가 반드시 온다. */
.tip { margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--line); }
.tip-title { font-size: 13px; font-weight: 700; }
.tip-lead { margin-top: 6px; font-size: 11px; line-height: 1.7; color: var(--ink-dim); }
.tip-in {
  display: block; width: 100%; margin-top: 8px; padding: 11px 12px;
  border: 1px solid var(--line); border-radius: 9px;
  background: var(--tile); color: var(--ink);
  /* 16px 미만이면 사파리가 화면을 확대해 버린다. 폰에서 그 순간 흐름이 깨진다. */
  font-size: 16px; font-family: inherit;
}
.tip-in::placeholder { color: var(--ink-dim); }
.tip-hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.tip-go {
  margin-top: 10px; padding: 11px 20px; border: 1px solid var(--line);
  border-radius: 9px; background: var(--tile); color: var(--ink);
  font-size: 14px; font-family: inherit; cursor: pointer;
}
.tip-said { margin-top: 8px; font-size: 11px; line-height: 1.6; color: var(--ink-dim); }
.tip-said:empty { display: none; }

/* ── 제보·문의 (/tip) ────────────────────────────────────────────────── */

/* 소식 목록 아래의 «버튼 한 줄». 칸 넷을 늘 펼쳐 두던 자리를 대신한다. */
.tip-cta { margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--line); text-align: center; }
.tip-cta-b {
  display: inline-block;
  padding: 12px 18px;
  border: 1px solid var(--line);
  border-radius: 12px;
  font-size: 13px;
  color: var(--ink);
}
.tip-cta-b:active { opacity: .6; }
.tip-cta-note { display: block; margin-top: 8px; font-size: 11px; line-height: 1.6; color: var(--ink-dim); }

/* 🔴 무엇을 보내는지 «먼저» 고르는 줄. 세 칸이 같은 폭이라야 셋이 동등해
   보인다 — 하나가 넓으면 그게 기본값처럼 읽힌다(광고 문의가 기본이 되면
   곤란하다). 그래서 flex:1 로 균등 분할한다. */
.pick { display: flex; gap: 6px; margin-top: 16px; }
.pick-b {
  flex: 1;
  /* 🔴 `min-width: 0` 이 없으면 flex 칸은 «글자보다 좁아지지 못한다». 세 칸의
     글자 폭 합이 화면보다 넓어지는 순간 줄 전체가 화면 밖으로 밀려나가고,
     그러면 페이지가 통째로 가로 스크롤된다(실측: 390px 에서 「광고 문의」가 잘림). */
  min-width: 0;
  padding: 11px 6px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: transparent;
  font: inherit;
  font-size: 12px;
  line-height: 1.4;
  color: var(--ink-dim);
  word-break: keep-all;
}
/* 고른 것만 금색 테두리. 배경을 칠하지 않는 이유는 어두운 판에서 칠한 칸이
   «눌린 상태»가 아니라 «다른 종류»로 보이기 때문이다. */
.pick-b.on { border-color: var(--accent); color: var(--accent); }
.pick-b:active { opacity: .6; }

.tipform { margin-top: 14px; }
/* 여러 줄 칸도 한 줄 칸과 «같은 모양»이라야 한 벌로 읽힌다. */
/* 🔴 `font: inherit` 로 쓰지 말 것 — 위 `.tip-in` 의 16px 를 덮어써서
   사파리가 입력할 때 화면을 확대해 버린다. 글꼴만 물려받고 크기는 지킨다. */
.tipform textarea.tip-in { resize: vertical; min-height: 96px; font-family: inherit; font-size: 16px; }
.tip-foot { margin-top: 18px; font-size: 11px; line-height: 1.7; color: var(--ink-dim); text-align: center; }
.tip-mail { color: var(--accent); }

.news-foot {
  margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line);
  font-size: 11px; line-height: 1.7; color: var(--ink-dim);
}

/* 제품 배너 — 칸이 아니라 격자 «아래에 나열» 한다 (대표 2026-08-28).
   돌지 않는다. 순서가 곧 보이는 순서다. 소식 «다음»에 온다 — 마술사가 보러 온
   것이 소식이고, 배너는 우리 것이다. */
.banners { margin-top: 20px; display: flex; flex-direction: column; gap: 10px; }
.banner {
  display: flex;
  flex-direction: column;
  gap: 3px;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 13px 15px;
  background: var(--tile);
}
/* 그림 배너는 껍데기(배경·테두리·모서리)가 **그림 안에** 그려져 있다. 그래서
   여기선 판을 벗는다 — 안 벗으면 테두리가 두 겹으로 보인다. */
.banner.has-img { padding: 0; border: 0; background: none; display: block; }
.banner img { display: block; width: 100%; height: auto; border-radius: 12px; }
.banner-name { font-size: 13px; font-weight: 600; }
.banner-line { font-size: 11px; color: var(--ink-dim); }
.banner-go { margin-top: 4px; font-size: 11px; color: var(--accent); }

/* ── 하단 문의 ── 광고판의 «창구». 격자·배너 다음, 화면 제일 아래에 온다.
   보이되 앞서지 않는다 — 마술을 하러 온 사람이 먼저 보는 건 «칸» 이어야 한다.
   그래서 선 하나로 본문과 끊고, 글씨는 작게, 주소만 금색으로 둔다. */
.foot {
  max-width: 560px;
  margin: 30px auto 0;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  text-align: center;
}
.foot-ask { font-size: 12px; line-height: 1.6; color: var(--ink-dim); }

/* 🔴 하단 두 칸 — «대칭» (대표 2026-09-10: 「이메일 주소랑 소식 전환 하는 버튼도
   같이 대칭 맞춰서 정리해서」). 둘의 «크기와 여백을 같게» 두는 게 핵심이다:
   한쪽만 테두리를 주거나 한쪽만 크면 그쪽이 본문이고 다른 쪽은 덤으로 읽힌다.
   ⚠️ 좁은 폰에서는 세로로 쌓인다. 그때 폭도 같아야 대칭이 유지된다 —
      그래서 감쌌을 때 둘 다 «꽉 차게» 늘어난다(flex: 1 1 200px). */
.foot-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 10px;
}
.foot-b {
  flex: 1 1 200px;
  max-width: 260px;
  /* 🔴 «상자를 같게» 만든다. 글자만 가운데 두면 한글(제보·문의)과 라틴
     (hello@…)의 줄높이가 달라 상자 높이가 1px 어긋난다 — 나란히 서면 그
     1px 가 보인다. 대표가 말한 「대칭」은 이 상자 얘기다. */
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  font-size: 13px;
  line-height: 1.5;
  text-align: center;
  color: var(--ink);
  word-break: keep-all;
}
/* 메일 쪽만 «주소»라서 글자가 길다. 색으로 가르되 크기는 건드리지 않는다. */
.foot-b.foot-mail { color: var(--accent); }
.foot-b:active { opacity: .6; }
/* 🔴 글자만 두면 폰에서 «보이는데 안 눌린다». 여백으로 손가락 자리(≈44px)를
   만든다 — 여기서 못 누르면 광고 문의가 통째로 사라지는 자리다. */
.foot-mail {
  display: inline-block;
  margin-top: 6px;
  padding: 12px 16px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--accent);
  /* 메일 주소는 길다. 좁은 폰에서 가로로 삐져나가지 않게 끊길 수 있게 둔다. */
  word-break: break-all;
}
.foot-mail:active { opacity: .6; }

/* 설치 안내가 떠 있는 동안에만 그 높이만큼 아래를 비운다. 안내는 `position:
   fixed` 라 흐름에 자리를 차지하지 않아서, 이게 없으면 문의 줄을 정확히 덮는다.
   👉 이 값은 `.install` 상자 높이 + 여유다. 안내 문구를 늘리면 같이 키울 것. */
body.has-install {
  padding-bottom: calc(max(28px, env(safe-area-inset-bottom)) + 128px);
}

/* 햄버거 — 설명서가 이 안에 있다. 🔴 마술 화면에는 없다(관객이 본다). */
.burger {
  font: inherit;
  font-size: 17px;
  line-height: 1;
  color: var(--ink-dim);
  background: transparent;
  border: 0;
  padding: 9px 11px;
  margin: -9px -11px;
}
.menu {
  position: fixed;
  top: calc(max(14px, env(safe-area-inset-top)) + 42px);
  right: 14px;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 2px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #101216;
  padding: 6px;
  min-width: 190px;
}
.menu a { font-size: 13px; padding: 10px 12px; border-radius: 8px; }
@media (hover: hover) { .menu a:hover { background: rgba(255, 255, 255, .06); } }

@media (hover: hover) {
  .tile.open:hover, .tile.locked:hover { border-color: #4A4E56; }
}

/* 설치 안내 — 격자 아래에 붙는다. 화면을 가리지 않게 아래에 눕힌다. */
.install {
  position: fixed;
  left: 12px; right: 12px;
  bottom: max(12px, env(safe-area-inset-bottom));
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #0C0D10;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12px;
  color: var(--ink-dim);
}
.install b { font-size: 13px; font-weight: 600; color: var(--ink); }
.install-row { display: flex; gap: 8px; margin-top: 6px; }
.install button {
  font: inherit;
  border-radius: 9px;
  padding: 8px 14px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink-dim);
}
.install #install-go {
  border-color: rgba(231, 183, 101, .45);
  color: var(--accent);
}

/* ── 어느 화면에나 있는 좌상단 로고 겸 홈 ── */
/* 카드·마지막 화면 «위» 에 따로 떠 있다. 마지막 화면은 아무 데나 누르면 숫자가
   뜨는데, 홈이 그 «안» 에 있으면 누를 때마다 숫자가 번쩍인다. 그래서 밖에 둔다.
   빈 자리는 `pointer-events: none` 이라 카드 스와이프를 가로막지 않는다. */
.topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 10;
  /* 🔴 «불투명한 덮개»다(대표 2026-09-09, 이 자리가 세 번 열렸다):
        「로고랑 지나간 윗쪽 페이지가 겹쳐지는거 없이 다 가려지게」
     position:fixed 만 주고 배경을 안 깔면 상단바는 «투명한 유리»다 — 스크롤한
     내용이 로고 «뒤로 그대로 지나간다». 간격(padding·top 값)을 아무리 벌려도
     안 고쳐진다. 가리는 것과 떨어뜨리는 것은 다른 문제다.
     ⚠️ 반투명(rgba)으로 바꾸지 말 것 — 뒤가 비치면 같은 고장이다.
     ⚠️ 이 한 줄을 지우면 «모든 화면»에서 다시 비친다. */
  background: var(--bg);
  padding: max(14px, env(safe-area-inset-top)) 18px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  color: var(--ink-dim);
  pointer-events: none;
}
/* 🔴 상단바 자체는 `pointer-events: none` 이고, **손가락을 받는 것만 여기 적는다.**
   빠뜨리면 그 버튼은 «있는데 안 눌린다» — 탭이 그냥 통과해 버린다. `button` 이
   빠져 있어서 햄버거가 죽어 있었다(대표 2026-08-28). 상단바에 새 버튼을 넣으면
   여기에 같이 적을 것. */
.topbar a, .topbar .back, .topbar button { pointer-events: auto; }

/* 격자 전용 워드마크 — 카드K 그림 + 「-Magic」(라틴, 대표 2026-09-01). 🔴 아래 `.home` 은 **건드리지 말 것**.
   마술 화면이 그걸 쓰고, 거기 로고는 「관객에게 안 보이게 죽인」 유일한 탈출구다.
   커지거나 밝아지면 안 된다. 그래서 격자용을 따로 만든다. */
.brandmark {
  display: inline-flex;
  align-items: center;
  padding: 9px 12px;
  margin: -9px -12px;
  color: var(--ink);
}
/* 🔴 **`height` 는 글자높이가 아니다.** 카드K가 12° 기울어 SVG 박스가 글자보다
   위아래로 크다 — `height: 22px` 로 두면 «글자는 15px» 로 줄어 최소치(16px)
   아래로 떨어진다. 원하는 글자높이에 파일별 배수를 곱해서 넣을 것
   (K매직 ×1.45 / K-Magic ×1.805 / 케이매직 ×1.00 — 피카님 인계문서 2번).
   지금 값 = 글자높이 22px × 1.805 ≒ 40px (폭 124px).
   **워드마크를 갈아끼우면 이 숫자도 같이 바꿔야 한다** — 2026-09-01 에 한글에서
   라틴으로 갈아끼우며 여기가 32px 로 남아 있었으면 글자가 17.7px 로 «조용히»
   줄어들 뻔했다. 배수는 파일마다 다르고, 화면은 아무 경고도 안 준다. */
/* 🔴 40px → 34px (대표 2026-09-09: 「로고 크기는 조금 줄여줘도 돼」).
 *    워드마크만 남아 가로가 길어졌으므로 세로를 줄여야 균형이 맞는다. */
.brandmark svg { height: 24px; width: auto; display: block; fill: currentColor; }
/* 🔴 획으로 그린 글자(M·A·G·I·C). fill 을 «CSS 로» 꺼야 한다 —
 *    SVG 속성 fill="none" 은 위 줄의 fill: currentColor 에 진다(CSS 가 더 세다).
 *    이 줄을 지우면 글자가 까맣게 칠해진 덩어리로 뜬다. */
.brandmark svg .wm-stroke {
  fill: none;
  stroke: currentColor;
  stroke-width: 12;
  stroke-linecap: butt;
  stroke-linejoin: miter;
}
.brandmark svg .wm-mark { fill: var(--accent); }             /* 카드만 금색 */
/* 🔴 마술 화면에선 카드도 죽인다. 지금은 워드마크가 격자에만 있어서 이 규칙이
   쓰일 일이 없지만, 나중에 누가 상단바를 공용으로 만들면 이게 안전망이 된다 —
   빠뜨리면 관객 앞 마지막 화면에서 금색 카드만 밝게 남는다(피카님 경고). */
.topbar.quiet .brandmark svg .wm-mark { fill: currentColor; }
.brandmark:active svg { opacity: .6; }

.home {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .3em;
  text-indent: .3em;
  padding: 9px 12px;            /* 손가락 목표는 넓게, 보이는 건 작게 */
  margin: -9px -12px;
}
.topbar-right { display: flex; align-items: center; gap: 15px; }
.back { padding: 9px 11px; margin: -9px -11px; font-size: 15px; }

/* 🔴 뒤로가기 — «왼쪽 아래» (대표 2026-09-09: 「나이맞추기에 뒤로가기 버튼이 카드
   아래 있게 하거나 다른 위치로」). 같은 날 햄버거가 우상단 붙박이가 되면서
   그 자리를 비켜 준 것이다. 둘을 나란히 두면 관객 앞에서 오른쪽 위가
   «버튼 두 개짜리 메뉴 막대»로 읽히고, 그 순간 이건 마술이 아니라 앱이 된다.

   🔴 이 좌표는 «묶음(deck)을 피해» 잰 값이다. 뒷장은 최대 30px 아래로 삐져나와
      화면 밑 24px 까지 내려온다. 다만 뒷장일수록 scaleX 로 좁아져서 왼쪽
      23~41px 안쪽으로 들어와 있다 — 그래서 이 버튼은 «왼쪽 끝 35px 안»에서만
      안전하다. 값을 키우거나 오른쪽으로 옮기면 화살표가 카드 테두리에 걸친다.
   ⚠️ `.back` 의 음수 margin 을 0 으로 되돌린다. position:fixed 에서는 그 값이
      «위치»를 밀어 버려서, 안 지우면 화면 밖으로 4px 씩 나간다. */
.back-bottom {
  position: fixed;
  left: 2px;
  bottom: max(5px, env(safe-area-inset-bottom));
  margin: 0;
  padding: 8px 10px;
}

/* 🔴 마지막 화면에선 햄버거도 «같이» 죽인다. `.burger` 는 색을 자기가 정해서
   (`var(--ink-dim)`) 위의 `.topbar.quiet` 한 줄로는 안 어두워진다 — 빠뜨리면
   관객이 제일 오래 보는 화면에 ☰ 하나만 밝게 남는다. */
.topbar.quiet .burger { color: #2A2C31; }
.count { color: #4A4E56; font-variant-numeric: tabular-nums; }
.doclink { border-bottom: 1px solid #24262C; padding-bottom: 2px; }

/* 마지막 화면 — 클라이맥스다. 관객 앞에서 상단바가 빛나면 안 되니 어둡게 죽인다.
   🔴 다만 «누를 수는 있다». 「↻ 처음부터」를 없앤 뒤로 여기서 나가는 길은 로고
   하나뿐이다. 로고는 `.reveal` «밖» 에 있어서 눌러도 숫자가 뜨지 않는다 —
   대표께서 "로고 영역과 「누르면 숫자」 영역이 겹치지 않게" 하라신 부분이다. */
/* 🔴 `.brandmark` 를 «반드시» 같이 적는다. 이 줄이 없어서 2026-09-09 까지
   마지막 화면에 워드마크가 «흰색 그대로» 떠 있었다 — 관객이 제일 오래 보는
   화면이다. 원인: 2026-09-01 에 `.home`(글자) 을 워드마크로 갈아끼우면서
   여기 선택자는 `.home` 인 채로 남았고, `.brandmark` 는 자기 색(`var(--ink)`)을
   따로 정해서 위의 상속을 «이긴다». 화면은 아무 경고도 안 준다.
   ⚠️ 상단바에 색을 스스로 정하는 것을 새로 넣으면 여기에 «같이» 적을 것. */
.topbar.quiet, .topbar.quiet .home, .topbar.quiet .brandmark { color: #2A2C31; }

/* ── 숫자 마술 ── */
.stage {
  position: fixed;
  inset: 0;
  touch-action: none;          /* 스와이프가 스크롤로 새지 않게 */
}

/* 카드·껍데기(ghost)·묶음(deck)이 «같은 자리» 를 차지해야 넘어가는 게 자연스럽다.
   그래서 셋 다 절대배치로 같은 상자를 쓴다. 값을 바꾸면 셋 다 같이 바꿀 것. */
.card, .deck {
  position: absolute;
  top: calc(max(14px, env(safe-area-inset-top)) + 34px);
  left: 14px; right: 14px;
  /* 뒷장이 앞장 «아래» 로 최대 30px 삐져나온다. 그만큼 자리를 안 비워두면
     제일 깊은 장이 화면 밖으로 잘려서 묶음이 두 장으로 보인다. */
  bottom: calc(max(20px, env(safe-area-inset-bottom)) + 34px);
}
.card {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  align-content: center;
  gap: 26px 4px;
  padding: 12px 16px;
  font-variant-numeric: tabular-nums;
  /* 카드로 보여야 «넘어갔다» 가 읽힌다. 바탕은 거의 검정 그대로 둔다 —
     어두운 공연장에서 판이 밝으면 관객 눈이 화면에만 간다. */
  border: 1px solid var(--line);
  border-radius: 16px;
  background: #050507;
}

/* 앞장 뒤에 남은 장. **가장자리만** 보인다 — 숫자가 새면 마술이 깨진다.
   넘길수록 얇아지는 게 「넘어갔다」는 신호다. 「3/6」 같은 숫자로 알리면
   관객에게 «여섯 번 답하게 돼 있다» 가 드러난다 (대표 2026-08-28). */
.deck { pointer-events: none; }
.deck i {
  position: absolute;
  inset: 0;
  /* 앞장 테두리보다 조금 밝다 — 어두운 공연장에서 «장이 더 있다» 가 보여야
     한다. 이게 안 보이면 마술사가 넘어간 걸 못 알아채고 한 번 더 넘긴다. */
  border: 1px solid #2E323A;
  border-radius: 16px;
  background: #050507;
}
/* 관객이 팔 길이에서 훑어봅니다. 작으면 «어디 보자» 하느라 흐름이 끊깁니다. */
.card span {
  font-size: clamp(28px, 9.4vw, 44px);
  font-weight: 500;
  text-align: center;
  letter-spacing: -.02em;
}


/* 카드마다 색조 — 🔴 «아주 은은하게». 진하면 앱 테마로 보이고 카드가 아니게 된다
   (대표 2026-08-28: "은은히"). 관객에게 «여섯 장» 이라는 증거를 주는 게 목적이다.
   순서마다 고정이라 마술사도 몇 번째인지 감을 잡는다.

   🔴 이게 **마지막 검정을 살린다** — 색·색·색·색·색·색 → 툭 꺼짐. 그래서
      `.reveal` 에는 색이 스미면 안 된다. 여기 색은 `.card` 에만 건다.
   ⚠️ 밝기(명도)는 거의 안 올린다. 부스는 어둡고 관객은 폰을 비스듬히 본다 —
      기울이면 옅은 색은 더 안 보인다. 숫자 대비는 그대로 두고 «색조» 만 얹는다. */
/* 🔴 **명도는 여섯 장이 거의 같고 «색상» 만 다르다.** 밝기로 구분하면 어떤 카드는
   허옇게 떠서 「밝기가 다른 화면」이 되고, 카드로 안 읽힌다. 색으로만 가른다.
   흰 글씨 대비를 직접 계산했다 — 가장 낮은 것이 15.4:1 로, 본문 최고기준(7:1)의
   2.2배다. 순검정이 18.9:1 이니 어두운 느낌도 그대로다(대표: "어두운건 좋아"). */
.card.tint0 { background: #101725; }   /* 남색   16.1:1 */
.card.tint1 { background: #1B1220; }   /* 자주   16.4:1 */
.card.tint2 { background: #0E1D1A; }   /* 청록   15.6:1 */
.card.tint3 { background: #211710; }   /* 적갈   15.8:1 */
.card.tint4 { background: #151E11; }   /* 올리브 15.4:1 */
.card.tint5 { background: #1A1226; }   /* 보라   16.3:1 */

/* 넘어가는 동안만 쓰는 껍데기. 손가락을 절대 가로막지 않는다.
   🔴 `.card.ghost` 로 «좁혀» 둔다. 전에는 `.ghost` 였는데, 나선 화면의 멈춤 버튼에
   `ghost` 를 꾸밈 클래스로 붙였더니 그 버튼이 `pointer-events: none` 을 물려받아
   **안 눌렸다**(안전 버튼이다). 흔한 이름은 반드시 좁혀 쓴다. */
.card.ghost { pointer-events: none; }

/* 관객 앞에서 여섯 번 반복한다. 한 번에 0.5초씩 걸리면 3초가 그냥 간다.
   0.18초 — 카드가 넘어간 걸 눈이 알아보되 기다림은 안 생기는 길이다. */
.card.fly {
  transition: transform .18s cubic-bezier(.22, .61, .36, 1), opacity .18s ease-out;
}
/* 애니메이션을 끈 기기에서도 «동작» 은 그대로다 — 보이는 것만 뺀다. */
@media (prefers-reduced-motion: reduce) {
  .card.fly { transition: none; }
}

/* 마지막 — 누르고 있는 동안에만 숫자가 보인다. 이게 이 마술의 전부다. */
.reveal {
  position: fixed;
  inset: 0;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: none;
}
.reveal b {
  font-size: clamp(96px, 40vw, 260px);
  font-weight: 600;
  letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
  opacity: 0;                   /* 기본은 안 보인다 */
}
/* 🔴 «절반만» 켠다 (대표 2026-09-09: 「몰래보는데 밝게 나와서 티가남」).
   이 화면은 관객에게 보여 주는 게 아니라 마술사가 «훔쳐보는» 것이다. 흰색
   가득이면 폰이 손전등이 돼서 얼굴이 밝아지고, 그걸 보면 뭔가 봤다는 게 티가
   난다. 숫자가 화면을 꽉 채우는 크기(최대 260px)라, 밝기를 반으로 줄여도
   흘긋 보는 데는 지장이 없다 — 읽기 쉬움은 «크기»가 만들고 티는 «밝기»가 낸다.
   ⚠️ 크기로 줄이지 말 것. 작고 밝은 숫자가 크고 어두운 숫자보다 훨씬 잘 틀린다.
   더 어둡게 하려면 이 숫자 하나만 내린다(0.35 까지는 아직 읽힌다). */
.reveal.on b { opacity: .5; }
[hidden] { display: none !important; }



/* ── 손이 부푼다 (나선 · 운동잔효) ──
 * 🔴 크기가 잔효의 세기를 정한다. 처음부터 화면 가득이다 — 이건 마술 화면이라
 *    「화면 가득」 버튼을 따로 누르게 하지 않는다. */
.spiral {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
  overflow: hidden;
}
#spiral {
  width: min(100vw, 100vh);
  height: min(100vw, 100vh);
  /* 🔴 기본 0.30초/바퀴. 느리면 «안 걸린다» — 2.5초로 만든 첫 판이 안 걸렸다.
     대표님이 「아주 빠르게(0.35)를 조금 더 빠르게」로 정하셨다. 늦추지 말 것. */
  animation: spiral-spin .30s linear infinite;
  animation-play-state: paused;
}
#spiral.run { animation-play-state: running; }
/* 반대로 돌리면 잔효도 반대가 된다 — 손이 «오그라들어» 보인다. */
#spiral.rev { animation-direction: reverse; }
@keyframes spiral-spin { to { transform: rotate(360deg); } }

/* 🔴 응시점 — 없으면 눈이 돌아다녀서 잔효가 안 쌓인다. 제일 흔한 실패 원인이다. */
.fix {
  position: fixed;
  left: 50%; top: 50%;
  width: 11px; height: 11px;
  margin: -5.5px 0 0 -5.5px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px rgba(0, 0, 0, .9);
  pointer-events: none;
  z-index: 5;
}

/* 안내는 최소로. 다만 이 마술은 관객이 «직접 보는» 것이라, 「가운데 점을 보세요」가
   없으면 아무도 못 한다 — 나이 맞히기와 성격이 다르다. */
.spiral-say {
  position: fixed;
  left: 0; right: 0;
  bottom: calc(max(20px, env(safe-area-inset-bottom)) + 66px);
  z-index: 6;
  text-align: center;
  font-size: 14px;
  color: var(--ink-dim);
  padding: 0 20px;
}
.spiral-say b { color: var(--ink); }
.spiral-count {
  position: fixed;
  left: 0; right: 0;
  bottom: calc(max(20px, env(safe-area-inset-bottom)) + 100px);
  z-index: 6;
  text-align: center;
  font-size: 12px;
  color: #4A4E56;
  font-variant-numeric: tabular-nums;
}
.spiral-row {
  position: fixed;
  left: 0; right: 0;
  bottom: max(20px, env(safe-area-inset-bottom));
  z-index: 6;
  display: flex;
  gap: 10px;
  justify-content: center;
}
.spiral-row button {
  font: inherit;
  font-size: 14px;
  padding: 11px 26px;
  border-radius: 10px;
  border: 1px solid rgba(231, 183, 101, .45);
  background: rgba(0, 0, 0, .55);
  color: var(--accent);
}
.spiral-row button.soft { border-color: var(--line); color: var(--ink-dim); }
.spiral-row button[disabled] { opacity: .4; }

/* ── 설명서 그림 ──
 * 🔴 방향은 **그림으로만** 말한다. 글로 「있다 → 왼쪽」이라고 쓰면 그 화살표가
 *    오른쪽을 가리켜서 반대로 읽힌다(대표 2026-08-28). 부스에서 반대로 외우면
 *    여섯 번 다 틀린다. 화살표가 가리키는 쪽 = 실제 넘기는 쪽이다.
 * 인라인 SVG 라서 `currentColor` 로 글자색을 따라간다 — 파일을 따로 안 받는다. */
.howto {
  display: block;
  width: 100%;
  max-width: 320px;
  height: auto;              /* 폰 폭에서 안 찌그러진다 */
  margin: 14px auto 18px;
}
.howto-label { fill: var(--accent); font-size: 17px; font-weight: 700; text-anchor: middle; }
.howto-note  { fill: var(--ink-dim); font-size: 12px; text-anchor: middle; }
.howto-phone { fill: none; stroke: #3A3E46; stroke-width: 2; }
.howto-card  { fill: #0C0D10; stroke: #4A4E56; stroke-width: 2; }
.howto-num   { fill: var(--ink); font-size: 20px; text-anchor: middle; }
.howto-answer{ fill: var(--ink); font-size: 30px; font-weight: 600; text-anchor: middle; }
.howto-logo  { fill: var(--accent); }
.howto-touch { fill: rgba(231, 183, 101, .22); stroke: var(--accent); stroke-width: 1.5; }
.howto-arrow { stroke: var(--accent); stroke-width: 3; stroke-linecap: round; }
.howto-head  { fill: var(--accent); }

/* 실전에서 제일 중요한 한 줄 — 모르면 관객 앞에서 갇힌다. */
.doc .keyline {
  border-left: 2px solid var(--accent);
  padding: 2px 0 2px 14px;
  margin: 14px 0;
}

/* ── 사용법 ── */
.doc { max-width: 560px; margin: 0 auto; font-size: 15px; line-height: 1.75; }
.doc h1 { font-size: 19px; font-weight: 700; }
.doc h2 {
  font-size: 12px; font-weight: 700; letter-spacing: .16em;
  color: var(--ink-dim); margin: 30px 0 10px;
}
.doc p, .doc li { color: #C7CAD0; }
.doc ol, .doc ul { padding-left: 20px; }
.doc li { margin: 7px 0; }
.doc .say {
  border-left: 2px solid #2A2C31;
  padding: 2px 0 2px 14px;
  margin: 10px 0;
  color: var(--ink);
}

/* ── 낱말 예언 (/same) ──
   🔴 관객이 «직접 밀어» 내려가는 마술이다. 그 시간이 「내가 자유롭게 했다」는
      확신을 만든다 — 목록을 짧게 접거나 눌러서 넘기게 바꾸면 마술이 약해진다. */
.same { max-width: 460px; margin: 0 auto; padding: 4px 18px 60px; }

/* 준비 화면 — 기본은 «아무것도 안 정해도 되는» 화면이다(대표 2026-09-09). */
.same-h1 { margin-top: 10px; font-size: 21px; font-weight: 700; }
.same-lead { margin-top: 10px; font-size: 13px; line-height: 1.8; color: var(--ink-dim); }
.same-lead b { color: var(--ink); }
.same-start {
  display: block; width: 100%; margin-top: 22px; padding: 15px;
  border: 1px solid #33363E; border-radius: 12px;
  background: var(--tile); color: var(--ink);
  font-size: 16px; font-family: inherit; cursor: pointer;
}
/* 커스텀은 «있는 줄만 알면 되는» 자리라 조용하게 둔다. */
.same-custom-go {
  display: block; width: 100%; margin-top: 10px; padding: 12px;
  border: 0; background: none; color: var(--ink-dim);
  font-size: 13px; font-family: inherit; cursor: pointer;
}
.same-custom {
  margin-top: 6px; padding: 16px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--tile);
}
.same-label { display: block; margin-top: 4px; font-size: 12px; color: var(--ink-dim); }
.same-custom .same-label + * { margin-top: 8px; }
.same-custom .same-label:not(:first-child) { margin-top: 18px; }
.same-in {
  display: block; width: 100%; padding: 13px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg); color: var(--ink);
  /* 16px 미만이면 사파리가 화면을 확대한다. */
  font-size: 18px; font-family: inherit; text-align: center;
}
.same-in::placeholder { color: #3A3D44; }
.same-hint { margin-top: 8px; font-size: 12px; color: var(--ink-dim); }
.same-hint b { color: var(--ink); }
.same-quiet { margin-top: 18px; font-size: 11px; line-height: 1.8; color: var(--ink-dim); }
.same-quiet b { color: #9AA0A9; }

/* 색 고르기 — «배경색»으로 보여준다. 목록에서 보이는 것과 같은 모양이다. */
.same-swatches { display: flex; gap: 8px; flex-wrap: wrap; }
.same-swatch {
  width: 44px; height: 44px; border-radius: 10px;
  border: 2px solid transparent; color: #0B0B0F;
  font-size: 19px; font-weight: 700; font-family: inherit; cursor: pointer;
}
/* 고른 색은 «흰 테두리»로 표시한다. 색으로 표시하면 그 색과 겹쳐 안 보인다. */
.same-swatch.on { border-color: var(--ink); }

/* 🔴 상단바는 position:fixed 라 «화면 맨 위»를 이미 차지한다. 여기에 top:0 을
   주면 로고와 안내문이 같은 자리에 서서 글자가 서로를 뚫는다(대표 2026-09-09
   「텍스트가 일단 겹침」). 그래서 «상단바 높이만큼» 내려서 붙인다.
   높이는 topbar.js 가 실제로 재서 --topbar-h 에 넣는다.
   🔴 배경을 «화면 폭 끝까지» 깐다. 안 그러면 목록이 옆으로 비껴 지나간다.
   🔴 「테두리 지우기」가 «오른쪽 빈 자리»에 온다(대표 2026-09-09) — 목록 맨
      아래에 두면 마흔 칸을 다 지나야 버튼을 만난다. */
.same-how {
  /* 🔴 «2px 겹쳐» 붙인다. 상단바 높이는 offsetHeight 라 정수로 반올림되고,
        딱 맞춰 놓으면 그 반올림 오차만큼 «머리카락 같은 틈»이 생겨 그 틈으로
        낱말이 지나간다. 겹쳐 두면 로고와 안내문이 «한 덩어리»가 된다.
        겹치는 2px 은 배경뿐이라 글자는 안 잘린다(padding-top 10px). */
  position: sticky; top: calc(var(--topbar-h, 60px) - 2px); z-index: 2;
  background: var(--bg); margin: 0 -18px; padding: 10px 18px 12px;
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 10px;
}
.same-steps { flex: 1; min-width: 0; }
.same-step { font-size: 12px; line-height: 1.7; color: var(--ink-dim); }
.same-step b { color: var(--ink); font-weight: 600; }
.same-release {
  flex: none; width: 74px; padding: 10px 4px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--tile); color: var(--ink-dim);
  font-size: 11px; line-height: 1.4; font-family: inherit; cursor: pointer;
}

/* 🔴 테두리 — «가두는 틀이 아니다»(대표 2026-09-09: 「드래그를 못하게 막으라는
   게 아니라」). 목록은 처음부터 자유롭게 오르내린다. 이 사각형은 「여기서
   고르세요」를 눈에 보이게 할 뿐이고, 내려가도 1~10번 자리에 그대로 남는다.
   ⚠️ 「밀면 되돌아오는 틀」 안은 폐기됐다. 되돌리지 말 것. */
.same-frame { position: relative; margin-top: 6px; }
.same-mark {
  position: absolute; left: -6px; right: -6px; top: -6px;
  border: 1px solid #3A3E47; border-radius: 12px;
  pointer-events: none;   /* 테두리가 손가락을 가로막으면 안 된다 */
}
.same-mark[hidden] { display: none; }

.same-list { list-style: none; }
/* 열 칸이 «한 화면에» 들어와야 테두리가 뜻을 갖는다 — 그래서 칸을 촘촘히 둔다. */
.same-row {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 12px; border-bottom: 1px solid var(--line);
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.same-no {
  min-width: 26px; text-align: right;
  font-size: 12px; color: #4A4D55; font-variant-numeric: tabular-nums;
}
/* 🔴 색은 «배경»으로 칠한다(대표 2026-09-09). 글자색만 쓰던 첫 안은 폰에서
   옅어 보여 「무슨 색인지」를 한눈에 못 골랐다 — 멈추는 색을 못 고르면 이
   마술이 성립하지 않는다. 되돌리지 말 것.
   굵기·아이콘은 «주지 않는다» — 주면 예전 ★처럼 「저기가 특별하다」가 보인다.
   글자는 어두운 색으로 고정한다. 여섯 색이 전부 밝은 쪽이라 대비가 선다. */
.same-word {
  font-size: 16px; line-height: 1.35; color: #0B0B0F;
  padding: 3px 10px; border-radius: 7px;
}

/* 🔴 손으로 짚은 자리. «숫자는 안 세준다»(대표 2026-09-09 「숫자는 안 세줘도 돼」)
   — 앱이 대신 세면 관객이 한 일이 없어진다. 여기 있다는 표시만 한다. */
.same-row.here { background: #14161B; }
.same-row.here .same-no { color: var(--ink); }

.same-open {
  display: block; width: 100%; margin-top: 26px; padding: 14px;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--tile); color: var(--ink-dim);
  font-size: 13px; font-family: inherit; cursor: pointer;
}
.same-answer {
  margin-top: 26px; text-align: center;
  font-size: 34px; font-weight: 700; color: var(--accent);
}

/* ── 자물쇠가 열립니다 (/lock) ── */
.lock { max-width: 420px; margin: 0 auto; padding: 8px 4px 60px; }

.lock-box { text-align: center; padding: 18px 0 22px; }
.lock-icon { width: 68px; height: 68px; stroke: var(--ink-dim); fill: none; }
/* 열리면 «금색». 이 앱에서 금색은 「지금 일어난 일」의 색이다. */
.lock-icon.open { stroke: var(--accent); }
.lock-say { margin-top: 14px; font-size: 13px; line-height: 1.8; color: var(--ink-dim); }
.lock-say b { color: var(--ink); }

.lock-step { margin-top: 8px; }
.lock-q { font-size: 16px; line-height: 1.7; }
.lock-note { margin-top: 6px; font-size: 12px; line-height: 1.7; color: var(--ink-dim); }
.lock-note b { color: var(--ink); }
.lock-quiet { margin-top: 16px; font-size: 11px; }

.lock-in {
  display: block; width: 100%; margin-top: 14px; padding: 14px;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--tile); color: var(--ink);
  /* 16px 미만이면 사파리가 화면을 확대한다 — 관객 앞에서 화면이 튀면 안 된다. */
  font-size: 22px; font-family: inherit; text-align: center;
  font-variant-numeric: tabular-nums; letter-spacing: .2em;
}
.lock-in::placeholder { color: #3A3D44; letter-spacing: .2em; }
.lock-pin { font-size: 28px; }

.lock-go {
  display: block; width: 100%; margin-top: 12px; padding: 14px;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--tile); color: var(--ink);
  font-size: 15px; font-family: inherit; cursor: pointer;
}
.lock-go:active { border-color: #33363E; }
.lock-warn { margin-top: 10px; font-size: 12px; color: var(--accent); min-height: 17px; }

.lock-calc { list-style: none; margin-top: 6px; }
.lock-line {
  padding: 12px 2px; border-bottom: 1px solid var(--line);
  font-size: 15px; color: var(--ink-dim); font-variant-numeric: tabular-nums;
}
.lock-line.big { font-size: 21px; font-weight: 700; color: var(--ink); border-bottom: 0; }

.lock-open { margin-top: 10px; text-align: center; font-size: 28px; font-weight: 700; color: var(--accent); }

/* ── 추천 링크 (/links) ──
   🔴 대표가 어드민에서 넣는 목록이다(대표 2026-09-09). 새 색·새 모양을 만들지
      않는다 — 소식 카드(.news-card)와 «같은 판»을 쓴다. 화면이 늘 때마다 카드
      모양이 하나씩 늘면 앱이 여러 사람이 만든 것처럼 보인다. */
.reco-list { margin-top: 16px; display: flex; flex-direction: column; gap: 10px; }
.reco {
  display: block;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--tile); padding: 14px 15px;
}
/* display:block 을 빼지 말 것 — <a> 안의 조각이라 빼면 이름과 설명이
   «한 문장으로 이어져 붙는다»(소식 카드에서 실제로 그랬다). */
.reco-name { display: block; font-size: 14px; font-weight: 600; line-height: 1.35; }
.reco-line { display: block; margin-top: 4px; font-size: 11px; color: var(--ink-dim); line-height: 1.5; }
/* 「없다」와 「못 불러왔다」가 둘 다 여기 앉는다. 글이 다르고 자리는 같다. */
.reco-empty { margin-top: 4px; font-size: 13px; color: var(--ink-dim); }

/* 메뉴 «맨 아래» 줄 — 개인정보 처리방침 자리 (대표 2026-09-09).
 * 위 항목들과 «같은 무게로 보이면 안 된다». 선을 긋고 작고 흐리게 둔다:
 * 찾는 사람에게는 있고, 안 찾는 사람에게는 안 걸린다. */
.menu .menu-foot {
  margin-top: 6px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  color: var(--ink-dim);
}

/* ── 법적 문서용 (개인정보 처리방침 등) ─────────────────────────────────
 * 🔴 .doc h2 는 「외워둘 것」처럼 «짧은 딱지»용이라 12px + 자간 .16em 이다.
 *    「제7조 (정보주체와 법정대리인의 권리·의무 및 행사방법)」 같은 긴 조문
 *    제목에 그대로 쓰면 잘게 흩어져 읽히지 않는다. 그래서 여기서만 되돌린다.
 * 🔴 word-break: keep-all — 한글은 «단어 가운데»가 잘리면 안 된다.
 *    브라우저 기본값이 글자 단위로 끊어서, 안 넣으면 조문 안에서 낱말이 쪼개진다.
 */
.doc.legal h2 {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--ink);
  margin: 34px 0 10px;
}
.doc.legal { word-break: keep-all; }
.doc.legal ul, .doc.legal ol { margin: 8px 0; }
.doc.legal li ul { margin: 6px 0; }

/* ── 마술 사이트 (/sites) ────────────────────────────────────────────────
 * 대표 2026-09-09: 「마술계 소식처럼 «가로로 한 줄씩» 먹도록 해줘.
 *                  지금은 버튼처럼 생겨서 공간낭비나는거 같아」
 *
 * 🔴 그래서 «격자가 아니라 목록»이다. 두 칸 격자는 이름 한 줄을 담자고 세로를
 *    128px 씩 먹었다 — 열 곳이면 화면 두 장이 그냥 여백이었다.
 * 🔴 로고가 없는 줄도 «같은 높이»로 선다. 로고 자리를 비워 두면 줄마다 들쭉날쭉해
 *    목록으로 안 읽힌다. 로고가 없으면 그 자리에 이름 첫 글자를 넣는다.
 * 🔴 로고 배경을 안 칠한다. 투명 배경 PNG 가 어두운 판 위에 그대로 뜨는 게 제일
 *    깔끔하고, 흰 판을 깔면 로고마다 흰 네모가 줄줄이 선다.
 */
.sites { margin-top: 20px; display: flex; flex-direction: column; gap: 8px; }

.site {
  display: flex;
  align-items: center;
  gap: 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--tile);
  padding: 12px 14px;
  text-align: left;
  word-break: keep-all;
}
.site:active { border-color: #33363E; }

.site-logo { width: 38px; height: 38px; object-fit: contain; display: block; flex: 0 0 38px; }
/* 로고가 없을 때 그 자리를 채우는 글자 한 자 */
.site-initial {
  width: 38px; height: 38px; flex: 0 0 38px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 9px; background: #16181D; color: var(--ink-dim);
  font-size: 15px; font-weight: 700;
}
.site-text { flex: 1 1 auto; min-width: 0; }
.site-name { display: block; font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
.site-line { display: block; margin-top: 2px; font-size: 12px; color: var(--ink-dim); line-height: 1.5; }
.site-go { flex: 0 0 auto; font-size: 13px; color: #4A4E56; }

.sites-empty { margin-top: 26px; font-size: 13px; color: var(--ink-dim); text-align: center; }

/* 🔴 「시작」 버튼 (대표 2026-09-09: 「연출버튼이 버튼처럼 만들어줘야 함.
 *    설명서만 버튼처럼 보여서 시작하는버튼이 따로 있는 것 처럼 해주는 가독성이 좋을듯」).
 *    칸 전체가 눌리긴 하지만, 눌러도 되는 곳처럼 «보이지» 않았다 — 옆의 설명서만
 *    버튼처럼 생겨서 「설명서를 보라는 칸」으로 읽혔다. 그래서 시작을 «채운» 버튼으로
 *    세우고 설명서는 «테두리만» 남긴다. 둘의 무게가 다르면 무엇이 본체인지가 보인다.
 * ⚠️ 두 버튼을 같은 모양으로 만들지 말 것. 그러면 다시 「둘 중 뭘 눌러야 하지」가 된다. */
.tile-act.tile-start {
  color: #0B0C0F;
  background: var(--accent);
  border-color: var(--accent);
  font-weight: 700;
}
.tile-act.tile-start:active { background: #D7A34F; border-color: #D7A34F; }

/* ── 설명서 (어린이도 한 번에) ───────────────────────────────────────────
 * 대표 2026-09-09: 「설명서는 자세하긴 한데 어린친구들도 한번에 이해할수있게」
 *
 * 🔴 맨 위 «세 걸음»이 이 화면의 본체다. 나머지는 필요할 때 읽는 것이라
 *    작고 흐리게 둔다. 셋의 크기가 같으면 어디부터 읽어야 할지 모른다.
 * 🔴 번호는 «동그라미»로 크게. 글을 빨리 못 읽는 사람도 순서는 알아본다.
 */
.doc.guide { word-break: keep-all; }
.guide-warn {
  margin-top: 10px; font-size: 13px; color: var(--accent);
  border: 1px solid rgba(231,183,101,.35); border-radius: 10px; padding: 10px 12px;
}
.guide-lead { font-size: 14px; color: #C7CAD0; margin-top: 14px; }

.steps { list-style: none; padding: 0; margin: 22px 0 0; counter-reset: step; }
.steps li {
  counter-increment: step;
  position: relative;
  padding: 14px 14px 14px 56px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--tile);
  margin: 0 0 10px;
}
.steps li::before {
  content: counter(step);
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; border-radius: 999px;
  background: var(--accent); color: #0B0C0F;
  font-size: 15px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.steps li b { display: block; font-size: 17px; font-weight: 700; letter-spacing: -.01em; }
.steps li span { display: block; margin-top: 3px; font-size: 13px; color: var(--ink-dim); line-height: 1.6; }

/* 조문 제목이 작은 딱지 스타일이라 설명서에선 너무 작다. 여기서만 키운다. */
.doc.guide h2 {
  font-size: 15px; font-weight: 700; letter-spacing: -.01em;
  color: var(--ink); margin: 34px 0 4px;
}

/* 낱말 예언 시작 화면 — 「예언 : 자전거 · 노란 낱말에서 멈춤」
 * 🔴 마술사만 보는 줄이다. 폰을 건네기 «전» 화면이라 관객은 못 본다.
 *    지난번에 고쳐둔 낱말로 모르고 시작하는 사고를 막는 게 목적이다.
 * 🔴 시작 버튼보다 «작게». 이건 확인하는 줄이지 누르는 것이 아니다. */
.same-now {
  margin: 14px 0 2px;
  font-size: 13px;
  color: var(--ink-dim);
  word-break: keep-all;
}
.same-now b { color: var(--accent); font-weight: 600; }
