// ── Lightbox (portal — outside .feed) ── .feed-lightbox { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.92); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 24px; &__close { position: absolute; top: 16px; right: 16px; width: 44px; height: 44px; border-radius: 50%; border: none; background: rgba(255, 255, 255, 0.1); color: #fff; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; z-index: 10; &:hover { background: rgba(255, 255, 255, 0.2); } } &__nav { position: absolute; top: 50%; transform: translateY(-50%); width: 48px; height: 48px; border-radius: 50%; border: none; background: rgba(255, 255, 255, 0.1); color: #fff; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; z-index: 10; &:hover { background: rgba(255, 255, 255, 0.25); } &--prev { left: 24px; } &--next { right: 24px; } } &__stage { max-width: 100%; max-height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; position: relative; } &__image { max-width: min(90vw, 1200px); max-height: 85vh; object-fit: contain; display: block; border-radius: 4px; } &__counter { position: absolute; bottom: -32px; left: 50%; transform: translateX(-50%); color: rgba(255, 255, 255, 0.8); font-size: 0.875rem; letter-spacing: 1px; } @media (max-width: 640px) { &__nav--prev { left: 8px; } &__nav--next { right: 8px; } &__close { top: 8px; right: 8px; } } } .feed { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; height: 100%; max-width: 1200px; margin: 0 auto; padding: 20px 16px; @media (min-width: 1024px) { // 메인과 사이드바 사이 간격을 gap 대신 좌우 padding 으로 처리 → // 가운데 세로 구분선을 main 의 border-right 로 두면 main 의 풀하이트만큼 자연스럽게 길어짐. grid-template-columns: minmax(0, 720px) 320px; gap: 0; align-items: stretch; } &__main { min-width: 0; display: flex; flex-direction: column; gap: 16px; @media (min-width: 1024px) { padding-right: 24px; border-right: 1px solid var(--border-default, #e5e7eb); } } &__header { display: flex; align-items: center; justify-content: space-between; gap: 12px; position: sticky; top: 0; background: var(--bg-page, #fff); padding: 8px 0; z-index: 10; border-bottom: 1px solid var(--border-default, #e5e7eb); &--tag, &--user { flex-direction: column; align-items: flex-start; padding: 16px 0; } } &__tabs { display: flex; align-items: center; gap: 0; flex: 1; } &__tab { padding: 12px 16px; font-size: 0.9375rem; font-weight: 500; color: var(--text-muted); text-decoration: none; position: relative; transition: color 0.15s ease; &--active { color: var(--fg-default, #0f0f0f); font-weight: 600; &::after { content: ''; position: absolute; bottom: -8px; left: 16px; right: 16px; height: 2px; background: var(--fg-default, #0f0f0f); border-radius: 2px 2px 0 0; } } &:hover { color: var(--fg-default, #0f0f0f); } } &__write-fab { display: inline-flex; align-items: center; justify-content: center; padding: 10px 22px; border-radius: 999px; background: #3b82f6; color: #fff; font-size: 0.9375rem; font-weight: 600; line-height: 1; white-space: nowrap; text-decoration: none; border: none; cursor: pointer; box-shadow: 0 2px 6px rgba(59, 130, 246, 0.25); &:hover { background: #2563eb; } } &__composer-dialog { max-width: 600px !important; width: calc(100vw - 32px); padding: 20px !important; .feed__composer { border: none; padding: 0; background: transparent; } } &__tag-title { font-size: 1.5rem; font-weight: 700; display: flex; align-items: baseline; gap: 4px; } &__tag-hash { color: var(--text-muted); } &__tag-meta, &__user-meta { font-size: 0.875rem; color: var(--text-muted); margin-top: 4px; } &__user-name { font-size: 1.5rem; font-weight: 700; } &__user-actions { margin-top: 8px; } &__write-title { font-size: 1.25rem; font-weight: 700; } // ── Card ── &__list { display: flex; flex-direction: column; } &__list-item { transition: outline 0.15s ease; &--focused { outline: 2px solid #3b82f6; outline-offset: 2px; border-radius: 12px; } } &__card { padding: 16px 4px; border-top: 1px solid var(--border-default, #e5e7eb); background: transparent; display: flex; flex-direction: column; gap: 12px; } // 마지막 카드에만 하단 경계선 부여 → 인접 카드 사이는 공유된 1px 선 하나만 &__list > &__list-item:last-child &__card { border-bottom: 1px solid var(--border-default, #e5e7eb); } &__card-header { display: flex; align-items: flex-start; gap: 12px; } &__card-avatar { width: 40px; height: 40px; border-radius: 50%; overflow: hidden; flex-shrink: 0; background: var(--bg-subtle, #f3f4f6); display: block; img { width: 100%; height: 100%; object-fit: cover; } } &__card-avatar-fallback { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 1rem; color: var(--text-muted); } &__card-meta { flex: 1; min-width: 0; } &__card-author-row { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; font-size: 0.875rem; } &__card-author { font-weight: 600; color: var(--fg-default); text-decoration: none; &:hover { text-decoration: underline; } } &__card-badge { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 50%; background: linear-gradient(135deg, #fbbf24, #f59e0b); color: #fff; font-size: 0.625rem; } &__card-time { color: var(--text-muted); font-size: 0.8125rem; } &__card-subject { display: block; margin-top: 2px; font-weight: 600; color: var(--fg-default); text-decoration: none; &:hover { color: #3b82f6; } } &__card-summary { margin: 2px 0 0; font-size: 0.8125rem; color: var(--text-muted); font-style: italic; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; } &__card-body { font-size: 0.9375rem; color: var(--text-primary, #1f2937); text-decoration: none; display: block; p { margin: 0; line-height: 1.55; display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; } } &__card-thumbnail { position: relative; display: block; border-radius: 12px; overflow: hidden; max-height: 420px; background: var(--bg-subtle, #f3f4f6); img { width: 100%; height: auto; max-height: 420px; object-fit: cover; display: block; } } &__card-image-count { position: absolute; right: 8px; bottom: 8px; padding: 2px 8px; border-radius: 999px; background: rgba(0, 0, 0, 0.6); color: #fff; font-size: 0.75rem; font-weight: 600; } &__card-tags { display: flex; flex-wrap: wrap; gap: 6px; } &__card-actions { display: flex; align-items: center; gap: 8px; padding-top: 8px; border-top: 1px solid var(--border-subtle, #f3f4f6); } &__action { display: inline-flex; align-items: center; gap: 4px; padding: 6px 10px; border-radius: 999px; border: none; background: transparent; color: var(--text-muted); font-size: 0.8125rem; cursor: pointer; text-decoration: none; transition: background 0.15s ease, color 0.15s ease; &:hover { background: var(--bg-subtle, #f3f4f6); color: var(--fg-default); } &--active { color: #ef4444; } } &__action-icon { font-size: 1rem; line-height: 1; } &__tag-chip { display: inline-flex; align-items: center; gap: 4px; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--border-default, #e5e7eb); color: var(--text-secondary, #4b5563); font-size: 0.8125rem; text-decoration: none; background: var(--bg-card, #fff); &:hover { border-color: #3b82f6; color: #3b82f6; } } &__tag-chip-count { color: var(--text-muted); font-size: 0.75rem; } // ── Empty / Sentinel ── &__empty { text-align: center; color: var(--text-muted); padding: 32px 16px; font-size: 0.9375rem; } &__sentinel { text-align: center; padding: 16px; color: var(--text-muted); font-size: 0.875rem; } // ── Sidebar ── &__sidebar { display: none; @media (min-width: 1024px) { display: block; position: sticky; top: 20px; padding-left: 24px; } } &__sidebar-section { padding: 8px 0; background: transparent; } &__sidebar-title { font-size: 1rem; font-weight: 700; margin-bottom: 12px; } &__sidebar-empty { color: var(--text-muted); font-size: 0.875rem; } &__sidebar-follows { display: flex; flex-direction: column; gap: 14px; list-style: none; padding: 0; margin: 0; } &__sidebar-follow { display: flex; align-items: flex-start; gap: 10px; } &__sidebar-follow-avatar { width: 40px; height: 40px; flex-shrink: 0; background: var(--bg-subtle, #f3f4f6); img { width: 100%; height: 100%; object-fit: cover; } } &__sidebar-follow-avatar-fallback { background: var(--bg-subtle, #f3f4f6); img { width: 60%; height: 60%; object-fit: contain; opacity: 0.55; } .dark & img { opacity: 0.7; filter: invert(0.85); } } &__sidebar-follow-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; } &__sidebar-follow-name { font-size: 0.875rem; font-weight: 600; color: var(--fg-default); text-decoration: none; display: inline-flex; align-items: center; gap: 4px; &:hover { text-decoration: underline; } } &__sidebar-follow-badge { display: inline-flex; align-items: center; justify-content: center; color: #3b82f6; } &__sidebar-follow-followers { font-size: 0.75rem; color: var(--text-muted); line-height: 1.4; margin: 0; } &__sidebar-follow-btn { font-size: 0.75rem !important; padding: 4px 12px !important; flex-shrink: 0; } // ── Page header (detail view) ── &__page-header { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border: 1px solid var(--border-default, #e5e7eb); border-radius: 12px; background: var(--bg-card, #fff); position: sticky; top: 0; z-index: 9; } &__page-back { width: 32px; height: 32px; border-radius: 50%; border: none; background: transparent; color: var(--fg-default); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: background 0.15s ease; &:hover { background: var(--bg-subtle, #f3f4f6); } } &__page-title { font-size: 1.125rem; font-weight: 700; color: var(--fg-default); margin: 0; } // ── Post detail view ── &__post { padding: 16px 4px; border-top: 1px solid var(--border-default, #e5e7eb); border-bottom: 1px solid var(--border-default, #e5e7eb); background: transparent; display: flex; flex-direction: column; gap: 16px; } &__post-header { display: flex; align-items: flex-start; gap: 12px; } &__post-avatar { width: 48px; height: 48px; border-radius: 50%; overflow: hidden; flex-shrink: 0; background: var(--bg-subtle, #f3f4f6); display: block; img { width: 100%; height: 100%; object-fit: cover; } } &__post-avatar-fallback { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--text-muted); } &__post-meta { flex: 1; min-width: 0; } &__post-author-row { display: flex; align-items: center; gap: 4px; } &__post-author { font-weight: 700; color: var(--fg-default); text-decoration: none; font-size: 1rem; &:hover { text-decoration: underline; } } &__post-badge { display: inline-flex; align-items: center; justify-content: center; color: #3b82f6; } &__post-meta-row { font-size: 0.8125rem; color: var(--text-muted); display: flex; align-items: center; gap: 4px; margin-top: 2px; } &__post-more { width: 32px; height: 32px; border-radius: 50%; border: none; background: transparent; color: var(--text-muted); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; &:hover { background: var(--bg-subtle, #f3f4f6); color: var(--fg-default); } } &__post-body { font-size: 1rem; } &__post-content { margin: 0; line-height: 1.6; white-space: pre-wrap; word-break: break-word; color: var(--text-primary, #1f2937); } &__post-gallery { display: grid; gap: 4px; border-radius: 12px; overflow: hidden; &--count-1 { grid-template-columns: 1fr; .feed__post-gallery-item { aspect-ratio: 16 / 10; } } &--count-2 { grid-template-columns: 1fr 1fr; .feed__post-gallery-item { aspect-ratio: 1 / 1; } } &--count-3, &--count-4 { grid-template-columns: 1fr 1fr; .feed__post-gallery-item { aspect-ratio: 1 / 1; } } } &__post-gallery-item { position: relative; border: none; padding: 0; background: var(--bg-subtle, #f3f4f6); cursor: zoom-in; overflow: hidden; min-height: 0; img { width: 100%; height: 100%; object-fit: cover; display: block; } &:hover img { opacity: 0.92; } } &__post-gallery-more { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.5); color: #fff; font-size: 1.25rem; font-weight: 700; } &__post-tags { display: flex; flex-wrap: wrap; gap: 6px; } &__post-actions { display: flex; align-items: center; gap: 8px; padding-top: 12px; border-top: 1px solid var(--border-subtle, #f3f4f6); } &__post-action { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 999px; border: none; background: transparent; color: var(--text-muted); font-size: 0.875rem; cursor: pointer; text-decoration: none; transition: background 0.15s ease, color 0.15s ease; &:hover:not(&--stat) { background: var(--bg-subtle, #f3f4f6); color: var(--fg-default); } &--active { color: #ef4444; } &--stat { cursor: default; } } // ── Reply composer ── &__reply-composer { display: flex; gap: 12px; padding: 16px 4px; border-bottom: 1px solid var(--border-default, #e5e7eb); background: transparent; &--login { justify-content: center; color: var(--text-muted); } } &__reply-composer-avatar { width: 36px; height: 36px; border-radius: 50%; overflow: hidden; flex-shrink: 0; background: var(--bg-subtle, #f3f4f6); img { width: 100%; height: 100%; object-fit: cover; } } &__reply-composer-avatar-fallback { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--text-muted); font-size: 0.875rem; } &__reply-composer-body { flex: 1; display: flex; flex-direction: column; gap: 8px; min-width: 0; } &__reply-composer-target { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; background: var(--bg-subtle, #f3f4f6); color: var(--text-secondary, #4b5563); font-size: 0.8125rem; align-self: flex-start; button { border: none; background: transparent; color: var(--text-muted); cursor: pointer; display: inline-flex; align-items: center; padding: 0; &:hover { color: var(--fg-default); } } } &__reply-composer-input { resize: vertical; min-height: 60px; padding: 10px 12px; border: 1px solid var(--border-strong); border-radius: 3px; background: var(--bg-input); font-size: 0.9375rem; color: var(--fg-default); outline: none; font-family: inherit; transition: border-color 0.3s ease, box-shadow 0.3s ease; &:hover, &:focus { border-color: var(--text-link); } &:focus { box-shadow: inset 1px 2px 2px rgba(0, 0, 0, 0.05), 0 0 4px rgba(44, 112, 170, 0.8); } } &__reply-composer-error { color: #dc2626; font-size: 0.8125rem; margin: 0; } &__reply-composer-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; } &__reply-composer-tools { display: flex; align-items: center; #emojiPicker > button { width: 32px; height: 32px; border-radius: 50%; border: none; background: transparent; padding: 0; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; color: var(--text-muted); svg { width: 18px; height: 18px; } &:hover { background: var(--bg-subtle, #f3f4f6); color: var(--text-link); } } } &__reply-composer-submit { display: flex; align-items: center; gap: 8px; } &__reply-composer-count { font-size: 0.8125rem; color: var(--text-muted); &--over { color: #dc2626; font-weight: 600; } } &__reply-composer-btn { padding: 6px 16px; border-radius: 4px; background: #3b82f6; color: #fff; font-size: 0.8125rem; font-weight: 600; border: 1px solid #3b82f6; cursor: pointer; &:hover:not(:disabled) { background: #2563eb; border-color: #2563eb; } &:disabled { background: var(--bg-subtle, #e5e7eb); color: var(--text-muted); border-color: var(--bg-subtle, #e5e7eb); cursor: not-allowed; } } // ── Reply list ── &__reply-list { display: flex; flex-direction: column; gap: 4px; } &__reply-count { font-size: 0.875rem; font-weight: 600; color: var(--fg-default); padding: 8px 4px; border-bottom: 1px solid var(--border-subtle, #f3f4f6); } &__reply-empty { text-align: center; color: var(--text-muted); padding: 32px 16px; font-size: 0.875rem; } &__reply-more-btn { align-self: center; margin-top: 8px; padding: 8px 20px; border-radius: 999px; background: transparent; border: 1px solid var(--border-default, #e5e7eb); color: var(--text-secondary); font-size: 0.8125rem; cursor: pointer; &:hover:not(:disabled) { background: var(--bg-subtle); } &:disabled { opacity: 0.6; cursor: not-allowed; } } &__reply { display: flex; gap: 10px; padding: 12px 4px; border-bottom: 1px solid var(--border-subtle, #f3f4f6); &:last-child { border-bottom: none; } &--nested { margin-left: 32px; } } &__reply-avatar { width: 32px; height: 32px; border-radius: 50%; overflow: hidden; flex-shrink: 0; background: var(--bg-subtle, #f3f4f6); display: block; img { width: 100%; height: 100%; object-fit: cover; } } &__reply-avatar-fallback { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--text-muted); font-size: 0.8125rem; } &__reply-body { flex: 1; min-width: 0; } &__reply-header { display: flex; align-items: center; gap: 4px; } &__reply-author { font-weight: 600; font-size: 0.875rem; color: var(--fg-default); text-decoration: none; &:hover { text-decoration: underline; } } &__reply-time { font-size: 0.75rem; color: var(--text-muted); } &__reply-more { margin-left: auto; width: 24px; height: 24px; border-radius: 50%; border: none; background: transparent; color: var(--text-muted); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; &:hover { background: var(--bg-subtle); color: var(--fg-default); } } &__reply-parent-ref { display: inline-flex; align-items: center; gap: 4px; font-size: 0.75rem; color: var(--text-muted); margin-top: 2px; } &__reply-content { margin: 4px 0; font-size: 0.9375rem; line-height: 1.5; color: var(--text-primary); white-space: pre-wrap; word-break: break-word; &--deleted { color: var(--text-muted); font-style: italic; } } &__reply-actions { display: flex; align-items: center; gap: 4px; margin-top: 4px; } &__reply-action { display: inline-flex; align-items: center; gap: 3px; padding: 4px 8px; border-radius: 999px; border: none; background: transparent; color: var(--text-muted); font-size: 0.75rem; cursor: pointer; &:hover { background: var(--bg-subtle); color: var(--fg-default); } &--active { color: #ef4444; } } // ── Toast (새 글 N개) ── &__toast { position: fixed; top: 72px; left: 50%; transform: translateX(-50%); display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; border-radius: 999px; background: #3b82f6; color: #fff; font-size: 0.875rem; font-weight: 600; border: none; cursor: pointer; box-shadow: 0 4px 12px rgba(59, 130, 246, 0.35); z-index: 50; &:hover { background: #2563eb; } } &__toast-dot { width: 8px; height: 8px; border-radius: 50%; background: #fff; animation: feed-pulse 1.4s ease-in-out infinite; } // ── Composer ── &__composer { display: flex; gap: 12px; padding: 16px; border: 1px solid var(--border-default, #e5e7eb); border-radius: 12px; background: var(--bg-card, #fff); &--login { justify-content: center; color: var(--text-muted); } } &__composer-avatar { width: 40px; height: 40px; border-radius: 50%; overflow: hidden; flex-shrink: 0; background: var(--bg-subtle, #f3f4f6); img { width: 100%; height: 100%; object-fit: cover; } } &__composer-avatar-fallback { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--text-muted); } &__composer-body { flex: 1; display: flex; flex-direction: column; gap: 10px; min-width: 0; } &__composer-input { resize: vertical; min-height: 80px; padding: 10px 12px; border: 1px solid var(--border-strong); border-radius: 3px; background: var(--bg-input); font-size: 1rem; color: var(--fg-default); outline: none; font-family: inherit; transition: border-color 0.3s ease, box-shadow 0.3s ease; &:hover, &:focus { border-color: var(--text-link); } &:focus { box-shadow: inset 1px 2px 2px rgba(0, 0, 0, 0.05), 0 0 4px rgba(44, 112, 170, 0.8); } } &__composer-previews { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 8px; } &__composer-preview { position: relative; aspect-ratio: 1 / 1; border-radius: 8px; overflow: hidden; background: var(--bg-subtle, #f3f4f6); img { width: 100%; height: 100%; object-fit: cover; } } &__composer-preview-remove { position: absolute; top: 6px; right: 6px; width: 22px; height: 22px; border-radius: 50%; border: none; background: rgba(0, 0, 0, 0.55); color: #fff; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; padding: 0; line-height: 1; transition: background 0.15s ease; &:hover { background: rgba(0, 0, 0, 0.8); } } &__composer-error { color: #dc2626; font-size: 0.8125rem; } &__composer-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; border-top: 1px solid var(--border-subtle, #f3f4f6); padding-top: 10px; } &__composer-tools { display: flex; align-items: center; gap: 4px; #emojiPicker { display: inline-flex; align-items: center; > button { width: 32px; height: 32px; border-radius: 50%; border: none; background: transparent; padding: 0; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; color: var(--text-muted); transition: background 0.15s ease, color 0.15s ease; svg { width: 18px; height: 18px; } &:hover, &:focus, &:active { background: var(--bg-subtle, #f3f4f6); color: var(--text-link); } } } } &__composer-tool { width: 32px; height: 32px; border-radius: 50%; border: none; background: transparent; padding: 0; display: inline-flex; align-items: center; justify-content: center; color: var(--text-muted); cursor: pointer; transition: background 0.15s ease, color 0.15s ease; &:hover:not(:disabled) { background: var(--bg-subtle, #f3f4f6); color: var(--fg-default); } &:disabled { opacity: 0.4; cursor: not-allowed; } } &__composer-submit { display: flex; align-items: center; gap: 8px; } &__composer-count { font-size: 0.8125rem; color: var(--text-muted); &--over { color: #dc2626; font-weight: 600; } } &__composer-submit-btn { padding: 8px 20px; border-radius: 4px; background: #3b82f6; color: #fff; font-size: 0.875rem; font-weight: 600; border: 1px solid #3b82f6; cursor: pointer; &:hover:not(:disabled) { background: #2563eb; border-color: #2563eb; } &:disabled { background: var(--bg-subtle, #e5e7eb); color: var(--text-muted); border-color: var(--bg-subtle, #e5e7eb); cursor: not-allowed; } } } @keyframes feed-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }