home.scss 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. // 메인 페이지 — 배너 + 라이브 채널 리스팅
  2. // 2K(2560px) 해상도까지 max-width 지원
  3. .home {
  4. width: 100%;
  5. padding: 16px;
  6. @media (min-width: 768px) {
  7. padding: 20px 24px;
  8. }
  9. @media (min-width: 1536px) {
  10. padding: 24px 32px;
  11. }
  12. @media (min-width: 2560px) {
  13. padding: 32px 48px;
  14. }
  15. &__inner {
  16. width: 100%;
  17. max-width: 1600px;
  18. margin: 0 auto;
  19. display: flex;
  20. flex-direction: column;
  21. gap: 24px;
  22. @media (min-width: 1024px) {
  23. gap: 32px;
  24. }
  25. }
  26. // ── 배너 섹션 ────────────────────────────
  27. &__banner {
  28. position: relative;
  29. width: 100%;
  30. overflow: hidden;
  31. border-radius: 12px;
  32. background: var(--bg-subtle);
  33. aspect-ratio: 1200 / 210;
  34. @media (max-width: 768px) {
  35. aspect-ratio: 3 / 2.34;
  36. border-radius: 8px;
  37. }
  38. }
  39. &__banner-slide {
  40. display: block;
  41. width: 100%;
  42. height: 100%;
  43. position: relative;
  44. overflow: hidden;
  45. }
  46. &__banner-picture {
  47. display: block;
  48. width: 100%;
  49. height: 100%;
  50. }
  51. &__banner-image {
  52. width: 100%;
  53. height: 100%;
  54. object-fit: cover;
  55. display: block;
  56. }
  57. // ── 섹션 공통 ────────────────────────────
  58. &__section-head {
  59. display: flex;
  60. align-items: center;
  61. justify-content: space-between;
  62. margin-bottom: 16px;
  63. @media (min-width: 1024px) {
  64. margin-bottom: 20px;
  65. }
  66. }
  67. &__section-title {
  68. font-size: 1.125rem;
  69. font-weight: 700;
  70. color: var(--text-primary);
  71. display: flex;
  72. align-items: center;
  73. gap: 8px;
  74. @media (min-width: 1024px) {
  75. font-size: 1.25rem;
  76. }
  77. }
  78. &__section-count {
  79. font-size: 0.875rem;
  80. font-weight: 500;
  81. color: var(--text-muted);
  82. }
  83. // ── Empty 상태 ──────────────────────────
  84. &__empty {
  85. display: flex;
  86. flex-direction: column;
  87. align-items: center;
  88. justify-content: center;
  89. gap: 8px;
  90. padding: 64px 16px;
  91. text-align: center;
  92. border: 1px dashed var(--border-default);
  93. border-radius: 12px;
  94. background: var(--bg-subtle);
  95. }
  96. &__empty-icon {
  97. width: 48px;
  98. height: 48px;
  99. color: var(--text-muted);
  100. opacity: 0.6;
  101. }
  102. &__empty-title {
  103. font-size: 1rem;
  104. font-weight: 600;
  105. color: var(--text-primary);
  106. margin: 0;
  107. }
  108. &__empty-desc {
  109. font-size: 0.875rem;
  110. color: var(--text-muted);
  111. margin: 0;
  112. }
  113. // ── 더 보기 ─────────────────────────────
  114. &__load-more {
  115. display: flex;
  116. justify-content: center;
  117. margin-top: 24px;
  118. }
  119. &__load-more-btn {
  120. min-width: 160px;
  121. padding: 12px 24px;
  122. border: 1px solid var(--border-default);
  123. background: var(--bg-elevated);
  124. color: var(--text-primary);
  125. font-size: 0.875rem;
  126. font-weight: 500;
  127. border-radius: 8px;
  128. cursor: pointer;
  129. transition: background 0.15s, border-color 0.15s;
  130. &:hover:not(:disabled) {
  131. background: var(--bg-subtle);
  132. border-color: var(--border-strong);
  133. }
  134. &:disabled {
  135. opacity: 0.6;
  136. cursor: not-allowed;
  137. }
  138. }
  139. &__error {
  140. margin-top: 12px;
  141. padding: 12px 16px;
  142. text-align: center;
  143. font-size: 0.875rem;
  144. color: var(--color-danger);
  145. background: var(--color-danger-bg);
  146. border-radius: 8px;
  147. }
  148. }
  149. // ═══════════════════════════════════════════
  150. // 라이브 그리드
  151. // 모바일 1 · 소형 2 · 중형 3 · 대형 4 · XL 5 · 2K 6열
  152. // ═══════════════════════════════════════════
  153. .live-grid {
  154. display: grid;
  155. grid-template-columns: repeat(1, minmax(0, 1fr));
  156. gap: 16px;
  157. @media (min-width: 640px) {
  158. grid-template-columns: repeat(2, minmax(0, 1fr));
  159. }
  160. @media (min-width: 896px) {
  161. grid-template-columns: repeat(3, minmax(0, 1fr));
  162. }
  163. @media (min-width: 1280px) {
  164. grid-template-columns: repeat(4, minmax(0, 1fr));
  165. gap: 20px;
  166. }
  167. @media (min-width: 1536px) {
  168. grid-template-columns: repeat(5, minmax(0, 1fr));
  169. }
  170. @media (min-width: 1920px) {
  171. grid-template-columns: repeat(6, minmax(0, 1fr));
  172. gap: 24px;
  173. }
  174. &__item {
  175. min-width: 0;
  176. }
  177. }
  178. // ═══════════════════════════════════════════
  179. // 라이브 카드
  180. // ═══════════════════════════════════════════
  181. .live-card {
  182. display: flex;
  183. flex-direction: column;
  184. gap: 10px;
  185. text-decoration: none;
  186. color: inherit;
  187. &:hover .live-card__title {
  188. color: var(--text-link);
  189. }
  190. &:focus-visible {
  191. outline: 2px solid var(--text-link);
  192. outline-offset: 4px;
  193. border-radius: 8px;
  194. }
  195. &__thumb-wrap {
  196. position: relative;
  197. aspect-ratio: 16 / 9;
  198. width: 100%;
  199. background: var(--bg-subtle);
  200. border-radius: 8px;
  201. overflow: hidden;
  202. transition: transform 0.2s ease;
  203. }
  204. &:hover &__thumb-wrap {
  205. transform: translateY(-2px);
  206. }
  207. &__thumb {
  208. object-fit: cover;
  209. }
  210. &__badge {
  211. position: absolute;
  212. top: 8px;
  213. left: 8px;
  214. display: inline-flex;
  215. align-items: center;
  216. gap: 4px;
  217. padding: 3px 6px;
  218. font-size: 0.6875rem;
  219. font-weight: 700;
  220. letter-spacing: 0.03em;
  221. color: #fff;
  222. background: var(--color-danger);
  223. border-radius: 4px;
  224. text-transform: uppercase;
  225. }
  226. &__viewers {
  227. position: absolute;
  228. bottom: 8px;
  229. right: 8px;
  230. display: inline-flex;
  231. align-items: center;
  232. gap: 4px;
  233. padding: 3px 6px;
  234. font-size: 0.75rem;
  235. font-weight: 500;
  236. color: #fff;
  237. background: rgba(0, 0, 0, 0.7);
  238. border-radius: 4px;
  239. }
  240. &__meta {
  241. display: flex;
  242. align-items: flex-start;
  243. gap: 10px;
  244. min-width: 0;
  245. }
  246. &__avatar {
  247. flex-shrink: 0;
  248. width: 36px;
  249. height: 36px;
  250. border-radius: 50%;
  251. overflow: hidden;
  252. background: var(--bg-subtle);
  253. display: flex;
  254. align-items: center;
  255. justify-content: center;
  256. }
  257. &__avatar-img {
  258. width: 100%;
  259. height: 100%;
  260. object-fit: cover;
  261. }
  262. &__avatar-fallback {
  263. font-size: 0.875rem;
  264. font-weight: 700;
  265. color: var(--text-muted);
  266. }
  267. &__text {
  268. flex: 1;
  269. min-width: 0;
  270. overflow: hidden;
  271. }
  272. &__title {
  273. display: -webkit-box;
  274. -webkit-line-clamp: 2;
  275. -webkit-box-orient: vertical;
  276. font-size: 0.9375rem;
  277. font-weight: 600;
  278. line-height: 1.35;
  279. color: var(--text-primary);
  280. overflow: hidden;
  281. word-break: break-word;
  282. margin: 0 0 4px 0;
  283. transition: color 0.15s;
  284. }
  285. &__channel-name {
  286. font-size: 0.8125rem;
  287. color: var(--text-secondary);
  288. white-space: nowrap;
  289. overflow: hidden;
  290. text-overflow: ellipsis;
  291. }
  292. &__handle {
  293. font-size: 0.75rem;
  294. color: var(--text-muted);
  295. white-space: nowrap;
  296. overflow: hidden;
  297. text-overflow: ellipsis;
  298. }
  299. }