/* 내장 테마.
 *
 * design_handoff_cms_admin 의 프론트 화면(히어로 · 3열 사업영역 · 2열 리스트)을
 * 옮긴 것이다. 관리자 화면과 같은 토큰 이름을 쓰되 값은 프론트 팔레트를 따른다
 * (frontBg / heroBg / heroInk / heroLine).
 *
 * 기본은 1b 모던 소프트. 다크 선호 시 1c 값으로 덮는다 (핸드오프 README
 * 「Dark Mode」 — 구조는 그대로 두고 토큰만 바꾼다).
 *
 * 이 파일은 폴백이다. 디스크 테마가 style.css 를 두면 그쪽이 쓰인다 (FR-302).
 */
:root {
  --font-sans: system-ui, -apple-system, "Apple SD Gothic Neo", "Malgun Gothic", "Noto Sans KR", sans-serif;

  /* 「1b 모던 소프트」의 값이다 — 관리자 화면의 기본과 같은 팔레트를 쓴다
   * (admin.css 1b, app.defaultAdminTheme). 앞뒤가 다른 사이트로 보이지 않게
   * 하는 것이 목적이고, 값이 한 벌이면 한쪽만 손보다 어긋날 일이 없다.
   *
   * 3px 모서리에 그림자 없는 1a 클래식이 기본이었다. 구조를 바꾼 것이 아니라
   * 토큰만 옮겼다 — 컴포넌트 규칙은 전부 그대로다. */
  --bg: #f7f5f2;        --panel: #fff;        --ink: #2b2723;      --line: #e7e2da;
  --accent: #1f7a63;    --accent-ink: #fff;
  --hero-bg: #fff;      --hero-ink: #2b2723;  --hero-line: #e7e2da;
  --thead-bg: #faf8f5;  --input-bg: #fbfaf8;  --badge-bg: #eaf2ef; --badge-ink: #1f7a63;
  --radius: 16px;       --chip-radius: 10px;
  --shadow: 0 4px 16px rgba(43, 39, 35, .06);
  --pad: 34px;          --gap: 24px;    --shell: 1040px;
  --err: #b3261e;       --err-bg: #fbeae9;
  --ok: #1f7a63;        --ok-bg: #eaf2ef;
  --link: #1f7a63;      --link-hover: #17594a;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* 체크박스·스크롤 막대처럼 브라우저가 그리는 것도 어둡게 — 흰 네모로 남았다. */
    color-scheme: dark;
    --bg: #101317;        --panel: #1b1f25;     --ink: #e5e9ee;      --line: #2b313a;
    --accent: #4fbf94;    --accent-ink: #0d1214;
    --hero-bg: #1b1f25;   --hero-ink: #e5e9ee;  --hero-line: #2b313a;
    --thead-bg: #20252c;  --input-bg: #171b20;  --badge-bg: #1e3830; --badge-ink: #6fd6ab;
    --radius: 10px;       --chip-radius: 8px;
    --shadow: 0 1px 0 rgba(255, 255, 255, .03);
    --err: #f2857c;       --err-bg: #3a2220;
    --ok: #4fbf94;        --ok-bg: #1e3830;
    --link: #6fd6ab;      --link-hover: #9be6c6;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font: 16px/1.6 var(--font-sans);
  color: var(--ink);
  background: var(--bg);
}

a { color: var(--link); }
a:hover { color: var(--link-hover); }

/* ---- 헤더 --------------------------------------------------------------- */
.site-header {
  display: flex;
  gap: 26px;
  align-items: center;
  flex-wrap: wrap;
  /* 가로 여백은 아래 「한 축」 규칙이 정한다 — 여기서 단축 속성으로 쓰면
     그 규칙이 덮이거나 덮어, 순서에 따라 헤더·푸터 중 한쪽만 맞는다. */
  padding-block: 16px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}

.site-name {
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -.02em;
  text-decoration: none;
  color: inherit;
}

/* 메뉴가 많거나 이름이 길면 **항목 단위로** 다음 줄로 간다. 한 줄에 우겨 넣으면 좁은
   화면에서 항목 안의 글자가 「고객/센터」「자유게/시판」처럼 갈라졌다(375px 실측). */
.site-menu ul { display: flex; flex-wrap: wrap; gap: 6px 16px; list-style: none; margin: 0; padding: 0; }
/* 낱말 안에서는 꺾지 않고 공백에서만 꺾는다 — nowrap 이면 긴 메뉴 제목(50자까지 된다)이
   휴대폰 폭을 넘어 body 의 overflow-x: hidden 에 소리 없이 잘린다. */
.site-menu li { word-break: keep-all; }
.site-menu ul ul { margin-left: 12px; }
.site-menu a { color: inherit; text-decoration: none; opacity: .8; font-size: 14px; }
.site-menu a:hover { opacity: 1; }
.site-menu li.current > a { font-weight: 700; opacity: 1; }

.account-nav {
  margin-left: auto;
  display: flex;
  gap: 12px;
  align-items: center;
  font-size: 14px;
  /* 좁으면 링크가 다음 줄로 내려간다. 줄바꿈이 없으면 링크마다 낱말 중간에서 꺾인다. */
  flex-wrap: wrap;
}

.account-nav a { color: inherit; text-decoration: none; opacity: .8; white-space: nowrap; }
/* 로그아웃은 폼 버튼이지만 옆 링크와 같은 모양이다 — 혼자 테두리 버튼이라 튀었다. */
.account-nav button {
  background: none; border: 0; padding: 0; font: inherit; color: inherit;
  opacity: .8; cursor: pointer; white-space: nowrap;
}
.account-nav button:hover { opacity: 1; }
.account-nav a:hover { opacity: 1; }
.inline { display: inline; }

/* ---- 본문 --------------------------------------------------------------- */
main { max-width: var(--shell); margin: 0 auto; padding: 32px var(--pad) 64px; }

