/* ==========================================================================
   SomiPaper — November 2026 Paper Planner (Editorial Web Edition)
   book.css — the physical book: desk stage, hardcover, page block, 3D turns.

   Everything here lives in the fixed 1024 × 768 px book space (spine at
   x = 512 px). The engine in js/page-turn.js only ever writes transforms,
   one `left` and a few opacities; all appearance is declared in this file.
   ========================================================================== */

/* ==========================================================================
   DESK STAGE (Desktop + iPad Mini Portrait/Landscape)
   ========================================================================== */
#canvas-viewport {
  z-index: 1;
  box-sizing: border-box;
  padding: var(--bar-top, 57px) 0 var(--bar-bottom, 64px);
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: visible;
  position: relative;
  touch-action: none;
}

#planner-stage {
  width: calc(1024px * var(--canvas-scale));
  height: calc(768px * var(--canvas-scale));
  position: relative;
  flex-shrink: 0;
  touch-action: none;
}

/* The book. The engine appends translateX() to centre the closed / open book. */
#planner-book {
  position: absolute;
  top: 0;
  left: 0;
  width: 1024px;
  height: 768px;
  transform-origin: top left;
  transform: scale(var(--canvas-scale));
}

/* ==========================================================================
   PAPER
   ========================================================================== */

/* 32 × 32 px Mathematical Square Grid on stationery paper */
.paper-surface {
  background-color: var(--color-paper);
  background-image:
    linear-gradient(to right, var(--color-grid) 0.65px, transparent 0.65px),
    linear-gradient(to bottom, var(--color-grid) 0.65px, transparent 0.65px);
  background-size: 32px 32px;
  background-position: 0 0;
}

#planner-book[data-paper="blank"] .paper-surface,
#planner-book[data-paper="blank"] .leaf-face.paper-surface {
  background-image: none;
}

/* Strict 1024 × 768 Planner Sheet (this element is what EXPORT PNG captures) */
#planner-canvas,
#canvas-content,
.turn-scene {
  position: absolute;
  left: 0;
  top: 0;
  width: 1024px;
  height: 768px;
}

.paper-half {
  position: absolute;
  top: 0;
  height: 768px;
}

/* When open, one continuous 1024px sheet avoids any compositing seam at x = 512px */
.paper-half--left {
  left: 0;
  width: 1024px;
}

.paper-half--right {
  left: 512px;
  width: 512px;
}

#canvas-content { overflow: hidden; }

body.is-dragging-folder-piece #canvas-content {
  overflow: visible;
}

/* While a leaf is in the air each live spread shows only its settled half */
.spread.clip-left {
  clip-path: inset(0 512px 0 0);
}

.spread.clip-right {
  clip-path: inset(0 0 0 512px);
}

/* Central Spine Line at x = 512px */
.spine-line {
  position: absolute;
  left: 512px;
  top: 0;
  width: 0.85px;
  height: 768px;
  background-color: var(--color-spine);
  z-index: 40;
  pointer-events: none;
}

/* Subtle Ambient Binding Crease (Screen only; hidden on PNG export) */
.spine-crease-ambient {
  position: absolute;
  left: 492px;
  top: 0;
  width: 40px;
  height: 768px;
  background: linear-gradient(
    to right,
    rgba(40, 38, 36, 0) 0%,
    rgba(40, 38, 36, 0.018) 42%,
    rgba(40, 38, 36, 0.038) 50%,
    rgba(255, 255, 255, 0.025) 54%,
    rgba(40, 38, 36, 0.012) 65%,
    rgba(40, 38, 36, 0) 100%
  );
  z-index: 39;
  pointer-events: none;
}

/* Where the front board rests while the book is closed */
.cover-slot {
  position: absolute;
  left: 512px;
  top: 0;
  width: 512px;
  height: 768px;
}

/* Front Hardcover Board (Flat clean presentation — ZERO FLOATING BUTTONS) */
.closed-book-cover {
  position: absolute;
  left: 0;
  top: 0;
  width: 512px;
  height: 768px;
  border-radius: 0;
  background-color: var(--color-cover-bg);
  border-left: 0;
  cursor: pointer;
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
  isolation: isolate;
}

.closed-book-cover.drag-over {
  outline: 3px dashed var(--spine-cloth-base, var(--color-outline-dashed));
  outline-offset: -12px;
}

