/* ─────────────────────────────────────────────────────────────
   happyshipb blog — 공개 화면 스타일

   색·모양은 전부 아래 :root 변수로만 다룬다. 하드코딩한 색을 새로 넣지 않는다.
   토큰 이름과 값은 포트폴리오(main/css/tokens.css)와 맞춰 두었다 —
   두 사이트를 나란히 놓았을 때 같은 이름이 같은 뜻이어야 하기 때문이다.

   다크 모드는 두지 않는다 (2026-08-18 결정).
   포트폴리오에 다크 모드가 없어서, 블로그에만 남기면 인상이 갈린다.
   ───────────────────────────────────────────────────────────── */

:root {
  color-scheme: light;

  /* ── 포트폴리오와 공유하는 토큰 ── */
  --paper:     #f2f0ea;   /* 페이지 바탕 */
  --tile:      #fffdf9;   /* 카드 바탕 */
  --ink:       #191713;   /* 본문 글자 */
  --muted:     #6d665a;   /* 부연 설명 */
  --faint:     #726b62;   /* 라벨·푸터. 타일 대비 5.17:1 — 더 밝히면 기준 아래로 */
  --line:      #e4dfd4;   /* 경계선 */
  --line-hi:   #d5cec0;   /* 호버했을 때의 경계선 */
  --accent:    #c2410c;   /* 강조 */
  --accent-bg: #fbeee6;   /* 강조 배경 */
  --dark:      #191713;   /* 어두운 면 */

  --gap:    16px;
  --radius: 22px;
  --ease:   cubic-bezier(.22, 1, .36, 1);
  --font:   -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo",
            "Segoe UI", Roboto, "Noto Sans KR", sans-serif;

  /* ── 블로그에만 있는 토큰 ── */
  --wrap:      50rem;   /* 읽는 사이트라 포트폴리오(1180px)보다 좁게 잡는다 */
  --measure:   68ch;    /* 본문 한 줄 길이 — 60~75자가 읽기 좋다 (P2 에서 쓴다) */
  --code-bg:   #f4f1ea; /* 코드블록 바탕 */
  --font-read: ui-serif, Georgia, "Iowan Old Style", "Times New Roman", serif;
  --font-code: ui-monospace, SFMono-Regular, Menlo, Consolas,
               "Liberation Mono", monospace;
  --danger:    #b91c1c; /* 위험 — 삭제 단추의 호버, 실패 토스트 (admin.css 가 쓴다) */
}

/* ── 바탕 ─────────────────────────────────────────────────── */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

h1, h2 { margin: 0; font-weight: 800; letter-spacing: -.035em; line-height: 1.15; }
p  { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
img, video { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font-family: inherit; }

[hidden] { display: none !important; }

/* 포트폴리오와 같은 포커스 링. 지금까지 블로그에는 아예 없던 것이다. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.skip-link {
  position: absolute; left: 50%; top: -100px; transform: translateX(-50%);
  z-index: 200; padding: 12px 20px; background: var(--ink); color: #fff;
  border-radius: 0 0 10px 10px; transition: top .2s;
}
.skip-link:focus { top: 0; }

/* ── 페이지 틀 ─────────────────────────────────────────────── */

/* 세로 flex 라서 내용이 짧아도 푸터가 화면 아래에 붙는다.
   404 처럼 내용이 한 줄뿐인 화면에서 푸터가 중간에 떠 있지 않게. */
.page {
  max-width: var(--wrap);
  min-height: 100dvh;
  margin: 0 auto;
  padding: clamp(20px, 4vw, 46px) clamp(16px, 3vw, 28px) 48px;
  display: flex;
  flex-direction: column;
}

main { flex: 1; }

/* ── 타일 ─────────────────────────────────────────────────── */

.tile {
  position: relative;
  display: block;
  padding: 26px 28px;
  background: var(--tile);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: transform .3s var(--ease), box-shadow .3s, border-color .3s;
}

/* 링크 역할을 하는 타일만 살짝 떠오른다 — 포트폴리오와 같은 움직임 */
a.tile:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 34px -18px rgba(25, 23, 19, .40);
  border-color: var(--line-hi);
}

