/* ── 밤의 서재, 그리고 비밀 문 — 단일 세계 ─────────────
     책장인 줄 알았는데 문이었다. 램프 두 개가 유일한 빛.
     스크롤바는 숨기고, 사다리가 그 역할을 대신한다. */
  :root {
    --dark: #171009;
    --wall: #241708;
    --wood: #3A2712;
    --wood2: #4A3218;
    --wood3: #6E4E28;
    --parchment: #E2D5B8;
    --parchment-dim: #A3947A;
    --brass: #E0B15E;
    --brass-dim: #97742F;
    --wax: #8E2F23;
    --line: #4A3A22;
    --room-glow: #2E2210;
    --paperlabel: #C9B98E;
    /* 읽음 상태 3색 — 서재의 재료에서 고른 검증 통과 팔레트: 이끼 녹, 놋쇠, 라피스 */
    --st-done: #3E8A5F;
    --st-doing: #BC852D;
    --st-todo: #5C79D0;
  }
  * { box-sizing: border-box; }
  /* hidden 속성은 브라우저 기본 스타일의 display:none 으로만 걸려 있어서,
     클래스 하나가 display 를 지정하면 조용히 무력해진다
     (.gate form { display: flex } 이 코드 입력란을 계속 보이게 했다).
     여기서 못을 박아 둔다 — hidden 은 언제나 숨은 것이다. */
  [hidden] { display: none !important; }
  /* 브라우저 스크롤바 숨김 — 사다리가 위치를 알려준다 */
  html { scrollbar-width: none; }

  /* 가로 넘침 주의: 스크롤바를 숨겨 두었기 때문에 무언가 옆으로 조금만
     넘쳐도 모바일에서는 화면이 축소되며 "좌우 여백이 넓어진" 것처럼 보이고,
     정작 원인은 보이지 않는다.
     html/body 에 overflow-x: clip 을 걸어 한 번에 막으려 해봤지만 통하지
     않는다 — 뿌리 요소의 overflow 는 뷰포트로 전파되어 clip 이 무시된다
     (직접 재본 결과). hidden 은 통하더라도 상단 막대의 position: sticky 를
     깨뜨리므로 쓰지 말 것. 넘치는 요소를 하나씩 잡는 수밖에 없다. */
  html::-webkit-scrollbar, body::-webkit-scrollbar { display: none; width: 0; }
  body {
    background: var(--dark); color: var(--parchment);
    font-family: "Noto Sans KR", "Apple SD Gothic Neo", sans-serif;
    font-weight: 300; line-height: 1.75;
    -webkit-font-smoothing: antialiased;
  }
  body::before { /* 서재 전체를 감싸는 어둠의 비네트 */
    content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
    background:
      radial-gradient(ellipse 120% 90% at 50% 30%, transparent 55%, rgba(0,0,0,.42) 100%),
      repeating-linear-gradient(90deg, rgba(0,0,0,.03) 0 2px, transparent 2px 90px);
  }
  ::selection { background: rgba(224,177,94,.32); color: #F5EDD4; }

  /* ── 입구 등장 — 촛불이 켜지듯 순서대로 ─────────────── */
  @keyframes riseIn {
    from { opacity: 0; transform: translateY(14px); }
    to { opacity: 1; transform: none; }
  }
  @keyframes viewIn {
    from { opacity: 0; transform: translateX(-50%) translateY(10px); }
    to { opacity: 1; transform: translateX(-50%); }
  }
  .foyer .latin { animation: riseIn .7s ease backwards; }
  .foyer h1 { animation: riseIn .7s ease .14s backwards; }
  .foyer p.sub { animation: riseIn .7s ease .28s backwards; }
  .foyer .secret { animation: riseIn .7s ease .42s backwards; }
  .foyer .viewrow { animation: viewIn .7s ease .56s backwards; }
  .wrap { max-width: 880px; margin: 0 auto; padding: 0 46px 0 18px; }
  @media (min-width: 990px) { .wrap { padding-right: 18px; } }

  /* ── 고정 머리띠 ─────────────────────────────────────── */
  .topbar {
    position: sticky; top: 0; z-index: 30;
    background: rgba(23, 16, 9, .93);
    border-bottom: 1px solid var(--line);
    backdrop-filter: blur(6px);
  }
  .topbar .inner {
    max-width: 880px; margin: 0 auto; padding: 10px 46px 10px 18px;
    display: flex; align-items: center; gap: 14px;
  }
  @media (min-width: 990px) { .topbar .inner { padding-right: 18px; } }
  .topbar .mark {
    font-family: "Gowun Batang", serif; font-weight: 700; font-size: 15px;
    letter-spacing: .1em; flex: none;
    display: flex; align-items: center; gap: 9px;
  }
  .topbar .tseal { /* 작은 장서인 */
    width: 22px; height: 22px; border-radius: 50%; flex: none;
    border: 1.5px solid var(--wax); color: var(--wax);
    display: grid; place-items: center;
    font-size: 11px; font-weight: 700; transform: rotate(-8deg);
  }
  .topbar input {
    flex: 1; min-width: 0; font: inherit; font-size: 13px;
    background: rgba(58,39,18,.5); color: var(--parchment);
    border: 1px solid var(--line); padding: 7px 14px;
    transition: border-color .2s ease;
  }
  .topbar input:focus-visible { outline: none; border-color: var(--brass-dim); box-shadow: 0 1px 0 var(--brass-dim); }
  .topbar input::placeholder { color: var(--parchment-dim); }
  .topbar .census {
    flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 3px;
    font-family: "IBM Plex Mono", monospace; font-size: 10.5px;
    color: var(--brass-dim); letter-spacing: .1em; font-variant-numeric: tabular-nums;
  }
  .topbar .census i {
    display: block; width: 84px; height: 3px; background: rgba(0,0,0,.5); border-radius: 999px; overflow: hidden;
  }
  .topbar .census i b { display: block; height: 100%; width: 98.8%; background: var(--brass-dim); }
  @media (max-width: 560px) { .topbar .census { display: none; } }

  /* ── 사다리 ──────────────────────────────────────────── */
  .ladder {
    position: fixed; right: 8px; top: 42vh; bottom: 14px;
    z-index: 35; display: flex; flex-direction: column; align-items: center;
    user-select: none;
  }
  .ladder .rail {
    position: relative; width: 24px; flex: 1; min-height: 180px;
    border-left: 2.5px solid var(--wood3); border-right: 2.5px solid var(--wood3);
    background: repeating-linear-gradient(180deg, transparent 0 13px, var(--wood2) 13px 15px);
    border-radius: 3px; cursor: pointer;
  }
  .ladder .car {
    position: absolute; left: -5px; right: -5px; height: 30px; top: 0;
    background: linear-gradient(180deg, var(--brass), var(--brass-dim));
    border-radius: 3px; box-shadow: 0 0 14px rgba(224,177,94,.45);
    transition: top .08s linear; pointer-events: none;
  }
  .ladder .rail::before, .ladder .rail::after { /* 위아래 무쇠 걸이 */
    content: ""; position: absolute; left: -5px; right: -5px; height: 5px;
    background: linear-gradient(180deg, #3A3A34, #1C1C18);
    border-radius: 3px;
  }
  .ladder .rail::before { top: -6px; }
  .ladder .rail::after { bottom: -6px; }
  .ladder .dot {
    position: absolute; left: 50%; transform: translate(-50%, -50%);
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--wood3); border: 1.5px solid var(--dark);
    cursor: pointer; z-index: 2; padding: 0; appearance: none;
    transition: background .25s ease, box-shadow .25s ease;
  }
  .ladder .dot.hit { background: var(--brass); box-shadow: 0 0 8px rgba(224,177,94,.7); }
  .ladder .dot.here { background: var(--parchment); box-shadow: 0 0 7px rgba(226,213,184,.65); }
  .ladder .dot:hover, .ladder .dot:focus-visible { background: var(--brass); outline: none; }
  .ladder .alt {
    margin-top: 8px; font-family: "IBM Plex Mono", monospace; font-size: 9.5px;
    color: var(--brass-dim); letter-spacing: .06em; writing-mode: vertical-rl;
    font-variant-numeric: tabular-nums;
  }
  @media (max-width: 620px) { .ladder { right: 5px; top: 48vh; } }

  /* ── 입구 ────────────────────────────────────────────── */
  .foyer {
    position: relative; text-align: center; overflow: hidden;
    padding: 70px 18px 88px;
    background:
      linear-gradient(180deg, #0E0A05 0%, var(--dark) 72%, #1E1409 100%);
  }
  .foyer::after { /* 마루 */
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 26px;
    background:
      repeating-linear-gradient(90deg, rgba(0,0,0,.25) 0 2px, transparent 2px 64px),
      linear-gradient(180deg, #2E1E0C, #241708);
  }
  .foyer .fcandle { /* 구분선 위에 세워진 밀랍초 */
    position: absolute; bottom: 24px; width: 11px; height: 38px;
    border-radius: 3px 3px 1px 1px; pointer-events: none;
    background: linear-gradient(180deg, #F2E7C8 0%, #E2D2AC 55%, #D6C6A0 100%);
    box-shadow: -1.5px 0 0 rgba(0,0,0,.28), inset -2px 0 3px rgba(0,0,0,.15);
  }
  .foyer .fcandle.l { left: 8%; } .foyer .fcandle.r { right: 8%; }
  .foyer .fcandle.c { left: 50%; transform: translateX(-50%); height: 30px; }
  .foyer .fcandle::before { /* 철제 받침 접시 */
    content: ""; position: absolute; bottom: -6px; left: 50%; transform: translateX(-50%);
    width: 24px; height: 6px; border-radius: 2px 2px 5px 5px;
    background: linear-gradient(180deg, #3A3A40, #1E1E24);
  }
  .foyer .fcandle::after { /* 불꽃 */
    content: ""; position: absolute; top: -16px; left: 50%; transform: translateX(-50%);
    width: 10px; height: 16px;
    border-radius: 50% 50% 50% 50% / 64% 64% 36% 36%;
    background: radial-gradient(circle at 50% 75%, #FFF2C4 0%, #EDBC55 52%, rgba(237,188,85,0) 100%);
    box-shadow: 0 0 26px 10px rgba(224,177,94,.5);
    animation: flick 2.6s ease-in-out infinite;
  }
  .foyer .fcandle.r::after { animation-duration: 2.1s; }
  .foyer .latin {
    font-family: "Cormorant", serif; font-style: italic; font-size: 13px;
    letter-spacing: .32em; color: var(--brass); text-transform: uppercase;
    display: block; margin-bottom: 12px;
  }
  .foyer h1 {
    margin: 0 0 12px; font-family: "Gowun Batang", serif; font-weight: 700;
    font-size: clamp(32px, 6.5vw, 48px); letter-spacing: .12em;
    text-shadow: 0 0 34px rgba(224,177,94,.22); text-wrap: balance;
  }
  .foyer p.sub { margin: 0; font-size: 13.5px; color: var(--parchment-dim); }
  .foyer .secret {
    margin-top: 16px; font-family: "IBM Plex Mono", monospace; font-size: 11px;
    letter-spacing: .2em; color: var(--brass-dim);
  }

  /* ── 서가 벽 섹션 ────────────────────────────────────── */
  .wallsec {
    margin-top: 44px; position: relative; transition: opacity .4s ease; scroll-margin-top: 64px;
    perspective: 850px; perspective-origin: 30% 50%; /* 경첩 쪽에서 보는 시점 — 열리는 쪽이 크게 다가온다 */
  }
  /* 내려갈수록 벽에 불이 켜진다 */
  .wallsec.pre { opacity: 0; transform: translateY(20px); }
  .wallsec.lit { opacity: 1; transform: none; transition: opacity .8s ease, transform .8s ease; }
  body.door-open .wallsec:not(.open) { opacity: .3; }
  .sec-label { display: flex; align-items: baseline; gap: 12px; margin-bottom: 10px; flex-wrap: wrap; }
  .sec-label b { font-family: "Gowun Batang", serif; font-weight: 700; font-size: 17px; letter-spacing: .08em; }
  .sec-label .desc { font-size: 12px; color: var(--parchment-dim); }
  .sec-label .hits {
    margin-left: auto; font-family: "IBM Plex Mono", monospace; font-size: 10.5px;
    color: var(--brass-dim); letter-spacing: .1em;
  }

  .panelbox { position: relative; }
  .panelbox::before { /* 문틈으로 새는 빛 */
    content: ""; position: absolute; left: -2px; top: 4px; bottom: 4px; width: 3px; z-index: 3;
    background: linear-gradient(180deg, transparent, var(--brass) 30%, var(--brass) 70%, transparent);
    opacity: 0; transition: opacity .3s ease; pointer-events: none;
    box-shadow: 0 0 18px 4px rgba(224,177,94,.5);
  }
  .panelbox.leak::before { opacity: .9; }

  .panel {
    position: relative; z-index: 2;
    border: 2px solid var(--wood2);
    border-left: 10px solid var(--wood3); border-right: 10px solid var(--wood3);
    background:
      repeating-linear-gradient(90deg, rgba(0,0,0,.16) 0 3px, transparent 3px 48px),
      repeating-linear-gradient(180deg, rgba(255,255,255,.015) 0 2px, transparent 2px 7px),
      linear-gradient(180deg, var(--wall), #1C1206);
    box-shadow:
      inset 0 0 46px rgba(0,0,0,.6),
      inset 4px 0 6px -2px rgba(0,0,0,.5), inset -4px 0 6px -2px rgba(0,0,0,.5),
      inset 0 3px 0 rgba(255,255,255,.04),
      0 16px 38px rgba(0,0,0,.55);
    padding: 28px 12px 12px;
    transform-origin: left center;
    /* 닫힐 때: 문이 즉시 다시 나타나며 부드럽게 스윙해 닫힌다 */
    transition: transform 1.3s cubic-bezier(.6, 0, .2, 1), opacity .45s ease;
  }
  .panel::before { /* 상단 몰딩(코니스) — 치형 장식과 이중 단 */
    content: ""; position: absolute; left: -10px; right: -10px; top: -4px; height: 16px;
    background:
      repeating-linear-gradient(90deg, rgba(0,0,0,.35) 0 3px, transparent 3px 9px) 0 100% / 100% 7px no-repeat,
      linear-gradient(180deg, #8A6840 0%, #7A5A36 30%, var(--wood3) 62%, #4A3218 100%);
    border-radius: 3px 3px 0 0;
    box-shadow: 0 4px 8px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.1);
  }
  .panel::after { /* 하단 받침(플린스) */
    content: ""; position: absolute; left: -10px; right: -10px; bottom: -4px; height: 11px;
    background: linear-gradient(180deg, #6E4E28, #4A3218 55%, #2A1B0C);
    border-radius: 0 0 3px 3px;
    box-shadow: 0 5px 10px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.06);
  }
  .wallsec.open .panel {
    /* 문이 커지며 다가오다가 활짝 젖혀진다 */
    transform: rotateY(-84deg) scale(1.18); opacity: 0; pointer-events: none;
    /* 열릴 때: 스윙 후반에야 사라진다 */
    transition: transform 1.3s cubic-bezier(.6, 0, .2, 1), opacity .5s ease .8s;
  }

  .shelfline { display: flex; align-items: flex-end; justify-content: center; gap: 2px; flex-wrap: wrap; }
  .tome {
    appearance: none; border: none; cursor: pointer; flex: none;
    writing-mode: vertical-rl; position: relative;
    font-family: "Gowun Batang", serif; font-weight: 700; font-size: 10px;
    letter-spacing: .05em; color: #D9BC7E;
    padding: 9px 0 7px;
    border-radius: 2px 2px 0 0;
    box-shadow: inset -2px 0 4px rgba(0,0,0,.5), inset 1px 0 2px rgba(255,255,255,.06);
    background-image: repeating-linear-gradient(180deg, transparent 0 12px, rgba(224,177,94,.34) 12px 13px, transparent 13px 19px);
    background-size: 100% 44px; background-position: 0 5px; background-repeat: no-repeat;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    transition: transform .16s ease;
  }
  .tome:hover, .tome:focus-visible { transform: translateY(-6px); outline: none; }
  .tome.dim { opacity: .2; }
  .tome.paper::after {
    content: ""; position: absolute; left: 3px; right: 3px; bottom: 7px; height: 14px;
    background: var(--paperlabel); opacity: .85; border-radius: 1px;
  }
  .tome.lean { transform: rotate(-4deg) translateY(-2px); }
  .tome.lean:hover { transform: rotate(-4deg) translateY(-7px); }
  .tome.folio { border-radius: 3px 3px 0 0; box-shadow: inset -3px 0 5px rgba(0,0,0,.55), inset 2px 0 2px rgba(255,255,255,.08); }
  .tome.latch {
    transform: rotate(-8deg) translateY(-4px);
    box-shadow: inset -2px 0 4px rgba(0,0,0,.5), 0 0 16px rgba(224,177,94,.4);
  }
  .tome.latch:hover, .tome.latch:focus-visible { animation: wiggle .5s ease infinite alternate; }
  @keyframes wiggle {
    from { transform: rotate(-8deg) translateY(-5px); }
    to { transform: rotate(-11deg) translateY(-8px); }
  }
  .plank {
    width: 100%; height: 9px; margin: 0 0 9px; border-radius: 1px;
    background: linear-gradient(var(--wood3), var(--wood) 70%, #241708);
    box-shadow: 0 3px 7px rgba(0,0,0,.5);
  }

  /* ── 서가 뒤의 방 ────────────────────────────────────── */
  .room {
    position: absolute; inset: 0; z-index: 1;
    border: 2px solid var(--wood2);
    background:
      /* 촛대 불빛 */
      radial-gradient(ellipse 56% 44% at 82% 10%, rgba(224,177,94,.26) 0%, rgba(224,177,94,0) 64%),
      /* 회벽의 얼룩 */
      radial-gradient(ellipse 90% 60% at 30% 30%, rgba(255,255,255,.02) 0%, transparent 60%),
      repeating-linear-gradient(94deg, rgba(0,0,0,.05) 0 3px, transparent 3px 26px),
      /* 벽과 징두리, 마루 */
      linear-gradient(180deg, var(--room-glow) 0%, #241A0D 58%, #17100A 58.5%, #1E1409 60%, #17100A 60.5%,
        #2A1B0C 61%, #241708 100%);
    box-shadow: inset 0 0 66px rgba(0,0,0,.72), inset 0 -18px 30px -10px rgba(0,0,0,.5);
    padding: 20px 22px 14px;
    overflow-y: auto; scrollbar-width: none;
    /* 닫힐 때: 방이 먼저 조용히 어두워진다 */
    opacity: 0; pointer-events: none; transition: opacity .35s ease;
  }
  .room::-webkit-scrollbar { display: none; }
  .wallsec.open .room {
    opacity: 1; pointer-events: auto;
    /* 열릴 때: 문이 젖혀진 뒤에야 방이 밝아진다 */
    transition: opacity .6s ease .7s;
  }
  .room .wallframe { /* 벽에 걸린 장서인 액자 */
    position: absolute; top: 18px; right: 64px; width: 34px; height: 42px;
    border: 3px solid #59401F; background: linear-gradient(174deg, #D6C6A0, #C9B98E);
    box-shadow: 0 3px 8px rgba(0,0,0,.5), inset 0 0 0 1px rgba(0,0,0,.2);
    display: grid; place-items: center; pointer-events: none;
    transform: rotate(2deg);
  }
  .room .wallframe::after {
    content: "藏"; font-family: "Gowun Batang", serif; font-size: 17px;
    color: var(--wax); transform: rotate(-4deg);
  }
  .room .roomlamp { /* 벽에 걸린 밀랍초 */
    position: absolute; top: 22px; right: 24px; width: 8px; height: 22px; border-radius: 2px;
    background: linear-gradient(180deg, #EDE2C4 0%, #D6C6A0 60%, #C9B98E 100%);
    box-shadow: -1px 0 0 rgba(0,0,0,.3);
    pointer-events: none;
  }
  .room .roomlamp::before { /* 철제 받침 접시 */
    content: ""; position: absolute; bottom: -7px; left: 50%; transform: translateX(-50%);
    width: 20px; height: 6px; border-radius: 2px 2px 4px 4px;
    background: linear-gradient(180deg, #3A3A40, #1E1E24);
  }
  .room .roomlamp::after { /* 불꽃 */
    content: ""; position: absolute; top: -14px; left: 50%; transform: translateX(-50%);
    width: 9px; height: 14px;
    border-radius: 50% 50% 50% 50% / 64% 64% 36% 36%;
    background: radial-gradient(circle at 50% 74%, #FFF2C4 0%, #EDBC55 52%, rgba(237,188,85,0) 100%);
    box-shadow: 0 0 22px 8px rgba(224,177,94,.55);
    animation: flick 2.3s ease-in-out infinite;
  }
  @keyframes flick {
    0%, 100% { transform: translateX(-50%) scale(1); }
    38% { transform: translateX(-56%) scale(1.06, .93); }
    72% { transform: translateX(-45%) scale(.94, 1.08); }
  }
  .room h4 {
    margin: 0 0 1px; font-family: "Gowun Batang", serif; font-weight: 700;
    font-size: 18px; letter-spacing: .1em; color: var(--brass);
  }
  .room .roomsub { margin: 0 0 10px; font-size: 12px; color: var(--parchment-dim); }
  .roommeta {
    display: flex; gap: 16px; align-items: center; flex-wrap: wrap;
    font-family: "IBM Plex Mono", monospace; font-size: 10.5px; color: var(--parchment-dim);
    letter-spacing: .1em; margin-bottom: 14px;
  }
  .roommeta .meter { display: flex; align-items: center; gap: 7px; }
  .roommeta .meter i { display: block; width: 74px; height: 4px; background: rgba(0,0,0,.5); border-radius: 999px; overflow: hidden; }
  .roommeta .meter i b { display: block; height: 100%; background: var(--brass); border-radius: 999px; }
  .innershelf .shelfline { justify-content: flex-start; }
  .innershelf .plank { height: 7px; margin-bottom: 12px; }
  .bookplate {
    appearance: none; cursor: pointer; font-family: inherit; text-align: left;
    display: flex; align-items: baseline; gap: 10px; width: 100%;
    background: none; border: none; border-bottom: 1px dashed var(--line);
    color: var(--parchment); padding: 6px 2px;
  }
  .bookplate:hover, .bookplate:focus-visible { background: rgba(224,177,94,.06); outline: none; }
  .bookplate .sw { flex: none; width: 8px; height: 15px; border-radius: 1px; align-self: center; }
  .bookplate b { font-family: "Gowun Batang", serif; font-weight: 400; font-size: 13.5px; flex: 1; min-width: 0; }
  .bookplate span { font-size: 11px; color: var(--parchment-dim); flex: none; }
  .room .shut {
    display: block; margin: 14px auto 2px; appearance: none; cursor: pointer;
    font-family: "Cormorant", serif; font-style: italic; font-size: 13.5px; letter-spacing: .2em;
    color: var(--brass); background: none; border: 1px solid var(--brass-dim);
    padding: 8px 24px;
  }
  .room .shut:hover, .room .shut:focus-visible { background: rgba(224,177,94,.1); outline: none; }
  .leafrow { border-bottom: 1px dashed var(--line); padding: 7px 2px; }
  .leafrow .tp { font-family: "IBM Plex Mono", monospace; font-size: 9.5px; letter-spacing: .2em; color: var(--brass-dim); }
  .leafrow b { display: block; font-family: "Gowun Batang", serif; font-weight: 400; font-size: 13.5px; margin: 2px 0 1px; }
  .leafrow p { margin: 0; font-size: 11.5px; color: var(--parchment-dim); }

  /* ── 새로 도착한 궤짝 ────────────────────────────────── */
  .crate { margin-top: 56px; scroll-margin-top: 64px; }
  .crate-label { display: flex; align-items: baseline; gap: 12px; margin-bottom: 10px; }
  .crate-label b { font-family: "Gowun Batang", serif; font-weight: 700; font-size: 17px; letter-spacing: .08em; }
  .crate-label span { font-family: "IBM Plex Mono", monospace; font-size: 10.5px; color: var(--brass-dim); letter-spacing: .12em; }
  .cratebox {
    border: 2px solid #3A2B14;
    background:
      repeating-linear-gradient(0deg, rgba(0,0,0,.28) 0 2px, transparent 2px 34px),
      radial-gradient(circle 5px at 78% 24%, rgba(0,0,0,.5) 0 40%, transparent 100%),
      radial-gradient(ellipse 80px 30px at 14% 80%, rgba(20,12,4,.5) 0%, transparent 72%),
      repeating-linear-gradient(108deg, transparent 0 64px, rgba(0,0,0,.22) 64px 65px, transparent 65px 128px),
      linear-gradient(180deg, #33220E, #241708);
    box-shadow: inset 0 0 36px rgba(0,0,0,.6), 0 12px 28px rgba(0,0,0,.5);
    padding: 18px 22px 14px;
    position: relative;
  }
  .cratebox::after { /* 궤짝 못자국 */
    content: ""; position: absolute; inset: 8px; pointer-events: none;
    background:
      radial-gradient(circle at 0 0, var(--wood3) 0 2px, transparent 3px),
      radial-gradient(circle at 100% 0, var(--wood3) 0 2px, transparent 3px),
      radial-gradient(circle at 0 100%, var(--wood3) 0 2px, transparent 3px),
      radial-gradient(circle at 100% 100%, var(--wood3) 0 2px, transparent 3px);
  }
  .cratebox .note { margin: 0 0 10px; font-size: 12.5px; color: var(--parchment-dim); }
  /* 궤짝 뚜껑 — 처음엔 잠겨 있다 */
  .cratewrap {
    position: relative; perspective: 1100px;
    /* 뚜껑이 젖혀지는 동안 아래쪽 모서리가 보는 사람 쪽으로 다가오면서
       원근 때문에 가로로 부풀어 궤짝 밖으로 삐져나간다. 모바일 Chrome 은
       그만큼 화면을 넓혀 잡아 사다리가 화면 밖으로 밀려난다.
       가로만 잘라낸다 — clip 은 visible 과 짝지을 수 있어서 위로 넘어가는
       스윙은 그대로 살아 있다 (hidden 이면 세로까지 잘려 뚜껑이 사라진다). */
    overflow-x: clip;
  }
  .cratelid { /* 낡은 청록 판재의 돔형 뚜껑 — 칠이 벗겨지고 긁힌 세월 */
    position: absolute; inset: 0; z-index: 5; cursor: pointer;
    appearance: none; border: 3px solid #120C05; padding: 0;
    border-radius: 18px 18px 0 0;
    background:
      /* 판재 이음새 */
      repeating-linear-gradient(90deg, rgba(0,0,0,.4) 0 2px, transparent 2px 34px),
      /* 칠이 벗겨져 드러난 나무 */
      radial-gradient(ellipse 90px 34px at 21% 64%, rgba(74,50,24,.6) 0%, rgba(74,50,24,0) 72%),
      radial-gradient(ellipse 60px 24px at 71% 22%, rgba(74,50,24,.45) 0%, rgba(74,50,24,0) 70%),
      radial-gradient(ellipse 70px 28px at 88% 74%, rgba(58,39,18,.55) 0%, rgba(58,39,18,0) 72%),
      /* 옹이 */
      radial-gradient(circle 5px at 33% 30%, rgba(0,0,0,.55) 0 40%, rgba(0,0,0,.2) 60%, transparent 100%),
      radial-gradient(circle 4px at 58% 78%, rgba(0,0,0,.5) 0 40%, rgba(0,0,0,.18) 60%, transparent 100%),
      /* 긁힌 자국 */
      repeating-linear-gradient(114deg, transparent 0 52px, rgba(0,0,0,.28) 52px 53px, transparent 53px 104px),
      repeating-linear-gradient(66deg, transparent 0 88px, rgba(0,0,0,.2) 88px 89px, transparent 89px 170px),
      /* 나뭇결 */
      repeating-linear-gradient(0deg, rgba(255,255,255,.02) 0 2px, transparent 2px 9px),
      /* 바탕 — 어둡게 바랜 청록 */
      linear-gradient(180deg, #2C4A44 0%, #213833 42%, #182A25 74%, #0E1815 100%);
    box-shadow:
      inset 0 8px 12px -6px rgba(255,255,255,.07),
      inset 0 -20px 32px -8px rgba(0,0,0,.75),
      inset 0 0 48px rgba(0,0,0,.5),
      0 16px 34px rgba(0,0,0,.7);
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
    transform-origin: 50% 0;
    transition: transform 1s cubic-bezier(.55, 0, .25, 1), opacity .4s ease .55s;
  }
  .cratelid::before, .cratelid::after { /* 무쇠 모서리 덮개 */
    content: ""; position: absolute; top: -3px; width: 28px; height: 24px; pointer-events: none;
    background: linear-gradient(135deg, #34342E 0%, #1C1C18 62%, #101010 100%);
    box-shadow: inset 0 0 0 1px rgba(0,0,0,.65), inset 2px 2px 3px rgba(255,255,255,.05);
  }
  .cratelid::before { left: -3px; border-radius: 16px 2px 8px 2px; }
  .cratelid::after { right: -3px; border-radius: 2px 16px 2px 8px; }
  .cratewrap.open .cratelid { transform: rotateX(104deg); opacity: 0; pointer-events: none; }
  /* 다 열린 뒤 — 투명하게 두지 않고 아예 치운다 (app.js 가 붙인다).
     젖혀진 판이 자리에 남으면 모바일에서 가로 넘침으로 계산될 수 있다. */
  .cratewrap.shut .cratelid { display: none; }
  .cratelid:focus-visible { outline: 2px solid var(--brass); outline-offset: 3px; }
  .cratelid .strap { /* 녹슬어 어두워진 무쇠 띠 — 리벳도 세월에 바랬다 */
    position: absolute; top: -3px; bottom: -3px; width: 38px;
    background:
      radial-gradient(circle, #C9A05C 0 1.8px, #6E5026 2.4px, rgba(0,0,0,.55) 3.4px, transparent 4.4px) left 4px top 10px / 10px 26px repeat-y,
      radial-gradient(circle, #C9A05C 0 1.8px, #6E5026 2.4px, rgba(0,0,0,.55) 3.4px, transparent 4.4px) right 4px top 10px / 10px 26px repeat-y,
      /* 녹 얼룩 */
      radial-gradient(ellipse 14px 30px at 50% 78%, rgba(110,42,30,.4) 0%, transparent 75%),
      linear-gradient(90deg, #120C05 0%, #46331A 24%, #66492A 50%, #46331A 76%, #120C05 100%);
    border-left: 1px solid #0C0803; border-right: 1px solid #0C0803;
    box-shadow: 3px 0 7px rgba(0,0,0,.5), -3px 0 7px rgba(0,0,0,.5), inset 0 0 10px rgba(0,0,0,.4);
    pointer-events: none;
  }
  .cratelid .strap.s1 { left: 13%; } .cratelid .strap.s2 { right: 13%; }
  .lock { position: relative; pointer-events: none; z-index: 2; }
  .lock .shackle { /* 걸쇠 혀 — 뚜껑에서 내려와 자물쇠판에 물린다 */
    display: block;
    width: 20px; height: 22px; margin: 0 auto -8px;
    background: linear-gradient(90deg, #6E4E28, #C9A24B 35%, #EFCB80 50%, #C9A24B 65%, #6E4E28);
    border: 1.5px solid #33220E; border-bottom: none;
    border-radius: 3px 3px 0 0;
    box-shadow: 0 3px 6px rgba(0,0,0,.5);
  }
  .lock .lockbody { /* 방패형 자물쇠판 */
    display: block;
    width: 54px; height: 58px; position: relative;
    clip-path: polygon(50% 0, 88% 9%, 100% 34%, 88% 72%, 50% 100%, 12% 72%, 0 34%, 12% 9%);
    background:
      radial-gradient(circle at 22% 16%, #5C4318 0 2.5px, transparent 3.5px),
      radial-gradient(circle at 78% 16%, #5C4318 0 2.5px, transparent 3.5px),
      radial-gradient(circle at 14% 40%, #5C4318 0 2.5px, transparent 3.5px),
      radial-gradient(circle at 86% 40%, #5C4318 0 2.5px, transparent 3.5px),
      /* 세월에 그을린 얼룩 */
      radial-gradient(ellipse 20px 14px at 30% 76%, rgba(40,26,10,.35) 0%, transparent 70%),
      linear-gradient(160deg, #E4C275 0%, #C9A45C 30%, #B08D42 52%, #8F6C2C 76%, #5C4118 100%);
    box-shadow: 0 0 20px 5px rgba(224,177,94,.55), 0 5px 10px rgba(0,0,0,.55);
    animation: lockglow 1.7s ease-in-out infinite alternate;
  }
  .lock .lockbody::after { /* 열쇠 구멍 */
    content: ""; position: absolute; left: 50%; top: 22px; transform: translateX(-50%);
    width: 8px; height: 8px; border-radius: 50%;
    background: #241708;
    box-shadow: 0 10px 0 -2.5px #241708, inset 0 1px 2px rgba(0,0,0,.9);
  }
  @keyframes lockglow {
    from { box-shadow: 0 0 12px 2px rgba(224,177,94,.4), 0 5px 10px rgba(0,0,0,.55); }
    to { box-shadow: 0 0 30px 10px rgba(224,177,94,.8), 0 5px 10px rgba(0,0,0,.55); }
  }
  .cratelid:hover .lockbody { animation-duration: .8s; }
  .cratelid .lidhint {
    font-family: "IBM Plex Mono", monospace; font-size: 10.5px;
    letter-spacing: .18em; color: #9EC4BC;
    text-shadow: 0 1px 3px rgba(0,0,0,.7);
  }
  .crateitem {
    border-top: 1px dashed var(--line); padding: 11px 0;
    display: flex; gap: 12px; align-items: flex-start; flex-wrap: wrap;
  }
  .crateitem .guess {
    font-family: "IBM Plex Mono", monospace; font-size: 12px; color: var(--wax);
    flex: none; min-width: 124px; padding-top: 4px;
  }
  .crateitem .cands { display: flex; gap: 8px; flex-wrap: wrap; flex: 1; }
  .cand {
    appearance: none; font: inherit; font-size: 12.5px; cursor: pointer;
    border: 1px solid var(--line); background: rgba(23,16,9,.5); color: var(--parchment);
    padding: 5px 12px;
  }
  .cand:hover, .cand:focus-visible { border-color: var(--brass-dim); outline: none; }
  .crateitem.resolved .cands { opacity: .4; }
  .crateitem.resolved .guess::after { content: " ✓ 꽂았다"; color: var(--brass); }

  /* ── 사진을 들이는 곳 ─────────────────────────────────
     주인에게만 열리는 자리 — 표본 화면에는 없다 */
  body:not(.owner) .intake { display: none; }
  .intake { margin-top: 56px; scroll-margin-top: 64px; }
  .intake.busy .dropzone { pointer-events: none; opacity: .6; }

  .intake-where {
    display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
    margin-bottom: 12px;
  }
  .intake-where label {
    display: inline-flex; align-items: center; gap: 7px;
    font-size: 12px; color: var(--parchment-dim); letter-spacing: .06em;
  }
  .intake-where select, .intake-where input {
    background: #1B1108; color: var(--parchment);
    border: 1px solid var(--line); border-radius: 2px;
    padding: 5px 8px; font: inherit; font-size: 12.5px;
  }
  .intake-where input { width: 66px; }
  .intake-where select:focus-visible, .intake-where input:focus-visible {
    outline: 2px solid var(--brass); outline-offset: 1px;
  }
  .intake-hint {
    font-family: "IBM Plex Mono", monospace;
    font-size: 10.5px; color: var(--brass-dim); letter-spacing: .08em;
  }

  .dropzone {
    display: flex; flex-direction: column; align-items: center; gap: 7px;
    width: 100%; padding: 30px 20px; cursor: pointer;
    color: var(--parchment); text-align: center;
    border: 2px dashed var(--line); border-radius: 3px;
    background:
      radial-gradient(ellipse 300px 90px at 50% 0%, rgba(224,177,94,.05), transparent 70%),
      linear-gradient(180deg, #221607, #1A1006);
    transition: border-color .25s, background .25s;
  }
  .dropzone:hover, .dropzone.over, .dropzone:focus-visible {
    border-color: var(--brass-dim); outline: none;
    background:
      radial-gradient(ellipse 300px 90px at 50% 0%, rgba(224,177,94,.11), transparent 70%),
      linear-gradient(180deg, #2A1B09, #1A1006);
  }
  .dropzone .dz-mark {
    font-size: 20px; color: var(--brass-dim); letter-spacing: .3em;
  }
  .dropzone b {
    font-family: "Gowun Batang", serif; font-weight: 400; font-size: 14.5px;
    letter-spacing: .04em;
  }
  .dropzone .dz-sub {
    font-size: 11.5px; color: var(--parchment-dim);
  }

  .intake-queue { list-style: none; margin: 12px 0 0; padding: 0; }
  .intake-queue li {
    display: flex; justify-content: space-between; gap: 12px;
    padding: 6px 2px; border-bottom: 1px solid rgba(74,58,34,.4);
    font-size: 12px;
  }
  .intake-queue .qn {
    color: var(--parchment-dim); overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap;
  }
  .intake-queue .qs {
    font-family: "IBM Plex Mono", monospace; font-size: 10.5px;
    color: var(--brass-dim); letter-spacing: .06em;
    /* 실패 사유가 길 수 있다 — 한 줄로 붙들면 좁은 화면에서 넘친다 */
    text-align: right; overflow-wrap: anywhere;
  }
  .intake-queue li.done .qs { color: var(--st-done); }
  .intake-queue li.bad .qs { color: var(--wax); }

  .intake-shelf { margin-top: 18px; }
  .intake-empty {
    margin: 10px 0 0; font-size: 11.5px;
    color: var(--parchment-dim); font-style: italic;
  }
  .photogrid {
    display: grid; gap: 12px;
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  }
  .photocard {
    margin: 0; position: relative;
    border: 1px solid var(--line); background: #1B1108;
    box-shadow: 0 6px 14px rgba(0,0,0,.45);
    transition: opacity .3s;
  }
  .photocard.going { opacity: .3; }
  .photocard .ph {
    aspect-ratio: 4 / 3; background: #120B04 center / cover no-repeat;
  }
  .photocard .ph.nophoto::after {
    content: "사진을 열지 못했습니다";
    display: grid; place-items: center; height: 100%;
    font-size: 10.5px; color: var(--parchment-dim);
  }
  .photocard figcaption {
    display: flex; justify-content: space-between; gap: 8px;
    padding: 6px 8px; font-size: 11px; color: var(--parchment-dim);
  }
  .photocard .pst {
    font-family: "IBM Plex Mono", monospace;
    font-size: 10px; color: var(--brass-dim); letter-spacing: .06em;
  }
  .photocard .phdel {
    position: absolute; top: 5px; right: 5px;
    padding: 3px 8px; font: inherit; font-size: 10.5px;
    color: var(--parchment); cursor: pointer;
    background: rgba(23,16,9,.82); border: 1px solid var(--line); border-radius: 2px;
    opacity: 0; transition: opacity .2s;
  }
  .photocard:hover .phdel, .photocard .phdel:focus-visible {
    opacity: 1; outline: none; border-color: var(--wax);
  }

  /* ── 바닥: 책상과 램프, 오늘의 책 ─────────────────────── */
  .desk {
    position: relative; margin-top: 64px; padding: 58px 18px 84px;
    text-align: center; scroll-margin-top: 64px;
    background: linear-gradient(180deg, var(--dark) 0%, #100A04 100%);
  }
  .desk::before { /* 촛불의 빛무리 — 숨쉬듯 일렁인다 */
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background: radial-gradient(ellipse 40% 46% at 44% 48%, rgba(224,177,94,.36) 0%, rgba(224,177,94,0) 68%);
    animation: glowbreathe 5.5s ease-in-out infinite alternate;
  }
  @keyframes glowbreathe {
    from { opacity: .72; }
    to { opacity: 1; }
  }
  .desk::after { /* 책상 상판 — 두꺼운 판재와 앞면 */
    content: ""; position: absolute; left: 7%; right: 7%; bottom: 46px; height: 20px;
    background:
      repeating-linear-gradient(90deg, rgba(0,0,0,.14) 0 2px, transparent 2px 60px),
      linear-gradient(180deg, #8A6840 0%, #6E4E28 28%, #4A3218 30%, #3A2712 70%, #241708 100%);
    border-radius: 3px 3px 1px 1px;
    box-shadow: 0 10px 26px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.1);
  }
  .desk .candlestick { /* 놋쇠 촛대 — 책상 위에 딱 붙어 선다 */
    position: absolute; left: 50%; bottom: 62px; transform: translateX(-109px);
    width: 34px; height: 26px; pointer-events: none; z-index: 1;
  }
  .desk .candlestick::before { /* 받침과 손잡이 고리 */
    content: ""; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%);
    width: 34px; height: 8px;
    background: linear-gradient(180deg, #D9B36A, #8A6B2E 60%, #59401F);
    border-radius: 40% 40% 4px 4px;
    box-shadow: 8px -2px 0 -2px #8A6B2E; /* 오른쪽 손잡이 고리 */
  }
  .desk .candlestick::after { /* 초꽂이 컵 */
    content: ""; position: absolute; bottom: 6px; left: 50%; transform: translateX(-50%);
    width: 14px; height: 7px;
    background: linear-gradient(180deg, #EFCB80, #A0782F);
    border-radius: 2px 2px 5px 5px;
  }
  .desk .candlewax { /* 밀랍초 — 촛대 컵 한가운데에 꽂힌다 */
    position: absolute; left: 50%; bottom: 73px; transform: translateX(-97px);
    width: 11px; height: 34px; pointer-events: none; z-index: 1;
    background: linear-gradient(180deg, #F2E7C8 0%, #E2D2AC 55%, #D6C6A0 100%);
    border-radius: 3px 3px 1px 1px;
    box-shadow: -1.5px 0 0 rgba(0,0,0,.25), inset -2px 0 3px rgba(0,0,0,.15);
  }
  .desk .candlewax::before { /* 촛농 줄기 */
    content: ""; position: absolute; left: -3px; top: 7px;
    width: 4px; height: 15px; border-radius: 2px 2px 3px 3px;
    background: linear-gradient(180deg, #F2E7C8, #DECFA8);
  }
  .desk .candlewax::after { /* 불꽃 */
    content: ""; position: absolute; top: -17px; left: 50%; transform: translateX(-50%);
    width: 11px; height: 17px;
    border-radius: 50% 50% 50% 50% / 64% 64% 36% 36%;
    background: radial-gradient(circle at 50% 76%, #FFF4CA 0%, #F2C155 48%, rgba(242,193,85,0) 100%);
    box-shadow: 0 0 26px 10px rgba(224,177,94,.6);
    animation: flick 2.1s ease-in-out infinite;
  }
  .desk .openbook { /* 펼쳐 놓은 책 — 가죽 표지 위의 양피지 */
    position: absolute; left: 50%; bottom: 63px; transform: translateX(-10px) rotate(-2deg);
    width: 116px; height: 30px; pointer-events: none;
    background: linear-gradient(180deg, #4A3218 0%, #33220E 100%); /* 밑에 깔린 가죽 표지 */
    border-radius: 4px 4px 7px 7px;
    filter: drop-shadow(0 7px 9px rgba(0,0,0,.6));
  }
  .desk .openbook::before, .desk .openbook::after { /* 좌우 페이지 — 가운데 골로 말려 들어간다 */
    content: ""; position: absolute; bottom: 3px; width: 52px; height: 26px;
    background-repeat: no-repeat;
    box-shadow: 0 2px 0 #C9B98E, 0 4px 0 -1px #A8946C; /* 겹쳐 쌓인 종이 단면 */
  }
  .desk .openbook::before {
    left: 3px; border-radius: 9px 2px 2px 5px;
    transform: perspective(70px) rotateY(7deg);
    background-image:
      repeating-linear-gradient(180deg, rgba(0,0,0,.05) 0 2px, transparent 2px 6px),
      linear-gradient(90deg, #D6C6A0 0%, #F2E9D0 55%, #C9B98E 90%, #8F7C58 100%);
  }
  .desk .openbook::after {
    right: 3px; border-radius: 2px 9px 5px 2px;
    transform: perspective(70px) rotateY(-7deg);
    background-image:
      repeating-linear-gradient(180deg, rgba(0,0,0,.05) 0 2px, transparent 2px 6px),
      linear-gradient(90deg, #8F7C58 0%, #C9B98E 10%, #F2E9D0 45%, #D6C6A0 100%);
  }
  .desk .openbook .ribbon { /* 책갈피 리본 */
    position: absolute; left: 50%; bottom: -10px; transform: translateX(-50%) rotate(4deg);
    width: 7px; height: 16px; z-index: 1;
    background: linear-gradient(180deg, #A0392C, #6E2118);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 76%, 0 100%);
    box-shadow: 0 2px 3px rgba(0,0,0,.4);
  }
  .desk .lampline {
    font-family: "IBM Plex Mono", monospace; font-size: 10.5px; letter-spacing: .22em;
    color: var(--brass-dim); display: block; margin-bottom: 12px;
  }
  .desk h3 {
    margin: 0 0 4px; font-family: "Gowun Batang", serif; font-weight: 700;
    font-size: 22px; letter-spacing: .1em; text-wrap: balance;
  }
  .desk p { margin: 0 0 18px; font-size: 12.5px; color: var(--parchment-dim); }
  .desk .open-today {
    appearance: none; cursor: pointer; position: relative; z-index: 1;
    font-family: "Gowun Batang", serif; font-weight: 700; font-size: 14px; letter-spacing: .14em;
    color: var(--brass); background: none; border: 1px solid var(--brass-dim);
    padding: 10px 28px;
  }
  .desk .open-today:hover, .desk .open-today:focus-visible {
    background: rgba(224,177,94,.12); outline: none;
    box-shadow: 0 0 22px rgba(224,177,94,.35);
  }

  /* ── 서표 카드(상세) ─────────────────────────────────── */
  .veil {
    position: fixed; inset: 0; z-index: 40; background: rgba(10, 7, 3, .76);
    opacity: 0; pointer-events: none; transition: opacity .22s ease;
  }
  .veil.show { opacity: 1; pointer-events: auto; }
  .exlibris {
    position: fixed; z-index: 50; left: 50%; top: 50%;
    transform: translate(-50%, -50%) scale(.96); opacity: 0; pointer-events: none;
    transition: opacity .22s ease, transform .22s ease;
    width: min(420px, calc(100vw - 32px)); max-height: 82vh; overflow-y: auto; scrollbar-width: none;
    background: linear-gradient(174deg, #33220F, #241708);
    border: 1px solid var(--brass-dim);
    box-shadow: inset 0 0 0 4px #241708, inset 0 0 0 5px rgba(224,177,94,.3), 0 26px 60px rgba(0,0,0,.7);
    padding: 26px 28px 24px;
  }
  .exlibris::-webkit-scrollbar { display: none; }
  .exlibris.show { opacity: 1; transform: translate(-50%, -50%) scale(1); pointer-events: auto; }
  .exlibris .close {
    position: absolute; top: 10px; right: 13px; appearance: none; border: none;
    background: none; cursor: pointer; color: var(--parchment-dim); font-size: 20px; line-height: 1;
  }
  .exlibris .mark {
    font-family: "IBM Plex Mono", monospace; font-size: 10.5px; letter-spacing: .16em;
    color: var(--brass-dim); display: block; margin-bottom: 13px;
  }
  .exlibris h3 {
    margin: 0 0 3px; font-family: "Gowun Batang", serif; font-weight: 700;
    font-size: 22px; line-height: 1.5; color: #E8CE93; text-wrap: balance;
  }
  .exlibris .byline { margin: 0 0 14px; font-size: 13px; color: var(--parchment-dim); }
  .exlibris .rule { height: 1px; background: linear-gradient(90deg, transparent, var(--brass-dim) 30%, transparent 50%, var(--brass-dim) 70%, transparent); margin: 13px 0; }
  .exlibris h4 {
    margin: 0 0 5px; font-family: "Cormorant", serif; font-style: italic;
    font-size: 12.5px; letter-spacing: .24em; color: var(--brass-dim); text-transform: uppercase;
  }
  .exlibris p.body { margin: 0 0 4px; font-size: 13.5px; line-height: 1.8; }
  .exlibris .marginalia {
    margin: 0; padding: 10px 14px; font-size: 13px;
    border-left: 2px solid var(--wax); background: rgba(142,47,35,.1);
  }
  .exlibris .undeciphered { margin: 0; font-size: 13px; font-style: italic; color: var(--parchment-dim); }
  .exlibris .sealmark { /* 봉랍 장서인 */
    position: absolute; right: 22px; bottom: 18px;
    width: 42px; height: 42px; border-radius: 50%;
    background: radial-gradient(circle at 36% 30%, #A6473A, var(--wax) 58%, #6E2118);
    box-shadow: 0 3px 8px rgba(0,0,0,.4);
    display: grid; place-items: center;
    color: #E5C9B8; font-family: "Gowun Batang", serif; font-size: 14px;
    transform: rotate(-9deg); pointer-events: none;
  }
  .exlibris .genbtn {
    margin-top: 10px; appearance: none; cursor: pointer; font: inherit; font-size: 12.5px;
    color: var(--brass); background: none; border: 1px solid var(--brass-dim); padding: 7px 18px;
  }
  .exlibris .genbtn:hover, .exlibris .genbtn:focus-visible { background: rgba(224,177,94,.1); outline: none; }

  /* ── 보기 전환 (서가/표지/목록/통계) — 입구 양초 사이에 선다 ── */
  .viewrow {
    position: absolute; left: 50%; bottom: 33px; transform: translateX(-50%);
    z-index: 2;
  }
  @media (max-width: 560px) {
    .viewrow .viewseg button { padding: 8px 13px; font-size: 12px; }
  }
  .viewseg {
    display: flex; border: 1px solid var(--wood3); border-radius: 2px; overflow: hidden;
    background: rgba(36,23,8,.6); box-shadow: 0 6px 14px rgba(0,0,0,.35);
  }
  .viewseg button {
    appearance: none; border: none; background: none; cursor: pointer;
    font-family: "Gowun Batang", serif; font-weight: 700; font-size: 13px;
    letter-spacing: .08em; color: var(--parchment-dim);
    padding: 8px 22px; border-right: 1px solid var(--line);
  }
  .viewseg button:last-child { border-right: none; }
  .viewseg button[aria-selected="true"] { background: var(--brass); color: #241708; }
  .viewseg button:focus-visible { outline: 2px solid var(--brass); outline-offset: -2px; }

  /* 표지 뷰 */
  .covers { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 14px; margin-top: 26px; }
  .cover { /* 가죽 장정 — 금박 압인 프레임 */
    aspect-ratio: 2 / 3; appearance: none; border: none; cursor: pointer; text-align: left;
    padding: 12px 11px; display: flex; flex-direction: column; justify-content: flex-end; gap: 4px;
    border-radius: 2px 5px 5px 2px;
    border-left: 4px solid rgba(0,0,0,.4);
    background-color: var(--cvr, #4A3218);
    background-image:
      radial-gradient(ellipse 70% 40% at 32% 16%, rgba(255,255,255,.09) 0%, transparent 60%),
      repeating-linear-gradient(0deg, rgba(0,0,0,.05) 0 1px, transparent 1px 3px),
      linear-gradient(160deg, rgba(255,255,255,.05) 0%, rgba(0,0,0,.3) 100%);
    box-shadow:
      inset 0 0 0 1px rgba(224,177,94,.22),
      inset 0 0 0 4px transparent, inset 0 0 0 5px rgba(224,177,94,.12),
      inset 10px 0 14px -8px rgba(0,0,0,.55),
      0 8px 18px rgba(0,0,0,.5);
    font-family: "Gowun Batang", serif; color: #E8CE93;
    transition: transform .16s ease, box-shadow .16s ease;
  }
  .cover:hover, .cover:focus-visible {
    transform: translateY(-5px); outline: none;
    box-shadow:
      inset 0 0 0 1px rgba(224,177,94,.4),
      inset 0 0 0 4px transparent, inset 0 0 0 5px rgba(224,177,94,.2),
      inset 10px 0 14px -8px rgba(0,0,0,.55),
      0 12px 24px rgba(0,0,0,.6), 0 0 18px rgba(224,177,94,.15);
  }
  .cover b {
    font-size: 12.5px; font-weight: 700; line-height: 1.45;
    border-top: 1px solid rgba(224,177,94,.32); padding-top: 6px;
  }
  .cover span { font-size: 10px; color: rgba(226,213,184,.6); font-family: "Noto Sans KR", sans-serif; font-weight: 300; }
  .cover-note {
    text-align: center; font-family: "IBM Plex Mono", monospace; font-size: 10.5px;
    letter-spacing: .14em; color: var(--parchment-dim); padding: 22px 0 0;
  }

  /* 목록 뷰 */
  .listwrap {
    overflow-x: auto; margin-top: 26px;
    border: 1px solid var(--wood3); background: rgba(36,23,8,.55);
    box-shadow: inset 0 0 30px rgba(0,0,0,.4);
  }
  table.ledger { width: 100%; border-collapse: collapse; font-size: 13px; }
  .ledger th {
    font-family: "IBM Plex Mono", monospace; font-weight: 500; font-size: 10px;
    letter-spacing: .18em; color: var(--brass-dim); text-align: left;
    padding: 11px 16px; border-bottom: 1px solid var(--wood3); white-space: nowrap;
  }
  .ledger td { padding: 8px 16px; border-bottom: 1px dashed var(--line); white-space: nowrap; color: var(--parchment); }
  .ledger td.t { font-family: "Gowun Batang", serif; font-weight: 700; color: #E8CE93; }
  .ledger tbody tr:hover td { background: rgba(224,177,94,.06); cursor: pointer; }
  .list-note {
    font-family: "IBM Plex Mono", monospace; font-size: 10.5px;
    color: var(--parchment-dim); letter-spacing: .1em; padding: 12px 2px;
  }
  .st-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 7px; vertical-align: 1px; }

  /* 통계 뷰 */
  .statgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 26px; }
  @media (max-width: 720px) { .statgrid { grid-template-columns: 1fr; } }
  .statpanel {
    border: 1px solid var(--wood3); background: linear-gradient(174deg, #2A1B0C, #211508);
    box-shadow: inset 0 0 26px rgba(0,0,0,.35), 0 10px 24px rgba(0,0,0,.4);
    padding: 18px 20px 16px;
  }
  .statpanel h4 { margin: 0 0 2px; font-family: "Gowun Batang", serif; font-size: 14.5px; letter-spacing: .08em; color: var(--brass); }
  .statpanel .ps { margin: 0 0 14px; font-size: 11.5px; color: var(--parchment-dim); }
  .hbar { display: grid; grid-template-columns: 64px 1fr 48px; gap: 10px; align-items: center; margin-bottom: 8px; }
  .hbar .lb { font-size: 12.5px; }
  .hbar .track { height: 12px; background: rgba(0,0,0,.45); border-radius: 0 4px 4px 0; }
  .hbar .fill { display: block; height: 100%; background: var(--brass); border-radius: 0 4px 4px 0; transition: width .9s cubic-bezier(.25, .6, .3, 1); }
  .hbar .val { font-family: "IBM Plex Mono", monospace; font-size: 11px; color: var(--parchment-dim); text-align: right; font-variant-numeric: tabular-nums; }
  .cols { display: flex; align-items: flex-end; gap: 7px; height: 118px; padding-top: 16px; }
  .col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 4px; height: 100%; justify-content: flex-end; }
  .col i { display: block; width: 100%; max-width: 30px; background: var(--brass); border-radius: 4px 4px 0 0; transition: height .9s cubic-bezier(.25, .6, .3, 1); }
  .col .yl { font-family: "IBM Plex Mono", monospace; font-size: 9.5px; color: var(--parchment-dim); }
  .col .vl { font-family: "IBM Plex Mono", monospace; font-size: 10.5px; height: 13px; color: var(--parchment); }
  .stack { display: flex; height: 24px; border-radius: 4px; overflow: hidden; gap: 2px; margin-bottom: 10px; }
  .stack i { display: flex; align-items: center; justify-content: center; font-family: "IBM Plex Mono", monospace; font-size: 11px; }
  .legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12px; }
  .legend span i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 6px; }

  footer.colophon {
    text-align: center; padding: 26px 16px;
    font-family: "IBM Plex Mono", monospace; font-size: 10.5px;
    color: var(--parchment-dim); letter-spacing: .16em;
  }

  @media (prefers-reduced-motion: reduce) {
    .panel, .room, .tome, .veil, .exlibris, .wallsec, .panelbox::before, .ladder .car, .cratelid,
    .hbar .fill, .col i, .ladder .dot,
    .dropzone, .photocard, .photocard .phdel { transition: none; }
    .tome.latch:hover { animation: none; }
    .lock .lockbody, .room .roomlamp::after, .desk .candlewax::after, .foyer .fcandle::after,
    .foyer .latin, .foyer h1, .foyer p.sub, .foyer .secret, .foyer .viewrow, .desk::before { animation: none; }
    .wallsec.pre { opacity: 1; transform: none; }
  }

  /* ── 열쇠와 문지방 (로그인) ──────────────────────────── */
  .keybtn {
    flex: none; appearance: none; cursor: pointer;
    font-family: "Gowun Batang", serif; font-weight: 700; font-size: 12.5px;
    letter-spacing: .12em; color: var(--brass);
    background: none; border: 1px solid var(--brass-dim);
    padding: 6px 15px; border-radius: 2px;
    transition: background .2s ease, box-shadow .2s ease;
  }
  .keybtn:hover, .keybtn:focus-visible {
    background: rgba(224,177,94,.12); outline: none;
    box-shadow: 0 0 16px rgba(224,177,94,.3);
  }
  .keybtn.in { color: var(--parchment-dim); border-color: var(--line); }

  .gate {
    position: fixed; z-index: 50; left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    width: min(400px, calc(100vw - 32px));
    background: linear-gradient(174deg, #33220F, #241708);
    border: 1px solid var(--brass-dim);
    box-shadow: inset 0 0 0 4px #241708, inset 0 0 0 5px rgba(224,177,94,.3), 0 26px 60px rgba(0,0,0,.7);
    padding: 28px 30px 26px;
  }
  .gate .close {
    position: absolute; top: 10px; right: 13px; appearance: none; border: none;
    background: none; cursor: pointer; color: var(--parchment-dim); font-size: 20px; line-height: 1;
  }
  .gate .mark {
    font-family: "Cormorant", serif; font-style: italic; font-size: 12.5px;
    letter-spacing: .28em; color: var(--brass-dim); text-transform: uppercase;
    display: block; margin-bottom: 10px;
  }
  .gate h3 {
    margin: 0 0 8px; font-family: "Gowun Batang", serif; font-weight: 700;
    font-size: 21px; color: #E8CE93; letter-spacing: .06em;
  }
  .gate .gate-sub { margin: 0 0 16px; font-size: 12.5px; color: var(--parchment-dim); line-height: 1.7; }
  .gate form { display: flex; gap: 8px; }
  .gate form + form { margin-top: 8px; }
  /* 메일 + 비밀번호 + 버튼 — 좁은 화면에서는 메일이 한 줄을 다 쓴다 */
  .gate .pwform { flex-wrap: wrap; }
  .gate .pwform input[type="email"] { flex: 1 1 100%; }
  .gate .pwform input[type="password"] { flex: 1 1 120px; }
  .gate .pwform .gate-go { flex: 0 0 auto; }
  .gate .gate-alt {
    margin: 14px 0 5px; font-size: 11.5px; line-height: 1.6;
    color: var(--parchment-dim); font-style: italic;
  }
  /* 문장 속에 놓이는 단추 — 생김새는 글자, 역할은 단추 */
  .gate .linkish {
    appearance: none; background: none; border: 0; padding: 0;
    font: inherit; font-style: italic; cursor: pointer;
    color: var(--brass); text-decoration: underline;
    text-underline-offset: 3px;
  }
  .gate .linkish:hover, .gate .linkish:focus-visible { color: var(--paperlabel); outline: none; }
  .gate .linkish:disabled { opacity: .45; cursor: default; }
  .gate .gate-who {
    margin: 0 0 14px; font-family: "IBM Plex Mono", monospace;
    font-size: 11.5px; color: var(--brass-dim); letter-spacing: .06em;
    overflow-wrap: anywhere;
  }
  .gate .gate-out {
    margin-top: 16px; width: 100%; appearance: none; cursor: pointer;
    padding: 8px 0; font: inherit; font-size: 12.5px;
    color: var(--parchment-dim); background: none;
    border: 1px solid var(--line); border-radius: 2px;
  }
  .gate .gate-out:hover, .gate .gate-out:focus-visible {
    color: var(--wax); border-color: var(--wax); outline: none;
  }
  .gate input {
    flex: 1; min-width: 0; font: inherit; font-size: 14px;
    background: rgba(23,16,9,.6); color: var(--parchment);
    border: 1px solid var(--line); padding: 9px 14px;
  }
  .gate input:focus-visible { outline: none; border-color: var(--brass-dim); }
  .gate input::placeholder { color: var(--parchment-dim); }
  #gate-code { letter-spacing: .4em; text-align: center; font-family: "IBM Plex Mono", monospace; }
  .gate .gate-go {
    flex: none; appearance: none; cursor: pointer;
    font-family: "Gowun Batang", serif; font-weight: 700; font-size: 13px; letter-spacing: .1em;
    color: var(--brass); background: none; border: 1px solid var(--brass-dim);
    padding: 9px 18px;
  }
  .gate .gate-go:hover, .gate .gate-go:focus-visible { background: rgba(224,177,94,.12); outline: none; }
  .gate .gate-go:disabled { opacity: .45; cursor: default; }
  .gate .gate-msg {
    margin: 14px 0 0; font-size: 12.5px; line-height: 1.7;
    color: var(--parchment-dim);
  }
  .gate .gate-msg.good { color: var(--brass); }
  .gate .gate-msg.bad {
    color: #E0A79C; border-left: 2px solid var(--wax);
    padding: 8px 12px; background: rgba(142,47,35,.12);
  }

  /* 주인이 아니면 서재는 표본이다 — 숨기지 않고 밝힌다 */
  body:not(.owner) .topbar .census::after {
    content: "표본"; margin-left: 8px;
    border: 1px solid var(--line); border-radius: 2px;
    padding: 1px 6px; letter-spacing: .1em; color: var(--parchment-dim);
  }