/* Full-Bleed Cover Artwork (Default NOV 2026 or User Uploaded Cover) */
.closed-book-cover-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
  display: block;
  pointer-events: none;
}

/* Typographic cover — worn by a notebook that has no artwork of its own.
   Set from the notebook's month in the planner's own type; the month number
   takes the colour of the spine cloth. */
.type-cover {
  position: absolute;
  left: 0;
  top: 0;
  width: 512px;
  height: 768px;
  background: var(--cover-stock, #E8EDF0);
  color: var(--color-ink-main);
  pointer-events: none;
}

.type-cover-header {
  position: absolute;
  left: 48px;
  top: 50px;
  width: 416px;
  height: 12px;
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 2.2px;
}

.type-cover-rule {
  flex: 1;
  height: 0.65px;
  background: var(--color-header-rule);
}

.type-cover-bar {
  position: absolute;
  left: 48px;
  top: 128px;
  width: 8px;
  height: 192px;
  background: var(--spine-cloth-base);
}

.type-cover-number {
  position: absolute;
  left: 76px;
  top: 112px;
  font-family: var(--font-kr-serif);
  font-size: 224px;
  line-height: 1;
  letter-spacing: -6px;
  color: var(--spine-cloth-base);
  white-space: nowrap;
}

.type-cover-month {
  position: absolute;
  left: 50px;
  top: 356px;
  font-family: var(--font-serif);
  font-size: 23px;
  line-height: 1.2;
  letter-spacing: 9px;
  white-space: nowrap;
}

.type-cover-date-row {
  position: absolute;
  left: 50px;
  top: 398px;
  width: 414px;
  display: flex;
  align-items: center;
  gap: 16px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 3px;
  color: var(--color-ink-muted);
}

.type-cover-index {
  position: absolute;
  left: 50px;
  bottom: 62px;
  display: flex;
  flex-direction: column;
  gap: 13px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 4.5px;
}

.type-cover-tick {
  width: 30px;
  height: 1.5px;
  background: var(--color-ink-main);
}

/* --- Which parts of the book exist in each state ------------------------- */
.book--closed .paper-half--left,
.book--cover-flight .paper-half--left,
.leaf-strip.is-back-facing > .leaf-front,
.leaf-strip:not(.is-back-facing) > .leaf-back,
.book3d .binder-case-labels,
.book-pending #library {
  visibility: hidden;
}

/* ==========================================================================
   3D TURN SCENE — leaves hinged on the spine (Zero Shadow Overlays)
   ========================================================================== */
.turn-scene {
  pointer-events: none;
  z-index: 30;
}

.leaf {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: var(--leaf-z, 1);
}

.leaf-strip {
  position: absolute;
  left: 512px;
  top: 0;
  height: 768px;
  transform-origin: 0 50%;
  transform-style: flat;
  -webkit-transform-style: flat;
}

.leaf-face {
  position: absolute;
  left: 0;
  top: 0;
  height: 768px;
  overflow: hidden;
}

.leaf-back {
  transform: scaleX(-1);
}
.leaf-content {
  position: absolute;
  top: 0;
  width: 1024px;
  height: 768px;
  isolation: isolate;
}
.leaf--paper .leaf-face {
  box-shadow: inset 0 0.65px 0 var(--color-leaf-edge-border), inset 0 -0.65px 0 var(--color-leaf-edge-border);
}
.leaf--paper .leaf-strip--free-edge .leaf-front {
  box-shadow: inset 0 0.65px 0 var(--color-leaf-edge-border), inset 0 -0.65px 0 var(--color-leaf-edge-border), inset -0.65px 0 0 var(--color-leaf-edge-border);
}
.leaf--paper .leaf-strip--free-edge .leaf-back {
  box-shadow: inset 0 0.65px 0 var(--color-leaf-edge-border), inset 0 -0.65px 0 var(--color-leaf-edge-border), inset 0.65px 0 0 var(--color-leaf-edge-border);
}
.page-edge-hint {
  position: absolute;
  top: 0;
  width: 36px;
  height: 768px;
  z-index: 45;
  cursor: pointer;
  opacity: 0;
  background: none;
  transition: opacity 0.2s ease;
  user-select: none;
  -webkit-user-select: none;
}
.page-edge-hint.edge-left { left: 0; }
.page-edge-hint.edge-right { right: 0; }

