/* ═══ of-components — 예약어 {{ of_user }} 위젯 기본 스타일 ═══
   스킨 마크업(로고/네비/모바일)은 명시적 작성이 원칙이라 이 파일은 예약어가
   생성하는 위젯만 담당한다. 꾸미기는 --of-* 변수를 덮거나 .of-user* 클래스를
   직접 타겟 (클래스명은 안정 계약, 내부 마크업 순서는 계약 아님).

   공통 JS 계약(site-base.js):
   - [data-of-toggle="mobile-nav"] 클릭 → 가장 가까운 <header>에 .of-open 토글
   - body.of-scrolled — 스크롤 20px 이상일 때
   - .of-user-btn 클릭 → .of-user에 .of-open 토글 (바깥 클릭·ESC로 닫힘)
   - [data-of-logout] 클릭 → XSRF 쿠키로 로그아웃 POST 후 data-of-home으로 이동 */

.of-user { position: relative; }

.of-user-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 4px 10px 4px 4px;
    background: var(--of-user-bg, transparent);
    border: 1px solid var(--of-user-border, rgba(15,23,42,.12));
    border-radius: 999px;
    cursor: pointer;
    font: inherit;
    color: inherit;
    transition: background .15s, border-color .15s, box-shadow .15s;
}
.of-user-btn:hover { background: var(--of-user-hover-bg, rgba(15,23,42,.04)); }
.of-user.of-open .of-user-btn { box-shadow: 0 0 0 3px rgba(99,102,241,.14); }

