:root {
  /* 미색(warm off-white) 팔레트 */
  --paper: #f3ede1;      /* 배경 */
  --card: #f8f3e9;       /* 카드 (배경보다 아주 살짝 밝은 미색) */
  --line: #d9cfbb;       /* 얇은 경계선 */
  --line-soft: #e6ddcb;  /* 더 옅은 구분선 */
  --ink: #322e26;        /* 본문 텍스트 (따뜻한 먹색) */
  --ink-soft: #6d6553;   /* 보조 텍스트 */
  --accent: #7a5a2e;     /* 절제된 오커/브라운 포인트 */
  /* '먹어봤어요' 도장 하나만 쓰는 벽돌빛 적갈 — hsl 4°,80%,34% (accent 는 35°,45%,33%).
     카드 배경(#f8f3e9) 대비 7.4:1.
     ⚠️ **이 사이트의 오류색과 색상이 겹친다** — #a3452f(로그인 오류, 11°) ·
        #b3453b(삭제·오류, 5°). 지금은 **채도로 갈린다**(80% ↔ 55%·50%). 명도도 이쪽이 조금 어둡다(34%).
        도장은 그림 위에 찍힌 도형이고 오류색은 글자라 맥락이 달라서 섞이진 않지만,
        **붉은 것을 새로 만들 때는 이 셋이 한 화면에 같이 나오는지 먼저 볼 것.**
        (18° 에서 여기까지 다섯 번 붉힌 것은 의도된 선택이다. 도장 테가 2.2px 로 얇아
         칠해진 면적이 작기 때문에, 채도를 이만큼 올려야 화면에서 붉게 읽힌다.
         더 가려면 색상 말고 **명도를 내릴 것** — 붉은 기는 살고 알림색과는 멀어진다)
     ⚠️ 다른 곳에 쓰지 말 것. 한 가지만 가리켜야 뜻이 안 흐려진다. */
  --seal: #9c1b11;

  /* 하위 페이지(갤러리·치즈함·관리자)의 가운데 본문 칸 너비.
     메인의 가운데 갤러리 칸과 비슷한 폭. 양옆은 위젯/광고 자리(--rail-width) */
  --page-width: 51.25rem;
  --rail-width: 12.5rem;

  /* ▶ 사진 규칙: 이 사이트의 사진은 **어디서든 1:1(정사각)** 로 보여준다.
     사진 상자에 aspect-ratio: 1/1 + object-fit: cover 를 함께 쓸 것.
     (카드 대표사진 / 모달 사진 / 치즈함 기록·미리보기 / 갤러리 글 썸네일·본문 / 관리자) */

  --font: -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo",
          "Pretendard", "Noto Sans KR", "Malgun Gothic", system-ui, sans-serif;
}

* { box-sizing: border-box; }

/* ===== 전체 배율 =====
   여기 하나로 사이트 전체 크기가 정해진다. 100% = 브라우저 기본(보통 16px).
   ⚠️ 그래서 css/style.css 의 여백·간격·폭은 **px 가 아니라 rem** 으로 적는다(2026-07-29).
      px 로 적으면 이 값을 올려도 글자만 커지고 상자는 그대로라 레이아웃이 어긋난다.
      **1~2px 은 예외** — 선과 작은 모서리는 또렷해야 해서 px 로 둔다.
   ⚠️ 배율은 **두 단**이다 (2026-07-29). 데스크톱은 125%, 좁은 화면(≤820px)은 100%.
      좁은 화면은 원래 크기가 더 나아서 되돌렸다 — 화면이 좁을수록 배율이 값비싸다.
   ⚠️ 미디어쿼리는 이 값을 따라오지 않는다(화면 폭은 그대로다). 그래서 **어느 배율 구간에서
      쓰이는 값이냐**에 따라 다르게 적어야 한다.
        125% 구간에서만 쓰임(>820px) → 원래 값 × 1.25   : 1450 · 1025 · 875
        100% 구간에서만 쓰임(≤820px) → 원래 값 그대로   : 560 · 480
      배율을 다시 바꾸면 앞의 셋만 새 비율로 곱하면 된다. */
html {
  font-size: 125%;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
/* 좁은 화면은 원래 크기로. 폭이 모자란 곳에서 배율을 올리면 한 줄에 들어가는 글자가 줄어
   오히려 읽기 나빠진다. 경계(820px)는 사이드바가 접히는 지점(.layout, 1025px)보다 아래라
   그 사이 구간은 125% 로 남는다. */
@media (max-width: 820px) {
  html { font-size: 100%; }
}

body {
  margin: 0;
  font-family: var(--font);
  color: var(--ink);
  background: var(--paper);
  line-height: 1.6;
}

/* ===== 상단 메뉴 띠 (모든 페이지 공통) =====
   마크업은 tools/prerender.py 의 sitebar_block() 이 **정적으로** 찍는다 —
   글자까지 HTML 에 들어 있어야 크롤러가 사이트 안 링크를 보고, 늦게 생겨 본문을
   밀어내지도 않는다(CLS, §0-8). 그래서 여기 CSS 는 자리만 잡는다.
   ⚠️ 화면에 붙어 따라온다(sticky). 어느 페이지 어느 위치에서도 다른 쪽으로 갈 수 있게.
      z-index 는 모달(100)보다 **낮아야** 한다 — 안 그러면 모달 위로 띠가 뜬다. */
.sitebar {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--card);
  border-bottom: 1px solid var(--line);
}
.sitebar__inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  max-width: 82.5rem;
  min-height: 3rem; /* 로그인 칸이 JS 로 채워져도 띠 높이가 안 변하게 */
  margin: 0 auto;
  padding: 0 1.5rem;
}
/* 사이트 이름 — 띠에서 제일 큰 글자다(이 사이트의 이름이므로).
   ⚠️ line-height 를 1 로 못박는다. 이모지(🧀)는 글자보다 위아래로 더 큰 상자를 갖는데,
      그 상자가 줄상자를 **위쪽으로만** 늘려서 이름이 메뉴보다 아래로 내려가 보였다.
      상자를 글자에 붙여두면 flex 의 세로 중앙 정렬이 글자 기준으로 맞는다. */
.sitebar__home {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 1.06rem;
  line-height: 1;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.sitebar__nav { display: flex; align-items: center; gap: 1.25rem; min-width: 0; }
.sitebar__link {
  font-size: 0.84rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  text-decoration: none;
  white-space: nowrap;
  padding: 0.25rem 0;
  /* ⚠️ 위아래 선을 짝으로 둔다. 아래만 두면 글자가 상자 가운데에서 0.5px 위로 떠서
     사이트 이름과 세로선이 어긋난다(밑줄은 hover 때 아래쪽에만 색이 들어간다). */
  border-top: 1px solid transparent;
  border-bottom: 1px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.sitebar__home:hover { color: var(--accent); }
.sitebar__link:hover { color: var(--accent); border-bottom-color: var(--accent); }
.sitebar__home:focus-visible,
.sitebar__link:focus-visible { outline: 2px solid var(--accent); outline-offset: 0.1875rem; }

/* 로그인 + 언어 — 띠의 오른쪽 끝.
   .topbar 는 app.js 의 accountRoot() 가 **띠 안에** 만들어 언어 스위처를 넣는다.
   ⚠️ 로그인이 꺼져 있으면 .topbar 가 아예 안 생기고 .lang-switch 가 직접 남는다.
      그래서 둘 다 오른쪽으로 밀어둔다 — 한쪽만 적으면 그때 언어 칩이 메뉴에 붙는다. */
.sitebar__inner > .topbar,
.sitebar__inner > .lang-switch { margin-left: auto; }
.topbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.625rem;
}
.topbar .lang-switch { max-width: none; margin: 0; padding: 0; }
/* 띠 안에서는 줄바꿈을 막는다 — 좁은 화면에서 "Sign in" 이 두 줄이 되며 띠가 두꺼워졌다 */
.sitebar .lang-btn, .sitebar .acct__who { white-space: nowrap; }

/* 좁은 화면 — **두 줄짜리 띠**가 된다.
     윗줄: 사이트 이름 … 로그인·언어
     아랫줄: 메뉴 셋이 폭을 삼등분해 꽉 채운다
   ⚠️ 한 줄로 버티면 안 된다. 360px 에서 실측해 보니 이름+메뉴 셋+로그인+언어가
      한 줄에 안 들어가 **로그인·언어가 화면 밖으로 밀려났다**(2026-07-29).
   ⚠️ 가로 스크롤로 밀어 보게 두는 것도 안 된다 — 띠에 스크롤이 걸린 걸 알 방법이 없다.
   접어 넣는 햄버거 버튼을 두지 않는 이유: 항목이 셋뿐이고, 버튼을 만들면 여닫는
   상태·바깥 클릭·포커스 가둠까지 따라온다. 셋은 그냥 보이는 편이 빠르다.
   ⚠️ 아랫줄은 `flex: 1 0 100%` 로 **자기 줄을 차지**한다. 여기서 wrap 을 빼면
      다시 한 줄로 붙어 위 증상으로 돌아간다. */
@media (max-width: 40rem) {
  .sitebar__inner {
    flex-wrap: wrap;
    gap: 0;
    min-height: 0;
    padding: 0 1rem;
  }
  .sitebar__home { padding: 0.5625rem 0; }
  .sitebar__inner > .topbar,
  .sitebar__inner > .lang-switch { padding: 0.5rem 0; }
  /* ⚠️ order 로 메뉴를 맨 뒤로 보낸다. DOM 순서는 [이름 · 메뉴 · 로그인] 이라
     그대로 두면 메뉴가 한 줄을 통째로 먹고 **로그인이 셋째 줄로 밀려난다.** */
  .sitebar__nav {
    order: 3;
    flex: 1 0 100%;
    gap: 0;
    border-top: 1px solid var(--line-soft);
  }
  /* 셋이 같은 몫을 갖는다 — 글자 길이가 달라도 칸은 같아야 띠로 보인다 */
  .sitebar__link {
    flex: 1;
    text-align: center;
    padding: 0.625rem 0.25rem;
    border-top: 0;
    border-bottom: 0;
  }
  .sitebar__link + .sitebar__link { border-left: 1px solid var(--line-soft); }
  .sitebar__link:hover { border-bottom: 0; background: #fdf9f0; }
}
.acct { position: relative; display: flex; align-items: center; gap: 0.5rem; }
/* 상단 버튼을 누르면 열리는 작은 로그인 창 (실제 공급자 버튼은 이 안에 있다) */
.acct__pop {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 60;
  width: 16.25rem;
  padding: 1rem;
  background: var(--card);
  border: 1px solid var(--line);
  text-align: left;
}
.acct__poptitle {
  margin: 0 0 0.375rem;
  font-size: 0.86rem;
  letter-spacing: 0.02em;
  color: var(--accent);
}
.acct__popdesc {
  margin: 0 0 0.875rem;
  font-size: 0.78rem;
  line-height: 1.65;
  color: var(--ink);
}
.acct__popbtns { display: flex; flex-direction: column; gap: 0.5rem; }
.acct__who {
  color: var(--ink-soft);
  font-size: 0.76rem;
  letter-spacing: 0.02em;
}
.acct .lang-btn { text-decoration: none; display: inline-block; }
.acct__err {
  margin: 0.75rem 0 0;
  color: #a3452f;
  font-size: 0.74rem;
  line-height: 1.6;
  letter-spacing: 0.01em;
  cursor: help;
}

/* ===== 언어 스위처 ===== */
.lang-switch {
  display: flex;
  justify-content: flex-end;
  gap: 0.375rem;
  max-width: 82.5rem;
  margin: 0 auto;
  padding: 0.875rem 1.5rem 0;
}
.lang-btn {
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  padding: 0.25rem 0.6875rem;
  border-radius: 2px;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.lang-btn:hover { border-color: var(--accent); color: var(--ink); }
.lang-btn.is-on {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* ===== 히어로 ===== */
/* 위 여백이 4rem 이던 시절에는 페이지 맨 위가 비어 있었다. 지금은 그 자리에
   메뉴 띠(.sitebar)가 있으므로 그만큼 줄인다 — 안 줄이면 띠와 제목이 멀어 보인다. */
.hero {
  max-width: 82.5rem;
  margin: 0 auto;
  padding: 2.5rem 1.5rem 1.75rem;
  text-align: center;
}

/* 헤더 치즈 아이콘 = 홈 버튼 (외형은 그대로, 클릭 가능) */
.hero__home {
  display: block;
  margin: 0 auto 0.875rem;
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 3.25rem;
  line-height: 1;
  cursor: pointer;
  transition: transform 0.15s ease, filter 0.15s ease;
}
.hero__home:hover { transform: translateY(-1px); filter: saturate(1.1); }
.hero__home:focus-visible { outline: 2px solid var(--accent); outline-offset: 0.25rem; border-radius: 2px; }

.hero__title {
  font-size: clamp(1.9rem, 5.6vw, 2.7rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--ink);
}

/* 제목 아래 얇은 포인트 룰 */
.hero__title::after {
  content: "";
  display: block;
  width: 2.5rem;
  height: 2px;
  background: var(--accent);
  margin: 1rem auto 0;
}

.hero__subtitle {
  margin: 1rem auto 0;
  max-width: 28.75rem;
  font-size: 0.95rem;
  color: var(--ink-soft);
  letter-spacing: 0.01em;
}
/* 부제 아래 한 줄 더 — 그 페이지의 규칙을 미리 알려주는 자리(치즈함의 "나만 봅니다").
   부제보다 한 단계 작고 옅게. 선을 더 긋지 않는다(§0-6) — 이 사이트의 다른 보조 문구
   (.reads__note · .ranking__note)와 같은 결이다. */
/* ===== 행동을 권하는 버튼 (알약) =====
   ⚠️ **둥근 모서리는 사이트에서 이 둘뿐이다** — 갤러리 히어로의 [🧀 치즈타임 자랑하기]
      (`.hero__cta`)와 읽을거리 글 끝의 [🧀 치즈 이야기 더 →](`.gdback__btn`).
      나머지는 전부 2px 각진 모서리다(버튼·입력칸·칩). 운영자가 고른 모양이고,
      **"다음에 뭘 할지 권하는 자리"라는 뜻으로 쓴다** — 그 뜻이 없는 곳에 셋째를
      만들면 모양이 규칙이 아니라 장식이 된다(§6).
   ⚠️ 그래서 모양·색·글자는 **이 한 규칙에서 함께 받는다.** 낱개로 갈리면 같은 약속인지
      알 수 없다(§0-6). 자리마다 다른 것은 **크기와 자리뿐**이다.
   ⚠️ 흰 3px 테두리도 이 한 벌에 든다. 흰색은 팔레트에 없는 색인데(면은 --card #f8f3e9,
      바탕은 --paper #f3ede1 — 둘 다 미색) 그래서 accent 면을 미색에서 떼어낸다.
      알약을 감싸는 여백처럼 보여 모서리도 더 둥글게 읽힌다.
   ⚠️ 폭을 100% 로 늘리지 않는다. 둘 다 가운데 정렬이라 꽉 찬 띠는 제출 버튼처럼 보인다.
   ⚠️ 좌우 여백이 위아래보다 넉넉한 것은 알약 모서리 때문이다 — 양끝이 안으로 말려서
      같은 값이면 글자가 끼어 보인다. */
.hero__cta,
.gdback__btn {
  display: inline-block;
  border: 3px solid #fff;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-decoration: none;
  transition: background 0.16s ease;
}
.hero__cta:hover,
.gdback__btn:hover { background: #6a4e28; }
.hero__cta:focus-visible,
.gdback__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* 히어로의 첫째 행동 — 갤러리에서 "글쓰기"가 그것이다.
   전에는 상단 바에서 [← 메인으로] 옆에 얇은 선 버튼으로 있었다. 이 페이지의 유일한
   목적인 행동이 **길 안내 줄에 섞여** 눈에 안 걸렸다(2026-07-30).
   모양·색·테두리는 위 한 벌에서 받고, 여기서 정하는 것은 자리와 크기뿐이다. */
.hero__cta {
  margin: 1.25rem auto 0;
  padding: 0.6875rem 1.75rem;
  font-size: 0.92rem;
}
.hero__cta[hidden] { display: none; }

.hero__note {
  margin: 0.5rem auto 0;
  max-width: 30rem;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--ink-soft);
  opacity: 0.85;
}

/* ===== 본문 레이아웃 ===== */
/* 하위 페이지: 좌측 위젯 · 본문 · 우측 위젯 3칸.
   본문은 가운데 고정 폭(--page-width), 양옆은 남는 만큼 위젯/광고 자리가 된다. */
.pagelayout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, var(--page-width)) minmax(0, 1fr);
  gap: 1.625rem;
  align-items: start;
}
.pagecol {
  max-width: var(--page-width);
  margin: 0 auto;
  width: 100%;
}

/* 양옆 칸 — 본문 쪽에 붙여 두고, 스크롤해도 따라오게 */
.rail {
  position: sticky;
  top: 1.25rem;
  width: 100%;
  max-width: var(--rail-width);
}
.rail[hidden],
.sidebar[hidden] { display: none; }
.rail--left { justify-self: end; }
.rail--right { justify-self: start; }

/* ⚠️ 칸을 **자리로** 못박는다. 위젯이 하나도 없어 rail 이 접히면(display:none) 그 격자 항목이
   사라져서, 남은 본문이 첫 칸(1fr ≈ 200px)으로 밀려 들어간다 — 관리자 페이지가 실제로 그랬다.
   위치를 지정해 두면 양옆이 있든 없든 본문은 늘 가운데 칸이다. */
.pagelayout > .rail--left { grid-column: 1; }
.pagelayout > :not(.rail) { grid-column: 2; }
.pagelayout > .rail--right { grid-column: 3; }

/* ===== 사이드 위젯 제목 — 다섯이 한 벌이다 =====
   나의 치즈함 · Hot Cheese · 치즈 용어 · 치즈타임 자랑하기 · 운영자 위젯.
   ⚠️ 여기 한 곳에서만 정한다. 예전엔 규칙이 다섯 군데로 흩어져 있어서
      .brag__title 만 0.94rem·먹색으로 남아 혼자 튀었다(2026-07-28).
   낱개로 다른 것(자간)만 각자의 규칙에서 덧쓴다. */
.mystash__title,
.ranking__title,
.glossary__title,
.brag__title,
.wslot__title {
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--accent);
}

/* ===== 사이드 위젯의 뼈대 — 다섯이 같은 것을 쓴다 =====
   카드(.wcard)는 **테두리만** 갖고, 안쪽 여백은 머리(.wcard__head)와 본문(.wcard__body)이
   각자 갖는다. 그래야 제목 아래 선이 카드 **끝에서 끝까지** 간다.
   ⚠️ 카드에 좌우 여백을 주고 제목에 선을 그으면 안 된다 — 선이 안쪽으로 들어와
      "카드 테두리와 나란하지만 짧은 선"이 하나 더 생긴다. 여백을 옮기는 것이 요점이다.
   ⚠️ 2026-07-29 이전에는 치즈타임(.brag)만 이 모양이었고 나머지 넷은 선이 없었다.
      제목과 내용이 붙어 있으면 좁은 칸(--rail-width 200px)에서 제목이 첫 줄처럼 읽힌다.
   · 목록이 스스로 좌우 여백을 갖는 위젯(치즈타임 글 목록)은 __body 를 쓰지 않는다 —
     줄 전체가 눌리는 자리라 hover 배경이 카드 끝까지 닿아야 한다. */
.wcard {
  background: var(--card);
  border: 1px solid var(--line);
}
.wcard__head {
  display: block;
  margin: 0;
  padding: 1rem 1.125rem 0.8125rem;
  border-bottom: 1px solid var(--line-soft);
}
.wcard__body { padding: 0.875rem 1.125rem 1rem; }

/* 운영자/광고 위젯 (WIDGETS.items) — 뼈대는 .wcard, 여기서는 간격과 본문 글자만 */
.wslot + .wslot { margin-top: 0.875rem; }
.wslot__body { font-size: 0.84rem; line-height: 1.65; color: var(--ink); }
.wslot__body img { max-width: 100%; height: auto; display: block; }

/* 아직 비어 있는 자리 (WIDGETS.showPlaceholder) — 머리도 본문도 없어 여백을 직접 갖는다 */
.wslot--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 10.5rem;
  padding: 0.875rem 1rem;
  border-style: dashed;
  background: transparent;
  font-size: 0.74rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  opacity: 0.6;
  text-align: center;
}