/* **헤더·플래시·본문·푸터가 한 축에 선다.**
 *
 * `main` 만 가운데로 모으고 헤더·푸터는 화면 전체 폭이면, 넓은 화면에서 사이트
 * 이름은 왼쪽 끝(x=34)에 붙고 본문 카드는 한참 안쪽(x=154)에서 시작한다 —
 * 세로줄이 두 개 생겨 어느 쪽이 이 페이지의 왼쪽인지 눈이 못 고른다.
 * 브라우저로 찍어 보고 알았다: 좌표 검사는 넘치지 않는 어긋남을 재지 않는다.
 *
 * 띠의 배경·구분선은 화면 전체를 덮어야 하므로 폭을 줄이지 않고 **안쪽 여백**
 * 으로 맞춘다. 화면이 `--shell` 보다 좁으면 여느 때의 여백으로 돌아간다. */
.site-header,
.site-footer,
.flash li {
  padding-inline: max(var(--pad), calc((100% - var(--shell)) / 2 + var(--pad)));
}

/* ---- 히어로 ------------------------------------------------------------- */
.hero {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: clamp(28px, 4vw, 52px) clamp(22px, 3vw, 44px);
  background: var(--hero-bg);
  color: var(--hero-ink);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.hero-eyebrow { font-size: 12px; letter-spacing: .14em; opacity: .65; }

.hero h1 {
  margin: 0;
  font-size: clamp(24px, 3vw, 34px);
  font-weight: 700;
  line-height: 1.32;
  letter-spacing: -.03em;
}

.hero .lede {
  margin: 0;
  font-size: 14.5px;
  opacity: .7;
  line-height: 1.8;
  max-width: 420px;
}

.hero-cta { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 4px; }

/* ---- 버튼 --------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 22px;
  border: 1px solid var(--hero-line);
  border-radius: var(--chip-radius);
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 14px;
  text-decoration: none;
  cursor: pointer;
}

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}

/* ---- 카드 · 리스트 ------------------------------------------------------- */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 26px;
  margin-top: 26px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}

.card-list h2 {
  display: flex;
  align-items: center;
  margin: 0 0 13px;
  font-size: 14.5px;
  font-weight: 600;
}

.card-list h2 a { margin-left: auto; font-size: 12px; opacity: .45; text-decoration: none; color: inherit; }

.card-list ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 13px; }
.card-list li { display: flex; gap: 12px; font-size: 13px; }
.card-list li a { color: inherit; text-decoration: none; }
.card-list li a:hover { text-decoration: underline; }
.card-list .meta { margin-left: auto; opacity: .4; flex: none; }

/* ---- 페이지 본문 --------------------------------------------------------- */
.page {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: clamp(24px, 3vw, 40px);
}

.page h1 { margin: 0 0 20px; font-size: clamp(22px, 2.6vw, 28px); letter-spacing: -.02em; }
.page-body { line-height: 1.8; }
/* 에디터로 쓴 본문 (FR-513). 사진·표·영상이 화면 폭을 넘지 않는다 — 휴대폰에서
   1920px 사진이 가로 스크롤을 만들지 않게. */
.rich img, .rich iframe, .rich table { max-width: 100%; }
.rich img { height: auto; }
.rich iframe { width: 100%; aspect-ratio: 16 / 9; height: auto; border: 0; }
.rich table { border-collapse: collapse; }
.rich td, .rich th { border: 1px solid var(--line); padding: .4em .6em; }
.rich figure { margin: 1em 0; }
/* 갤러리 목록 (FR-515). 카드 한 칸이 썸네일(480px) 크기를 넘지 않는다. */
.gallery { list-style: none; padding: 0; display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr)); }
.gallery-card a { display: block; color: inherit; text-decoration: none; }
.gallery-card img, .gallery-blank { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: 6px; background: var(--line); }
.gallery-title { display: block; margin-top: .4em; font-weight: 600; }
/* 공개 폼의 Turnstile 위젯 (FR-216, partials/spam.html) — 위젯 자체는 Cloudflare 가 그린다. */
.cf-turnstile { margin: .5rem 0; }

/* ---- 폼 ----------------------------------------------------------------- */
.form {
  display: grid;
  gap: 6px;
  max-width: 24rem;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: clamp(20px, 3vw, 32px);
}

/* **그리드 칸이 줄어들 수 있어야 한다.** 그리드 아이템의 기본 `min-width`
   는 `auto` 라 열이 가장 넓은 아이템의 min-content 아래로 못 내려간다 —
   파일 선택 칸("파일 선택 · 선택된 파일 없음")이 321px 를 요구해서, 375px
   화면에서 폼 전체가 상자 밖으로 28px 밀려나 있었다. 브라우저에서 열을 재
   보고 알았다. */
.form > * { min-width: 0; max-width: 100%; }

.form label { font-size: 12.5px; opacity: .6; margin-top: 14px; }

/* **입력칸을 감싼 라벨은 세로다.** 마크업이 두 형태로 쓰인다 —
   `<label for>텍스트</label><input>` 과 `<label>텍스트<input></label>` —
   후자는 라벨이 블록이 아니면 텍스트와 칸이 한 줄에 붙어, 같은 폼 안에서
   줄마다 모양이 달라진다. 회원 탈퇴 화면이 그랬다.
   체크박스·라디오는 가로가 맞으므로 아래에서 되돌린다. */
.form label > input:not([type="checkbox"]):not([type="radio"]),
.form label > select,
.form label > textarea { display: block; width: 100%; margin-top: 6px; }

/* ---- 폼 요소 (컨테이너와 무관) -------------------------------------------
 *
 * **요소 선택자다.** 같은 규칙이 `.form`·`.board-filter`·`.sort` 세 곳에
 * 복사돼 있었고, 그 세 곳 밖의 입력칸은 브라우저 기본 모양으로 남았다 —
 * 장바구니의 수량칸과 「변경」 버튼이 그랬다. 어디에 놓이든 같은 모양이어야
 * 하므로 요소에 건다. 컨테이너는 배치(폭·정렬)만 정한다.
 *
 * 상속받지 않는 것을 명시한다: 폼 요소는 `font` 를 상속하지 않아서, 적지
 * 않으면 브라우저 기본 글꼴이 나온다. */
input,
select,
textarea {
  /* 버튼(44px)과 같다 — 검색칸·수량칸 옆에 버튼이 붙는다. */
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--chip-radius);
  background: var(--input-bg);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  /* 좁은 화면에서 기본 폭(대략 20자)이 부모를 밀어낸다. */
  max-width: 100%;
}

textarea { min-height: 8rem; padding: 14px; line-height: 1.7; }