/* 타일 맨 위의 작은 라벨 줄. 목록 카드 · 머리말 · 이웃 글이 전부 이것을 쓴다.
   조각을 여럿 담을 수 있게 flex 로 둔다 (카테고리 · 날짜 · 고친 날짜).

   text-transform: uppercase 는 뺐다 (2026-08-20). 카테고리 이름이 DB 에
   Dev 로 들어 있는데 화면에만 DEV 로 보여서, 관리자 화면에서 고친 이름과
   공개 화면이 어긋나 보였다. 여기 들어오는 글자는 Dev ·
   Updated · Error 404 · 관리자 로 전부 이미 제 대소문자를 갖고 있다. */
.tile__label {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 7px;
  margin-bottom: 14px;
  /* 대문자를 그만두면 같은 크기라도 작아 보인다 (소문자는 x-height 만큼만 찬다).
     11.5 → 12px 로 올려 눈에 보이는 무게를 맞춘다. */
  font-size: 12px; font-weight: 700;
  /* 자간도 같이 줄인다. 넓은 자간은 대문자를 위한 것이고,
     소문자에 그대로 쓰면 글자가 흩어져 읽힌다. */
  letter-spacing: .05em;
  color: var(--faint);
}

/* 자간은 마지막 글자 「뒤에도」 붙는다. 그대로 두면 Dev 와 · 사이가
   · 와 날짜 사이보다 넓어져 가운뎃점이 한쪽으로 쏠려 보인다.
   그만큼 도로 당겨서 · 를 가운데에 세운다. .sep 자신은 제외한다. */
.tile__label > :not(.sep) { margin-right: -.05em; }

/* 날짜는 자릿수 폭을 고정해 카드마다 날짜가 같은 자리에서 끝나게 한다.
   라벨 자간이 .05em 로 내려온 뒤로는 숫자도 그대로 둬도 흩어지지 않는다. */
.tile__label time { white-space: nowrap; font-variant-numeric: tabular-nums; }

.tile__cat { color: var(--accent); }
a.tile__cat:hover { text-decoration: underline; }

/* ── 머리 ─────────────────────────────────────────────────── */

.topbar {
  display: flex;
  align-items: center;
  gap: var(--gap);
  margin-bottom: var(--gap);
}

.brand {
  font-size: 15.5px; font-weight: 800; letter-spacing: -.025em;
  white-space: nowrap;
  transition: color .18s;
}
.brand:hover { color: var(--accent); }

/* 포트폴리오의 언어 전환 알약과 같은 모양 */
.nav {
  display: flex;
  gap: 3px;
  margin-left: auto;
  padding: 5px;
  background: var(--tile);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: 0 8px 22px -16px rgba(25, 23, 19, .45);
  /* 카테고리가 늘어나면 두 줄로 접히는 대신 옆으로 밀린다 */
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}
.nav::-webkit-scrollbar { display: none; }