.paper-half--right,
.cover-slot,
.spine-line,
.spine-crease-ambient,
.binder-case-labels,
.page-edge-hint.is-disabled,
.book--closed .page-edge-hint.edge-left,
.book--cover-flight .page-edge-hint.edge-left,
.book3d #planner-book:not(.book--closed) #planner-canvas .paper-half--right,
.desk-zoom-reset.hidden {
  display: none;
}
:is(.book--closed, .book--cover-flight) :is(.paper-half--right, .cover-slot),
#planner-book[data-binder]:not(.book--closed) .binder-case-labels {
  display: block;
}

.closed-book-cover::after, .shelf-book-art::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: var(--material-grain); opacity: 0.07;
}
[data-material="cloth"] {
  --material-grain: repeating-linear-gradient(0deg, transparent 0 2px, rgb(42 61 77 / 0.17) 2px 3px), repeating-linear-gradient(90deg, transparent 0 2px, rgb(255 255 255 / 0.4) 2px 3px);
}
.type-cover--number .type-cover-number { left: 34px; top: 104px; font-size: 280px; letter-spacing: -4px; white-space: nowrap; }
.type-cover--number .type-cover-bar { top: 416px; height: 2px; width: 416px; }
.type-cover--number .type-cover-month {
  top: 462px;
  max-width: 416px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.type-cover--number .type-cover-date-row { top: 508px; }
.type-cover--number .type-cover-index { flex-direction: row; bottom: 60px; gap: 12px; font-size: 8px; letter-spacing: 1px; }
/* Four numerals and short page counts sit cleanly above the horizontal rule */
.type-cover--number.type-cover--yearly .type-cover-number,
.type-cover--number.type-cover--blank .type-cover-number {
  top: 196px;
  left: 44px;
  font-size: 156px;
  letter-spacing: -3px;
}

/* ==========================================================================
   THE WEBGL NOTEBOOK (js/book3d.js)
   The object — boards, cloth, spine, paper blocks, shadow — is drawn on a
   canvas behind the planner; the DOM holds pages, hitboxes, and PNG sources.
   ========================================================================== */
#book3d-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  z-index: 1;
}

#book3d-rings-canvas {
  position: absolute;
  left: 464px;
  top: 0;
  width: 96px;
  height: 768px;
  display: block;
  pointer-events: none;
  z-index: 35;
}

/* First paint: nothing of the book is shown until it is finished, then it dissolves in.
   Target #canvas-viewport (never #planner-stage, whose getAnimations() is reserved for shelf flight). */
.book-pending #canvas-viewport,
.book-pending #library,
.book-pending #book3d-canvas { opacity: 0; pointer-events: none; }
.book-revealing #canvas-viewport,
.book-revealing #library,
.book-revealing #book3d-canvas { transition: opacity 160ms cubic-bezier(0.2, 0, 0.2, 1); }

/* The cover is in the scene. The DOM cover stays in place, unseen, to take the hand. */
.book3d #planner-book.book--closed,
.book3d .board-front,
.book3d .shelf-book-cover { opacity: 0; }

/* Open sewn notebooks get lit 3D paper, 32 px shader grid, grain, and gutter shading from the scene.
   Keep card backgrounds transparent so flat DOM rects never snap brighter on page turn, and apply the
   same continuous spine valley shade at rest and during turns. */