/* iOS Safari 는 select 를 자기 알약 모양으로 더 낮게 그려 옆 입력칸과 높이·모서리가 달랐다.
   기본 모양을 끄고 화살표를 배경 그림으로 단다 — 회색 하나라 밝은·어두운 바탕 모두에서 보인다. */
select:not([multiple]) {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 36px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23888' stroke-width='1.6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 12px 8px;
}

/* 체크박스·라디오는 상자다. 위 규칙의 높이·여백을 그대로 받으면 커다란
   빈 사각형이 된다. */
input[type="checkbox"],
input[type="radio"] {
  min-height: 0;
  width: 18px;
  height: 18px;
  padding: 0;
  accent-color: var(--accent);
}

input[type="file"] { padding: 9px 12px; }

button {
  /* **버튼은 한 가지 높이다.** 42 와 44 가 섞여 있어 같은 줄에 선 버튼들의
     아랫변이 어긋났다 — 좁은 화면의 터치 타깃 기준(44px)에 맞춘다. 크기 위계는
     `--sm` 같은 변형이 맡고, 기본값이 두 개면 그것은 위계가 아니라 실수다. */
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid var(--line);
  border-radius: var(--chip-radius);
  background: var(--panel);
  color: inherit;
  font: inherit;
  font-size: 14px;
  /* **버튼 글자는 줄바꿈하지 않는다.** 좁은 머리글에서 「로그아웃」이 두 줄로
     접혀 높이가 92px 이 됐다 — 옆의 44px 짜리와 나란히 서서 줄이 어긋났다.
     자리가 없으면 버튼이 줄을 바꾸는 편이 낫지, 글자가 접히면 안 된다. */
  white-space: nowrap;
  /* 인라인 요소는 min-height 가 듣지 않는다. 검색 버튼이 47px 로 혼자 튀던
     이유이고, 정렬은 세로 가운데로 맞춘다. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

button:disabled { opacity: .5; cursor: not-allowed; }

/* 폼의 제출 버튼은 주 동작이다. */
.form button[type="submit"],
.form button:not([type]) {
  margin-top: 20px;
  min-height: 44px;
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}

.hint { opacity: .45; font-size: 12.5px; margin: 4px 0 0; }
.readonly { opacity: .55; margin: 4px 0; }

/* ---- 알림 --------------------------------------------------------------- */
.error { color: var(--err); font-weight: 600; }

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

.flash li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-block: 14px;
  font-size: 13px;
  background: var(--ok-bg);
  color: var(--ok);
}

.flash li::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 99px;
  background: currentColor;
  flex-shrink: 0;
}

.flash .flash-error { background: var(--err-bg); color: var(--err); }

/* ---- 푸터 --------------------------------------------------------------- */
.site-footer {
  border-top: 1px solid var(--line);
  padding-block: 24px;
  font-size: 13px;
  opacity: .55;
}

.site-footer p { margin: 0 0 8px; }
/* 「라벨 · 값」 목록. 바닥글의 사업자 정보와 영수증의 받는 분·판매자 칸이 같은 모양이다. */
.business,
.receipt-info { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin: 0; }
.totals + .receipt-info,
h2 + .receipt-info { margin-top: 16px; }
.business dt,
.receipt-info dt { opacity: .7; }
.business dd,
.receipt-info dd { margin: 0; }

.dev-detail {
  background: var(--thead-bg);
  padding: 14px;
  border-radius: var(--chip-radius);
  overflow: auto;
  font-size: 13px;
}

/* ---- 반응형 ------------------------------------------------------------- */

/* 어떤 폭에서도 **가로 스크롤이 생기지 않는다.** 표는 자기 안에서 스크롤하고
   (.table-wrap), 긴 낱말은 끊는다 — 주문번호·SKU·URL 이 그런 것들이다. */
/* 한국어는 낱말 사이에서만 꺾는다. 기본값은 음절마다 줄을 바꿔 「배송완/료」「온돌빌/딩」이
   됐다. 한 줄에 다 안 들어가는 긴 낱말은 아래 `overflow-wrap` 이 받는다. */
body { overflow-x: hidden; word-break: keep-all; }

.page,
.card-list li,
.product-list li,
.cart > li,
.comments li,
.hero,
.auth,
.flash li { overflow-wrap: anywhere; }

/* ---- 상호작용 ------------------------------------------------------------
 * 「부드럽다」는 모서리와 그림자만으로 만들어지지 않는다. 상태가 순간이동하면
 * 값이 아무리 부드러워도 화면은 딱딱하게 느껴진다.
 *
 * `prefers-reduced-motion` 을 존중한다 — 전정 장애가 있는 사람에게 움직임은
 * 취향이 아니라 증상이다. */
a,
button,
input,
select,
textarea,
/* 그림자·테두리가 상태에 따라 바뀌는 것들. `.card`·`.panel` 을 적어 뒀었는데
   그런 클래스를 쓰는 템플릿이 없었다 — 있지도 않은 화면의 규칙이었다.
   `.page` 는 위에 이미 정의돼 있어 여기 다시 적지 않는다 (호버 상태가 없다). */
.product-list li {
  transition: background-color .16s ease, border-color .16s ease,
              box-shadow .16s ease, color .16s ease, transform .16s ease;
}

button:not(:disabled):hover { filter: brightness(1.06); }
button:not(:disabled):active { transform: translateY(1px); }

input:focus-visible,
select:focus-visible,
textarea:focus-visible,
button:focus-visible,
a:focus-visible {
  /* 윤곽선을 지우고 그림자로 대신하지 않는다 — 고대비 모드에서 그림자는
   * 그려지지 않고, 그러면 키보드 사용자는 어디에 있는지 알 수 없게 된다. */
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
  }
}

/* 체크박스는 라벨과 한 줄에 놓는다. .form label 의 세로 배치를 그대로 쓰면
 * 상자와 글자가 두 줄로 갈라져 무엇을 체크하는지 읽히지 않는다 (P-110). */
/* 체크박스를 품은 라벨은 가로다 — 상자와 글자가 두 줄로 갈라지면 무엇을
   체크하는지 읽히지 않는다. */
.form label.checkbox {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  opacity: 1;
}

.form label.checkbox input { width: 18px; height: 18px; padding: 0; }