.nav__btn {
  padding: 7px 15px;
  border-radius: 999px;
  color: var(--muted);
  font-size: 13px; font-weight: 700; letter-spacing: -.01em;
  line-height: 1;
  white-space: nowrap;
  transition: background .18s, color .18s;
}
.nav__btn:hover { background: var(--paper); color: var(--ink); }
.nav__btn[aria-current="page"] { background: var(--ink); color: #fff; }

/* 켜진 탭 옆의 글 개수. 탭 글씨보다 한 단계 작고 흐리게 — 이름이 주인공이다. */
.nav__count {
  margin-left: 2px;
  font-size: 11px; font-weight: 600;
  font-variant-numeric: tabular-nums;
  opacity: .55;
}

/* ── 화면 머리말 (P2 글 본문 · 404 공용) ────────────────────── */
/* 홈 · 카테고리는 2026-08-20 에 이 카드를 뺐다 (views/home.ejs) */

.hero {
  margin-bottom: var(--gap);
  padding: 36px 32px;
  /* 포트폴리오 이름 타일과 같은 사선 번짐 */
  background:
    radial-gradient(120% 130% at 100% 0%, var(--accent-bg) 0%, transparent 58%),
    var(--tile);
}

.hero h1 {
  font-size: clamp(26px, 4vw, 34px);
  letter-spacing: -.045em;
  line-height: 1.05;
  overflow-wrap: anywhere;
}

.hero__sub {
  margin-top: 14px;
  max-width: var(--measure);
  font-size: 15px;
  color: var(--muted);
}

.hero__sub a { color: var(--accent); font-weight: 600; }
.hero__sub a:hover { text-decoration: underline; }

/* ── 글 목록 ───────────────────────────────────────────────── */

.post-list {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}

/* 섬네일이 왼쪽, 글이 오른쪽.
   2026-08-24 요약을 없앤 뒤 카드를 눌러 접었다 — 글줄이 라벨+제목 두 줄뿐이라
   flex-start 로 두면 섬네일 아래가 빈 채로 남는다. 가운데 정렬이 균형이 맞는다. */
.card {
  padding: 16px 20px;
  display: flex;
  align-items: center;
  gap: 16px;
}

/* 정사각형 섬네일. 원본이 세로로 길든 가로로 길든 object-fit: cover 가
   가운데를 잘라 정사각으로 채운다 — 찌그러뜨리지 않는다.

   모서리는 14px. 타일의 --radius(22px)보다 작아야 한다.
   안쪽이 바깥보다 더 둥글면 두 곡선이 어긋나 보인다.

   background 는 그림이 도착하기 전과 주소가 깨졌을 때 남는 자리다.
   비워 두면 그 동안 카드에 흰 구멍이 뚫린다. */
.card__thumb {
  flex: none;
  width: 84px;                 /* 112 → 84 (2026-08-24 카드 접기). home.ejs 의 width·height 속성과 짝 */
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 12px;         /* 크기를 줄였으니 모서리도 한 급 — 타일 --radius 보다 작게 유지 */
  background: var(--code-bg);
  border: 1px solid var(--line);
  transition: border-color .3s;
}

/* 카드 안에서는 라벨 아래 간격을 한 급 줄인다 — .tile__label 의 14px 는
   머리말(hero)·댓글처럼 큰 덩어리용이고, 접은 카드에서는 헐겁다. */
.card .tile__label { margin-bottom: 6px; }

a.card:hover .card__thumb { border-color: var(--line-hi); }

/* flex 칸은 기본이 min-width: auto 라 안의 긴 낱말만큼 벌어진다.
   0 으로 내려야 긴 제목이 카드를 밀어내지 않고 제자리에서 줄바꿈한다. */
.card__body { min-width: 0; }

.card__title {
  font-size: clamp(17px, 2vw, 19px);   /* 19~23 → 17~19 (2026-08-24 카드 접기) */
  letter-spacing: -.03em;
  line-height: 1.25;
  /* 아주 긴 제목이 와도 타일이 무너지지 않게 */
  overflow-wrap: anywhere;
  transition: color .18s;
}

a.card:hover .card__title { color: var(--accent); }

/* 제목 옆 댓글 개수 — 1개부터만 찍힌다.
   제목의 굵기(800)를 그대로 물려받으면 개수가 제목처럼 보여서 한 겹 눌러 둔다. */
.card__comments {
  /* 글자 크기는 제목과 똑같이 둔다 (2026-08-24).
     .62em → .75em 으로 키워 봐도 제목보다 작으면 밑줄만 맞아서 상하가 계속
     어긋나 보였다. 크기가 같으면 밑줄이 곧 가운데라 vertical-align 으로
     손볼 자리가 없어진다. 제목과의 구별은 굵기와 색으로만 한다. */
  font-size: 1em;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--faint);
  white-space: nowrap;         /* (12 처럼 괄호와 숫자가 줄 끝에서 갈라지지 않게 */
}
a.card:hover .card__comments { color: var(--accent); }

/* 글이 하나도 없을 때의 한 줄 (P1 · P3). 머리말 카드를 없앤 뒤로
   이것이 없으면 빈 카테고리 화면이 통째로 빈다 (views/home.ejs). */
.empty {
  padding: 8px 4px;
  font-size: 15px;
  color: var(--muted);
}

/* ── P2 · 글 본문 ──────────────────────────────────────────── */