.book3d #planner-book:not(.book--closed) #planner-canvas > .paper-half,
.book3d #planner-book:not(.book--closed) #planner-canvas #canvas-content :is(.monthly-table, .dec-mini-card, .daily-mini-calendar, .daily-memo-card),
#planner-book[data-binder] .paper-surface,
.book3d #planner-book[data-binder] .paper-half {
  background: transparent;
}
.book3d #planner-book:not(.book--closed) #planner-canvas .monthly-table-header {
  background: rgb(var(--notebook-accent-rgb, 56 88 112) / 0.068);
}
.book3d #planner-book:not(.book--closed) .leaf .leaf-face.paper-surface {
  --color-paper: #F4F6F7;
}
.book3d #planner-book:not(.book--closed) .leaf :is(.monthly-table, .dec-mini-card, .daily-mini-calendar, .daily-memo-card) {
  background-color: #F4F6F7;
}
.book3d #planner-book:not(.book--closed) #planner-canvas #canvas-content > .spread:not(.binder-view)::after,
.book3d .leaf--paper .leaf-content::after {
  content: "";
  position: absolute;
  left: 400px;
  top: 0;
  width: 224px;
  height: 768px;
  pointer-events: none;
  opacity: var(--valley-shade, 1);
  background: linear-gradient(
    to right,
    rgb(28 48 68 / 0) 0%,
    rgb(28 48 68 / 0.008) 25%,
    rgb(28 48 68 / 0.022) 42%,
    rgb(28 48 68 / 0.044) 48.5%,
    rgb(28 48 68 / 0.068) 50%,
    rgb(28 48 68 / 0.044) 51.5%,
    rgb(28 48 68 / 0.022) 58%,
    rgb(28 48 68 / 0.008) 75%,
    rgb(28 48 68 / 0) 100%
  );
}
/* Page 1 rests flat inside the front cover on the left, so the spine shadow only affects the right page. */
.book3d #planner-book:not(.book--closed) #planner-canvas #canvas-content > .spread[data-page-index="0"]:not(.binder-view)::after {
  left: 512px;
  width: 112px;
  background: linear-gradient(
    to right,
    rgb(28 48 68 / 0.068) 0%,
    rgb(28 48 68 / 0.044) 3%,
    rgb(28 48 68 / 0.022) 16%,
    rgb(28 48 68 / 0.008) 50%,
    rgb(28 48 68 / 0) 100%
  );
}

/* The shelf holds the same objects. Each card keeps its DOM cover in place, unseen:
   it says where the notebook lies and takes the hand. */
.book3d .shelf-book,
.book3d .shelf-book-open { transform-style: flat; -webkit-transform-style: flat; }

/* Loose clear sleeves: no graph paper, white page block or paper edges.
   The scene supplies the cloth case and its pale inner lining underneath. */
#planner-book[data-binder] .leaf-face { box-shadow: none; }
.leaf--sleeve .binder-sheet { perspective: none; transform-style: flat; }
.leaf--sleeve .binder-rest-panel { transform: none; transform-style: flat; }
.leaf--sleeve .binder-card { isolation: isolate; opacity: 1; background-color: #F5F4EF; }
.leaf--sleeve .binder-card img { opacity: 1; backface-visibility: visible; -webkit-backface-visibility: visible; }
#planner-book[data-binder] .paper-half { background: #BEC9CE; }
#planner-book[data-binder] .binder-view .spread-top-header { color: #435661; }
#planner-book[data-binder] .binder-view .spread-top-rule { background: rgb(55 76 89 / 0.2); }

/* Free desk view (pinch / two-finger pan): fingers move the free view cleanly. */
.desk-free #canvas-viewport,
.desk-free #planner-stage,
.desk-free #canvas-content [contenteditable] { touch-action: none; }
.desk-zoom-reset {
  position: fixed;
  right: max(18px, env(safe-area-inset-right));
  bottom: calc(74px + env(safe-area-inset-bottom));
  z-index: 46;
  min-height: 32px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: rgba(251, 251, 248, 0.88);
  box-shadow: 0 2px 10px rgba(40, 52, 63, 0.08);
  color: var(--ink-soft, #55626D);
  font: 400 12px/1 var(--ui-sans);
  letter-spacing: 0.06em;
  cursor: pointer;
}
.desk-zoom-reset:hover { color: var(--ink); }

/* Case printing is separate from every loose leaf. WebGL draws it on the
   inner board faces; this static rendition serves CSS fallback and PNGs. */
.binder-case-labels { position: absolute; inset: 0; pointer-events: none; transition: opacity 280ms ease; }
.book--cover-flight .binder-case-labels { opacity: 0; transition-duration: 120ms; }
.binder-case-label { position: absolute; top: 28px; width: 464px; display: flex; align-items: center; gap: 20px; color: #53636E; font: 400 9px/1 var(--ui-sans); }
.binder-case-label--left { left: 24px; }
.binder-case-label--right { left: 536px; }
.binder-case-label i { flex: 1; height: .5px; background: #ACB8C0; }