/* 되돌릴 수 없는 동작은 색으로 먼저 말한다 (P-110 탈퇴). */
.form button.danger { background: var(--err); }

/* ═══ 목록·표 ═══════════════════════════════════════════════════════════════
 *
 * 여기부터는 게시판·상품·주문 화면의 규칙이다. **템플릿은 이 클래스들을 이미
 * 쓰고 있었는데 규칙이 없었다** — 마크업이 그려지고 브라우저는 오류를 내지
 * 않으므로, 게시판 목록의 표가 한 줄로 뭉쳐 있는 동안 통합 테스트 900건이
 * 전부 초록이었다. TestEveryBuiltinClassHasAStyle 이 다시 벌어지는 것을 막는다.
 */

/* 좁은 화면에서 표는 **자기 안에서** 가로 스크롤한다. 페이지가 통째로
 * 흔들리면 나머지 화면까지 못 쓰게 된다. */
.table-wrap {
  overflow-x: auto;
  margin: 0 0 18px;
  /* 밀 수 있다는 표시: 덮개(local)는 내용과 함께 움직이고 그림자(scroll)는 가장자리에
   * 머문다 — 더 밀 것이 남은 쪽에만 그림자가 보인다. 휴대폰에는 스크롤 막대가 없다. */
  background:
    linear-gradient(to right, var(--panel) 30%, transparent) left / 32px 100% no-repeat local,
    linear-gradient(to left, var(--panel) 30%, transparent) right / 32px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, color-mix(in srgb, var(--ink) 22%, transparent), transparent) left / 12px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, color-mix(in srgb, var(--ink) 22%, transparent), transparent) right / 12px 100% no-repeat scroll;
}

.board-list,
.order-list {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.board-list th,
.order-list th {
  padding: 12px 14px;
  text-align: left;
  font-size: 12.5px;
  font-weight: 600;
  color: inherit;
  opacity: .55;
  background: var(--thead-bg);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

.board-list th:first-child { border-top-left-radius: var(--chip-radius); }
.board-list th:last-child  { border-top-right-radius: var(--chip-radius); }

.board-list td,
.order-list td {
  padding: 14px;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}

/* 마지막 행의 아래 선은 지운다 — 행 사이를 가르는 것이 목적이고, 마지막 행
   아래에는 가를 것이 없다. 감싼 상자의 경계와 겹쳐 굵어 보인다. */
.board-list tbody tr:last-child td,
.order-list tbody tr:last-child td { border-bottom: 0; }

.board-list tbody tr:hover,
.order-list tbody tr:hover { background: var(--thead-bg); }

.board-list a,
.order-list a { color: inherit; text-decoration: none; }
.board-list a:hover,
.order-list a:hover { text-decoration: underline; }

/* 제목 외의 칸은 부차적이다. 같은 굵기로 두면 목록에서 눈이 쉴 곳이 없다. */
.meta { opacity: .5; font-size: 13px; white-space: nowrap; }
.count { opacity: .55; font-size: 12.5px; margin-left: 4px; }
.clip { margin-left: 6px; opacity: .5; }
.excerpt { opacity: .6; font-size: 13.5px; margin: 4px 0 0; }

/* 비어 있는 목록도 화면이다. 아무것도 없이 두면 고장으로 읽힌다. */
.empty {
  padding: 32px 14px;
  text-align: center;
  opacity: .45;
  font-size: 13.5px;
}

/* ═══ 배지·칩 ═══════════════════════════════════════════════════════════════ */
.badge {
  /* **inline-block 이 아니라 inline-flex 다.** flex 컨테이너의 자식이 되면
     inline-block 은 stretch 돼 가로로 늘어난다 — 상품 카드(.product-list li)가
     세로 flex 라서 「품절」 배지가 칩이 아니라 막대로 그려지고 있었다.
     align-self 로 함께 고정한다: 바깥이 어떤 정렬을 쓰든 배지는 내용만큼만
     차지해야 한다. */
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  width: fit-content;
  padding: 2px 9px;
  border-radius: 99px;
  background: var(--badge-bg);
  color: var(--badge-ink);
  font-size: 11.5px;
  font-weight: 600;
  vertical-align: middle;
}

.badge--outline {
  background: transparent;
  border: 1px solid currentColor;
  opacity: .7;
}
/* 「품절」은 좋은 소식이 아니다 — 강조색(초록) 배지면 판매 중처럼 읽혔다. */
.badge--soldout {
  background: var(--line);
  color: inherit;
}

/* ═══ 필터·정렬 줄 ══════════════════════════════════════════════════════════ */
.board-filter,
.sort {
  display: flex;
  gap: 10px;
  align-items: center;
  /* 정렬 상자는 오른쪽에 붙인다 — 목록의 시작이 아니라 끝에 놓이는 조작이다. */
  margin-left: auto;
  flex-wrap: wrap;
  margin: 0 0 18px;
}

/* 모양은 요소 선택자가 정한다 (위). 여기서는 배치만. */
/* `type` 속성이 없는 `<input>` 은 text 지만 `input[type="text"]` 로는 잡히지
   않는다 — 게시판 검색칸이 그것이라 폭 규칙이 통째로 빗나가고 있었다.
   체크박스·라디오만 빼고 태그로 건다. */
.board-filter input:not([type="checkbox"]):not([type="radio"]) {
  flex: 1 1 12rem;
  min-width: 0;
}
.btn--sm { min-height: 34px; padding: 0 14px; font-size: 13px; }

/* ═══ 글 보기 ═══════════════════════════════════════════════════════════════ */
.crumb { font-size: 13px; opacity: .55; margin: 0 0 10px; }
.crumb a { color: inherit; text-decoration: none; }
.crumb a:hover { text-decoration: underline; }

.actions { display: flex; gap: 10px; flex-wrap: wrap; margin: 26px 0 0; }

/* 커스텀 필드는 이름-값 쌍이다. 게시판마다 개수가 달라 열 수를 못 정하므로
 * 그리드가 스스로 접히게 둔다 (FR-503). */
.custom-fields {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px 16px;
  margin: 0 0 20px;
  padding: 16px 18px;
  border-radius: var(--chip-radius);
  background: var(--thead-bg);
  font-size: 13.5px;
}

.custom-fields dt { opacity: .55; }
/* 여러 줄 필드(textarea)의 줄바꿈을 살린다 — 없으면 한 문단으로 붙는다. */
.custom-fields dd { margin: 0; white-space: pre-line; }

/* ═══ 댓글 ═════════════════════════════════════════════════════════════════ */
.comments { margin-top: 26px; }
.comments ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }

.comments li {
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--chip-radius);
  background: var(--panel);
  font-size: 14px;
}