/* A2 미리보기 띠. /admin/preview/<id> 가 이 화면(post.ejs)을
   빌려 쓸 때만 뜬다 — 발행된 화면과 헷갈리지 않게 하는 표시다. */
.preview-banner {
  margin-bottom: var(--gap);
  padding: 12px 22px;
  border: 1px dashed var(--accent);
  border-radius: var(--radius);
  background: var(--accent-bg);
  color: var(--accent);
  font-size: 14px;
  font-weight: 700;
}
/* 발행된 글의 진짜 주소로 가는 링크 — A2 의 「보기 ↗」가 없어지면서
   공개 주소를 여는 유일한 문이다 */
.preview-banner a { color: inherit; text-decoration: underline; }

.article { padding: 36px 40px; }

/* 여기서만 serif 로 간다. 제목·라벨·메뉴는 그대로 sans 다.
   「읽는 곳」과 「조작하는 곳」을 눈으로 가르기 위한 것이다. */
.prose {
  max-width: var(--measure);
  font-family: var(--font-read);
  font-size: 18px;
  line-height: 1.75;
  color: var(--ink);
}

.prose > :first-child { margin-top: 0; }
.prose > :last-child  { margin-bottom: 0; }

.prose p { margin: 1.15em 0; }

/* 소제목은 sans 로 되돌린다 — 본문 덩어리와 구분되게 */
.prose h2, .prose h3 {
  font-family: var(--font);
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1.25;
}
.prose h2 { margin: 2.2em 0 .6em; font-size: 24px; }
.prose h3 { margin: 1.8em 0 .5em; font-size: 19px; }

/* 바탕에서 list-style 을 지웠으므로 본문에서만 되살린다 */
.prose ul, .prose ol {
  margin: 1.15em 0;
  padding-left: 1.4em;
  list-style: revert;
}
.prose li { margin: .4em 0; }
.prose li::marker { color: var(--faint); }

.prose a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}
.prose a:hover { text-decoration-thickness: 2px; }

.prose strong { font-weight: 700; }
.prose em { font-style: italic; }

.prose blockquote {
  margin: 1.8em 0;
  padding: 2px 0 2px 1.2em;
  border-left: 3px solid var(--accent);
  color: var(--muted);
}

.prose img {
  margin: 1.8em 0;
  border: 1px solid var(--line);
  border-radius: 12px;
}

/* 코드블록. 세 가지 모양이 다 온다.
     pre                        — 손으로 쓴 것
     pre.ql-syntax              — Quill v1
     div.ql-code-block-container — Quill v2 (A2 가 쓰는 것)
   v2 는 바깥 div 안에 한 줄씩 div 를 넣는다. 바깥이 상자를 맡고 안쪽이 줄을 맡는다. */
.prose pre,
.prose .ql-syntax,
.prose .ql-code-block-container {
  margin: 1.6em 0;
  padding: 18px 20px;
  background: var(--code-bg);
  border: 1px solid var(--line);
  border-radius: 12px;
  /* 긴 줄은 잘리지 않고 이 안에서만 옆으로 밀린다 */
  overflow-x: auto;
  font-family: var(--font-code);
  font-size: 14px;
  line-height: 1.6;
  white-space: pre;
}

.prose code {
  padding: .12em .38em;
  background: var(--code-bg);
  border-radius: 6px;
  font-family: var(--font-code);
  font-size: .875em;
}

/* 코드블록 안의 code 에는 배경을 두 번 깔지 않는다 */
.prose pre code,
.prose .ql-syntax code,
.prose .ql-code-block code { padding: 0; background: none; font-size: inherit; }

/* v2 의 한 줄. 긴 줄은 바깥 상자 안에서만 옆으로 밀린다. */
.prose .ql-code-block { white-space: pre; font-family: inherit; }
/* 빈 줄은 높이가 0 이 되어 사라진다. 눈에 안 보이는 글자를 하나 세워 둔다. */
.prose .ql-code-block:empty::after { content: "\00a0"; }