.wrap {
  max-width: 82.5rem;
  margin: 0 auto;
  padding: 1.25rem 1.5rem 4.5rem;
}

.layout {
  display: grid;
  grid-template-columns: 14.5rem 1fr 16.125rem;
  gap: 2.125rem;
  align-items: start;
}
/* .pagelayout 과 같은 이유로 칸을 못박는다 — 사이드바가 접혀도 갤러리가 안 밀리게 */
.layout > .sidebar--left { grid-column: 1; }
.layout > :not(.sidebar) { grid-column: 2; }
.layout > .sidebar--right { grid-column: 3; }

/* ===== 갤러리 상단 정렬 필터 ===== */
.gallery-head {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.875rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}
.gallery-sort {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}
.gallery-sort__label {
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}
/* ⚠️ **네모 상자로 만들지 말 것 — 그 모양은 "거르는 것" 이다** (2026-07-31).
   전에는 테두리 1px --line · 배경 --card · 모서리 2px · 글자 0.76rem/0.02em ·
   패딩 0.25rem 이라 **바로 아래 줄의 태그 칩(.cchip)과 값이 거의 같았다.**
   그 줄이 칩 줄이라 "네모 상자를 누르면 걸러진다" 는 약속이 이미 서 있는데,
   순서를 정하는 물건이 그 모양을 빌려 쓰고 있었다(§0-6 "같은 모양은 같은 일을 한다").
   지금은 상자를 걷어내고 **값 아래 얇은 선 한 줄**만 남긴다 —
     네모 상자 = 거르는 것 (검색칸 · 태그 칩 · 나라 칩)
     밑줄 글자 = 고르는 것 (정렬)
   ⚠️ <select> 는 그대로 둔다. 기준이 늘어나도 줄이 안 길어지고(js/sort.js 는 계속
      추가될 전제로 쓰여 있다) 번역·키보드·모바일 선택기가 공짜로 따라온다. */
.gallery-sort__select {
  font-family: inherit;
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  color: var(--ink);
  background-color: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  padding: 0.25rem 1.0625rem 0.1875rem 0.125rem;
  cursor: pointer;
  /* 미색 톤에 맞춘 얇은 오커색 화살표 */
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='7' viewBox='0 0 10 7'><path d='M1 1l4 4 4-4' fill='none' stroke='%237a5a2e' stroke-width='1.4'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.125rem center;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.gallery-sort__select:hover { border-bottom-color: var(--accent); }
.gallery-sort__select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 펼쳐진 목록은 OS 가 그린다 — 배경이 투명하면 글자가 안 보이는 브라우저가 있어 되돌려 준다 */
.gallery-sort__select option { background: var(--card); color: var(--ink); }

/* ===== 갤러리 ===== */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10.75rem, 1fr));
  gap: 1px;                 /* 카드끼리 얇은 선으로만 구분되는 느낌 */
  background: var(--line-soft);
  border: 1px solid var(--line);
}

/* ===== 계정 연결 안내 (나의 치즈함) ===== */
/* 이 기기에만 있는 기록 경고 — 치즈함 맨 위.
   관리자 경고(.awarn)와 **같은 결**을 쓴다. 이 사이트에서 "주의"를 뜻하는 색이 하나여야
   한다(§0-6) — 새 색을 만들면 방문자가 두 경고를 다른 종류로 읽는다.
   ⚠️ 빨강을 쓰지 않는다. 잘못한 것이 아니라 아직 안 한 것이고, 로그인은 강제가 아니다. */
.stwarn {
  margin: 0 0 1.125rem;
  padding: 0.75rem 1rem;
  background: #fbf3e6;
  border: 1px solid #e2cfa8;
}
.stwarn__msg {
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.65;
  color: var(--ink);
}
/* 어떻게 잃는지 — 로그인 전 칸(.stlogin__loss)과 같은 결. 두 화면이 같은 두 문장을 쓴다 */
.stwarn__loss {
  margin: 0.1875rem 0 0;
  font-size: 0.76rem;
  line-height: 1.65;
  color: var(--ink-soft);
}
.stwarn__acts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.875rem;
  margin: 0.625rem 0 0;
}
.stwarn__btn {
  padding: 0.375rem 0.875rem;
  border: 1px solid var(--accent);
  border-radius: 2px;
  background: none;
  color: var(--accent);
  font-family: inherit;
  font-size: 0.78rem;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.stwarn__btn:hover { background: var(--accent); color: var(--paper); }
.stwarn__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.stwarn__btn[disabled] { cursor: default; opacity: 0.55; }

/* 화면 맨 위에 놓이는 안내. **왼쪽 정렬이다** — 이 사이트는 카드·기록·칩·안내가 전부
   왼쪽에서 시작하는 편집 디자인이라, 이 칸만 가운데로 모으면 혼자 튀고 아래 기록들과
   세로선도 어긋난다. "기록이 아니라 권유" 라는 것은 정렬이 아니라 테두리와 배경이 말한다.
   ⚠️ 안에 또 상자를 두지 말 것 — 테두리를 두 번 두르는 순간 안쪽이 남남으로 읽힌다
      (갤러리 글↔댓글에서 겪은 것과 같다). 세 줄의 무게는 글자 크기와 색으로만 가른다. */
.stlogin {
  margin: 0 0 1.375rem;
  padding: 1.375rem 1.5rem;
  background: var(--card);
  border: 1px solid var(--line);
}
/* 제목 = 이 기기에만 있는 기록 수. 사람을 움직이는 건 권유가 아니라 이 숫자다 */
.stlogin__title {
  margin: 0 0 0.375rem;
  font-size: 0.92rem;
  letter-spacing: 0.02em;
  color: var(--accent);
}
/* 어떻게 잃는지 — 제목을 받는 말이라 한 단계 작고 흐리게. 새 선을 긋지 않는다(§0-6) */
.stlogin__loss {
  margin: 0 0 0.625rem;
  font-size: 0.78rem;
  line-height: 1.65;
  color: var(--ink-soft);
}
.stlogin__desc {
  margin: 0 0 1rem;
  max-width: 30rem;
  font-size: 0.84rem;
  line-height: 1.7;
  color: var(--ink);
}
.stlogin__btns {
  display: flex;
  flex-wrap: wrap;
  gap: 0.625rem;
}
.stlogin__btn {
  padding: 0.5rem 1.125rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--paper);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.82rem;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.stlogin__btn:hover { border-color: var(--accent); color: var(--accent); background: #fff; }
.stlogin__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ===== 구글 로그인 버튼 — 구글 브랜딩 규정을 따른다 =====
   ⚠️ 여기 값들은 우리 디자인 토큰이 아니라 **구글이 정한 값**이다. 톤을 맞추려고 고치지 말 것.
      배경 #FFFFFF · 테두리 #747775 1px(안쪽) · 글자 #1F1F1F ·
      여백 왼쪽 12px / 로고 뒤 10px / 오른쪽 12px · 로고는 색·크기 변경 금지.
   글꼴만 규정(Google Sans Medium)과 다르다 — 이 사이트는 외부 폰트를 쓰지 않기 때문(§1).
   시스템 고딕의 medium 두께로 대신한다.
   https://developers.google.com/identity/branding-guidelines */
.gbtn {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  min-height: 2.5rem;
  padding: 0 0.75rem;
  border: 1px solid #747775;
  border-radius: 4px;
  background: #fff;
  color: #1f1f1f;
  font-family: inherit;
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.15px;
  cursor: pointer;
  transition: background 0.15s ease, box-shadow 0.15s ease;
}
.gbtn__logo { display: block; flex: none; }
.gbtn:hover { background: #f7f8f8; }
.gbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 기록이 없을 때(= 불러오기 안내)는 한 톤 낮춘다 — 권유가 아니라 안내다 */
.stlogin--quiet {
  background: none;
  border-style: dashed;
}
/* "기록 N개가 이 기기에만 있어요" — 권유가 아니라 사실이라 제목 위에 둔다.
   ⚠️ 여기서도 .stwarn 과 **같은 주의색**을 쓴다. 이 사이트에서 "주의" 는 색이 하나여야
      한다(§0-6) — 로그인 전에는 이 줄이, 로그인 뒤에는 .stwarn 이 같은 말을 한다. */
.stlogin__note,
.stlogin__err {
  margin: 0.875rem 0 0;
  font-size: 0.76rem;
  color: var(--ink-soft);
}
.stlogin__err { color: #b3453b; }


/* 기록 카드 — 치즈 한 칸. 안에 기록이 여러 개 세로로 쌓인다.
   ⚠️ 최신 기록과 이전 기록은 **같은 모양**(.strec__entry)이다.
      달라 보이면 관계가 안 읽히고, 버튼이 어느 기록 것인지도 헷갈린다. */
.strec {
  background: var(--card);
  border: 1px solid var(--line);
  padding: 0.875rem 1.125rem 1rem;
}

/* 모달에서 "치즈함에서 보기 →" 로 왔을 때 잠깐 짚어준다 */
.strec--found { border-color: var(--accent); }

/* 칸 머리: 치즈 이름 + 기록 수 */
.strec__head {
  display: flex;
  align-items: baseline;
  gap: 0.625rem;
  padding-bottom: 0.625rem;
  border-bottom: 1px solid var(--line-soft);
}
.strec__cheese {
  font-size: 0.86rem;
  font-weight: 700;
  color: var(--ink);
  text-decoration: none;
}
.strec__cheese:hover { color: var(--accent); }
.strec__cheese:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.strec__count { margin-left: auto; font-size: 0.72rem; color: var(--ink-soft); }

/* 접어둔 이전 기록 — 펼치면 최신 기록과 같은 모양으로 이어진다 */
.strec__older > summary {
  display: flex;
  align-items: center;
  gap: 0.4375rem;
  cursor: pointer;
  list-style: none;
  padding-top: 0.75rem;
  font-size: 0.76rem;
  color: var(--ink-soft);
}
.strec__older > summary::-webkit-details-marker { display: none; }
/* ⚠️ 화살표는 **글자가 아니라 CSS 로 그린다.** 전에는 ⌄(U+2304)·⌃(U+2303) 였는데
   ⌃ 는 시스템 폰트에 있고 ⌄ 는 없다 — 없는 쪽만 다른 폰트로 대체돼 굵기·크기·높이가
   접었을 때와 펼쳤을 때 서로 달라 보였다. 같은 네모를 돌려 쓰면 두 상태가 어긋날 수 없고,
   선 하나로 그린 모양이라 이 사이트의 결에도 맞는다(설계원칙 §0-6). */
.strec__older > summary::before {
  content: "";
  flex: 0 0 auto;
  width: 0.375rem;
  height: 0.375rem;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  /* 돌린 뒤 남는 위아래 쏠림만 눌러준다 — 꺾인 자리가 아니라 뾰족한 끝이 치우친다 */
  transform: translateY(-0.1em) rotate(45deg);
  transition: transform 0.16s ease;
}
.strec__older[open] > summary::before { transform: translateY(0.08em) rotate(-135deg); }
.strec__older > summary:hover { color: var(--accent); }

/* 기록 하나 — 사진 + 글 + 그 기록의 버튼 */
/* ⚠️ display 를 주는 요소는 [hidden] 을 명시해야 한다 — 안 그러면 이 규칙이
   브라우저 기본 display:none 을 이겨서 감춰지지 않는다(그 자리 수정에서 실제로 겪음). */
.strec__entry[hidden] { display: none; }

/* ===== 선반 — 그 치즈의 기록이 정사각 타일로 나란히 =====
   ⚠️ 넘치면 **줄바꿈**한다. 가로 스크롤 금지 — 태그 칩에서 한 번 겪고 되돌린 실수다.
   타일 폭은 고정이다. 1fr 로 늘리면 기록이 하나뿐인 치즈의 타일이 폭을 다 먹어
   예전의 "가로로 긴 카드" 로 되돌아간다. */
.stshelf {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start; /* [+] 타일은 글자가 없어 낮다 — 늘리지 말고 위로 맞춘다 */
  gap: 0.875rem;
  padding: 0.75rem 0 0.25rem;
}
.sttile {
  width: 7.5rem;
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
/* 사진은 어디서든 1:1 (설계원칙 §0-7) */
.sttile__thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--paper);
  transition: border-color 0.15s ease;
}
/* ⚠️ margin·border 를 0 으로 되돌리는 것이 핵심 — 대표 사진은 .card__illust(아래 여백)와
   .card__cover(테두리)를 달고 들어온다. 그대로 두면 위로 밀려 아래가 빈다. */
.sttile__thumb img { width: 100%; height: 100%; margin: 0; border: 0; object-fit: cover; display: block; }
.sttile__thumb svg.card__illust { width: 62%; height: auto; margin: 0; }
.sttile__date {
  display: block;
  margin-top: 0.4375rem;
  font-size: 0.68rem;
  color: var(--ink-soft);
}
.sttile__title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: 0.125rem;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--ink);
  transition: color 0.15s ease;
}
/* 선반 끝의 [+] — 아직 안 놓은 칸이라 점선이다(빈 사진칸 .m-col-preview 와 같은 결) */
.sttile--add .sttile__thumb {
  border-style: dashed;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--ink-soft);
  transition: border-color 0.15s ease, color 0.15s ease;
}
.sttile--add:hover .sttile__thumb { color: var(--accent); }