/* 답글은 들여쓴다. 깊이는 한 단계뿐이라 값 하나로 끝난다. */
.comments li.reply { margin-left: clamp(16px, 5vw, 44px); }
.deleted { opacity: .4; font-style: italic; margin: 0; }

/* ═══ 상품 ═════════════════════════════════════════════════════════════════ */
.categories {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 20px;
  font-size: 13.5px;
}

.categories a {
  padding: 6px 14px;
  border: 1px solid var(--line);
  border-radius: 99px;
  color: inherit;
  text-decoration: none;
}

.categories a:hover { background: var(--thead-bg); }

.product-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--gap);
}

.product-list li {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--shadow);
}

.product-list li:hover { transform: translateY(-2px); }
.product-list a { color: inherit; text-decoration: none; font-weight: 600; font-size: 14.5px; }
.product-list .empty { grid-column: 1 / -1; }

/* 상품 이미지. **원본을 그대로 받는다** (썸네일을 만들지 않는다) — 그래서 크기와
   비율은 여기서 정한다. aspect-ratio 가 그림이 오기 전에 자리를 잡아 레이아웃이
   밀리지 않고, object-fit 이 비율이 다른 원본을 찌그러뜨리지 않는다. */
.product-thumb {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: calc(var(--radius) - 4px);
  background: var(--thead-bg);
}
.product-thumb--small { width: 40px; flex: none; border-radius: 6px; }

.product-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: var(--gap);
  margin: 0 0 18px;
}
.product-gallery img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
}

.price { font-size: 15px; font-weight: 700; letter-spacing: -.01em; }
.stock { font-size: 12.5px; opacity: .55; }
.option { display: grid; gap: 6px; margin: 0 0 14px; }

/* ═══ 장바구니·주문 ═════════════════════════════════════════════════════════ */
.cart,
.shipments,
.refunds,
.returns,
.connections,
.search-results {
  list-style: none;
  margin: 0 0 20px;
  padding: 0;
  display: grid;
  gap: 12px;
}

/* 약관 동의는 **목록이 아니라 폼 묶음**이다 (`<fieldset>`).
 *
 * 목록 규칙(`.terms > li`)에 얹어 두었더니 `label` 에는 아무것도 닿지 않고
 * `fieldset` 의 브라우저 기본 테두리만 남아, 결제 화면 맨 아래에 「약관」이라고
 * 적힌 얇은 상자 하나가 다른 폼과 전혀 다른 모양으로 떠 있었다. 375px 스크린샷
 * 에서 보고 알았다. */
.terms {
  border: 0;
  margin: 14px 0 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.terms > legend { padding: 0; font-size: 12.5px; opacity: .6; }

.terms label {
  display: flex;
  gap: 9px;
  align-items: center;
  margin: 0;
  font-size: 14px;
  opacity: 1;
}

.terms em { font-style: normal; color: var(--err); font-size: 12px; }

.cart > li,
.shipments > li,
.refunds > li,
.returns > li,
.connections > li,
.search-results > li {
  display: flex;
  gap: 14px;
  align-items: baseline;
  flex-wrap: wrap;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--chip-radius);
  background: var(--panel);
  font-size: 14px;
}

.search-results > li { display: block; }

.qty { opacity: .6; font-size: 13px; }
.amount { margin-left: auto; font-weight: 600; white-space: nowrap; }
.reason { opacity: .6; font-size: 13px; flex-basis: 100%; }
.refund-line,
.return-line { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; padding: 8px 0; }

/* 합계는 **금액이 결론**인 자리다. 다른 줄과 같은 무게로 두면 얼마를 내는지
 * 한 번에 보이지 않는다. */
.totals {
  /* **`<dl>` 이다.** dt 와 dd 가 따로 자식이므로 각각을 flex 행으로 만들면
     레이블과 금액이 두 줄로 갈라진다 — 장바구니 합계가 실제로 그렇게 그려지고
     있었다. 2열 그리드가 쌍을 한 줄에 붙인다. */
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px 16px;
  margin: 20px 0 0;
  padding: 18px 20px;
  border-radius: var(--chip-radius);
  background: var(--thead-bg);
  font-size: 14px;
}

.totals dt { opacity: .6; }

.totals dd {
  margin: 0;
  text-align: right;
  /* 금액은 자릿수가 맞아야 위아래로 읽힌다. */
  font-variant-numeric: tabular-nums;
}

/* dl 이 아닌 자식(안내 문단 등)은 한 줄을 통째로 쓴다. */
.totals > p,
.totals > div { grid-column: 1 / -1; margin: 0; }

/* 마지막 쌍이 결제 금액이다 — 다른 줄과 같은 무게면 결론이 안 보인다. */
.totals dt:last-of-type,
.totals dd:last-of-type { font-size: 16px; font-weight: 700; opacity: 1; }

.totals strong { font-size: 16px; }
.discount { color: var(--ok); }

/* ═══ 소셜 로그인 ═══════════════════════════════════════════════════════════ */
.social-login { display: grid; gap: 10px; margin: 20px 0 0; }