/* ── Quill v2 의 목록 ──────────────────────────────────────
   v2 는 **점 목록도 <ol> 로 준다.** 종류는 li 의 data-list 에 적혀 있다.
   그대로 두면 점 목록이 1. 2. 3. 으로 찍힌다.

   data-list 가 붙은 목록만 우리가 표를 직접 그린다 —
   손으로 쓴 <ul>·<ol> 은 위의 규칙을 그대로 쓴다.
   ──────────────────────────────────────────────────────── */

.prose ol:has(> li[data-list]) {
  padding-left: 0;
  list-style: none;
  counter-reset: qa qb qc qd;
}

.prose li[data-list] { position: relative; padding-left: 1.6em; }

.prose li[data-list]::before {
  position: absolute;
  left: 0;
  width: 1.2em;
  text-align: right;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}

.prose li[data-list="bullet"]::before { content: "•"; }
.prose li[data-list="ordered"] { counter-increment: qa; }
.prose li[data-list="ordered"]::before { content: counter(qa) "."; }

/* 들여쓰기. Quill 은 중첩 목록을 진짜 중첩이 아니라 같은 목록 안의
   ql-indent-N 클래스로 적는다. 그래서 단계마다 세는 것을 따로 둔다.

   한계: 한 목록 안에 들여쓴 번호 덩어리가 여럿이면 번호가 이어진다.
   진짜 중첩 <ol> 이 아니라서 덩어리가 어디서 끊기는지 CSS 로는 알 수 없다. */
.prose li.ql-indent-1 { margin-left: 1.8em; }
.prose li.ql-indent-2 { margin-left: 3.6em; }
.prose li.ql-indent-3 { margin-left: 5.4em; }

.prose li[data-list="bullet"].ql-indent-1::before { content: "◦"; }
.prose li[data-list="bullet"].ql-indent-2::before,
.prose li[data-list="bullet"].ql-indent-3::before { content: "▪"; }

.prose li[data-list="ordered"].ql-indent-1 { counter-increment: qb; }
.prose li[data-list="ordered"].ql-indent-1::before { content: counter(qb, lower-alpha) "."; }
.prose li[data-list="ordered"].ql-indent-2 { counter-increment: qc; }
.prose li[data-list="ordered"].ql-indent-2::before { content: counter(qc, lower-roman) "."; }
.prose li[data-list="ordered"].ql-indent-3 { counter-increment: qd; }
.prose li[data-list="ordered"].ql-indent-3::before { content: counter(qd) "."; }

/* 목록이 아닌 문단의 들여쓰기 */
.prose p.ql-indent-1 { padding-left: 3em; }
.prose p.ql-indent-2 { padding-left: 6em; }
.prose p.ql-indent-3 { padding-left: 9em; }

/* 정렬. 툴바에 단추는 없지만 다른 곳에서 붙여 넣을 때 따라올 수 있다.
   새니타이저가 허용 목록에 두고 있으므로 화면도 알아들어야 한다. */
.prose .ql-align-center  { text-align: center; }
.prose .ql-align-right   { text-align: right; }
.prose .ql-align-justify { text-align: justify; }

.prose hr {
  margin: 2.4em 0;
  border: 0;
  border-top: 1px solid var(--line);
}

/* ── P2 · 댓글 ─────────────────────────────────── */

.comments { margin-top: 40px; }

.comments__title {
  margin-bottom: 16px;
  font-size: 20px;
  letter-spacing: -.03em;
}

.comments__list {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  margin-bottom: var(--gap);
}

.comment { padding: 20px 24px; }

.comment__author { color: var(--ink); }

/* 서식 없는 텍스트라 줄바꿈은 여기서 살린다 — 태그(br)가 아니라 CSS 다 */
.comment__body {
  margin-top: 2px;
  font-size: 15.5px;
  white-space: pre-line;
  overflow-wrap: break-word;
}

.comment__actions {
  display: flex;
  /* 글자 사이는 gap(8) + 두 단추의 좌우 패딩(10+10) = 28px 로 벌어진다.
     10px 이던 것을 넓힌 이유는 아래 .comment__btn 에 있다 (2026-08-24). */
  gap: 8px;
  /* 단추가 위아래로 12px 씩 커진 만큼 되돌린다 — 댓글 모양은 그대로 둔다.
     왼쪽 -10px 은 첫 단추의 패딩만큼 줄을 당겨 글자를 제자리에 놓는 것이고,
     아래 -12px 은 늘어난 아래쪽을 거둬 댓글의 아래 여백을 지킨다.
     위쪽은 원래 12px 이었는데 커진 12px 이 그 자리를 채우므로 0 이다. */
  margin: 0 -10px -12px;
}