.sttile:hover .sttile__thumb { border-color: var(--accent); }
.sttile:hover .sttile__title { color: var(--accent); }
.sttile:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* 펼쳐 둔 타일 — 아래 전폭 줄이 **이 타일의 내용**이라는 표시 */
.sttile[aria-expanded="true"] .sttile__thumb { border-color: var(--accent); border-width: 2px; }
/* 고른 타일은 제목 줄임을 푼다 — 펼친 줄에 제목을 다시 쓰지 않기 위한 짝이다.
   ⚠️ 이걸 지우면 제목이 긴 기록은 어디에서도 전문을 볼 수 없게 된다. */
.sttile[aria-expanded="true"] .sttile__title {
  color: var(--accent);
  -webkit-line-clamp: unset;
}
/* 위아래를 대칭으로 준다. 아래가 0 이면 구분선이 버튼줄에 딱 붙는다. */
.strec__entry {
  display: flex;
  gap: 1rem;
  padding: 0.875rem 0;
}
.strec__entry:not([hidden]) { border-top: 1px solid var(--line-soft); }
/* 그 자리 수정 폼 — 기록이 있던 자리에 들어오므로 기록과 같은 여백을 준다.
   안 그러면 윗 글(치즈 이름 줄이나 앞 기록)에 딱 붙는다. */
.strec .m-col-form { padding: 0.875rem 0; }
/* 사진칸도 **기록 썸네일과 같은 크기·같은 간격**으로 맞춘다.
   [수정]을 누르면 기록이 감춰지고 이 폼이 그 자리에 들어오는데, 기본값(9.25rem)이면
   사진이 갑자기 커지고 글 칸의 왼쪽 끝이 50px 쯤 오른쪽으로 밀린다 —
   **누른 순간 배치가 통째로 바뀌어** 다른 화면으로 넘어간 것처럼 보인다.
   기록 줄 자체에는 이제 사진이 없다(선반의 타일이 보여준다). 그래도 폼 사진칸은 6rem 로
   둔다 — 기본값(9.25rem)이면 편집할 때만 폼이 혼자 커져 선반 타일보다 커진다.
   ⚠️ .strec 안으로 한정한다 — 새 기록 폼(.stnew)·모달·치즈 상세의 폼은 무엇을 대신
      들어가는 것이 아니라 맞출 자리가 없다. 그쪽은 그대로 9.25rem 이다. */
.strec .m-col-editrow { gap: 1rem; }
.strec .m-col-photocol { flex-basis: 6rem; }
.strec .m-col-photopick,
.strec .m-col-preview { width: 6rem; }
/* 같은 이유로 **메모 라벨만** 눈에서 감춘다(읽어주기에는 남긴다).
   보기 상태의 줄은 [날짜 · 제목 · 메모] 셋인데 폼은 [제목라벨 · 제목칸 · 메모라벨 · 메모칸]
   넷이라, 짝이 없는 그 한 줄이 메모칸을 56px 아래로 밀어냈다(실측).
   제목 라벨은 남긴다 — 작고 흐린 한 줄이라 **날짜 줄의 자리를 그대로 대신한다.**
   지금은 사진·제목칸이 5px 안쪽, 메모칸이 20px 안쪽에서 겹친다.
   ⚠️ 완전히 같은 자리는 될 수 없다 — 입력칸은 테두리·안여백 때문에 글자보다 16px 높다.
      더 좁히겠다고 안여백을 줄이면 누를 곳이 작아지고 다른 폼과도 어긋난다. */
.strec .m-col-lines .m-col-field + .m-col-field { position: relative; margin-top: 0.375rem; }
.strec .m-col-lines .m-col-field + .m-col-field > span:first-child {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.strec__entry + .m-col-form { border-top: 1px solid var(--line-soft); }
/* 폼 뒤에 또 기록이 오면 아래에도 선을 둔다 — 편집 중인 구간이 위아래로 닫혀 보이게. */
.m-col-form:not([hidden]) + .strec__entry,
.m-col-form:not([hidden]) + .strec__older { border-top: 1px solid var(--line-soft); }

.strec__thumb {
  /* 글 블록(날짜+제목+메모+버튼)이 대략 95px 이다. 116px 이던 시절에는 글이 짧으면
     사진만 아래로 튀어나와 빈 자리가 남았다. 1:1 은 그대로 지킨다(설계원칙 §0-7). */
  flex: 0 0 6rem;
  height: 6rem;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--paper);
  display: flex;
  align-items: center;
  justify-content: center;
}
/* 사진은 정사각이 아니어도 칸을 꽉 채운다 (메인 카드와 같은 방식).
   ⚠️ margin·border 를 0 으로 되돌리는 것이 핵심 — 대표 사진은 .card__illust(margin-bottom 16px)
      와 .card__cover(border 1px) 를 달고 들어오므로, 그대로 두면 위로 밀려 아래가 빈다. */
.strec__thumb img {
  width: 100%;
  height: 100%;
  margin: 0;
  border: 0;
  object-fit: cover;
  display: block;
}
/* 일러스트일 때만 작게 — 대표 사진(img)은 위의 img 규칙대로 칸을 꽉 채운다.
   ⚠️ svg 로 좁히지 않으면 사진에도 74px 이 걸린다. */
.strec__thumb svg.card__illust { width: 3.875rem; height: auto; margin: 0; }

.strec__body { flex: 1 1 auto; min-width: 0; }
.strec__note {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0.375rem 0 0;
  font-size: 0.84rem;
  line-height: 1.6;
  color: var(--ink-soft);
}
/* 버튼은 그 기록 바로 아래 — 무엇을 고치고 지우는지 분명하게 */
/* 셋을 왼쪽에 붙여 한 덩어리로 둔다. [삭제] 를 오른쪽 끝으로 떼어 놓았던 적이 있는데
   (되돌릴 수 없으니 잘못 누르지 말라고), 기록 폭만큼 벌어져 오히려 줄이 두 덩이로 갈렸다.
   오식은 삭제할 때 뜨는 확인 창(stashEntryDelConfirm)이 막는다 — 거리로 막을 일이 아니다. */
.strec__acts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.875rem;
  margin: 0.75rem 0 0;
}

@media (max-width: 560px) {
  .strec__entry { flex-direction: column; }
  .strec__thumb { flex-basis: auto; width: 7.25rem; }
}

/* ===== 치즈함: 치즈 한 칸에 기록 여러 개 ===== */
/* 기록마다 붙는 줄 (자랑하기 · 수정 · 삭제) */
/* 모달의 기록 한 줄 — 사진·제목·날짜·수정이 한 줄에 */
.m-col-record .m-col-lines { flex: 1 1 auto; min-width: 0; }
.m-col-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: 0.75rem;
}

/* 날짜가 제목 **위**에 온다 — 언제 적은 기록인지 먼저 읽히게. */
.m-col-rdate { margin: 0 0 2px; font-size: 0.74rem; color: var(--ink-soft); }
.m-col-rtitle { margin: 0; font-size: 0.9rem; color: var(--ink); font-weight: 700; }
/* 메모 — 모달은 좁으니 두 줄까지만 보여주고 나머지는 줄인다.
   전체는 치즈함 페이지에서 본다(제목 옆 화살표). */
.m-col-rnote {
  margin: 0.25rem 0 0;
  font-size: 0.82rem;
  line-height: 1.6;
  color: var(--ink-soft);
  white-space: pre-wrap;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ===== 읽을거리 위젯 (메인) + 목록 페이지 (reads.html) =====
   글이 스무 편이 넘어가면서 점 찍은 목록으로는 읽히지 않았다.
   한 칸씩 테두리를 준 격자로 바꾸고, 메인에서는 **앞의 여섯 칸만** 보여준다.
   순서는 js/app.js 의 renderReads() 가 최근 한 달 조회수 순으로 다시 세운다.
   → DOM 에는 전부 들어 있고 CSS 가 자르므로, 다시 세우기만 하면 많이 읽은 글이 위로 온다. */
.reads {
  margin-top: 2.125rem;
  padding-top: 1.625rem;
  border-top: 1px solid var(--line);
}
.reads__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 0.875rem;
}
.reads__title {
  margin: 0;
  font-size: 0.9rem;
  letter-spacing: 0.02em;
  color: var(--accent);
}
.reads__note {
  font-size: 0.74rem;
  color: var(--ink-soft);
}

.reads__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.625rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.read { display: flex; }
.read__a {
  display: block;
  flex: 1;
  padding: 0.8125rem 0.9375rem;
  background: var(--card);
  border: 1px solid var(--line);
  text-decoration: none;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.read__a:hover { border-color: var(--accent); }
.read__a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.read__t {
  display: block;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--ink);
}
.read__d {
  margin-top: 0.3125rem;
  font-size: 0.75rem;
  line-height: 1.6;
  color: var(--ink-soft);
  /* 요약 길이가 제각각이라 두 줄로 잘라야 칸 높이가 고르다 */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* 많이 읽은 글 표시 — renderReads() 가 상위 몇 개에만 붙인다 */
.read--top .read__a { border-color: var(--accent); }
.read__badge {
  display: inline-block;
  margin-right: 0.375rem;
  padding: 1px 0.375rem;
  font-size: 0.66rem;
  letter-spacing: 0.02em;
  color: var(--accent);
  border: 1px solid var(--line);
  vertical-align: 1px;
}

/* 메인 위젯: 앞의 여섯 칸만 보여준다 (나머지는 링크로만 남는다) */
.reads[data-reads="widget"] .read:nth-child(n + 7) { display: none; }

.reads__all {
  display: inline-block;
  margin-top: 0.875rem;
  font-size: 0.78rem;
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
}
.reads__all:hover { color: var(--accent); border-color: var(--accent); }

/* 목록 페이지에서는 전부 보이고, 위쪽 구분선이 필요 없다 */
.reads--page { margin-top: 0; padding-top: 0; border-top: 0; }
.reads__note--page { margin: 0 0 0.875rem; }

@media (max-width: 875px) {
  .reads__grid { grid-template-columns: minmax(0, 1fr); }
}

/* 글 본문 */
.gd {
  background: var(--card);
  border: 1px solid var(--line);
  padding: 1.625rem 1.875rem 2rem;
}
.gd__lead {
  margin: 0 0 0.25rem;
  font-size: 0.95rem;
  line-height: 1.8;
  color: var(--ink);
}
.gd__sec { margin-top: 1.625rem; }
.gd__h {
  margin: 0 0 0.5rem;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  color: var(--accent);
}
.gd__p {
  margin: 0;
  font-size: 0.88rem;
  line-height: 1.85;
  color: var(--ink);
}
/* 칩 앞의 소개 문장 — 본문이 아니라 **칩을 받는 말**이라 결이 달라야 한다.
   본문(.gd__p)보다 한 단계 작고 옅게. 선을 더 긋지 않는다 — 이 사이트는 선을 아끼는 톤이다(§0-6).
   같은 역할을 하는 .reads__note · .ranking__note 와 같은 결이다.
   ⚠️ 이탤릭을 쓰지 말 것 — 한글은 진짜 이탤릭이 없어 브라우저가 기울이면 획이 뭉개진다. */
.gd__cue {
  margin: 0.875rem 0 0;
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--ink-soft);
}
.gd__cue + .gd__cheeses { margin-top: 0.4375rem; }  /* 문장이 있으면 칩을 그 문장에 붙인다 */
.gd__cheeses { margin-top: 0.75rem; }

/* 본진으로 보내는 링크 · 글 끝의 근거 자료.
   둘 다 본문이 아니라 **본문을 거드는 말**이라 .gd__cue 와 같은 결을 쓴다 —
   한 단계 작고 옅게, 선을 더 긋지 않는다(§0-6). 새 스타일을 늘리지 않으려는 것이다.
   ⚠️ 알약 버튼(.gdback__btn)을 쓰지 말 것 — 그 모양은 "다음에 뭘 할지 권하는 자리"
      전용이고(§6), 이건 읽던 흐름 안에서 옆으로 새는 길이라 뜻이 다르다. */
.gd__more,
.gd__srcs {
  margin: 0.875rem 0 0;
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--ink-soft);
}
.gd__more a,
.gd__srcs a { color: var(--ink-soft); }
.gd__more a:hover,
.gd__more a:focus-visible,
.gd__srcs a:hover,
.gd__srcs a:focus-visible { color: var(--accent); }