.social-btn {
  /* **`width: fit-content` 을 물려받지 않게 한다.** `.badge` 에 준 것이
     `inline-flex` 를 통해 여기까지 오지는 않지만, grid 자식이 자기 내용만큼만
     차지하면 버튼 폭이 글자 수를 따라 제각각이 된다 — 「구글로 로그인」과
     「카카오로 로그인」이 다른 크기로 서면 목록이 아니라 우연으로 보인다. */
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  border: 1px solid var(--line);
  border-radius: var(--chip-radius);
  background: var(--panel);
  color: inherit;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.social-btn:hover { background: var(--thead-bg); }

/* 프로바이더별 색은 **각 브랜드 가이드가 정한다.** 여기서는 구분만 하고,
 * 정확한 값이 필요해지면 그때 각 가이드를 보고 넣는다 (D74). */
.social-btn--google { border-color: #dadce0; }
.social-btn--kakao { background: #fee500; color: #191600; border-color: #fee500; }
.social-btn--naver { background: #03c75a; color: #fff; border-color: #03c75a; }

/* ═══ 페이지네이션 ══════════════════════════════════════════════════════════ */
.pager {
  display: flex;
  gap: 6px;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  margin: 24px 0 0;
  font-size: 13.5px;
}

.pager a,
.pager .page-current {
  min-width: 36px;
  min-height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: var(--chip-radius);
  text-decoration: none;
}

/* `color: inherit` 는 **링크에만** 준다. 위 묶음에 두었더니 특이성이
   `.pager .page-current`(클래스 둘)라 아래 `.page-current`(클래스 하나)의
   `--accent-ink` 를 이겼다 — 현재 페이지 칩이 강조색 배경 위에 본문 색으로
   그려졌고, 대비가 라이트 2.84:1 · 다크 1.87:1 이었다 (AA 는 4.5:1).
   의도한 색이 한 번도 적용된 적이 없다. `make ui` 의 대비 규칙이 찾았다. */
.pager a { color: inherit; }

.pager a:hover { background: var(--thead-bg); }

.pager .page-current {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}

/* ═══ 기타 ═════════════════════════════════════════════════════════════════ */
.who { font-weight: 600; }
.form--wide { max-width: 46rem; }

.error-page { text-align: center; padding: clamp(40px, 8vw, 90px) 0; }
.error-page h1 { font-size: clamp(22px, 3vw, 30px); margin: 0 0 10px; }

/* ═══ 좁은 화면 ════════════════════════════════════════════════════════════
 *
 * **파일 맨 끝이다.** 이 블록이 중간에 있으면 뒤에 오는 규칙이 같은 특정도로
 * 덮어써서 좁은 화면 규칙이 조용히 사라진다 — 게시판 검색칸의 `flex` 되돌림이
 * 실제로 그렇게 무시됐고, 화면에서는 입력칸이 12rem 높이 상자로 늘어났다.
 * 규칙을 더할 때는 **이 블록 위에** 더한다.
 */
/* 이름은 왼쪽, 액션은 오른쪽. 둘이 붙어 있으면 어느 버튼이 어느 줄의 것인지
   눈으로 이어야 하고, 오른쪽이 통째로 비면 목록이 아니라 찌꺼기로 보인다. */
.connections > li > :first-child { flex: 1 1 auto; }
.connections > li form,
.connections > li .hint { margin-left: auto; }

/* ═══ 인증 · 내 계정 ═══════════════════════════════════════════════════════
 *
 * **한 축에 세운다.** 제목은 화면 폭, 폼은 24rem, 소셜 버튼은 또 화면 폭 —
 * 셋이 각자 다른 폭에 서 있으면 어느 것이 이 화면의 본체인지 눈이 못 고른다.
 * 로그인 화면이 그 상태였다.
 *
 * 폭을 여기서 정하므로 `.form` 의 `max-width` 는 이 안에서 푼다. 두 곳이
 * 폭을 정하면 어느 쪽이 이겼는지 보고 고쳐야 한다.
 */
.auth {
  max-width: 26rem;
  margin: 0 auto;
  display: grid;
  gap: 16px;
}

.auth h1 {
  margin: 0;
  font-size: clamp(22px, 2.6vw, 28px);
  letter-spacing: -.02em;
}

.auth .form,
.auth .form--wide { max-width: none; margin: 0; }
.auth .social-login { margin: 0; }
.auth > p { margin: 0; font-size: 13.5px; }

/* 링크 줄은 카드 밖이라 배경이 없다 — 가운데로 모으면 카드와 축이 맞는다. */
.auth > p:last-child { text-align: center; opacity: .7; }

/* ---- 목록 화면 (.listing) ------------------------------------------------
 * 항목 자체가 카드인 화면이다 (상품 목록·상품 검색). 여기서 패널로 또 감싸면
 * 카드 안의 카드가 되어 경계가 두 겹으로 보인다 — 그래서 상자가 아니라
 * **제목과 도구를 카드 격자 위에 세우는 머리 부분**만 만든다. */
.listing { display: grid; gap: 18px; }
.listing h1 { margin: 0; font-size: clamp(22px, 2.6vw, 28px); letter-spacing: -.02em; }

.shop-search {
  display: flex;
  gap: 8px;
  align-items: center;
}

/* 머리글의 검색은 메뉴와 계정 사이에 끼어 있다 — 줄어들 수 있어야 좁은
   화면에서 계정 링크를 밀어내지 않는다. */
.site-search {
  display: flex;
  gap: 8px;
  align-items: center;
  /* 기준 폭이 작아야 머리글이 꽉 찰 때 검색칸이 먼저 줄어든다 — 200px 이면 계정 링크가
     둘째 줄로 내려갔다(1280px 회원 실측, 머리글 146px). */
  flex: 1 1 140px;
  min-width: 0;
  max-width: 320px;
}
.shop-search label { font-size: 13px; opacity: .6; flex: none; }
.site-search input { min-width: 0; }

/* ---- 주문 이후의 동작 (.order-actions) -----------------------------------
 * 영수증·취소·환불·반품·교환으로 가는 줄. 버튼이 여럿이고 상태에 따라 개수가
 * 달라지므로 줄바꿈을 허용한다 — 좁은 화면에서 가로로 삐져나가면 그 자체가
 * 「깨진 화면」으로 보인다. */
.order-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 20px;
}

/* ---- 첨부 목록 (FR-506) --------------------------------------------------- */
.attachments {
  list-style: none;
  margin: 20px 0 0;
  padding: 14px 16px;
  display: grid;
  gap: 8px;
  border: 1px solid var(--line);
  border-radius: var(--chip-radius);
  background: var(--bg);
  font-size: 13.5px;
}
.attachments li { display: flex; gap: 10px; align-items: baseline; }
.attachments .meta { margin-left: auto; opacity: .45; flex: none; }

/* ---- 안내 문장 (.notice) --------------------------------------------------
 * 오류가 아니라 상태다 — 「판매 준비 중」처럼 지금은 할 수 없다는 사실.
 * .error 와 색이 달라야 사용자가 자기 잘못을 찾지 않는다. */
.notice {
  margin: 20px 0 0;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--chip-radius);
  font-size: 14px;
  opacity: .75;
}

/* ---- 바닥글 링크 ---------------------------------------------------------- */
.foot-links { margin: 8px 0 0; font-size: 12.5px; }
.foot-links a { color: inherit; opacity: .6; }
.foot-links a:hover { opacity: 1; }

/* ---- 위험한 동작 ----------------------------------------------------------
 * 삭제·탈퇴처럼 되돌릴 수 없는 것. 채우지 않고 테두리로만 표시한다 — 빨간
 * 덩어리가 화면에 있으면 눈이 먼저 그리로 가고, 그것은 주된 동작이 아니다. */
.btn--danger {
  border-color: color-mix(in srgb, var(--err) 45%, var(--line));
  color: var(--err);
}
.btn--danger:hover { background: color-mix(in srgb, var(--err) 8%, transparent); }

/* ═══ 간격·정렬 정리 ═══════════════════════════════════════════════════════
 *
 * 화면을 전부 찍어 놓고 보니 같은 어긋남이 여러 화면에 반복됐다: 카드 안에 또
 * 카드(`.page` 안의 `.form`), 서로 맞닿은 구역(합계 상자와 그 아래 폼), 표인데
 * 목록 규칙을 받아 한 줄로 뭉친 주문 품목. 화면마다 고치지 않고 규칙으로 고친다.
 */

/* 바닥글은 바닥에 선다. 본문이 짧으면 바닥글이 화면 중간에 떠 있었다. */
body { min-height: 100vh; display: flex; flex-direction: column; }
main { flex: 1 0 auto; width: 100%; }

/* **카드 안의 폼은 카드가 아니다.** `.page` 가 이미 상자인데 `.form` 이 테두리·
   그림자·여백을 또 그려, 주문서·글쓰기·환불 화면이 상자 속 상자였다. */
.page .form {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: none;
  padding: 0;
}

/* 카드 안의 구역은 20px 씩 떨어진다. 합계 상자(.totals)는 위 여백만 있어서 바로
   아래 것(배송지·폼)과 맞닿았다. */
.page > * + .form,
.page > .totals + *,
.page > .table-wrap + .totals { margin-top: 20px; }
.page > .totals { margin-top: 0; }
.page > p { margin: 0 0 16px; }
.page > :last-child { margin-bottom: 0; }

/* 한 카드에 폼이 둘이면 선으로 가른다 (환불 요청 / 주문 취소). */
.page > .form + .form { margin-top: 24px; padding-top: 24px; border-top: 1px solid var(--line); }
.page > .form > :first-child { margin-top: 0; }
/* 글쓰기처럼 넓은 폼은 카드 폭을 다 쓴다 — 46rem 에서 끊기면 오른쪽이 빈다. */
.page .form--wide { max-width: none; }

address { font-style: normal; font-size: 14px; line-height: 1.7; }

/* 묶음 상자. 브라우저 기본(굵은 회색 홈 테두리)이 다른 상자와 모양이 달랐다. */
fieldset {
  min-width: 0;
  margin: 14px 0 0;
  padding: 12px 16px 16px;
  border: 1px solid var(--line);
  border-radius: var(--chip-radius);
}
legend { padding: 0 6px; font-size: 12.5px; opacity: .6; }
.form fieldset label { margin: 0; opacity: 1; font-size: 14px; }
.refund-line label,
.return-line label { display: flex; gap: 9px; align-items: center; flex: 1 1 14rem; flex-wrap: wrap; }
.refund-line input[type="number"],
.return-line input[type="number"] { width: 5.5rem; }

/* 장바구니 줄: 이름·옵션·금액·수량이 한 줄의 가운데에 선다. `.option` 은 상품
   화면의 선택 묶음(grid·아래 여백 14px)과 이름이 같아, 줄 안의 옵션 글자가 그
   여백을 받아 줄 아래가 비어 있었다. */
.cart > li { align-items: center; }
.cart .option { display: inline; margin: 0; opacity: .65; font-size: 13px; }
.cart > li > .price { margin-right: auto; }

/* 주문번호는 눌러서 들어가는 것이다 — 본문 색에 밑줄도 없으면 링크인지 모른다. */
.order-list a { color: var(--link); font-weight: 600; }

/* 표의 칸과 머리글 링크는 낱말 중간에서 꺾이지 않는다. `.page` 의
   `overflow-wrap: anywhere` 가 375px 에서 「1,00/0원」「장바구/니」를 만들었다 —
   모자란 폭은 표는 `.table-wrap` 의 가로 스크롤이, 머리글은 줄바꿈(.account-nav)이 받는다. */
.order-list td { white-space: nowrap; }
/* 글 제목은 낱말 사이에서만 꺾인다 — 375px 에서 「sqlc 점/검 글 (수/정)」이 됐다. */
.board-list td { word-break: keep-all; overflow-wrap: normal; }
/* 영수증의 주문자 줄은 그 위 배송지와 같은 글자 크기다. */
address + p { font-size: 14px; margin-top: 6px; }

/* 댓글 목록과 입력 폼 사이. 맞닿아 있었다. */
.comments h2 { margin: 0 0 14px; font-size: 18px; }
.comments > .form,
.comments > form { margin-top: 18px; max-width: none; }

/* 상품 목록의 도구 줄: 검색은 왼쪽, 정렬은 오른쪽. 따로 한 줄씩 차지하면서
   서로 다른 간격(18px·36px)으로 떨어져 있었다. */
.listing-tools { display: flex; gap: 12px 20px; align-items: center; flex-wrap: wrap; }
.listing-tools .sort { margin: 0 0 0 auto; }
.listing .categories { margin: 0; }
.sort label { font-size: 13px; opacity: .6; }

/* 상품 상세: 넓은 화면에서는 그림과 정보가 나란히 선다. 그림이 카드 폭을 다
   쓰면(890px) 이름과 가격이 한 화면 아래로 밀려난다. */
.product-detail { display: grid; gap: var(--gap); }
.product-detail .product-gallery { margin: 0; align-self: start; }
.product-info > :first-child { margin-top: 0; }
.product-info .price { margin: 0 0 16px; font-size: 18px; }
.product-info .form { max-width: 24rem; }
.product-info .form .price,
.product-info .form .stock { margin: 8px 0 0; font-size: 13.5px; }
@media (min-width: 768px) {
  .product-detail:has(.product-gallery) { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); align-items: start; }
}

@media (max-width: 767px) {
  :root { --pad: 16px; --gap: 14px; }
  /* iOS Safari 는 글자가 16px 미만인 칸에 초점이 가면 화면을 확대한다(14px 였다). 플랫폼의
     문턱이라 더 구체적인 규칙(필터줄 13px 등)도 이기도록 !important 다. */
  input, select, textarea { font-size: 16px !important; }

  /* **손가락이 누를 수 있는 크기.** 머리글의 링크는 줄 높이(22px)만큼만 높아서
     좁은 화면에서 옆 링크를 같이 누르게 된다. 문장 속 링크는 대상이 아니다 —
     줄 높이를 따라야 글이 읽힌다. */
  .account-nav a,
  .account-nav button,
  .site-menu a,
  .terms a,
  .card-list h2 a,
  .foot-links a,
  .crumb a {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  main { padding: 20px var(--pad) 48px; }
  .site-header { gap: 14px; }
  .account-nav { width: 100%; margin-left: 0; }
  /* 검색칸은 한 줄을 다 쓴다 — 오른쪽이 비어 있었다. */
  .site-search { flex-basis: 100%; max-width: none; }
  .site-search input { flex: 1; }
  /* 홈 히어로의 버튼은 머리글 메뉴와 같다. 휴대폰에서는 첫 화면 절반을 메뉴가 두 번
     차지해서 숨긴다 — 머리글 메뉴가 그대로 있다. */
  .hero-cta { display: none; }

  /* 폼은 좁은 화면에서 폭 제한을 푼다. `max-width: 24rem` 이 그대로 남으면
     화면 한쪽에 몰려 나머지가 빈 채로 남는다. */
  .form,
  .form--wide { max-width: none; }

  /* 필터줄은 세로로 쌓는다. 가로로 두면 입력칸이 버튼에 밀려 한 글자만 남는다.
   *
   * **`flex` 를 되돌린다.** 가로 배치일 때 준 `flex: 1 1 12rem` 은 주축이
   * 가로라는 전제의 값이다. 방향을 세로로 바꾸면 같은 값이 **세로 크기**가
   * 되어 입력칸이 12rem 높이의 상자로 늘어난다 — 실제로 그렇게 그려졌다. */
  .board-filter,
  .sort { flex-direction: column; align-items: stretch; }
  .sort { margin-left: 0; }
  .listing-tools { flex-direction: column; align-items: stretch; }
  .listing-tools .sort { margin: 0; }
  .shop-search input { flex: 1 1 auto; min-width: 0; }
  .board-filter input:not([type="checkbox"]):not([type="radio"]) { flex: none; }

  /* `.btn` 은 `<a>` 에도 붙는다 — `button` 선택자로는 안 잡힌다. */
  .board-filter button,
  .board-filter .btn,
  .sort button,
  .sort .btn { width: 100%; }

  /* 합계는 좁아도 두 열을 유지한다 — 금액이 레이블 아래로 떨어지면 무엇의
     금액인지 읽는 데 눈이 한 번 더 간다. 대신 여백을 줄인다. */
  .totals { padding: 14px 16px; gap: 6px 10px; }

  /* 목록 카드는 한 줄에 하나. 여러 개를 밀어 넣으면 글자가 두 자씩 끊긴다. */
  .product-list { grid-template-columns: 1fr; }

  /* 가로로 붙어 있던 것들이 줄바꿈되면 세로 간격이 필요하다. */
  .cart > li,
    .refunds > li,
  .returns > li { gap: 8px 14px; }
  /* 가격까지가 한 줄, 수량·빼기는 다음 줄 — 상품명 길이에 따라 행마다 버튼 자리가 달랐다. */
  .cart > li > .price { flex-basis: 100%; }

  /* 답글 들여쓰기를 줄인다. 화면이 좁으면 들여쓴 만큼 본문이 사라진다. */
  .comments li.reply { margin-left: 14px; }
}

/* **목록 표는 행마다 한 덩어리로 쌓는다.** 칸을 옆으로 늘어놓으면 줄바꿈하지 않는
 * 작성자·작성일·금액이 자리를 먼저 차지해, 390px 에서 글 제목이 낱말마다 꺾였고
 * 주문 내역의 378,000원은 칸 밖으로 밀려 「378」로 보였다. 첫 칸(제목·주문번호·상품)이
 * 한 줄을 다 쓰고 나머지는 그 아래에 잇는다. 머리줄이 숨으니 숫자 칸은 `data-label` 을 단다.
 * `screen` 인 까닭: A4 인쇄 폭(약 720px)도 767px 에 걸려 영수증이 카드로 풀린다. */
@media screen and (max-width: 767px) {
  .board-list,
  .order-list,
  .board-list tbody,
  .order-list tbody { display: block; }
  .board-list thead,
  .order-list thead { display: none; }
  .board-list tr,
  .order-list tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 12px;
    padding: 12px 4px;
    border-bottom: 1px solid var(--line);
  }
  .board-list tbody tr:last-child,
  .order-list tbody tr:last-child { border-bottom: 0; }
  .board-list td,
  .order-list td { padding: 0; border: 0; white-space: normal; }
  .board-list td:first-child,
  .order-list td:first-child { flex-basis: 100%; white-space: normal; }
  /* 값이 없는 사용자 필드 칸이 빈 자리를 차지했다(「색상」). */
  .board-list td:empty,
  .order-list td:empty { display: none; }
  .board-list td.empty,
  .order-list td.empty { padding: 24px 0; }
  .board-list td[data-label]::before,
  .order-list td[data-label]::before { content: attr(data-label) " "; opacity: .55; font-size: 12.5px; }
}

/* 인쇄: 영수증(P-509)을 종이로 낼 때 머리글 메뉴·검색칸·바닥글·동작 버튼이 같이 찍혔다. */
@media print {
  .site-header, .site-footer, .flash, .order-actions { display: none; }
  main { padding: 0; }
}