/* 글자만 한 작은 단추 — 댓글마다 있어서 .btn 처럼 무거우면 목록이 시끄럽다.
   글씨는 12.5px 그대로 두고 **누를 수 있는 면적만** 40px 로 넓힌다
   (2026-08-24). 예전에는 padding: 0 이라 실제로 누를 곳이 글자 높이인
   15px 뿐이었다 — 마우스로는 되지만 손가락에는 작고, 하필 Delete 가
   Edit 바로 옆이라 폰에서 잘못 누르기 쉬웠다. 넓힌 면적은 눈에 보이지
   않으므로 (배경도 테두리도 없다) 목록의 모양은 예전과 같다. */
.comment__btn {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 10px;
  border: 0;
  background: none;
  font-size: 12.5px; font-weight: 700;
  color: var(--faint);
  cursor: pointer;
  transition: color .18s;
}
.comment__btn:hover { color: var(--accent); }

.comment__btn--admin { color: var(--accent); }
.comment__btn--admin:hover { text-decoration: underline; }

/* 수정 폼 — 댓글 본문 자리에 comments.js 가 끼워 넣는다 */
.comment-edit { margin-top: 10px; }
.comment-edit .field__input { margin-bottom: 10px; }

.comment-form { padding: 24px 28px; }

.comment-form__title {
  margin: 0 0 14px;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: -.02em;
}

/* 이름·비밀번호를 한 줄에 — 좁은 화면에서는 아래에서 한 칸씩으로 되돌린다 */
.comment-form__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 14px;
}

.comment-form__hint {
  margin: -4px 0 14px;
  font-size: 12.5px;
  color: var(--faint);
}

.comment-form__textarea { resize: vertical; min-height: 96px; }

.comment-form__error {
  margin: 0 0 12px;
  padding: 11px 14px;
  background: var(--accent-bg);
  border-left: 3px solid var(--accent);
  border-radius: 0 12px 12px 0;
  font-size: 13.5px;
  color: var(--accent);
}

/* 폼 전체 폭 단추는 과하다 — 내용만큼만 */
.comment-form__submit { width: auto; padding: 11px 26px; }

/* ── 관리자 · 입력칸과 버튼 (A1 에서 굳히고 A2 가 물려받는다) ── */

.field { margin-bottom: 14px; }

.field__label {
  display: block;
  margin-bottom: 6px;
  font-size: 12px; font-weight: 700;
  letter-spacing: -.01em;
  color: var(--faint);
}

/* 타일 안에 놓이므로 바탕을 종이색으로 두어 한 겹 들어가 보이게 한다.
   포트폴리오가 타일 안 목록에 쓰는 방식과 같다. */
.field__input {
  display: block;
  width: 100%;
  padding: 11px 14px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--ink);
  /* 16px 아래로 내리지 않는다 (2026-08-24). iOS 사파리는 16px 미만인 입력칸에
     손을 대면 화면을 확 당기고, 한 번 당겨지면 스스로 돌아오지 않아 댓글을
     쓰는 내내 어긋난 채로 남는다. 원래 15px 이었다. */
  font-size: 16px;
  line-height: 1.4;
  transition: border-color .18s, background .18s;
}
.field__input:hover { border-color: var(--line-hi); }
.field__input:focus { background: var(--tile); border-color: var(--accent); }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 12px 20px;
  background: var(--dark);
  border: 1px solid var(--dark);
  border-radius: 999px;
  color: #fff;
  font-size: 14.5px; font-weight: 700; letter-spacing: -.01em;
  cursor: pointer;
  transition: transform .18s var(--ease), box-shadow .3s;
}
.btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 26px -16px rgba(25, 23, 19, .55);
}
.btn:active { transform: translateY(0); }

/* ── A1 · 로그인 ───────────────────────────────────────────── */