/* 치즈 상세 아래의 "이 치즈가 나오는 읽을거리".
   ⚠️ .pagelayout 격자 **바깥**이라 폭만 .pagecol 에서 빌린다(tools/prerender.py 주석 참고).
   위젯 제목(.wcard__head)과 같은 결을 쓴다 — 작고 옅은 대문자 라벨 + 그 아래 목록.
   새 스타일을 만들지 않으려는 것이고, 본문이 끝난 자리라 제목이 크면 본문처럼 읽힌다. */
.cheese-reads {
  margin: 2rem auto 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}
.cheese-reads__title {
  margin: 0 0 0.625rem;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--accent);
}
.cheese-reads__list { margin: 0; padding: 0; list-style: none; }
.cheese-reads__list li + li { margin-top: 0.4375rem; }
.cheese-reads__list a {
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
}
.cheese-reads__list a:hover,
.cheese-reads__list a:focus-visible { color: var(--accent); border-bottom-color: var(--accent); }

/* 근거는 글 끝에 모인다 — 본문 흐름을 끊지 않으면서 "누가 그러는데"를 밝히는 자리 */
.gd__srcs { list-style: none; padding: 0; }
.gd__srcs li + li { margin-top: 0.3125rem; }
.gd__srcs a { word-break: break-word; }        /* 긴 주소가 좁은 화면을 밀지 않게 */

/* 글 끝의 다음 글 권유 — 다 읽은 사람을 목록으로 보내는 자리다. 상단 바의
   .cback(담담한 글자 링크)과 **같은 곳으로 가지만 하는 일이 다르다**: 저쪽은 길 안내,
   이쪽은 권유. 그래서 화살표도 앞(→)을 가리키고 가운데에 크게 놓인다.
   ⚠️ 글 상자(.gd) **밖**이다 — 콘텐츠가 아니라 이동 수단이다(갤러리 .cdetail__more 와 같은 이유).
   ⚠️ 모양·색·흰 테두리는 위쪽 "행동을 권하는 버튼 (알약)" 규칙에서 .hero__cta 와
      **함께 받는다.** 여기서 덧쓰는 것은 자리(가운데·위 여백)와 크기뿐이다.
   ⚠️ 히어로 CTA 보다 한 단계 작다(0.88 ↔ 0.92rem). 히어로는 그 페이지의 유일한 목적이고
      이건 글을 다 읽은 **뒤에** 오는 권유라, 같은 크기면 본문보다 세게 읽힌다. */
.gdback { margin-top: 1.5rem; text-align: center; }
.gdback__btn {
  padding: 0.625rem 1.75rem;
  font-size: 0.88rem;
}

@media (max-width: 560px) {
  .gd { padding: 1.25rem 1.125rem 1.5rem; }
}

/* ===== 갤러리 검색 ===== */
.gallery-search {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1 1 15rem;
  min-width: 0;
}
.gallery-search__label {
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  white-space: nowrap;
}
/* ⚠️ **흰색은 적는 칸 전용이다** — 글 제목·내용(.m-col-field)·댓글(.ccmt-form__*)·
   닉네임이 흰색이고, 검색·정렬처럼 **거르는 칸**은 미색이다. 2026-07-30 에 검색칸을
   흰색으로 맞췄다가 되돌렸다: 적는 칸과 구분이 사라져 어느 쪽에 글이 들어가는지 헷갈린다.
   ⚠️ 대신 **바탕과 같은 색이 되면 안 된다.** 칸 색은 절대값이 아니라 바탕에서 한 단
      어긋난 값이다 — 이 칸은 페이지 바탕(--paper) 위에 있으므로 한 단 밝은 --card,
      카드 위에 놓이는 치즈 고르기(.stpick__input)는 한 단 어두운 --paper 를 쓴다.
      그게 처음 문제였다(폼 안 검색칸이 카드와 같은 색이라 테두리 1px 로만 버텼다). */
.gallery-search__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.3125rem 0.5625rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--card);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.82rem;
}
.gallery-search__input:focus { outline: none; border-color: var(--accent); }
/* 브라우저 기본 x 는 숨기고 우리 버튼을 쓴다 (모양이 제각각이라) */
.gallery-search__input::-webkit-search-cancel-button { display: none; }
.gallery-search__clear {
  border: 0;
  background: none;
  padding: 2px 0.25rem;
  font-size: 1rem;
  line-height: 1;
  color: var(--ink-soft);
  cursor: pointer;
}
.gallery-search__clear:hover { color: var(--accent); }
.gallery-search__clear[hidden] { display: none; }

.gallery-head__count {
  font-size: 0.76rem;
  color: var(--ink-soft);
  white-space: nowrap;
}
.gallery-head__count[hidden] { display: none; }

/* 검색 결과가 없을 때 (갤러리 격자 한 칸을 다 쓴다) */
.gallery__none {
  grid-column: 1 / -1;
  margin: 0;
  padding: 2.5rem 1.5rem;
  text-align: center;
  background: var(--card);
  color: var(--ink-soft);
  font-size: 0.88rem;
}

/* JS 가 아직 안 돌았을 때(또는 검색로봇이) 보는 치즈 목록.
   tools/prerender.py 가 넣고, app.js 의 renderGalleryCards() 가 카드로 덮어쓴다.
   → 크롤러에게 치즈 이름과 상세로 가는 내부 링크를 준다(설계원칙 §0-8). */
/* ===== 카드 ===== */
.card {
  position: relative;
  background: var(--card);
  /* 위쪽 여백은 상단 줄(갤러리·조회수)이 그림과 붙지 않도록 넉넉히.
     좌우는 태그 세 개가 한 줄에 들어가도록 16px (2026-07-29) */
  padding: 2.25rem 1rem 1.5rem;
  text-align: center;
  transition: background 0.18s ease;
  cursor: pointer;
}

.card:hover { background: #fcf8f0; }
.card:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* 조회수 (우측 상단, 눈에 덜 띄게) */
.card__views {
  position: absolute;
  top: 0.5625rem;
  right: 0.5625rem;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  /* 안쪽 여백으로 카드 모서리와 거리를 둔다 (top/right 는 그만큼 줄여 위치 유지) */
  padding: 0.25rem 0.375rem;
  font-size: 0.68rem;
  color: var(--ink-soft);
  opacity: 0.5;
  pointer-events: none;
}
.card__views-icon { display: block; }



.card__illust {
  /* 일러스트와 대표 사진이 **같은 자리**를 쓴다 — 한쪽만 키우면 카드 높이가 갈린다.
     ⚠️ 여기를 바꾸면 tools/prerender.py 의 gallery_block() 주석과
        CLAUDE.md §4 의 치수도 같이 고칠 것 (프리렌더가 같은 크기의 빈 상자를 찍는다). */
  width: 5.75rem;
  height: 5.75rem;
  margin: 0 auto 1rem;
  display: block;
}

/* 대표 사진이 등록된 카드 (관리자 페이지에서 올림) — 일러스트 자리에 사진 */
.card__cover {
  object-fit: cover;
  border: 1px solid var(--line);
  background: var(--paper);
}

/* 카드 이름은 상세 페이지 링크지만 겉모습은 글자 그대로 (크롤러용 경로) */
.card__namelink { color: inherit; text-decoration: none; }
.card__namelink:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.card__name {
  font-size: 1.12rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0 0 0.25rem;
  color: var(--ink);
}

.card__origin {
  font-size: 0.8rem;
  color: var(--ink-soft);
  margin: 0 0 1rem;
}

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  justify-content: center;
}

/* 태그 상자. 카드에 태그가 평균 6~7개 붙으므로 **한 줄에 세 개**가 들어가는 크기로 맞췄다
   (2026-07-29). 카드 안쪽 폭이 3열일 때 205px 인데, 4자 태그 60px × 3 + 간격 8 = 188px 이다.
   ⚠️ 세로 여백은 안 줄였다 — 눌러야 하는 것이라 높이까지 깎으면 손가락으로 맞추기 어려워진다. */
.tag {
  font-size: 0.7rem;
  letter-spacing: 0.02em;
  padding: 0.1875rem 0.375rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: transparent;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* 카드의 태그는 <button> 이다(눌러서 검색). 브라우저 기본 글꼴·줄높이·여백을 벗겨
   옆의 <span class="tag"> 와 **같은 크기**로 만든다 — 안 그러면 카드마다 태그 줄 높이가 갈린다. */
button.tag {
  font-family: inherit;
  line-height: inherit;
  margin: 0;
}

/* 클릭 가능한 태그
   ① 모달의 "비슷한 치즈" → 그 치즈 모달로 이동
   ② 카드의 태그 → 그 말로 갤러리 검색 (js/app.js 의 searchByTag) */
.tag--link {
  cursor: pointer;
  transition: color 0.14s ease, border-color 0.14s ease, background 0.14s ease;
}
.tag--link:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: #fff;
}
.tag--link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* 아직 도감에 없는(클릭 불가) 비슷한 치즈 */
.tag--soon {
  opacity: 0.45;
  border-style: dashed;
  cursor: default;
}

/* ===== 우측 사이드바 ===== */
.sidebar {
  position: sticky;
  top: 1.5rem;
}

/* ===== Hot Cheese 랭킹 ===== */

/* 카드·여백은 .wcard 가 준다 (§ 사이드 위젯의 뼈대) */

/* 영문 "HOT CHEESE" 라 대문자 + 넓은 자간만 덧쓴다 */
.ranking__title {
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.ranking__flame { font-size: 0.9em; }

.ranking__note {
  margin: 0 0 0.875rem;
  font-size: 0.78rem;
  color: var(--ink-soft);
}

/* 랭킹 기준 툴팁 (제목 옆 ⓘ) */
.rank-info { position: relative; display: inline-block; }
/* ⓘ 는 글자 하나라 그대로 두면 11×13px 이라 손가락으로 못 누른다.
   보이는 크기는 그대로 두고 **누르는 영역만** 26×26 으로 넓힌다.
   세로 음수 여백은 이 버튼 때문에 제목 줄 높이가 늘어나지 않게 하는 것. */
.rank-info__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.625rem;
  height: 1.625rem;
  margin: -0.4375rem 0;
  border: 0;
  background: none;
  padding: 0;
  font-family: inherit;
  font-size: 0.8rem;
  line-height: 1;
  color: var(--ink-soft);
  cursor: help;
  transition: color 0.15s ease;
}
.rank-info__btn:hover { color: var(--accent); }
.rank-info__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.rank-tip {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  width: 13.625rem;
  padding: 0.625rem 0.75rem;
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: 0 2px 10px rgba(74, 66, 52, 0.09);
  font-size: 0.73rem;
  font-weight: 400;
  line-height: 1.65;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-soft);
  text-align: left;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.14s ease, visibility 0.14s ease;
}
/* 위쪽을 가리키는 작은 삼각형 */
.rank-tip::before {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 50%;
  margin-left: -0.3125rem;
  border: 5px solid transparent;
  border-bottom-color: var(--line);
}
.rank-info:hover .rank-tip,
.rank-info:focus-within .rank-tip,
.rank-info.is-open .rank-tip { visibility: visible; opacity: 1; }

.ranking__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.rank-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6875rem 0;
  border-top: 1px solid var(--line-soft);
  cursor: pointer;
}

.rank-item:hover .rank-item__name { color: var(--accent); }
.rank-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.rank-item:first-child { border-top: none; }

.rank-item__num {
  flex: 0 0 auto;
  min-width: 1rem;
  font-size: 0.9rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
  text-align: center;
}

.rank-item:first-child .rank-item__num { color: var(--accent); }

.rank-item__mini { width: 1.75rem; height: 1.75rem; flex: 0 0 1.75rem; }

.rank-item__name {
  font-size: 0.92rem;
  color: var(--ink);
}

/* (미래) 점수/변동 표시 */
/* 순위 변동 ▲▼ — 이 자리에 점수를 찍던 때보다 한 단계 작다.
   꽉 찬 삼각형은 같은 크기의 숫자보다 무겁게 보인다. 색은 위아래 모두 --ink-soft 다
   (오름/내림에 색을 나눠 주면 이 사이트에 "주의" 말고 다른 뜻의 색이 하나 더 생긴다, §0-6) */
.rank-item__trend {
  margin-left: auto;
  font-size: 0.68rem;
  color: var(--ink-soft);
}

.ranking__criteria {
  margin: 1rem 0 0;
  padding-top: 0.8125rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.73rem;
  color: var(--ink-soft);
  text-align: center;
}

/* ===== 나의 치즈함 진행률 (좌측 상단) ===== */
/* 카드·여백은 .wcard 가 준다 (§ 사이드 위젯의 뼈대) */
.mystash { margin-bottom: 1.25rem; }
/* 문구 앞에 붙는 라인 아이콘 (data-t-icon / stashIcon / galleryIcon) */
.ui-icon { display: block; flex: 0 0 auto; }
/* 글줄 안에 섞여 들어갈 때 (예: "갤러리 공개됨") */
.ui-icon--inline {
  display: inline-block;
  vertical-align: -2px;
  margin-right: 0.25rem;
}

.mystash__title {
  display: flex;
  align-items: center;
}
.mystash__link {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  color: inherit;
  text-decoration: none;
  transition: color 0.15s ease;
}
.mystash__link:hover { color: var(--ink); }
.mystash__count {
  font-size: 0.9rem;
  color: var(--ink-soft);
}
/* 먹어본 치즈 칩 — 갤러리 필터와 같은 부품(.cchip)을 좁은 사이드바에 맞춰 쓴다 */
.mystash__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3125rem;
  margin-top: 0.6875rem;
}
.mystash__chips .cchip { font-size: 0.73rem; padding: 0.1875rem 0.5rem; }
/* 칩에 붙는 건수 — 치즈함(기록 수)과 갤러리 필터(글 수)가 같은 부품을 쓴다 */
.cchip__n {
  margin-left: 0.3125rem;
  font-size: 0.9em;
  color: var(--accent);
}
/* ⚠️ 켜진 칩 안에서는 색을 물려받아야 한다. 켜진 칩은 배경이 accent 인데(.cchip.is-on ·
   .gcat[aria-pressed="true"]) 숫자까지 accent 면 **배경에 묻혀 안 보인다.**
   갤러리 필터의 [전체]는 기본이 켜진 상태라 첫 화면부터 숫자가 사라진다. */
.cchip.is-on .cchip__n,
.gcat[aria-pressed="true"] .cchip__n {
  color: inherit;
  opacity: 0.75;
}
.cchip--more { color: var(--ink-soft); }
/* 카드의 '먹어봤어요' 도장 — 그림 우측 하단 모서리에 **걸쳐서** 찍힌다.
   그림은 js/app.js 의 eatenSeal() 이 그린다(모양·색 고르는 법은 거기 주석).

   ⚠️ 카드 위쪽 두 모서리는 이미 UI 자리다(왼쪽 갤러리 링크·오른쪽 조회수).
      도장이 위로 가면 "카드에 붙은 부품"으로 읽히고, 제일 좁은 카드(10.75rem)에서는
      조회수 배지와 몇 px 겹친다. 인장은 원래 끝나는 자리에 찍힌다.
   ⚠️ 아래로 나오는 폭은 **그림 아래 여백(1rem) 안**에 있어야 한다. 그 바로 밑이
      치즈 이름이고, `Cottage cheese`·`그라나 파다노` 같은 긴 이름은 폭을 꽉 채운다.
      지름 1.5rem 을 모서리에 반씩 걸치면 12px 만 내려와 4px 남는다.
      더 키우고 싶으면 아래로 내리지 말고 안쪽으로 밀어 넣을 것. */