.of-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 700;
    line-height: 1;
    color: var(--of-avatar-color, #ffffff);
    background: var(--of-avatar-bg, linear-gradient(135deg, #6366f1, #8b5cf6));
    flex-shrink: 0;
}

.of-user-name {
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    max-width: 120px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.of-user-caret { width: 14px; height: 14px; opacity: .5; transition: transform .18s; flex-shrink: 0; }
.of-user.of-open .of-user-caret { transform: rotate(180deg); }

.of-user-menu {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    min-width: 220px;
    padding: 6px;
    background: var(--of-menu-bg, #ffffff);
    color: var(--of-menu-color, #334155);
    border: 1px solid var(--of-menu-border, rgba(15,23,42,.08));
    border-radius: 12px;
    box-shadow: 0 18px 40px rgba(15,23,42,.14);
    opacity: 0;
    visibility: hidden;
    transform: translateY(6px);
    transition: opacity .18s ease, transform .18s ease, visibility .18s;
    z-index: 120;
}
.of-user.of-open .of-user-menu { opacity: 1; visibility: visible; transform: translateY(0); }

.of-user-info {
    padding: 10px 12px 9px;
    border-bottom: 1px solid rgba(15,23,42,.06);
    margin-bottom: 6px;
}
.of-user-info strong { display: block; font-size: 14px; }
.of-user-info span   { display: block; font-size: 12px; opacity: .6; margin-top: 1px; }

.of-user-item {
    display: flex;
    width: 100%;
    align-items: center;
    gap: 8px;
    padding: 9px 12px;
    border-radius: 8px;
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    text-align: left;
    color: inherit;
    text-decoration: none;
    background: none;
    border: none;
    cursor: pointer;
    transition: background .15s;
}
.of-user-item:hover { background: var(--of-menu-hover-bg, rgba(15,23,42,.05)); }
.of-user-logout { color: var(--of-logout-color, #dc2626); }

/* ═══ of_login_form — 로그인 폼 위젯 기본 스타일 ═══
   폼 마크업은 시스템이 렌더(예약어)하지만 꾸미기는 열려 있다. 스킨 CSS에서
   아래 --of-auth-* 변수를 덮거나 .of-auth-* 클래스를 직접 타겟하면 된다.
   (필드명 email/password/remember 는 계약 — 마크업 순서엔 의존 금지) */
.of-auth-form {
    display: flex;
    flex-direction: column;
    gap: var(--of-auth-gap, 16px);
    width: 100%;
}
.of-auth-field { display: flex; flex-direction: column; gap: 6px; }
.of-auth-label {
    font-size: var(--of-auth-label-size, .875rem);
    font-weight: 500;
    color: var(--of-auth-label-color, #374151);
}
.of-auth-input {
    width: 100%;
    padding: var(--of-auth-input-pad, 11px 14px);
    font-size: var(--of-auth-input-size, .9375rem);
    color: var(--of-auth-input-color, #111827);
    background: var(--of-auth-input-bg, #fff);
    border: var(--of-auth-input-border-width, 1px) solid var(--of-auth-input-border, #d1d5db);
    border-radius: var(--of-auth-input-radius, 8px);
    outline: none;
    transition: border-color .15s, box-shadow .15s;
}
.of-auth-input:focus {
    border-color: var(--of-auth-focus, #4f46e5);
    box-shadow: 0 0 0 3px var(--of-auth-focus-ring, rgba(79,70,229,.15));
}
.of-auth-error {
    margin: -4px 0 0;
    font-size: .8125rem;
    color: var(--of-auth-error-color, #ef4444);
}
/* ═══ 브레드크럼 계약 클래스 — breadcrumb 데이터를 스킨이 명시적 마크업으로 렌더 ═══
   <nav class="of-crumb">{% for c in breadcrumb %}…{% endfor %}</nav>
   상단 줄(브레드크럼 좌 + 글쓰기 버튼 우)은 .of-crumb-row 로 감싼다. */
.of-crumb-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: var(--of-crumb-row-mb, 1.5rem);
}
.of-crumb {
    display: flex;
    align-items: center;
    gap: .375rem;
    font-size: var(--of-crumb-size, .8125rem);
    color: var(--of-crumb-color, var(--color-text-muted, #6b7280));
    min-width: 0;
    flex-wrap: wrap;
}
.of-crumb a { color: inherit; text-decoration: none; }
.of-crumb a:hover { color: var(--of-crumb-hover, var(--color-text, #111827)); text-decoration: underline; }
.of-crumb-sep { opacity: .4; }
.of-crumb-cur { color: var(--of-crumb-cur-color, inherit); }

/* ═══ of_board_write_btn — 게시판 목록의 글쓰기 버튼 예약어 ═══
   위치는 스킨이 정하고 모양은 --of-write-btn-* 변수 또는 .of-write-btn으로 꾸민다.
   직접 디자인하려면 예약어 대신 can_write/write_url 데이터로 자체 마크업 가능. */
.of-write-btn {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    padding: var(--of-write-btn-pad, 8px 16px);
    background: var(--of-write-btn-bg, var(--of-btn-bg, var(--color-primary, #4f46e5)));
    color: var(--of-write-btn-color, var(--of-btn-text, #fff));
    border-radius: var(--of-write-btn-radius, 8px);
    font-size: var(--of-write-btn-size, .875rem);
    font-weight: 600;
    text-decoration: none;
    transition: opacity .15s;
}
.of-write-btn:hover { opacity: .9; }

/* ═══ of_board_search — 게시판 목록 검색 폼 예약어 ═══
   위치는 스킨이 정하고 모양은 --of-search-* 변수 또는 .of-search-*로 꾸민다.
   직접 디자인하려면 예약어 대신 search.keyword/active/action 데이터로 자체 마크업 가능
   (GET 파라미터명은 q 고정). */
.of-search {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    height: var(--of-search-height, 36px);
    border: 1px solid var(--of-search-border, var(--color-border, #e5e7eb));
    border-radius: var(--of-search-radius, 8px);
    background: var(--of-search-bg, var(--color-surface, #fff));
    overflow: hidden;
    transition: border-color .15s;
}
.of-search:focus-within { border-color: var(--of-search-focus, var(--color-primary, #4f46e5)); }
.of-search-input {
    width: var(--of-search-width, 180px);
    max-width: 100%;
    height: 100%;
    padding: 0 4px 0 12px;
    border: none;
    background: none;
    font-size: var(--of-search-size, .875rem);
    color: var(--of-search-color, var(--color-text, #111827));
    outline: none;
    font-family: inherit;
}
.of-search-input::placeholder { color: var(--of-search-placeholder, var(--color-text-muted, #9ca3af)); }
/* 브라우저 기본 X(취소) 버튼 중복 방지 — 검색 초기화는 재검색/빈 검색으로 */
.of-search-input::-webkit-search-cancel-button { display: none; }
.of-search-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 100%;
    border: none;
    background: none;
    color: var(--of-search-icon-color, var(--color-text-muted, #6b7280));
    cursor: pointer;
}
.of-search-btn:hover { color: var(--of-search-focus, var(--color-primary, #4f46e5)); }
.of-search-icon { width: 16px; height: 16px; }
@media (max-width: 640px) { .of-search-input { width: var(--of-search-width-m, 120px); } }

/* 게시판 글쓰기 — of_board_write (of-auth-* 공유 + 아래 추가) */
.of-auth-textarea { resize: vertical; min-height: 120px; line-height: 1.6; font-family: inherit; }
.of-write-req { color: var(--of-auth-error-color, #ef4444); }
.of-write-choices { display: flex; flex-wrap: wrap; gap: 8px 16px; padding: 4px 0; }
.of-write-choice { display: inline-flex; align-items: center; gap: 6px; font-size: .9375rem; color: var(--of-auth-input-color, #111827); cursor: pointer; }
.of-write-choice input { width: 15px; height: 15px; accent-color: var(--of-auth-submit-bg, var(--of-btn-bg, #4f46e5)); cursor: pointer; }
.of-auth-remember {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: .875rem;
    color: var(--of-auth-muted, #6b7280);
    cursor: pointer;
    user-select: none;
}
.of-auth-remember input { width: 15px; height: 15px; accent-color: var(--of-auth-submit-bg, var(--of-btn-bg, #4f46e5)); cursor: pointer; }
.of-auth-submit {
    width: 100%;
    padding: var(--of-auth-submit-pad, 12px);
    font-size: var(--of-auth-submit-size, 1rem);
    font-weight: 600;
    color: var(--of-auth-submit-color, var(--of-btn-text, #fff));
    background: var(--of-auth-submit-bg, var(--of-btn-bg, #4f46e5));
    border: none;
    border-radius: var(--of-auth-submit-radius, 8px);
    cursor: pointer;
    transition: opacity .15s, transform .1s;
}
.of-auth-submit:hover { opacity: .9; }
.of-auth-submit:active { transform: translateY(1px); }
.of-auth-links {
    text-align: center;
    font-size: .8125rem;
    color: var(--of-auth-muted, #6b7280);
}
.of-auth-link { color: var(--of-auth-link-color, #4f46e5); text-decoration: none; font-weight: 500; }
.of-auth-link:hover { text-decoration: underline; }
/* 가입 동의 문구 — 활성 약관(/terms, /privacy)이 있을 때만 렌더 (2026-07-28) */
.of-auth-agree {
    font-size: .75rem;
    line-height: 1.6;
    color: var(--of-auth-muted, #6b7280);
    text-align: center;
    word-break: keep-all;
}

/* ═══ of_mypage — 마이페이지 위젯 기본 스타일 ═══
   회원 정보 + 정보수정/로그아웃. 꾸미기는 --of-my-* 변수 또는 .of-my-* 클래스로. */
.of-my { width: 100%; }
.of-my-head { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }
.of-my-avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 52px; height: 52px; flex-shrink: 0;
    border-radius: 50%;
    font-size: 22px; font-weight: 700;
    color: var(--of-my-avatar-color, #fff);
    background: var(--of-my-avatar-bg, #4f46e5);
}
.of-my-id { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.of-my-name { font-size: 1.0625rem; font-weight: 700; color: var(--of-my-name-color, #111827); }
.of-my-email { font-size: .8125rem; color: var(--of-my-muted, #6b7280); overflow: hidden; text-overflow: ellipsis; }
.of-my-meta { margin: 0 0 20px; }
.of-my-row {
    display: flex; justify-content: space-between; align-items: center;
    padding: 11px 0;
    font-size: .875rem;
    border-top: 1px solid var(--of-my-divider, #f0f1f3);
}
.of-my-key { color: var(--of-my-muted, #6b7280); }
.of-my-val { color: var(--of-my-name-color, #111827); font-weight: 500; }
.of-my-actions { display: flex; gap: 8px; align-items: stretch; }
.of-my-logout-form { flex: 1; display: flex; margin: 0; }
.of-my-btn {
    flex: 1;
    padding: 11px 12px;
    font-size: .9375rem; font-weight: 600;
    text-align: center; text-decoration: none;
    border-radius: var(--of-my-btn-radius, 8px);
    cursor: pointer;
    transition: opacity .15s, background .15s;
}
.of-my-edit {
    color: var(--of-my-edit-color, #374151);
    background: var(--of-my-edit-bg, #fff);
    border: 1px solid var(--of-my-edit-border, #e5e7eb);
}
.of-my-edit:hover { background: var(--of-my-edit-hover, #f9fafb); }
.of-my-logout {
    color: var(--of-my-logout-color, var(--of-btn-text, #fff));
    background: var(--of-my-logout-bg, var(--of-btn-bg, #4f46e5));
    border: none;
}
.of-my-logout:hover { opacity: .9; }

/* ═══ of_mypage 내 예약 탭 + 예약 상세(/reserve/{id}) — 마이페이지와 같은 결 (2026-09-06) ═══ */
.of-my-rv-list { display: flex; flex-direction: column; margin-top: 8px; }
.of-my-rv-row {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 13px 0; text-decoration: none; color: inherit;
    border-top: 1px solid var(--of-my-divider, #f0f1f3);
}
.of-my-rv-row:hover .of-my-rv-title { color: var(--of-my-accent, var(--color-primary, #4f46e5)); }
.of-my-rv-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.of-my-rv-title { font-size: .9375rem; font-weight: 700; }
.of-my-rv-sub { font-size: .8125rem; color: var(--of-my-muted, #6b7280); }
.of-my-rv-count { font-size: .8125rem; font-weight: 600; color: var(--of-my-muted, #9ca3af); margin-left: 4px; }
.of-my-rv-badge { flex: 0 0 auto; padding: 3px 9px; border-radius: 999px; font-size: .75rem; font-weight: 700; background: #f3f4f6; color: #6b7280; }
.of-my-rv-badge.is-pending { background: #eff6ff; color: #1e40af; }
.of-my-rv-badge.is-confirmed { background: color-mix(in srgb, var(--of-my-accent, var(--color-primary, #4f46e5)) 14%, #fff); color: var(--of-my-accent, var(--color-primary, #4f46e5)); }
.of-my-rv-badge.is-completed { background: #f3f4f6; color: #374151; }
.of-my-rv-badge.is-cancel_requested { background: #fff7e6; color: #b25e09; }
.of-my-rv-badge.is-cancelled, .of-my-rv-badge.is-no_show { background: #f3f4f6; color: #9ca3af; }
/* 예약 상세 */
.of-my-rv-status { display: flex; align-items: center; gap: 8px; padding: 12px 16px; border-radius: var(--of-my-radius, 12px); font-size: .9375rem; font-weight: 700; color: #fff; background: #6b7280; }
.of-my-rv-status.is-confirmed { background: var(--of-my-accent, var(--color-primary, #4f46e5)); }
.of-my-rv-status.is-pending { background: #3182f6; } .of-my-rv-status.is-cancel_requested { background: #f59e0b; }
.of-my-rv-status.is-completed { background: #374151; } .of-my-rv-status.is-cancelled, .of-my-rv-status.is-no_show { background: #9ca3af; }
.of-my-rv-no { font-size: .8125rem; font-weight: 600; color: var(--of-my-accent, var(--color-primary, #4f46e5)); }
.of-my-rv-item { font-size: 1.125rem; font-weight: 800; margin: 2px 0 10px; }
.of-my-rv-reply { margin-top: 14px; padding: 12px 14px; border: 1px solid var(--of-my-card-border, #e5e7eb); border-radius: 10px; font-size: .875rem; line-height: 1.6; white-space: pre-wrap; }
.of-my-rv-reply-title { font-weight: 700; margin-bottom: 4px; }
.of-my-rv-pre { white-space: pre-wrap; word-break: keep-all; font-size: .875rem; line-height: 1.7; color: var(--of-my-ink, #1a1f2e); }
.of-my-rv-notice { padding: 12px 14px; border-radius: 10px; background: #fffbeb; border: 1px solid #ffe4a3; }
.of-my-rv-notice-title { font-size: .875rem; font-weight: 700; color: #92400e; margin-bottom: 4px; }
.of-my-rv-danger { color: #b42318 !important; border-color: #fecdd3 !important; }
.of-my-rv-timeline { list-style: none; padding: 0; margin: 0; }
.of-my-rv-timeline li { display: flex; justify-content: space-between; padding: 9px 0; font-size: .875rem; border-top: 1px solid var(--of-my-divider, #f0f1f3); }
.of-my-rv-timeline li span { color: var(--of-my-muted, #6b7280); }

/* ═══ of_comments — 댓글 위젯 ═══ */
.of-comments { margin-top: 8px; }
.of-comments-title { font-size: 1rem; font-weight: 700; margin: 0 0 16px; }
.of-comments-count { color: var(--of-auth-submit-bg, var(--of-btn-bg, #4f46e5)); }
.of-comment-list { list-style: none; padding: 0; margin: 0 0 20px; display: flex; flex-direction: column; }
.of-comment { padding: 14px 0; border-top: 1px solid var(--color-border, #eef0f2); }
.of-comment-head { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.of-comment-name { font-size: .875rem; font-weight: 600; }
.of-comment-admin { font-size: .6875rem; font-weight: 600; color: var(--of-btn-text, #fff); background: var(--of-auth-submit-bg, var(--of-btn-bg, #4f46e5)); padding: 1px 6px; border-radius: 4px; }
.of-comment-date { margin-left: auto; font-size: .75rem; color: var(--color-text-muted, #9ca3af); }
.of-comment-body { font-size: .9375rem; line-height: 1.6; color: var(--color-text, #374151); }
.of-comment-empty { padding: 20px 0; color: var(--color-text-muted, #9ca3af); font-size: .875rem; text-align: center; }
/* 톰스톤(삭제 자리) 안내 — 스킨 deleted 분기·폴백 정규화(ofNormalizeTombstones) 공통 한 줄 스타일 */
.of-comment-deleted { color: var(--color-text-muted, #9ca3af); font-size: .875rem; line-height: 1.6; }
.of-comment-form { display: flex; flex-direction: column; gap: 10px; }
.of-comment-input { width: 100%; padding: 11px 14px; font-size: .9375rem; border: 1px solid var(--of-auth-input-border, #d1d5db); border-radius: 8px; resize: vertical; min-height: 72px; font-family: inherit; outline: none; }
.of-comment-input:focus { border-color: var(--of-auth-focus, #4f46e5); }
.of-comment-submit { align-self: flex-end; padding: 9px 22px; font-size: .9375rem; font-weight: 600; color: var(--of-btn-text, #fff); background: var(--of-auth-submit-bg, var(--of-btn-bg, #4f46e5)); border: none; border-radius: 8px; cursor: pointer; }
.of-comment-submit:hover { opacity: .9; }
/* Turnstile 위젯과 등록 버튼을 한 줄로 — 위젯 없으면(:empty) 버튼만 우측 정렬 */
.of-comment-foot { display: flex; align-items: center; gap: 12px; }
.of-comment-foot .of-turnstile { margin: 0; }
.of-comment-foot .of-comment-submit { align-self: center; margin-left: auto; }
.of-comment-login { padding: 16px 0; color: var(--color-text-muted, #6b7280); font-size: .875rem; }
.of-comment-login a { color: var(--of-auth-link-color, #4f46e5); font-weight: 500; }
/* 더보기 — of-comment-more 계약 버튼 (모든 스킨 공통 기본 스타일, 스킨 block_style로 덮기 가능) */
.of-comment-more { display: block; width: 100%; margin: 4px 0 20px; padding: 11px; font-size: .875rem; font-weight: 600; color: var(--color-text, #374151); background: var(--color-surface, #f9fafb); border: 1px solid var(--color-border, #e5e7eb); border-radius: 8px; cursor: pointer; transition: background .15s, opacity .15s; font-family: inherit; }
.of-comment-more:hover { background: color-mix(in srgb, var(--color-primary, #4f46e5) 6%, var(--color-surface, #f9fafb)); }
.of-comment-more:disabled { opacity: .6; cursor: default; }
/* 대댓글 접기 토글 — 펼침 상태(aria-expanded=true)에 따라 '보기'/'숨기기' 라벨 전환 (of-replies-toggle 계약) */
.of-replies-hide { display: none; }
.of-replies-toggle[aria-expanded="true"] .of-replies-show { display: none; }
.of-replies-toggle[aria-expanded="true"] .of-replies-hide { display: inline; }

/* ═══ 안내(notice) 공통 컴포넌트 ═══
   형태(패딩/라운드/폰트)는 여기 한 곳에서만 정의하고, 색은 상태 색상 변수
   (--of-success/--of-warn/--of-info — 기본 스타일 설정에서 조정, 셸이 :root 주입)에서
   자동 파생(color-mix)한다. 새 안내가 필요하면 .of-notice + 변형 클래스만 조합할 것. */
.of-notice,
.of-write-status,
.of-write-secret-note,
.of-write-blocked {
    margin: 0 0 16px;
    padding: 11px 14px;
    border-radius: 8px;
    font-size: .875rem;
    line-height: 1.6;
    border: 1px solid transparent;
}
/* 성공(등록 완료 등) */
.of-notice-success,
.of-write-status {
    color:        color-mix(in srgb, var(--of-success, #10b981) 62%, #000);
    background:   color-mix(in srgb, var(--of-success, #10b981) 10%, #fff);
    border-color: color-mix(in srgb, var(--of-success, #10b981) 32%, #fff);
}
/* 경고(재등록 제한 등) */
.of-notice-warn,
.of-write-blocked {
    color:        color-mix(in srgb, var(--of-warn, #f59e0b) 55%, #000);
    background:   color-mix(in srgb, var(--of-warn, #f59e0b) 10%, #fff);
    border-color: color-mix(in srgb, var(--of-warn, #f59e0b) 35%, #fff);
}
/* 안내(비밀글 등 정보성) */
.of-notice-info,
.of-write-secret-note {
    color:        color-mix(in srgb, var(--of-info, #6366f1) 62%, #000);
    background:   color-mix(in srgb, var(--of-info, #6366f1) 9%, #fff);
    border-color: color-mix(in srgb, var(--of-info, #6366f1) 30%, #fff);
}
.of-write-secret-note { margin-bottom: 0; }

/* ═══ 레이어(모달) 공통 — 비밀글 비밀번호 확인 등, 페이지 이동 없는 확인 창 ═══ */
.of-layer-backdrop {
    position: fixed; inset: 0; z-index: 9000;
    background: rgba(15, 23, 42, .5);
    display: flex; align-items: center; justify-content: center;
    padding: 20px;
}
.of-layer {
    width: 100%; max-width: 360px;
    background: var(--of-layer-bg, #fff);
    border-radius: var(--of-layer-radius, 14px);
    padding: 28px 24px 24px;
    text-align: center;
    box-shadow: 0 20px 50px -12px rgba(15, 23, 42, .35);
    animation: ofLayerIn .18s ease-out;
}
@keyframes ofLayerIn { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }
/* 자물쇠 아이콘 — 라인 SVG(currentColor). 색·배경·크기를 --of-layer-ico-* 로 재정의 가능 */
.of-layer-ico {
    width: var(--of-layer-ico-size, 52px); height: var(--of-layer-ico-size, 52px);
    margin: 0 auto 14px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--of-layer-ico-bg, var(--color-surface, #f3f4f6));
    color: var(--of-layer-ico-color, var(--color-text-muted, #9ca3af));
}
.of-layer-ico svg { width: 24px; height: 24px; }
.of-layer-title { font-size: 1.0625rem; font-weight: 700; color: var(--color-text, #111827); }
.of-layer-desc { font-size: .8438rem; color: var(--color-text-muted, #6b7280); margin-top: 6px; line-height: 1.6; }
.of-layer-form { display: flex; gap: 8px; margin-top: 18px; }
.of-layer-form .of-auth-input { flex: 1; }
.of-layer-error { margin: 10px 0 0; font-size: .8125rem; color: var(--of-auth-error-color, #ef4444); }
.of-layer-actions { display: flex; gap: 8px; margin-top: 18px; }
.of-layer-btn {
    flex: 1; padding: 10px 14px; border-radius: 8px;
    font-size: .9rem; font-weight: 600; cursor: pointer; font-family: inherit;
    transition: opacity .15s, background .15s;
}
.of-layer-btn-primary { background: var(--of-btn-bg, var(--color-primary, #4f46e5)); color: var(--of-btn-text, #fff); border: none; }
.of-layer-btn-primary:hover { opacity: .9; }
.of-layer-btn-ghost { background: transparent; color: var(--color-text, #374151); border: 1px solid var(--color-border, #e5e7eb); }
.of-layer-btn-ghost:hover { background: var(--color-surface, #f9fafb); }

/* 비밀글 목록 자물쇠 */
.of-lock { font-size: .8em; margin-right: 4px; opacity: .75; }
.of-write-secret { user-select: none; }
.of-auth-submit:disabled { opacity: .5; cursor: not-allowed; transform: none; }

/* 게스트 작성 필드 (이름/비밀번호) — of_board_write가 비로그인일 때 렌더 */
.of-write-guest { display: grid; grid-template-columns: 1fr 1fr; gap: var(--of-auth-gap, 16px); }
.of-write-hint { font-size: .75rem; font-weight: 400; color: var(--of-auth-muted, #9ca3af); margin-left: 4px; }
@media (max-width: 560px) { .of-write-guest { grid-template-columns: 1fr; } }

/* ═══ of_post_actions — 게시글 액션 ═══ */
.of-post-actions { display: flex; gap: 8px; margin: 28px 0; }
.of-post-del-form { margin: 0; }
.of-post-btn { display: inline-flex; align-items: center; padding: 9px 18px; font-size: .875rem; font-weight: 600; border-radius: 8px; text-decoration: none; cursor: pointer; border: 1px solid var(--color-border, #e5e7eb); background: #fff; color: var(--color-text, #374151); }
.of-post-btn:hover { background: var(--color-surface, #f9fafb); }
.of-post-del { color: #dc2626; border-color: #fecaca; }
.of-post-del:hover { background: #fef2f2; }

/* 게스트 글 삭제 — 비밀번호 입력 (details/summary 네이티브 토글) */
.of-post-guest-del { position: relative; }
.of-post-guest-del summary { list-style: none; cursor: pointer; user-select: none; }
.of-post-guest-del summary::-webkit-details-marker { display: none; }
.of-post-guest-del-form { display: flex; gap: 8px; align-items: center; margin-top: 8px; }
.of-post-guest-del-form .of-auth-input { width: 160px; padding: 8px 12px; font-size: .875rem; }
.of-post-guest-del .of-auth-error { margin-top: 6px; }

/* ── 첨부 파일 (of_board_write 드롭존 + 상세 첨부 목록) ─────────────
   재정의 훅: --of-attach-border, --of-attach-bg, --of-attach-hover */
.of-attach { display: flex; flex-direction: column; gap: 8px; }
.of-attach-drop {
    display: block; width: 100%; padding: 22px 14px; cursor: pointer;
    border: 1.5px dashed var(--of-attach-border, var(--color-border, #d1d5db));
    border-radius: 10px; background: var(--of-attach-bg, transparent);
    color: var(--color-text-muted, #6b7280); font-size: .8438rem; text-align: center;
    transition: border-color .12s, background .12s;
}
.of-attach-drop:hover, .of-attach-drop.of-attach-over {
    border-color: var(--color-primary, #4f46e5);
    background: var(--of-attach-hover, color-mix(in srgb, var(--color-primary, #4f46e5) 4%, transparent));
}
.of-attach-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.of-attach-item {
    display: flex; align-items: center; gap: 8px; padding: 7px 10px;
    border: 1px solid var(--color-border, #e5e7eb); border-radius: 8px; font-size: .8125rem;
}
.of-attach-uploading { opacity: .55; }
/* 읽기 화면(콘텐츠·게시판 상세)의 첨부 항목 — 항목 전체가 다운로드 링크 (2026-08-03) */
.of-attach-link {
    display: flex; align-items: center; gap: 8px; width: 100%;
    color: inherit; text-decoration: none; min-width: 0;
}
.of-attach-link:hover .of-attach-name { color: var(--color-primary, #4f46e5); text-decoration: underline; }
.of-attach-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.of-attach-size { flex-shrink: 0; margin-left: auto; color: var(--color-text-muted, #9ca3af); font-size: .75rem; }
.of-attach-rm {
    flex-shrink: 0; width: 20px; height: 20px; border: none; border-radius: 50%;
    background: transparent; color: var(--color-text-muted, #9ca3af);
    font-size: 15px; line-height: 1; cursor: pointer;
}
.of-attach-rm:hover { background: var(--color-surface, #f3f4f6); color: #ef4444; }
.of-attach-error { margin: 0; font-size: .8125rem; color: var(--of-auth-error-color, #ef4444); }

/* Cloudflare Turnstile 위젯 — 폼 제출 버튼 위 여백. 관리형은 배지 없음(비가시 모드만 배지) */
.of-turnstile { margin: 0 0 14px; }
.of-turnstile:empty { display: none; }

/* 댓글 폼 — 게스트 필드/답글 배너/오류 (of_comment_form 예약어 요소) */
.of-comment-guest { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.of-comment-guest input { padding: 9px 12px; border: 1px solid var(--color-border, #e5e7eb); border-radius: 8px; font-size: .875rem; background: var(--color-bg, #fff); }
.of-comment-replying { display: flex; align-items: center; gap: 6px; font-size: .8125rem; color: var(--color-text-muted, #6b7280); background: var(--color-bg-soft, #f8fafc); border: 1px solid var(--color-border, #eef0f2); border-radius: 8px; padding: 7px 10px; }
.of-comment-replying[hidden] { display: none; } /* display:flex가 UA의 [hidden] 규칙을 이기므로 명시 필요 */
.of-comment-replying-name { font-weight: 600; color: var(--color-text, #374151); }
.of-comment-reply-cancel { margin-left: auto; border: none; background: none; color: var(--color-text-muted, #9ca3af); font-size: .75rem; cursor: pointer; text-decoration: underline; }
.of-comment-error { margin: 0; font-size: .8125rem; color: #dc2626; }
@media (max-width: 560px) { .of-comment-guest { grid-template-columns: 1fr; } }

/* ── 소셜 로그인 버튼 (of_login_form / of_register_form 자동 렌더) ──
   꾸미기: .of-social-* 클래스 / --of-social-* 변수. 브랜드 색은 각 사 가이드 기본값 */
.of-social { margin-top: var(--of-social-mt, 4px); }
.of-social-divider {
    display: flex; align-items: center; gap: 12px;
    margin: var(--of-social-divider-my, 14px) 0;
    color: var(--of-auth-muted, #9ca3af); font-size: .8125rem;
}
.of-social-divider::before, .of-social-divider::after {
    content: ""; flex: 1; height: 1px;
    background: var(--of-social-divider-line, #e5e7eb);
}
.of-social-btns { display: flex; flex-direction: column; gap: 8px; }
.of-social-btn {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    width: 100%; padding: var(--of-social-btn-pad, 11px);
    font-size: var(--of-social-btn-size, .9375rem); font-weight: 500;
    border-radius: var(--of-social-btn-radius, 8px);
    border: 1px solid transparent;
    text-decoration: none; cursor: pointer;
    transition: filter .15s, transform .1s;
}
.of-social-btn:hover { filter: brightness(.96); }
.of-social-btn:active { transform: translateY(1px); }
.of-social-icon { flex: 0 0 auto; }
.of-social--google { background: #fff; color: #3c4043; border-color: #dadce0; }
.of-social--kakao  { background: #FEE500; color: #191919; }
.of-social--naver  { background: #03C75A; color: #fff; }

/* ── 마이페이지 풀 레이아웃 (of_mypage 2026-07-21 개편) ──
   꾸미기: --of-my-* 변수 / .of-my-* 클래스. 구조·기능 마크업은 시스템 소유 */
.of-my--full {
    display: grid; grid-template-columns: var(--of-my-side-w, 240px) 1fr;
    gap: var(--of-my-gap, 20px); align-items: start;
    max-width: var(--of-my-max-w, 960px); margin: 0 auto;
    font-size: .9375rem; color: var(--of-my-ink, #1a1f2e);
}
@media (max-width: 720px) { .of-my--full { grid-template-columns: 1fr; } }

.of-my--full .of-my-card {
    background: var(--of-my-card-bg, #fff);
    border: 1px solid var(--of-my-card-border, #e5e7eb);
    border-radius: var(--of-my-radius, 12px);
    padding: var(--of-my-card-pad, 22px);
}
.of-my-side { display: flex; flex-direction: column; gap: 12px; position: sticky; top: var(--of-my-sticky-top, 0px); }
@media (max-width: 720px) { .of-my-side { position: static; } }

.of-my-profilecard { display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center; }
.of-my--full .of-my-avatar {
    width: 56px; height: 56px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--of-my-avatar-bg, var(--of-my-accent, var(--color-primary, #4f46e5)));
    color: var(--of-my-avatar-color, #fff);
    font-size: 1.25rem; font-weight: 700; margin-bottom: 6px;
}
.of-my--full .of-my-name { font-size: 1.0625rem; font-weight: 700; }
.of-my--full .of-my-email { font-size: .8125rem; color: var(--of-my-muted, #6b7280); word-break: break-all; }
.of-my-joined { font-size: .75rem; color: var(--of-my-muted, #9ca3af); margin-top: 2px; }

.of-my-nav { display: flex; flex-direction: column; background: var(--of-my-card-bg, #fff); border: 1px solid var(--of-my-card-border, #e5e7eb); border-radius: var(--of-my-radius, 12px); overflow: hidden; }
.of-my-nav-item {
    text-align: left; padding: 13px 16px; font-size: .875rem; font-weight: 500;
    background: none; border: none; cursor: pointer; color: inherit;
    border-bottom: 1px solid var(--of-my-card-border, #f3f4f6);
}
.of-my-nav-item:last-child { border-bottom: none; }
.of-my-nav-item:hover { background: var(--of-my-nav-hover, #f9fafb); }
/* 선택(활성) 상태는 버튼색이 아니라 포인트 색상(--color-primary)을 따른다 —
   버튼 배경이 흰색 계열인 테마에서 활성 표시가 사라지는 문제 방지 (2026-07-21) */
.of-my-nav-item.is-active {
    background: var(--of-my-nav-active, color-mix(in srgb, var(--of-my-accent, var(--color-primary, #4f46e5)) 12%, #fff));
    color: var(--of-my-accent, var(--color-primary, #4f46e5));
    font-weight: 600;
}

.of-my-main { display: flex; flex-direction: column; min-width: 0; }
.of-my-panel { display: flex; flex-direction: column; gap: 16px; }
.of-my-panel[hidden] { display: none; }

.of-my-card-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.of-my-card-title { font-size: 1rem; font-weight: 700; margin: 0 0 4px; }
.of-my-desc { font-size: .8125rem; color: var(--of-my-muted, #6b7280); margin: 0 0 14px; }
.of-my-hint { font-size: .75rem; color: var(--of-my-muted, #9ca3af); margin-top: 4px; }
.of-my-card-foot { display: flex; justify-content: flex-end; margin-top: 6px; }
.of-my-status { font-size: .875rem; color: #059669; background: #ecfdf5; border-radius: 8px; padding: 10px 14px; margin-bottom: var(--of-my-gap, 20px); }

.of-my-form { display: flex; flex-direction: column; gap: 14px; }
.of-my-pwchange summary { cursor: pointer; font-size: .875rem; color: var(--of-my-accent, var(--color-primary, #4f46e5)); user-select: none; }
.of-my-pwchange[open] { display: flex; flex-direction: column; gap: 14px; }
.of-my-pwchange[open] summary { margin-bottom: 2px; }

.of-my--full .of-my-btn {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 10px 18px; font-size: .875rem; font-weight: 600;
    border-radius: 8px; border: 1px solid var(--of-my-btn-border, var(--of-my-card-border, #e5e7eb));
    background: var(--of-my-btn-bg, var(--of-my-card-bg, #fff));
    color: var(--of-my-btn-color, inherit); cursor: pointer; text-decoration: none;
}
.of-my-btn--primary {
    background: var(--of-my-accent, var(--of-btn-bg, var(--color-primary, #4f46e5)));
    border-color: transparent;
    color: var(--of-btn-text, #fff);
}
.of-my-btn--danger { background: #dc2626; border-color: transparent; color: #fff; }
.of-my-btn:disabled { opacity: .5; cursor: not-allowed; }
.of-my--full .of-my-logout { width: 100%; color: var(--of-my-muted, #6b7280); }

.of-my-card--danger { border-color: #fecaca; background: var(--of-my-danger-bg, #fef2f2); }
.of-my-card--danger .of-my-card-title { color: #dc2626; }

/* 계정 탈퇴 — details 접기(1차 확인) + 동의 체크 + 본인 확인 폼 */
.of-my-withdraw summary { list-style: none; display: inline-flex; cursor: pointer; }
.of-my-withdraw summary::-webkit-details-marker { display: none; }
.of-my-withdraw[open] summary { display: none; }
.of-my-withdraw-body { display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
.of-my-withdraw-send { align-self: flex-start; }
.of-my-check { display: flex; align-items: center; gap: 8px; font-size: .875rem; cursor: pointer; }
.of-my-check input { accent-color: #dc2626; }

.of-my-badge { font-size: .75rem; font-weight: 600; color: #6b7280; background: #f3f4f6; border-radius: 99px; padding: 3px 10px; white-space: nowrap; }
.of-my-badge--on { color: #059669; background: #ecfdf5; }

.of-my-social-list { display: flex; flex-direction: column; }
.of-my-social-row { display: flex; align-items: center; gap: 12px; padding: 13px 0; border-bottom: 1px solid var(--of-my-card-border, #f3f4f6); }
.of-my-social-row:last-child { border-bottom: none; }
.of-my-social-icon { width: 38px; height: 38px; border-radius: 10px; display: flex; align-items: center; justify-content: center; flex: none; border: 1px solid var(--of-my-card-border, #e5e7eb); background: var(--of-my-card-bg, #fff); }
.of-my-social-icon--kakao { background: #FEE500; border-color: transparent; }
.of-my-social-icon--naver { background: #03C75A; border-color: transparent; }
.of-my-social-info { display: flex; flex-direction: column; min-width: 0; }
.of-my-social-info strong { font-size: .875rem; }
.of-my-social-info span { font-size: .78125rem; color: var(--of-my-muted, #9ca3af); }
.of-my-social-action { margin-left: auto; }
.of-my-social-btn {
    margin-left: auto; padding: 7px 14px; font-size: .8125rem; font-weight: 600;
    border-radius: 8px; border: 1px solid var(--of-my-btn-border, var(--of-my-card-border, #e5e7eb));
    background: var(--of-my-btn-bg, var(--of-my-card-bg, #fff));
    cursor: pointer; text-decoration: none; color: var(--of-my-btn-color, inherit);
}
.of-my-social-btn--unlink { color: var(--of-my-muted, #9ca3af); border: none; background: none; }
.of-my-social-btn--unlink:hover { color: #dc2626; }

/* 보안 탭 임베드 (2026-07-21 — 비밀번호 변경 이동 + 2FA 페이지 이동 없이) */
.of-my-coderow { display: flex; gap: 8px; }
.of-my-coderow .of-auth-input { flex: 1; min-width: 0; }
.of-my-coderow .of-my-btn { flex: none; white-space: nowrap; }
.of-my-tfchoice { display: flex; flex-direction: column; gap: 8px; }
.of-my-qrwrap { display: flex; justify-content: center; padding: 6px 0 2px; }
.of-my-qrwrap svg { background: #fff; border: 1px solid var(--of-my-card-border, #e5e7eb); border-radius: 10px; padding: 8px; }
.of-my-recovery { border: 1px solid #f59e0b; background: #fffbeb; border-radius: 10px; padding: 14px 16px; margin-bottom: 14px; }
.of-my-recovery strong { font-size: .875rem; }
.of-my-recovery p { font-size: .78125rem; color: #92400e; margin: 5px 0 10px; }
.of-my-recovery-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; font-family: monospace; font-size: .8125rem; }

/* 프로필 이미지 (2026-07-21) — 업로드 라벨 오버레이 + 이미지 아바타 */
.of-my-avatarwrap { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.of-my-avatar-edit { position: relative; cursor: pointer; display: inline-block; }
.of-my-avatar-edit input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; }
.of-my-avatar-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.of-my--full .of-my-avatar--img { width: 56px; height: 56px; border-radius: 50%; object-fit: cover; display: block; margin-bottom: 6px; }
.of-my-avatar-badge {
    position: absolute; right: -2px; bottom: 2px;
    width: 20px; height: 20px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 11px; background: var(--of-my-card-bg, #fff); color: var(--of-my-muted, #6b7280);
    border: 1px solid var(--of-my-card-border, #e5e7eb);
}
/* 제거 × 배지 — 아바타 우상단 (연필 배지와 짝) */
.of-my-avatarwrap { position: relative; }
.of-my-avatar-removeform { position: absolute; top: -6px; left: calc(50% + 20px); margin: 0; }
.of-my-avatar-remove {
    width: 20px; height: 20px; border-radius: 50%; padding: 0;
    display: flex; align-items: center; justify-content: center;
    font-size: 13px; line-height: 1; cursor: pointer;
    background: var(--of-my-card-bg, #fff);
    color: var(--of-my-muted, #9ca3af);
    border: 1px solid var(--of-my-card-border, #e5e7eb);
    transition: color .12s, border-color .12s;
}
.of-my-avatar-remove:hover { color: #dc2626; border-color: #fca5a5; }
.of-avatar--img { width: var(--of-avatar-size, 32px); height: var(--of-avatar-size, 32px); border-radius: 50%; object-fit: cover; }

/* ══ 갤러리 라이트박스 뷰어 (data-of-gallery 계약, 2026-08-07) ══════════════════
   동작·구조는 시스템 소유(site-base.js) — 스킨은 아래 CSS 변수로 톤만 조절한다:
   --of-viewer-bg(백드롭) / --of-viewer-icon(화살표·닫기 색) / --of-viewer-counter(카운터 색) */
.of-viewer {
  position: fixed; inset: 0; z-index: 9500;
  display: none; align-items: center; justify-content: center;
  background: var(--of-viewer-bg, rgba(0, 0, 0, .92));
  touch-action: pan-y;
}
.of-viewer.of-open { display: flex; }
body.of-viewer-lock { overflow: hidden; }
/* 스테이지 — 2겹 레이어로 크로스페이드+방향 슬라이드 전환 (site-base.js가 교대).
   슬라이드 transform은 레이어(div)가, 핀치 줌 transform은 안의 img가 각자 소유 — 충돌 방지.
   touch-action: none — 핀치·스와이프를 브라우저 제스처에 뺏기지 않고 직접 처리 */
.of-viewer-stage { position: relative; width: 100%; height: 100%; touch-action: none; }
.of-viewer-layer {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none;
  transition: opacity .28s ease, transform .28s ease;
}
.of-viewer-layer.is-active { opacity: 1; }
.of-viewer-layer img {
  max-width: 92vw; max-height: 78vh;
  object-fit: contain; border-radius: 4px;
  user-select: none; -webkit-user-drag: none;
}
.of-viewer-close {
  position: absolute; top: 14px; right: 14px; z-index: 2;
  width: 44px; height: 44px; background: none; border: none; cursor: pointer;
}
.of-viewer-close span { position: absolute; left: 50%; top: 50%; width: 22px; height: 2px; border-radius: 2px; background: var(--of-viewer-icon, #fff); }
.of-viewer-close span:first-child { transform: translate(-50%, -50%) rotate(45deg); }
.of-viewer-close span:last-child  { transform: translate(-50%, -50%) rotate(-45deg); }
.of-viewer-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 48px; height: 72px; background: none; border: none; cursor: pointer;
  font-size: 44px; line-height: 1; color: var(--of-viewer-icon, #fff); opacity: .75; transition: opacity .15s;
}
.of-viewer-nav:hover { opacity: 1; }
.of-viewer-prev { left: 6px; }
.of-viewer-next { right: 6px; }
.of-viewer-counter {
  position: absolute; bottom: 92px; left: 50%; transform: translateX(-50%);
  font-size: 13px; letter-spacing: .06em; color: var(--of-viewer-counter, rgba(255, 255, 255, .75));
}

/* 하단 썸네일 스트립 — 현재 장 하이라이트, 클릭 점프, 많으면 가로 스크롤 */
.of-viewer-thumbs {
  position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%);
  display: flex; gap: 8px; max-width: 92vw; padding: 4px;
  overflow-x: auto; scrollbar-width: none;
}
.of-viewer-thumbs::-webkit-scrollbar { display: none; }
.of-viewer-thumb {
  flex-shrink: 0; width: 56px; height: 42px; padding: 0;
  border: 2px solid transparent; border-radius: 6px; overflow: hidden;
  background: none; cursor: pointer; opacity: .45; transition: opacity .15s, border-color .15s;
}
.of-viewer-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.of-viewer-thumb:hover { opacity: .8; }
.of-viewer-thumb.is-active { opacity: 1; border-color: var(--of-viewer-icon, #fff); }

@media (max-width: 640px) {
  .of-viewer-nav { display: none; }                          /* 모바일은 스와이프 전용 */
  .of-viewer-thumb { width: 44px; height: 33px; }
  .of-viewer-counter { bottom: 76px; }
}

/* ══ of-reveal — 스크롤 등장 모션 공통 계약 (2026-08-08) ═══════════════════
   사용: 등장시킬 태그에 class="of-reveal" 하나. 시차는 style="--of-delay:.15s".
   실행: site-base.js의 공유 옵저버 한 곳이 뷰포트 진입 시 .in을 부여 —
   블록마다 옵저버 스크립트를 복사하지 않는다.
   안전장치: 숨김 상태는 html.of-anim(옵저버 초기화가 부여) 하위에서만 적용 —
   JS 미실행·미지원·구버전 캐시에서는 그냥 보인다(백지 방지 폴백).
   에디터 캔버스·미리보기는 자체 reveal 무력화가 있어 항상 완성형으로 보인다. */
/* 전환은 등장(.in) 쪽에만 둔다 — 숨김 규칙에 transition이 있으면 html.of-anim이 붙는 순간 1→0으로 서서히
   사라지는 전환이 먼저 돌고 곧바로 등장이 겹쳐 상쇄된다(첫 화면 히어로가 "모션 없음"으로 보이던 실체, 2026-09-05 실측) */
html.of-anim .of-reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: none;   /* 숨김은 즉시 — 블록이 .of-reveal에 transition을 덮어써도 사라지는 전환이 생기지 않게 */
}
html.of-anim .of-reveal.in {
  opacity: 1;
  transform: none;
  transition: opacity var(--of-dur, .6s) ease, transform var(--of-dur, .6s) ease;   /* 블록 조정은 --of-dur 변수로 */
  transition-delay: var(--of-delay, 0s);
}
@media (prefers-reduced-motion: reduce) {
  html.of-anim .of-reveal { opacity: 1; transform: none; transition: none; }
}

/* ── 문의 블록 폼 (of_contact_form 계약, 2026-08-09) ──────────────────────────
   구조 계약: form.of-contact[data-of-contact] > .of-contact-body(필드들) + .of-contact-done.
   서버(ContactFormBlock)가 마크업을 렌더하므로 스킨·블록은 이 클래스로 꾸미기만 한다.
   색은 전부 디자인 토큰 — 어느 사이트에 놓아도 무난한 기본기 */
.of-contact { max-width: 640px; margin: 0 auto; }
.of-contact-row {
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
}
@media (max-width: 640px) { .of-contact-row { grid-template-columns: 1fr; } }
.of-contact-field { margin-bottom: 14px; }
.of-contact-label {
  display: block; margin-bottom: 6px;
  font-size: .875rem; font-weight: 600; color: var(--color-text, #111827);
}
.of-contact-input, .of-contact-textarea {
  width: 100%; padding: 11px 14px;
  border: 1px solid var(--color-border, #E5E7EB);
  border-radius: var(--radius, 8px);
  background: var(--color-bg, #fff); color: var(--color-text, #111827);
  font: inherit; font-size: .9375rem;
}
.of-contact-input:focus, .of-contact-textarea:focus {
  outline: none; border-color: var(--color-primary, #3B82F6);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary, #3B82F6) 15%, transparent);
}
.of-contact-textarea { resize: vertical; min-height: 130px; line-height: 1.7; }
.of-contact-error {
  margin: 0 0 12px; font-size: .875rem; color: #DC2626;
}
.of-contact-submit {
  display: inline-flex; align-items: center; justify-content: center;
  width: 100%; padding: 13px 20px; border: 0; cursor: pointer;
  border-radius: var(--radius, 8px);
  background: var(--color-primary, #3B82F6); color: var(--color-primary-text, #fff);
  font: inherit; font-size: .9375rem; font-weight: 700;
  transition: filter .15s;
  text-decoration: none;
}
.of-contact-submit:hover { filter: brightness(1.06); }
.of-contact-submit:disabled { opacity: .55; cursor: default; }
.of-contact-submit.is-busy { opacity: .7; }
/* 인라인 완료 — 제출 성공 시 폼 자리를 대신한다 (site-base.js가 전환) */
.of-contact-done {
  padding: 44px 20px; text-align: center;
  border: 1px solid var(--color-border, #E5E7EB);
  border-radius: var(--radius, 8px);
  background: color-mix(in srgb, var(--color-primary, #3B82F6) 4%, var(--color-bg, #fff));
}
.of-contact-done-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; margin-bottom: 12px; border-radius: 50%;
  background: var(--color-primary, #3B82F6); color: var(--color-primary-text, #fff);
  font-size: 1.25rem; font-weight: 800;
}
.of-contact-done-text {
  margin: 0; font-size: 1rem; font-weight: 600;
  color: var(--color-text, #111827); word-break: keep-all;
}
/* 회원 전용 게시판 + 비로그인 — 로그인 안내 박스 */
.of-contact--login {
  padding: 40px 20px; text-align: center;
  border: 1px solid var(--color-border, #E5E7EB); border-radius: var(--radius, 8px);
}
.of-contact-login-text { margin: 0 0 16px; font-size: .9375rem; color: var(--color-text-muted, #6B7280); }
.of-contact-login-btn { width: auto; padding: 11px 32px; }
/* 미리보기 목업 안내 줄 (에디터·자산 관리에서만 보임) */
.of-contact-note {
  margin: 10px 0 0; text-align: center;
  font-size: .8125rem; color: var(--color-text-muted, #6B7280);
}

/* ══ of-scroll — 스크롤 진행률 공통 계약 (2026-08-25, 3호 아카데미아) ═══════════
   사용: 컨테이너에 data-of-scroll(+range), 블록 CSS는 var(--of-p)(0~1)로 transform/opacity/
   clip-path를 계산. 값 기록은 site-base.js 한 곳. 여기의 --of-p:1은 폴백(JS 미실행·에디터 캔버스·
   미리보기 = 완성형). 자식 구간 매핑 예: --p2: clamp(0, calc((var(--of-p) - .3) / .7), 1). */
[data-of-scroll] { --of-p: 1; }
@media (prefers-reduced-motion: reduce) { [data-of-scroll] { --of-p: 1 !important; } }

/* ══ of-fullpage — 풀페이지 스냅 공통 계약 (2026-08-25, 4호 슬래시 스튜디오) ═══════
   켜는 곳: 페이지 설정 ▸ 모션 "풀페이지 스냅" → 셸 <main data-of-fullpage>. 최상위 섹션 = 한 화면.
   proximity(강제 아님): 100vh보다 긴 섹션은 안에서 자연 스크롤, 맞는 데서만 스냅.
   도트 내비(.of-fp-nav)는 site-base가 생성 — 테마는 이 클래스로 꾸민다. ≤767·터치는 일반 스크롤 폴백. */
html:has(main[data-of-fullpage]) { scroll-snap-type: y proximity; }
main[data-of-fullpage] > * { min-height: 100vh; min-height: 100svh; scroll-snap-align: start; scroll-snap-stop: normal; }
.of-fp-nav { position: fixed; right: clamp(12px, 1.6vw, 28px); top: 50%; transform: translateY(-50%); z-index: 60; display: flex; flex-direction: column; gap: 10px; margin: 0; padding: 0; list-style: none; }
.of-fp-dot { display: block; width: 8px; height: 8px; border-radius: 999px; border: 1px solid var(--of-fp-dot, rgba(255,255,255,.55)); background: transparent; cursor: pointer; padding: 0; transition: transform .25s ease, background .25s ease; }
.of-fp-dot.is-current { background: var(--of-fp-dot-on, #fff); border-color: var(--of-fp-dot-on, #fff); transform: scale(1.35); }
@media (max-width: 767px), (hover: none) {
  html:has(main[data-of-fullpage]) { scroll-snap-type: none; }
  main[data-of-fullpage] > * { scroll-snap-align: none; }
  .of-fp-nav { display: none; }
}
@media (prefers-reduced-motion: reduce) { html:has(main[data-of-fullpage]) { scroll-behavior: auto; } }
/* 밝은 섹션 위 도트 — 섹션 루트 data-of-theme="light" (site-base가 nav data-theme로 반영) */
.of-fp-nav[data-theme="light"] .of-fp-dot { border-color: var(--of-fp-dot-light, rgba(11,11,12,.45)); }
.of-fp-nav[data-theme="light"] .of-fp-dot.is-current { background: var(--of-fp-dot-on-light, #0B0B0C); border-color: var(--of-fp-dot-on-light, #0B0B0C); }