/* 세로 가운데로 온다. main 의 높이에 기대지 않고 뷰포트를 기준으로 잡는다 —
   퍼센트 높이는 부모 높이가 정해져 있어야 해서 어긋나기 쉽다. */
.auth {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 60vh;
  padding: 24px 0;
}

.auth__card { width: 100%; max-width: 24rem; }

.auth__title { font-size: 28px; letter-spacing: -.04em; }

.auth__desc {
  margin-top: 8px;
  font-size: 14.5px;
  color: var(--muted);
}

/* 로그인 실패 같은 실제 오류 문구가 들어올 자리 */
.auth__alert {
  margin-top: 12px;
  padding: 11px 14px;
  background: var(--accent-bg);
  border-left: 3px solid var(--accent);
  border-radius: 0 12px 12px 0;
  font-size: 13.5px;
  color: var(--accent);
}

.auth__form { margin-top: 20px; }

.auth__back {
  margin-top: 18px;
  text-align: center;
  font-size: 13px;
  color: var(--faint);
}
.auth__back a { transition: color .18s; }
.auth__back a:hover { color: var(--accent); }

/* ── 페이지 넘기기 ─────────────────────────────────────────── */

/* 번호 알약 하나만 가운데 둔다. 양옆 단추가 없어져 격자가 필요 없다. */
.pager {
  display: flex;
  justify-content: center;
  margin-top: var(--gap);
}

/* 쪽 번호 알약. 위 메뉴(.nav)와 같은 차림이다 */
.pager__pages {
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 5px;
  list-style: none;
  background: var(--tile);
  border: 1px solid var(--line);
  border-radius: 999px;
}

.pager__page {
  display: block;
  min-width: 34px;
  padding: 9px 10px;
  border-radius: 999px;
  text-align: center;
  font-size: 13px; font-weight: 700;
  line-height: 1;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  transition: background .18s, color .18s;
}
a.pager__page:hover { background: var(--paper); color: var(--ink); }
.pager__page[aria-current="page"] { background: var(--ink); color: #fff; }

.pager__gap {
  padding: 0 4px;
  font-size: 13px; font-weight: 700;
  color: var(--faint);
}

/* ── 꼬리 ─────────────────────────────────────────────────── */

.foot {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 10px;
  margin-top: 34px;
  font-size: 13px;
  color: var(--faint);
}

.foot a { transition: color .18s, opacity .18s; }
.foot a:hover { color: var(--accent); }

/* 관리자용 문. 나만 쓰는 것이라 평소에는 한 겹 더 흐리게 두고,
   가리키거나 키보드로 짚으면 제자리로 돌아온다. */
.foot__admin { opacity: .5; }
.foot__admin:hover,
.foot__admin:focus-visible { opacity: 1; }

/* 카드 라벨과 푸터에서 같이 쓰는 가운뎃점 */
.sep { opacity: .45; }

/* ── 좁은 화면 ─────────────────────────────────────────────── */

@media (max-width: 640px) {
  :root { --gap: 12px; --radius: 18px; }

  .topbar {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
  .nav { margin-left: 0; justify-content: flex-start; }

  .hero { padding: 28px 22px; }
  .tile { padding: 22px 22px; }
  .card { padding: 12px 14px; gap: 12px; }
  /* 좁은 화면에서는 섬네일을 한 급 더 줄인다 — 글이 들어갈 폭이 먼저다 */
  .card__thumb { width: 64px; border-radius: 10px; }

  .article { padding: 26px 22px; }
  .prose { font-size: 17px; }
  .prose h2 { font-size: 21px; }

  /* 이름·비밀번호를 도로 한 칸씩 — 좁은 화면에서 반반은 너무 좁다 */
  .comment-form__row { grid-template-columns: 1fr; gap: 0; }
  .comment { padding: 18px 20px; }
  .comment-form { padding: 20px 22px; }

  /* 번호가 최대 9칸이라 좁은 화면에서는 알약을 한 겹 줄인다 */
  .pager__pages { gap: 2px; padding: 4px; }
  .pager__page { min-width: 28px; padding: 9px 6px; }
}

/* ── 모션 최소화 ───────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  a.tile:hover { transform: none; }
}