.card__visual {
  position: relative;
  /* 그림 크기를 여기 옮겨 적지 않으려고 감싸서 그대로 따라간다
     (치수는 .card__illust 한 곳 — prerender 가 같은 크기의 빈 상자를 찍는다) */
  display: block;
  width: max-content;
  /* 그림이 갖고 있던 아래 여백을 그대로 물려받는다 → 카드 높이가 안 변한다 */
  margin: 0 auto 1rem;
}
.card__visual > .card__illust { margin: 0; }

.card__eaten {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 1.5rem;
  height: 1.5rem;
  transform: translate(50%, 50%);
  pointer-events: none; /* 카드 전체가 누르는 자리다 */
}
.card__eaten svg { display: block; width: 100%; height: 100%; }

/* ⚠️ **도장 색은 반드시 여기서 준다.** SVG 표현 속성(fill="var(--seal)")에 CSS 변수를
   쓰면 브라우저에 따라 안 먹어서, --seal 을 바꿔도 그림이 그대로인 일이 있었다.
   채움이 늘 카드색인 이유: 대표 사진 위에서는 사진이 비치면 안 읽히고,
   일러스트(투명 SVG) 위에서는 배경이 비쳐 떠 보인다. */
.card__eaten .seal__ring { fill: var(--card); stroke: var(--seal); }
.card__eaten .seal__mark { fill: none; stroke: var(--seal); }
/* 꽉 찬 원(SEAL_SHAPE="solid") — 색을 뒤집어 ✓ 를 파낸다 */
.card__eaten--solid .seal__ring { fill: var(--seal); stroke: none; }
.card__eaten--solid .seal__mark { stroke: var(--card); }

/* ===== 치즈 용어 사전 (좌측) ===== */
/* 카드·여백은 .wcard 가 준다 (§ 사이드 위젯의 뼈대) */
.glossary { margin-top: 1.25rem; }
/* 아코디언 줄이 위아래 여백을 스스로 갖는다 — 본문 기본값을 그만큼 줄인다 */
.glossary__list { margin: 0; padding-top: 0.375rem; padding-bottom: 0.5rem; }

.term { border-top: 1px solid var(--line-soft); }
.term:first-child { border-top: none; }

.term__word {
  list-style: none;
  cursor: pointer;
  padding: 0.5625rem 0;
  font-size: 0.86rem;
  color: var(--ink);
  position: relative;
  padding-right: 1.125rem;
}
.term__word::-webkit-details-marker { display: none; }
.term__word::after {
  content: "+";
  position: absolute;
  right: 2px;
  top: 0.5625rem;
  color: var(--ink-soft);
  transition: transform 0.15s ease;
}
.term[open] .term__word::after { content: "–"; }
.term__word:hover { color: var(--accent); }

.term__desc {
  margin: 0 0 0.6875rem;
  font-size: 0.8rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

/* ===== 커뮤니티 "치즈타임 자랑하기" ===== */
/* 카드·여백은 .wcard 가 준다 (§ 사이드 위젯의 뼈대 — 그 모양이 여기서 나왔다) */
.brag { margin-top: 1.25rem; }
/* 우측 사이드바에 단독으로 있을 땐 상단 여백 제거 */
.sidebar--right .brag { margin-top: 0; }

/* 제목 한 줄 = 갤러리로 가는 링크. 화살표는 제목 안에 붙어 함께 접힌다.
   ⚠️ 전에는 제목과 "갤러리 →" 두 덩이를 space-between 으로 벌려 놓았는데, 좁은 위젯 칸
      (--rail-width 200px)에서는 한 줄에 못 들어가 제목이 글자 단위로 끊기거나 "갤러리 →"
      가 아랫줄로 내려갔다. 목적지를 글자로 또 적지 않으니 그 문제 자체가 없어졌다. */
/* 여백과 아래 선은 .wcard__head 가 준다 — 여기는 "링크"라서 다른 것만 */
.brag__head {
  text-decoration: none;
  color: inherit;
}
.brag__head:hover .brag__title { color: var(--ink); }

.brag__title { transition: color 0.15s ease; }

.brag__list { list-style: none; margin: 0; padding: 0; }

.brag__item { border-top: 1px solid var(--line-soft); }
.brag__item:first-child { border-top: none; }

.brag__link {
  display: flex;
  flex-direction: column;
  gap: 0.5625rem;
  padding: 0.8125rem 1.125rem 0.9375rem;
  text-decoration: none;
  color: inherit;
  transition: background 0.16s ease;
}
.brag__link:hover { background: #fcf8f0; }

.brag__text { min-width: 0; }
.brag__ptitle {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 0.88rem;
  line-height: 1.4;
  color: var(--ink);
}
.brag__meta {
  display: block;
  margin-top: 0.1875rem;
  font-size: 0.72rem;
  color: var(--ink-soft);
}

/* 사진 없는 글 — 빈 사진칸 대신 본문 2줄 */
.brag__body {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 0.82rem;
  line-height: 1.6;
  color: var(--ink-soft);
}

/* 큰 썸네일 (제목 아래) */
.brag__thumb {
  width: 100%;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--paper);
  display: flex;
  align-items: center;
  justify-content: center;
}
.brag__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.brag__empty {
  padding: 1.125rem;
  text-align: center;
  font-size: 0.8rem;
  color: var(--ink-soft);
}

/* ===== 푸터 ===== */
.site-footer {
  border-top: 1px solid var(--line);
  text-align: center;
  padding: 1.375rem;
  color: var(--ink-soft);
  font-size: 0.82rem;
  letter-spacing: 0.02em;
}
.site-footer p { margin: 0; }
.site-footer p + p { margin-top: 0.5625rem; }

/* ===== 상세 모달 ===== */
.modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}
.modal[hidden] { display: none; }

.modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(34, 30, 22, 0.46);
}

.modal__panel {
  position: relative;
  background: var(--card);
  border: 1px solid var(--line);
  width: 100%;
  max-width: 32.5rem;
  max-height: 88vh;
  overflow-y: auto;
  padding: 2.125rem 2.125rem 1.875rem;
  animation: modalIn 0.16s ease;
}

@keyframes modalIn {
  from { opacity: 0; transform: translateY(0.375rem); }
  to   { opacity: 1; transform: translateY(0); }
}

/* 모달 상단 바: [← 직전치즈] | [×] */
.modal__bar {
  position: absolute;
  top: 0.75rem;
  right: 0.875rem;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0.625rem;
}
.modal__back[hidden],
.modal__bar-sep[hidden] { display: none; }

.modal__back {
  display: inline-flex;
  align-items: center;
  gap: 0.3125rem;
  border: none;
  background: none;
  cursor: pointer;
  padding: 0.1875rem 0.25rem;
  font-family: inherit;
  font-size: 0.82rem;
  color: var(--ink-soft);
  transition: color 0.15s ease;
}
.modal__back:hover { color: var(--accent); }
.modal__back-name { font-weight: 600; }

.modal__bar-sep {
  width: 1px;
  height: 0.9375rem;
  background: var(--line);
}

.modal__close {
  border: none;
  background: none;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--ink-soft);
  cursor: pointer;
  padding: 0 0.25rem;
}
.modal__close:hover { color: var(--ink); }

/* 모달 내부 */
.m-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-bottom: 1.125rem;
  border-bottom: 1px solid var(--line);
}
.m-head .card__illust { width: 4rem; height: 4rem; margin: 0; flex: 0 0 4rem; }

.m-name-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5625rem;
  margin-bottom: 0.1875rem;
}
.m-name {
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0;
}
.m-meta { margin: 0; font-size: 0.82rem; color: var(--ink-soft); }

/* 이름 발음 듣기 */
.m-pronounce {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4375rem;
  margin-top: 0.625rem;
}
.m-pronounce__label {
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}
.m-pron-btns { display: inline-flex; gap: 0.3125rem; }
.m-pron-btn {
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--paper);
  cursor: pointer;
  padding: 2px 0.4375rem;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--ink);
  font-family: inherit;
  transition: border-color 0.14s ease, background 0.14s ease;
}
.m-pron-btn:hover { border-color: var(--accent); background: #fff; }
.m-pron-btn:active { background: var(--line-soft); }

/* 사진 영역 (모달 상단): 사진 + 세로 '사진 더 보기' 버튼 */
.m-gallery-row {
  display: flex;
  align-items: stretch;
  gap: 0.5rem;
  margin-top: 1.125rem;
}
.m-gallery-row .m-photos {
  flex: 1;
  min-width: 0;
  margin-top: 0;
}
.m-morephotos[hidden] { display: none; }
.m-morephotos {
  flex: 0 0 3.75rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--paper);
  color: var(--ink);
  text-decoration: none;
  transition: background 0.16s ease, border-color 0.16s ease, color 0.16s ease;
}
.m-morephotos:hover { background: #fff; border-color: var(--accent); color: var(--accent); }
.m-morephotos__t { font-size: 0.76rem; line-height: 1.35; text-align: center; }
.m-morephotos__a { font-size: 0.95rem; }

.m-photos {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
  margin-top: 1.125rem;
}
.m-photo {
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--paper);
}
/* 갤러리 글에서 가져온 사진 — 모서리의 갤러리 아이콘 하나로 출처를 밝힌다.
   설명 문구를 붙이지 않는 대신, 사이트가 이미 쓰는 그림을 그대로 쓴다. */
.m-photo--post {
  position: relative;
  display: block;
  transition: border-color 0.15s ease;
}
.m-photo--post:hover,
.m-photo--post:focus-visible { border-color: var(--accent); }
.m-photo__badge {
  position: absolute;
  top: 0.3125rem;
  right: 0.3125rem;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.25rem;
  height: 1.25rem;
  background: rgba(250, 246, 237, 0.92);
  border: 1px solid var(--line);
  border-radius: 2px;
  color: var(--ink-soft);
}
.m-photo--post:hover .m-photo__badge { color: var(--accent); border-color: var(--accent); }
.m-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.m-photo--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  border-style: dashed;
  color: var(--ink-soft);
  font-size: 0.8rem;
  letter-spacing: 0.02em;
}

.m-level {
  display: inline-block;
  margin: 0;
  padding: 0.1875rem 0.625rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  font-size: 0.75rem;
  letter-spacing: 0.02em;
  color: var(--accent);
}

.m-dots { display: inline-flex; gap: 0.3125rem; }
.m-dot {
  width: 0.5625rem;
  height: 0.5625rem;
  border-radius: 50%;
  border: 1px solid var(--accent);
}
.m-dot.is-on { background: var(--accent); }

.m-summary {
  margin: 1rem 0 0;
  font-size: 0.98rem;
  color: var(--ink);
  line-height: 1.65;
}

.m-sections { margin-top: 0.375rem; }

.m-block {
  padding: 0.9375rem 0;
  border-top: 1px solid var(--line-soft);
}
.m-block__label {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.375rem;
}
.m-block__body {
  font-size: 0.92rem;
  color: var(--ink);
  line-height: 1.6;
}

/* 페어링 */
.m-pairs { display: flex; flex-direction: column; gap: 0.4375rem; }
.m-pair { display: flex; gap: 0.625rem; font-size: 0.9rem; }
.m-pair span { flex: 0 0 3.875rem; color: var(--ink-soft); }
.m-pair em { font-style: normal; color: var(--ink); }

/* 제휴 링크 — 본문 글자 그대로 두고 점선 밑줄로만 표시 (SHOP 이 켜졌을 때만 생김) */
.shoplink {
  color: inherit;
  text-decoration: underline dotted var(--line);
  text-underline-offset: 0.1875rem;
  transition: color 0.15s ease, text-decoration-color 0.15s ease;
}
.shoplink:hover { color: var(--accent); text-decoration-color: var(--accent); }

/* 대가성 표기 (제휴 링크가 있을 때만) */
.m-shopnote {
  margin: 1.125rem 0 0;
  padding-top: 0.75rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.72rem;
  line-height: 1.6;
  color: var(--ink-soft);
}

.tags--left { justify-content: flex-start; }
/* 모달·치즈 상세의 머리 바로 아래 오는 태그 줄 — 구분선에 붙지 않게 띄운다.
   ⚠️ 정적 HTML(prerender)과 JS(modalBody)가 **같은 마크업**이라 이 여백도 양쪽에 똑같이 걸린다.
      한쪽만 바뀌면 JS 가 뜰 때 그만큼 페이지가 튄다. */
.m-head + .tags--left { margin-top: 0.875rem; }

/* ===== 모달: 나의 치즈함 (이름 바로 아래) ===== */
.m-collection {
  padding: 1rem 0 1.125rem;
  border-bottom: 1px solid var(--line);
}
.m-collection__head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}
/* 제목 **바로 옆** 바로가기 — "이 치즈 N건 기록함 →".
   치즈함의 그 치즈 칸(#stash-…)으로 간다.
   ⚠️ 오른쪽 끝에 두지 않는다. 제목과 떨어지면 무엇의 개수인지 읽히지 않는다.
   ⚠️ display 를 주므로 [hidden] 규칙을 함께 둘 것 — 없으면 el.hidden 이 안 먹는다
      (수정 모드에서 이 링크를 감춘다). */
.m-collection__title {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--accent);
}

.m-col-add[hidden] { display: none; }
.m-col-add {
  width: 100%;
  padding: 0.6875rem;
  border: 1px dashed var(--line);
  border-radius: 2px;
  background: var(--paper);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.9rem;
  cursor: pointer;
  transition: border-color 0.16s ease, background 0.16s ease, color 0.16s ease;
}
.m-col-add:hover { border-color: var(--accent); color: var(--accent); background: #fff; }
/* 기록이 이미 있을 때의 "기록 추가"는 큰 점선 버튼일 이유가 없다 (내용만큼만).
   ⚠️ .m-col-add 규칙보다 **뒤에** 두어야 폭이 덮인다 — 같은 특이도라 순서가 이긴다. */
.m-col-foot .m-col-add--more {
  width: auto;
  margin: 0;
  padding: 0.375rem 0.875rem;
  font-size: 0.82rem;
}

/* 저장된 기록 — 모달은 좁으므로 썸네일 + 한 줄 메타로 컴팩트하게 */
.m-col-record[hidden] { display: none; }
/* ===== 기록 필름스트립 (모달·치즈 상세) =====
   치즈함 페이지의 선반과 같은 부품, 다른 밀도 — 여기 타일은 **사진만** 이다.
   날짜·제목까지 달면 한 줄이 206px 이 되어 모달이 90px 길어진다(실측). */
/* ⚠️ display 를 주는 요소는 [hidden] 규칙을 **같이** 둔다. 안 그러면 이 규칙이 브라우저
   기본 display:none 을 이겨서, 기록을 쓰는 중에도 스트립이 남고 **고른 칸의 진한 테두리가
   그대로 보인다**(2026-07-30에 실제로 그랬다. .strec__entry 도 같은 함정이었다). */
.mstrip[hidden] { display: none; }
.mstrip {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.5rem;
  margin: 0.5rem 0 0.625rem;
}
.mstrip__tile {
  width: 2.75rem;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  text-decoration: none;
}
.mstrip__thumb {
  position: relative; /* "+N" 덮개의 기준 */
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 1 / 1; /* 사진은 어디서든 1:1 (설계원칙 §0-7) */
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink-soft);
  transition: border-color 0.15s ease, color 0.15s ease;
}
.mstrip__thumb img { width: 100%; height: 100%; margin: 0; border: 0; object-fit: cover; display: block; }
.mstrip__thumb svg.card__illust { width: 68%; height: auto; margin: 0; }
.mstrip__tile:hover .mstrip__thumb { border-color: var(--accent); color: var(--accent); }
.mstrip__tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.mstrip__tile[aria-expanded="true"] .mstrip__thumb { border-color: var(--accent); border-width: 2px; }
/* 더 있음 — 사진 위 **미색** 덮개. 검정 딤은 이 사이트 톤이 아니다(§0-6) */
.mstrip__more {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(243, 237, 225, 0.82);
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--ink);
}
/* 추가 — 아직 안 놓은 칸이라 점선 (선반의 [+] 와 같은 결) */
.mstrip__tile--add .mstrip__thumb {
  border-style: dashed;
  font-size: 1.15rem;
  line-height: 1;
}

.m-col-record {
  font-size: 0.9rem;
}
/* 날짜와 [수정]을 한 줄에 — 오른쪽 끝에 두면 본문과 멀어 무엇을 고치는지 안 이어지고,
   아래에 따로 한 줄을 주면 섹션이 39px 길어진다(모달은 이미 스크롤이 길다) */
.m-col-rdate { display: flex; align-items: baseline; gap: 0.75rem; }
.m-col-lines { min-width: 0; flex: 1; }
.m-col-rtitle {
  margin: 0 0 0.1875rem;
  font-size: 0.98rem;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.4;
}
/* 모달의 기록은 **요약 한 줄**이라 썸네일도 작게. (사진은 1:1 — 설계원칙 §0-7)
   기록을 크게 보는 건 치즈함 페이지가 한다. */

/* 날짜 · 공개됨 · 댓글수 를 한 줄에 (가운뎃점 구분) */
/* 섹션 하단 우측 — 공개 여부·댓글 수 (부수 정보라 작고 옅게) */
.m-col-foot {
  display: flex;
  justify-content: flex-end;
  align-items: baseline;
  margin-top: 0.625rem;
  font-size: 0.72rem;
  color: var(--ink-soft);
  opacity: 0.75;
}
.m-col-foot[hidden] { display: none; }
.m-col-form .m-col-foot { opacity: 1; font-size: 0.8rem; }

/* 수정·삭제는 제목 줄 오른쪽에, 테두리 없는 작은 글자로 (내용보다 튀지 않게) */
.m-col-actions { display: flex; align-items: baseline; gap: 0.75rem; }
.m-col-actions[hidden] { display: none; }
/* 단, 폼을 **마무리하는** 저장은 다르다 — 글쓰기·댓글 폼과 같은 채워진 버튼을 쓴다.
   셋 다 같은 .m-col-* 입력 부품을 쓰는데 여기만 흐린 글자여서 잘 안 보였다.
   취소와 붙어 있어 잘못 누르기도 쉬웠으므로 간격도 16px 로 벌린다(.cwrite__btns 와 같은 값). */
.m-col-form .m-col-actions--edit { align-items: center; gap: 1rem; }
/* ⚠️ `text-decoration: none` 을 빼지 말 것. 이 부품은 <button> 으로도 <a> 로도 쓰이는데
   (치즈함 기록 줄이 [자랑하기]=링크 · [수정]·[삭제]=버튼으로 셋이 나란하다),
   빼면 링크에만 브라우저 기본 밑줄이 붙어 **같은 클래스인데 하나만** 밑줄 그어진다. */
.linkbtn {
  border: 0;
  background: none;
  padding: 0;
  text-decoration: none;
  font-family: inherit;
  font-size: 0.76rem;
  color: var(--ink-soft);
  opacity: 0.75;
  cursor: pointer;
  transition: color 0.15s ease, opacity 0.15s ease;
}
.linkbtn:hover { color: var(--accent); opacity: 1; }
.linkbtn--del:hover { color: #b3453b; }
.linkbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 폼 — 저장된 기록과 같은 배치(왼쪽 사진 / 오른쪽 글 / 하단 우측 공개) */
.m-col-form[hidden] { display: none; }
.m-col-form { display: block; }
.m-col-editrow {
  display: flex;
  gap: 0.8125rem;
  align-items: flex-start;
}
.m-col-lines .m-col-field + .m-col-field { margin-top: 0.625rem; }
/* 메모/내용칸의 아랫선을 **사진칸의 아랫선과 같은 줄**에 맞춘다.
   전에는 메모칸이 더 아래로 내려와 폼이 기울어 보였다.
   글 칸을 늘리고(stretch) 마지막 칸(메모)이 남은 높이를 먹는 방식이다.
   ⚠️ textarea 는 `rows="1"` 이어야 한다 — rows 가 크면 글 칸의 자연 높이가
      사진칸보다 커져서 **그쪽이 줄 높이를 정해버리고** 사진 아래에 빈 자리가 남는다.
   ⚠️ 사진칸 옆에 이 배치를 쓰는 폼은 **둘 다** 여기에 적는다 —
      치즈함 편집 폼(.m-col-form)과 갤러리 글쓰기 폼(.cwrite__form).
      한때 글쓰기 폼은 "칸이 더 많아 필요 없다" 고 적어두고 빼놨는데,
      실제로는 rows="4" 짜리 내용칸이 사진보다 아래로 내려가 있었다. */
.m-col-form .m-col-editrow,
.cwrite__form .m-col-editrow { align-items: stretch; }
.m-col-form .m-col-lines,
.cwrite__form .m-col-lines { display: flex; flex-direction: column; }
.m-col-form .m-col-lines .m-col-field:last-child,
.cwrite__form .m-col-lines .m-col-field:last-child { flex: 1 1 auto; }
/* ⚠️ min-height 를 주지 말 것. 한 줄(기본 높이)보다 크게 잡으면 그 값이 줄 높이를
   밀어 올려 다시 어긋난다 — 어차피 남은 높이를 먹으므로 바닥이 될 일이 없다. */
.m-col-form .m-col-lines .m-col-field:last-child textarea,
.cwrite__form .m-col-lines .m-col-field:last-child textarea { flex: 1 1 auto; }
.m-col-field {
  display: flex;
  flex-direction: column;
  gap: 0.3125rem;
  font-size: 0.76rem;
  color: var(--ink-soft);
}

/* 사진 고르기 — 미리보기 네모를 누르면 파일 선택 */
.m-col-photocol {
  flex: 0 0 9.25rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.375rem;
  position: relative; /* 지우기 버튼을 사진 위에 얹는 기준 */
}
/* 사진 고르기 — **상자 자체가 버튼이다.**
   전에는 빈 상자 아래에 "사진 올리기" 가 따로 놓여 있어서, 상자를 누르는 것인지
   그 글자를 누르는 것인지 알 수 없었다(상자는 완전히 비어 있었다).
   이제 **빈 상자일 때는 안내를 상자 안 가운데**에 둔다 — 상자가 곧 버튼이다.
   사진이 들어오면 안내는 상자 밖 아래로 내려간다(사진을 가리지 않게).
   글자는 js 가 상태에 맞춰 갈아끼우므로(사진 올리기 ↔ 사진 바꾸기)
   여기서는 자리만 잡는다. */
.m-col-photopick {
  position: relative;
  display: block;
  width: 9.25rem;
  cursor: pointer;
}
/* 사진 지우기 — 사진 **우측 상단**의 × 상자.
   ⚠️ label 밖에 있어야 한다. 안에 넣으면 지우려고 눌렀는데 파일 선택창이 열린다.
   "바꾸기" 는 상자 **아래** 글자, "지우기" 는 상자 **위** 모서리 — 자리로 역할이 갈린다.
   hover 로 감추지 않는다. 터치 화면에서는 나타날 방법이 없다. */
.m-col-photodel {
  position: absolute;
  top: 0.3125rem;
  right: 0.3125rem;
  width: 1.75rem;
  height: 1.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: rgba(250, 246, 237, 0.94);
  color: #b3453b; /* 이 사이트의 "지우기" 빨강 — .linkbtn--del 등과 같은 값 */
  font-family: inherit;
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.m-col-photodel:hover { background: #b3453b; border-color: #b3453b; color: #fff; }
.m-col-photodel:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.m-col-photodel[hidden] { display: none; }
.m-col-photohint {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.625rem;
  font-size: 0.78rem;
  text-align: center;
  color: var(--ink-soft);
  pointer-events: none; /* 클릭은 label 이 받는다 */
  transition: color 0.15s ease, opacity 0.15s ease;
}
/* 사진이 들어오면 안내가 상자 **밖 아래**로 내려간다 — 사진을 조금도 가리지 않는다.
   ⚠️ 늘 보인다. hover 로 감추지 않는다:
      ① 터치 화면에는 hover 가 없어서 나타날 방법이 없고
      ② 수정 중에는 "여기를 눌러 바꾼다" 가 계속 보이는 편이 낫다.
   글자도 label 안이라 눌러도 파일 선택창이 열린다. */
.m-col-preview:not(:empty) + .m-col-photohint {
  position: static;
  padding: 0.375rem 0 0;
}
.m-col-photopick:hover .m-col-photohint,
.m-col-photopick:focus-within .m-col-photohint { color: var(--accent); }
.m-col-photopick:hover .m-col-preview,
.m-col-photopick:focus-within .m-col-preview { border-color: var(--accent); }
.m-col-field input[type="text"],
.m-col-field textarea {
  font-family: inherit;
  font-size: 0.9rem;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 0.5rem 0.625rem;
}
.m-col-field textarea { resize: vertical; }
.m-col-field input:focus,
.m-col-field textarea:focus { outline: none; border-color: var(--accent); }

/* 필수 표시(*) + 미입력 안내 */
.m-col-req { font-style: normal; color: #b3453b; }
.m-col-err { font-size: 0.76rem; color: #b3453b; }
.m-col-err[hidden] { display: none; }

.m-col-preview {
  /* 기록 썸네일(.mstrip__thumb)과 같은 1:1 (설계원칙 §0-7) */
  display: block;
  width: 9.25rem;
  aspect-ratio: 1 / 1;
  border: 1px dashed var(--line);
  background: var(--paper);
  overflow: hidden;
  transition: border-color 0.15s ease;
}
.m-col-preview:not(:empty) { border-style: solid; }
.m-col-preview img { display: block; width: 100%; height: 100%; object-fit: cover; }


/* 공용 버튼 (댓글 쓰기 등) */
.btn {
  padding: 0.5rem 1rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--paper);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  transition: border-color 0.16s ease, background 0.16s ease, color 0.16s ease;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.btn--primary:hover { background: #6a4e28; color: #fff; }
/* 못 누르는 상태 — 제목이 비었을 때(치즈함 기록)와 저장하는 중일 때(글쓰기·댓글)에 쓴다.
   전에는 disabled 로 만들어놓고 생김새가 그대로라 "왜 안 눌리지"가 됐다. */
.btn:disabled, .btn:disabled:hover {
  opacity: 0.45;
  cursor: not-allowed;
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.btn:not(.btn--primary):disabled, .btn:not(.btn--primary):disabled:hover {
  background: var(--paper);
  border-color: var(--line);
  color: var(--ink);
}


/* 보관법 안의 숙성기간 (박스 없이 텍스트로 분리감) */
.m-aging {
  display: flex;
  align-items: baseline;
  gap: 0.5625rem;
  margin-top: 0.6875rem;
}
.m-aging__label {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  white-space: nowrap;
}
.m-aging__value {
  font-size: 0.84rem;
  font-style: italic;
  color: var(--ink-soft);
}

/* 라벨 없는 블록(맛/질감)의 첫 행은 위 여백 제거 */
.m-block > :first-child { margin-top: 0; }

/* 맛 섹션 안 인라인 ([태그] + 설명) */
.m-inline {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.6875rem;
}
.m-inline__text {
  font-size: 0.9rem;
  color: var(--ink);
  line-height: 1.55;
}
.m-inline--mid { align-items: center; }

/* 맛 섹션 안의 '비슷한 치즈' (한 줄 인라인) */
.m-similar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.625rem;
}
.m-similar__label {
  font-size: 0.74rem;
  color: var(--ink-soft);
  white-space: nowrap;
}
.m-similar .tags { margin: 0; }

/* 맛 섹션 안의 '뭐가 다른가' — 바로 위 '비슷한 치즈' 칩 줄과 **한 벌이다.**
   칩이 "무엇인지" 를 말하고 이 문단이 "왜 그것들인지" 를 말한다.
   ⚠️ 별도 .m-block 으로 빼지 말 것. .m-block 에 border-top 이 있어서 칩과 이 문단 사이에
      선이 그어지고, 그 선 하나가 둘을 남남으로 보이게 한다 — 2026-07-30 에 그렇게 만들었다가
      되돌렸다. 갤러리에서 글과 댓글을 한 장의 종이로 합친 것과 같은 근거다(§4 커뮤니티).
   ⚠️ 라벨은 .m-similar__label 과 **같은 값**이어야 한다. 둘이 한 벌이라는 것을 그 닮음이 말한다.
      한쪽만 크기·색을 바꾸면 다시 남남으로 읽힌다. */
.m-diff {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.25rem 0.5rem;
  /* .m-similar 의 0.625rem 보다 좁게 — 칩 줄에 붙어 보여야 한다 */
  margin-top: 0.375rem;
}
.m-diff__label {
  font-size: 0.74rem;
  color: var(--ink-soft);
  white-space: nowrap;
}
/* 문단이 라벨 아래 제 줄에서 시작하게 한다 — 150자쯤 되는 산문이라
   라벨 옆에 붙이면 첫 줄만 짧게 들여쓰인 것처럼 어긋나 보인다 */
.m-diff__text {
  flex: 1 1 100%;
  font-size: 0.9rem;
  color: var(--ink);
  line-height: 1.55;
}

/* ===== 자랑 갤러리 페이지 (community.html) =====
   갤러리/카드와 같은 규칙: 미색 면 + 1px 선 + 각진 모서리 */

/* 히어로의 치즈 아이콘이 이 페이지에선 <a> (도감으로 가는 링크) */
a.hero__home { text-decoration: none; }

/* 상단 바: 돌아가기 + 글 개수 */
.cbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.875rem;
}
.cbar__count {
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}

/* 목록 상단 "글쓰기" — 얇은 선 버튼, 사이트 톤 그대로 */
.cwrite-btn {
  margin-left: auto;
  padding: 0.3125rem 0.8125rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--card);
  font-size: 0.76rem;
  color: var(--ink);
  text-decoration: none;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.cwrite-btn:hover { border-color: var(--accent); color: var(--accent); }
.cwrite-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 글쓰기 폼 — 치즈함 편집 폼(.m-col-*)과 같은 부품을 쓴다 */
.cwrite__row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.875rem;
  margin-top: 1rem;
}
.cwrite__row .m-col-field { flex: 1 1 12.5rem; }
/* 치즈 고르기(.stpick)가 이 줄을 통째로 쓴다 — 검색칸 위, 칩 줄 아래로 이어져야 한다.
   폼 맨 아래 칸이라 아래 여백은 필요 없다(버튼 줄이 이미 선을 긋는다) */
.cwrite__row .stpick { flex: 1 1 100%; margin-bottom: 0; }

/* 작성자 줄 — 버튼 줄 왼쪽 끝. 평소엔 이름 글자이고 누르면 입력칸이 된다.
   ⚠️ 이름은 <button> 이지만 **글자처럼** 보인다. 이 줄에서 버튼처럼 생긴 것은 오른쪽
      [올리기] 하나여야 한다 — 왼쪽에 또 하나 있으면 어느 쪽이 저장인지 흐려진다.
      누를 수 있다는 것은 밑줄이 밝힌다(.linkbtn·번역 버튼과 같은 약속). */
.cwrite__author {
  margin: 0 auto 0 0; /* 오른쪽 버튼들과 반대편으로 밀어둔다 */
  display: flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.8rem;
  color: var(--ink-soft);
}
.cwrite__author-name {
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 0.8rem;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.cwrite__author-name:hover { color: var(--accent); }
.cwrite__author-name[hidden] { display: none; }
.cwrite__nick {
  font-family: inherit;
  font-size: 0.8rem;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 0.1875rem 0.375rem;
  max-width: 9rem;
}
.cwrite__nick:focus { outline: none; border-color: var(--accent); }
.cwrite__nick[hidden] { display: none; }
.cwrite__btns {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1rem;
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
}
.cwrite .m-col-lines { flex: 1 1 auto; min-width: 0; }

/* ===== 좁은 화면에서는 글 쓰는 칸을 시원하게 편다 (2026-07-30) =====
   넓은 화면은 [사진 | 제목·내용] 두 칸이고, 내용칸이 **사진 높이에 맞춰 늘어난다**
   (그래서 위쪽 규칙이 rows="1" 을 요구하고 min-height 를 금지한다).
   좁은 화면에서 그대로 두면 두 가지가 겹쳐 나빠진다 —
     ① 사진이 폭의 절반 가까이를 먹어 제목·내용이 손바닥만 해진다
     ② 세로로 쌓는 순간 **늘릴 대상(사진 높이)이 사라져** 내용칸이 한 줄로 쪼그라든다
   그래서 여기서는 제목·내용이 각각 가로 한 줄을 통째로 쓰고, 내용칸은 min-height 로
   직사각형을 갖는다. **min-height 금지는 넓은 화면 규칙이지 여기 규칙이 아니다.**
   ⚠️ 세 화면이 같은 부품을 쓴다 — 치즈함(기록 추가·수정)·갤러리 글쓰기·치즈 모달.
      `.cwrite` 만 적어두면 나머지 둘은 좁은 화면에서 계속 두 칸으로 남는다(그랬다). */
@media (max-width: 560px) {
  .m-col-form .m-col-editrow,
  .cwrite__form .m-col-editrow {
    flex-direction: column;
    align-items: stretch;
  }
  /* 사진칸은 제 크기만 차지하고 왼쪽에 선다 (늘어나면 폰에서 화면을 다 먹는다) */
  .m-col-form .m-col-photocol,
  .cwrite__form .m-col-photocol { flex-basis: auto; align-self: flex-start; }
  .m-col-form .m-col-lines .m-col-field + .m-col-field,
  .cwrite__form .m-col-lines .m-col-field + .m-col-field { margin-top: 0.75rem; }
  .m-col-form .m-col-lines .m-col-field:last-child textarea,
  .cwrite__form .m-col-lines .m-col-field:last-child textarea { min-height: 7.5rem; }
  /* 기록 수정 폼은 기록 썸네일(6rem)에 맞춰 좁혀 두었는데, 세로로 쌓이면 그 이유가 없어진다 */
  .strec .m-col-editrow { gap: 0.8125rem; }
}
/* 상단 바의 두 갈래 길 — 왼쪽 .cback(전체 목록) · 오른쪽 .cdetail__more(그 치즈 목록).
   ⚠️ **한 벌이다.** 같은 줄에서 같은 일(목록으로 가기)을 하므로 크기·색이 갈리면
      한쪽이 더 중요한 것처럼 보인다. 규칙 하나로 묶어 둔 이유다(§0-6). */
.cback,
.cdetail__more {
  font-size: 0.8rem;
  color: var(--ink-soft);
  text-decoration: none;
  transition: color 0.15s ease;
}
.cback:hover,
.cdetail__more:hover { color: var(--accent); }

/* 치즈 필터 칩 줄 */
.cfilter {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding-bottom: 0.875rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: 1.125rem;
}
.cfilter__label {
  flex: 0 0 auto;
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}
.cfilter__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}
.cchip {
  display: inline-block;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink-soft);
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  padding: 0.25rem 0.6875rem;
  border-radius: 2px;
  text-decoration: none;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.cchip:hover { border-color: var(--accent); color: var(--ink); }
.cchip.is-on {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* 메인 갤러리의 태그 칩 줄 (js/tags.js)
   갤러리 필터 칩(.cchip)을 그대로 쓰되, 검색·정렬 줄 바로 아래라
   구분선 없이 간격만 둔다. 눌리는 것이라 <a> 가 아니라 <button> 이다.

   ⚠️ 여기만 **격자**다(다른 .cfilter 는 라벨 하나 + 칩 줄 하나라 flex 로 충분하다).
      태그가 32종이라 묶음별로 줄을 나누고, 왼쪽 열에 묶음 이름을 세로로 정렬한다 —
      라벨을 칩 위에 얹으면 묶음마다 한 줄씩 더 들어 갤러리가 그만큼 밀려 내려간다.
      묶음 이름은 **라벨이지 칩이 아니다**(js/tags.js 의 groups 주석).
   ⚠️ 그래서 이 요소에는 .cfilter 를 붙이지 않는다. 자식 클래스(.cfilter__label /
      .cfilter__chips)는 부모와 무관하게 생김새만 주므로 그대로 쓴다. */
.gallery-tags {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: 0.75rem;
  row-gap: 0.5rem;
  align-items: start;
  margin-bottom: 0.875rem;
  /* 아직 안 그려졌을 때도 자리를 잡아둔다 — 늦게 채워져 갤러리가 밀리지 않게.
     보통은 tools/prerender.py 가 칩을 미리 찍어두므로 여기까지 오지 않는다
     (node 가 없어 정적 주입을 건너뛴 경우의 최소 높이) */
  min-height: 1.6875rem;
}
/* 칩이 32개라 한 줄에 안 들어간다. 넘치면 **줄을 바꾼다.**
   ⚠️ 전에는 nowrap + 가로 스크롤이었다. 줄 수가 변하면 아래 갤러리가 밀린다(CLS)는
      이유였는데, 실제로는 스크롤바를 숨겨둬서 **뒤쪽 칩에 닿을 방법이 없었다.**
      지금은 tools/prerender.py 가 정적 HTML 에 같은 칩을 미리 찍어 높이를 잡으므로
      줄이 몇 줄이든 밀리지 않는다 — 줄바꿈을 막을 이유가 사라졌다. */
.gallery-tags .cfilter__chips {
  flex-wrap: wrap;
  min-width: 0;
  row-gap: 0.375rem;
}
/* 라벨을 첫 줄 칩과 나란히. 칩의 글자 위치 = padding 4px + 테두리 1px 이므로 그만큼 내린다
   (line-height 는 .gcat 과 같은 1.4) */
.gallery-tags .cfilter__label { padding-top: 0.3125rem; line-height: 1.4; }
.gcat {
  flex: 0 0 auto;
  font-family: inherit;
  line-height: 1.4;
  cursor: pointer;
}
.gcat[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.gcat:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* 고른 나라 한 줄 — 태그 칩 줄과 같은 부품(.cfilter/.gcat)을 쓰되 자기 줄을 갖는다.
   태그 줄에 끼워 넣으면 "왜 이건 태그고 저건 나라인가"를 설명할 방법이 없다.
   ⚠️ display 를 주므로 [hidden] 규칙을 같이 둔다 — 안 그러면 el.hidden = true 가 안 먹는다. */
.gallery-origin {
  align-items: flex-start;
  padding-bottom: 0;
  border-bottom: 0;
  margin-bottom: 0.875rem;
}
.gallery-origin[hidden] { display: none; }
.gallery-origin .cfilter__label { padding-top: 0.3125rem; line-height: 1.4; }
/* 켜져 있는 상태로만 존재하는 칩이라 색은 .gcat[aria-pressed="true"] 가 준다.
   × 는 "누르면 풀린다"는 것만 알려주면 되므로 옅게.
   ⚠️ **태그 칩과 같은 부품이다.** 태그 줄에는 [전체] 칩이 없어(2026-08-02) 켜진 칩이 곧
      해제 버튼인데, 나라 칩과 다른 모양이면 같은 약속을 두 가지로 알리는 셈이 된다. */
.gorigin,
.gallery-tags .gcat[aria-pressed="true"] {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}
.gcat__x { font-size: 0.9rem; line-height: 1; opacity: 0.75; }

/* 글 그리드 — 글 수가 들쭉날쭉해 카드마다 선을 두르는 방식
   (치즈 갤러리처럼 붙여 놓으면 마지막 줄 빈칸이 회색 덩어리로 보임) */
.cgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14.5rem, 1fr));
  gap: 0.875rem;
}

.cpost {
  position: relative;
  background: var(--card);
  border: 1px solid var(--line);
  padding: 1rem 1rem 2.75rem;
  transition: background 0.16s ease;
}
.cpost:hover { background: #fcf8f0; }

.cpost__link {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  text-decoration: none;
  color: inherit;
}
.cpost__link:focus-visible { outline: 2px solid var(--accent); outline-offset: 0.1875rem; }

.cpost__thumb {
  width: 100%;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--paper);
  display: flex;
  align-items: center;
  justify-content: center;
}
.cpost__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.cpost__title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--ink);
}
.cpost__meta {
  font-size: 0.72rem;
  color: var(--ink-soft);
}
/* 날짜와 제목은 한 덩어리로 붙인다 — 카드의 10px 간격은 사진과의 사이에만 필요하다 */
.cpost__meta + .cpost__title { margin-top: -0.375rem; }

/* 내 글 표시 (카드 우측 상단) */
.cpost__mine {
  position: absolute;
  top: 0;
  right: 0;
  padding: 0.1875rem 0.5625rem;
  background: var(--accent);
  color: #fff;
  font-size: 0.68rem;
  letter-spacing: 0.02em;
}

/* 카드 하단 고정 태그 칩 */
.cchip--tag {
  position: absolute;
  left: 1rem;
  bottom: 0.875rem;
  font-size: 0.72rem;
  padding: 0.1875rem 0.5625rem;
}

/* 빈 상태 / 안내 문구 */
.cempty {
  margin: 0;
  padding: 2.875rem 1.125rem;
  text-align: center;
  font-size: 0.86rem;
  color: var(--ink-soft);
  background: var(--card);
  border: 1px solid var(--line);
}
.cnote {
  margin: 1rem 0 0;
  font-size: 0.76rem;
  line-height: 1.6;
  color: var(--ink-soft);
}

/* 글 상세 — 글과 댓글이 **한 장의 종이** 안에 들어간다.
   댓글은 별개 콘텐츠가 아니라 이 글에 달린 반응이므로, 카드를 따로 세워
   테두리를 두 번 두르지 않는다. 나누는 것은 얇은 선 하나뿐(설계원칙 §0-6). */
.cdetail {
  background: var(--card);
  border: 1px solid var(--line);
}
/* 글 본체. 우측 상단 수정·삭제(absolute)의 기준점이 여기다 —
   .cdetail 에 두면 댓글까지 포함한 높이가 기준이 된다 */
.cdetail__post {
  position: relative;
  padding: 1.875rem 1.875rem 2.125rem;
}
/* 내 글에만 나오는 수정·삭제 (우측 상단) */
.cdetail__own {
  position: absolute;
  top: 1.625rem;
  right: 1.875rem;
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
}

.cdetail__title {
  margin: 0;
  padding-right: 5.75rem; /* 우측 상단 수정·삭제 자리 */
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.4;
  color: var(--ink);
}
.cdetail__meta {
  margin: 0 0 0.375rem; /* 제목 위에 온다 */
  font-size: 0.76rem;
  color: var(--ink-soft);
}
.cdetail__tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.875rem;
  padding-top: 0.875rem;
  border-top: 1px solid var(--line-soft);
}
/* 상세의 치즈 칩 — 카드 칩과 달리 자리에 못박지 않는다(누르면 모달) */
.cchip--cheese { font-size: 0.76rem; }

/* 같은 치즈의 다른 글로 가는 링크(.cdetail__more)는 상단 바로 옮겼다 —
   생김새는 .cback 과 한 규칙에서 함께 받는다(위쪽 "상단 바의 두 갈래 길") */

.cdetail__photo {
  margin-top: 1.125rem;
  width: min(100%, 26.25rem);
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--paper);
}
.cdetail__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

.cdetail__body {
  margin: 1.125rem 0 0;
  font-size: 0.9rem;
  line-height: 1.75;
  color: var(--ink);
  white-space: pre-wrap;
}

/* 번역 버튼이 놓이는 줄 — 본문 바로 아래. 본문과 붙되 붙어 보이지는 않을 만큼만 띄운다.
   (본문의 마지막 요소다 — 같은 치즈의 다른 글로 가는 길은 상단 바로 나갔다) */
.cdetail__trans { margin: 0.625rem 0 0; }

/* 번역 버튼 — 글 상세의 본문 아래와 댓글 머리에 **같은 부품**으로 들어간다.
   본문이 아니라 도구라서 .linkbtn · .ccmt__del 과 같은 결(작고 연한 글자)을 쓰고,
   선을 더 긋지 않는다(설계원칙 §0-6).
   ⚠️ 밑줄은 장식이 아니다 — 둘레의 날짜·작성자와 크기·색이 같아서, 이것 말고는
      "누를 수 있다"를 알릴 단서가 없다. 번역된 상태에서는 accent 색으로 남아
      지금 보고 있는 것이 원문이 아님을 계속 알려준다. */
.ctrans {
  border: 0;
  background: none;
  padding: 0;
  font-family: inherit;
  font-size: 0.72rem;
  color: var(--ink-soft);
  text-decoration: underline;
  text-decoration-color: var(--line);
  text-underline-offset: 0.15em;
  cursor: pointer;
  transition: color 0.15s ease;
}
.ctrans:hover { color: var(--accent); text-decoration-color: currentColor; }
.ctrans:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ctrans[disabled] { cursor: default; opacity: 0.55; }
.ctrans[data-on] { color: var(--accent); text-decoration-color: currentColor; }

/* ===== 관리자 페이지 (admin.html) ===== */
.awarn {
  margin: 0 0 1.125rem;
  padding: 0.75rem 1rem;
  background: #fbf3e6;
  border: 1px solid #e2cfa8;
  font-size: 0.8rem;
  line-height: 1.65;
  color: var(--ink);
}

.asec {
  background: var(--card);
  border: 1px solid var(--line);
  padding: 1.375rem 1.625rem 1.625rem;
}
.asec__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--line);
}
.asec__title {
  margin: 0;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--accent);
}
.asec__count {
  font-size: 0.76rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.asec__desc {
  margin: 0.75rem 0 1.125rem;
  font-size: 0.8rem;
  line-height: 1.7;
  color: var(--ink-soft);
}

/* 치즈 한 줄 */
.apics {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16.75rem, 1fr));
  gap: 0.875rem;
}
.apic {
  display: flex;
  gap: 0.875rem;
  align-items: center;
  padding: 0.8125rem 0.875rem;
  border: 1px solid var(--line);
  background: var(--paper);
}
.apic.is-set { background: #fff; }

.apic__thumb {
  flex: 0 0 4.5rem;
  height: 4.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--paper);
}
.apic__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.apic__thumb .card__illust { width: 3.625rem; height: 3.625rem; margin: 0; }

.apic__body { min-width: 0; }
.apic__name {
  margin: 0 0 2px;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--ink);
}
.apic__state {
  margin: 0 0 0.5625rem;
  font-size: 0.73rem;
  color: var(--ink-soft);
}
.apic__flash {
  margin-left: 0.4375rem;
  color: var(--accent);
  font-weight: 700;
}

.apic__btns { display: flex; flex-wrap: wrap; gap: 0.4375rem; }
.apic__btn {
  display: inline-block;
  padding: 0.3125rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--card);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.76rem;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.apic__btn:hover { border-color: var(--accent); color: var(--accent); background: #fff; }
.apic__btn:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.apic__btn--del:hover { border-color: #b3453b; color: #b3453b; }

/* 관리자 로그인 카드 — 이제 구글 버튼 하나뿐이다(입력칸이 없다).
   버튼 자체(.gbtn)는 구글 브랜딩 규정을 따르므로 여기서 색·크기를 건드리지 않는다. */
.alogin__providers {
  display: flex;
  flex-wrap: wrap;
  gap: 0.625rem;
  margin-top: 1rem;
}
.alogin__msg {
  margin: 0.75rem 0 0;
  font-size: 0.78rem;
  line-height: 1.65;
  color: var(--ink-soft);
}

/* ===== 문서 페이지 (개인정보처리방침 등) ===== */
.doc {
  background: var(--card);
  border: 1px solid var(--line);
  padding: 1.875rem 1.875rem 2.125rem;
}
.doc__lead { margin: 0 0 0.375rem; font-size: 0.95rem; line-height: 1.75; color: var(--ink); }
.doc__h {
  margin: 1.625rem 0 0.5rem;
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--accent);
}
.doc__p { margin: 0; font-size: 0.9rem; line-height: 1.8; color: var(--ink); }
/* 본문 안의 링크(문의 메일 주소 등) — 제휴 링크와 같은 점선 밑줄 idiom.
   이 사이트엔 기본 a 스타일이 없어서, 규칙이 없으면 브라우저 기본 파란 밑줄이 나온다. */
.doc__p a {
  color: inherit;
  text-decoration: underline dotted var(--line);
  text-underline-offset: 0.1875rem;
  transition: color 0.15s ease, text-decoration-color 0.15s ease;
}
.doc__p a:hover { color: var(--accent); text-decoration-color: var(--accent); }
/* .doc__table 은 2026-07-28 에 지웠다 — 방침에서 저장소 키 표를 걷어내면서
   쓰는 곳이 없어졌다(js/privacy-page.js 머리 주석). 문서에 표가 다시 필요해지면 그때 만든다. */
.doc__updated {
  margin: 1.625rem 0 0;
  padding-top: 0.75rem;
  border-top: 1px solid var(--line);
  font-size: 0.76rem;
  color: var(--ink-soft);
}

/* 푸터의 보조 링크 */
.site-footer__link {
  font-size: 0.74rem;
  color: var(--ink-soft);
  text-decoration: none;
  opacity: 0.7;
  transition: opacity 0.15s ease, color 0.15s ease;
}
.site-footer__link:hover { opacity: 1; color: var(--accent); }
/* 링크 사이의 가운뎃점. 링크와 같은 크기·색이되 눌리지 않는다는 것이 옅기로 드러난다. */
.site-footer__sep {
  font-size: 0.74rem;
  color: var(--ink-soft);
  opacity: 0.45;
}

/* ===== 제목 아래 바이라인 (누가 썼고 언제 고쳤나) =====
   치즈 상세·읽을거리·소개의 히어로에 들어간다. 만드는 곳은
   tools/prerender.py 의 byline_block() 한 곳이다.

   ⚠️ `.hero__note`(치즈함의 "나만 봅니다")와 **같은 결**을 쓴다 — 부제보다 한 단계
      작고 옅게, 선을 더 긋지 않는다(§0-6). 새 스타일을 만들지 않으려는 것이고,
      이 줄은 콘텐츠가 아니라 콘텐츠에 붙는 꼬리표라 그 자리가 맞다.
   ⚠️ 크게 만들지 말 것. 신뢰는 이 줄이 눈에 띄어서가 아니라 **있어서** 생긴다 —
      제목과 본문 사이에서 크게 굴면 읽는 흐름만 끊는다. */
.hero__byline {
  margin: 0.625rem auto 0;
  font-size: 0.74rem;
  letter-spacing: 0.01em;
  color: var(--ink-soft);
  opacity: 0.8;
}
.hero__byline__a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.hero__byline__a:hover,
.hero__byline__a:focus-visible {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.hero__byline__sep { opacity: 0.55; }

/* 올렸는데 아직 저장소로 안 가져온 사진 (관리자 전용).
   경고이므로 오류색을 쓰되, 줄 하나라 상자를 두르지 않는다(§0-6). */
.apic__pending {
  margin: 0.25rem 0 0;
  font-size: 0.72rem;
  line-height: 1.5;
  color: #a3452f;
}

/* ===== 치즈 상세 페이지 (cheese.html) ===== */
.cheesepage {
  display: block;
  background: var(--card);
  border: 1px solid var(--line);
  padding: 1.875rem 1.875rem 2.125rem;
}
/* 히어로에 이미 치즈 이름(h1)이 크게 있으니 본문 제목은 감춘다 */
.cheesepage .m-name { display: none; }
.cheesepage .m-head { padding-top: 0; }
/* 페이지는 모달보다 넓어서 사진이 과하게 커진다 — 모달과 비슷한 크기로 제한 */
.cheesepage .m-gallery-row { max-width: 32.5rem; }

/* ===== 나의 치즈함 페이지 (mystash.html) ===== */
/* 먹어본 치즈 칩 줄 — 목록을 그 치즈 하나로 좁힌다.
   갤러리 태그 줄(.gallery-tags)과 **같은 부품**이라 새 스타일이 늘지 않는다:
   칩이 여러 줄이 될 수 있으므로 라벨을 첫 줄 칩에 맞춰 내린다(.gcat 과 같은 line-height). */
.stfilter { align-items: flex-start; }
.stfilter .cfilter__label { padding-top: 0.3125rem; line-height: 1.4; }
.stfilter .cfilter__chips { row-gap: 0.375rem; }

.stlist { display: flex; flex-direction: column; gap: 0.875rem; }

/* 새 기록 — 버튼 하나와 그 아래 펼쳐지는 폼.
   폼이 열리면 버튼은 감춘다(모달의 .m-col-add 와 같은 규칙). */
.stnew { margin-bottom: 0.875rem; }
.stnew .m-col-form {
  background: var(--card);
  border: 1px solid var(--line);
  padding: 1rem 1.125rem 1.125rem;
}

/* 치즈 고르기 — 검색칸 + 칩 줄. 아래 입력칸들과 한 벌로 보이게 같은 토큰을 쓴다. */
/* ⚠️ **바탕을 메인 갤러리와 같게 맞춘다** (2026-07-30). 이 안의 검색칸(.gallery-search__input)
   과 칩(.cchip)은 사이트 공통 부품이고 배경이 --card 인데, 폼 카드(--card) 위에 그대로
   놓으면 **바탕과 같은 색**이 되어 테두리 1px 로만 버틴다.
   부품마다 예외를 다는 대신(그러면 같은 칩이 화면마다 다른 색이 된다) **면을 바꾼다** —
   메인에서 그것들이 앉아 있는 바탕이 --paper 이므로 여기서도 --paper 를 깔아준다.
   그러면 검색칸·칩은 메인과 완전히 같은 규칙을 쓰고, 여기서 정할 것은 바탕 하나뿐이다.
   ⚠️ 테두리는 긋지 않는다 — 색이 이미 영역을 밝힌다(§0-6, 선을 아끼는 톤). */
.stpick {
  background: var(--paper);
  padding: 0.8125rem 0.875rem;
  margin-bottom: 0.875rem;
}
.stpick__label {
  display: block;
  margin-bottom: 0.5rem;
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}
/* 갤러리 검색칸(.gallery-search)은 한 줄 안에서 늘어나는 부품이라 flex 로 놓여 있다.
   여기서는 자기 줄을 통째로 쓴다 — 아래 칩 줄과 세로로 이어져야 하므로. */
.stpick__search { display: flex; margin-bottom: 0.5rem; max-width: 18rem; }

.stpick__chips { row-gap: 0.375rem; }
.stpick__none { margin: 0; font-size: 0.8rem; color: var(--ink-soft); }
/* ⚠️ display 를 주므로 [hidden] 규칙을 같이 둔다 — 안 그러면 el.hidden = true 가 안 먹는다 */
.stpick__err { display: block; margin-top: 0.5rem; }
.stpick__err[hidden] { display: none; }

.stempty__cta {
  display: inline-block;
  margin-top: 0.625rem;
  color: var(--accent);
  text-decoration: none;
  font-size: 0.86rem;
}
.stempty__cta:hover { text-decoration: underline; }

/* ===== 댓글 (글 상세) ===== */
.cpost__cmt {
  position: absolute;
  right: 1rem;
  bottom: 1rem;
  font-size: 0.72rem;
  color: var(--ink-soft);
}
/* 댓글 — 글과 같은 테두리 안에 이어 붙는다(위의 .cdetail 주석 참고).
   종이 톤(--paper)으로 한 단만 낮춰 "글에 달린 반응"임을 보이고,
   좌우 여백은 글 칸과 **같은 값**이라 본문과 댓글의 세로선이 맞는다. */
.ccmts {
  padding: 1.25rem 1.875rem 1.5rem;
  border-top: 1px solid var(--line);
  background: var(--paper);
}
.ccmts__title {
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--accent);
  margin: 0 0 0.875rem;
}
.ccmts__empty { margin: 0 0 1rem; font-size: 0.86rem; color: var(--ink-soft); }
.ccmts__list {
  list-style: none;
  margin: 0 0 1.125rem;
  padding: 0;
  display: flex;
  flex-direction: column;
}
/* 댓글 사이는 더 옅은 선으로. 진한 선(--line)은 글↔댓글, 댓글↔쓰기처럼
   성격이 바뀌는 자리에만 쓴다 — 같은 굵기로 다 그으면 층이 안 보인다 */
.ccmt { padding: 0.75rem 0; border-top: 1px solid var(--line-soft); }
.ccmt:first-child { border-top: 0; padding-top: 0; }
.ccmt__head { display: flex; align-items: baseline; gap: 0.5625rem; margin-bottom: 0.25rem; }
.ccmt__author { font-size: 0.82rem; font-weight: 700; color: var(--ink); }
.ccmt__date { font-size: 0.72rem; color: var(--ink-soft); }
.ccmt__del {
  margin-left: auto;
  border: 0;
  background: none;
  padding: 0;
  font-family: inherit;
  font-size: 0.72rem;
  color: var(--ink-soft);
  cursor: pointer;
}
.ccmt__del:hover { color: #b3453b; }
.ccmt__body { margin: 0; font-size: 0.88rem; line-height: 1.65; color: var(--ink); white-space: pre-wrap; }

.ccmt-form {
  display: flex;
  flex-direction: column;
  gap: 0.5625rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
}
.ccmt-form__author,
.ccmt-form__body {
  font-family: inherit;
  font-size: 0.88rem;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 0.5rem 0.625rem;
}
.ccmt-form__author { max-width: 13.75rem; }
.ccmt-form__body { resize: vertical; }
.ccmt-form__author:focus,
.ccmt-form__body:focus { outline: none; border-color: var(--accent); }
.ccmt-form__btns { display: flex; }

/* ===== 반응형 ===== */
/* 양옆 칸이 들어갈 폭이 안 나오면 한 줄로 접고, 위젯은 본문 아래로 */
@media (max-width: 1450px) {
  .pagelayout { grid-template-columns: minmax(0, 1fr); gap: 1.25rem; }
  /* 한 칸짜리 격자다 — 위에서 못박은 1·2·3 칸을 풀어줘야 한다
     (안 풀면 grid-column: 3 이 없는 칸을 만들어 옆으로 늘어선다) */
  .pagelayout > .rail--left,
  .pagelayout > .rail--right,
  .pagelayout > :not(.rail) { grid-column: 1; }
  .rail { position: static; max-width: none; justify-self: stretch; }
  .pagecol { order: -1; }
  .wslot--empty { min-height: 6rem; }
}

@media (max-width: 1025px) {
  .layout { grid-template-columns: 1fr; gap: 1.75rem; }
  /* 한 칸짜리 격자 — 위에서 못박은 칸을 풀어준다 (.pagelayout 쪽과 같은 이유) */
  .layout > .sidebar--left,
  .layout > .sidebar--right,
  .layout > :not(.sidebar) { grid-column: 1; }
  .sidebar { position: static; }
  .gallery { order: 1; }
  .sidebar--left { order: 2; }
  .sidebar--right { order: 3; }
}

@media (max-width: 1025px) {
  .cfilter { flex-direction: column; gap: 0.5rem; }
  /* 좁아지면 라벨("나라")을 칩 위로 올린다 — 옆에 두면 칩이 쓸 폭이 그만큼 준다 */
  .gallery-origin { flex-direction: column; align-items: stretch; gap: 0.5rem; }
  .gallery-origin .cfilter__label { padding-top: 0; }
  /* ⚠️ 태그 줄은 예외다 — 묶음이 넷이라 라벨을 위로 올리면 줄이 넷 더 생긴다.
        묶음 이름은 두세 글자라 좁은 화면에서도 왼쪽 열이 40px 남짓이다. */
}

@media (max-width: 480px) {
  .gallery { grid-template-columns: repeat(auto-fill, minmax(9.375rem, 1fr)); }
  .hero { padding: 2.75rem 1.25rem 1.25rem; }
  .modal__panel { padding: 1.875rem 1.375rem 1.5rem; }
  .cgrid { grid-template-columns: 1fr; }
  /* 좌우 여백은 글 칸과 댓글 칸이 같아야 세로선이 맞는다 */
  .cdetail__post { padding: 1.5rem 1.25rem 1.625rem; }
  .cdetail__own { top: 1.25rem; right: 1.25rem; }
  .ccmts { padding: 1.125rem 1.25rem 1.25rem; }
}

/* 카드의 원산지 — 나라마다 눌러서 그 나라로 검색한다(js/app.js 의 searchByOrigin).
   <p> 안의 <button> 이라 브라우저 기본 글꼴·여백을 벗겨 원래 글자와 같아 보이게 한다. */
.card__origin__go {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  border-bottom: 1px solid transparent;
  transition: color 0.14s ease, border-color 0.14s ease;
}
.card__origin__go:hover { color: var(--accent); border-bottom-color: var(--accent); }
.card__origin__go:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
