/* 019 Ribbon-tied gatefold (inv05_more w2, A1350). A thick ivory cotton gatefold (code: paper, grain, seam, light from
   the upper left) tied with a photographed sage satin band and bow. Pull or tap the bow: the ribbon slips off, the two
   panels swing open INTO the screen (D-017), and the real hero behind (he004) clears into focus as the reveal.
   This file is the poster + the CSS open; the live layer (gate.js) is its twin and adds the paper's light and touch. */
.op019 { position: fixed; inset: 0; z-index: 100; overflow: hidden; touch-action: none; overscroll-behavior: contain;
  --op019-paper: #FDF8F0; --op019-back: #F5EEE3; /* the grain darkens these ~1.9% on average: the live layer applies the same factor */ --op019-ground: var(--k-paper-deep, #EAE5DA); --op019-ink: var(--k-ink, #3E3832);
  --op019-soft: var(--k-ink-soft, #6F6458); --op019-press: rgba(255, 255, 255, .75); --op019-seam: rgba(74, 63, 53, .16);
  --op019-w: 100vw; --op019-h: 100svh; --op019-bandy: 64%; --op019-band: calc(var(--op019-h) * .062); --op019-bow: min(36%, calc(var(--op019-h) * .2));
  background: transparent; }
[data-kjy-skin-ground="dark"] .op019 { --op019-ground: var(--c-primary-dark, #2B1A12); }
/* tablet + desktop: a 9:16 card on the page ground (D-030) */
@media (min-aspect-ratio: 10/16) { .op019 { --op019-h: calc(100svh - 48px); --op019-w: calc(var(--op019-h) * 9 / 16); } }
@media (min-aspect-ratio: 10/16) and (max-height: 520px) { .op019 { --op019-h: calc(100svh - 16px); } }

/* the page ground around the card (it fades on the open, so the hero shows around the card too) */
.op019::before { content: ""; position: absolute; inset: 0; background: var(--op019-ground); }
.op019-card { position: absolute; left: calc(50% - var(--op019-w) / 2); top: calc(50% - var(--op019-h) / 2);
  width: var(--op019-w); height: var(--op019-h); perspective: 1600px; }
.op019-card--top { perspective: none; pointer-events: none; }
.op019-card--top .op019-bow { pointer-events: auto; }
.op019-stage { position: absolute; inset: 0; }

/* ---- the gatefold (poster) ---- */
.op019-fold { position: absolute; inset: 0; filter: drop-shadow(0 2px 10px rgba(74, 63, 53, .14)); }
.op019-panel { position: absolute; top: 0; bottom: 0; width: 50%; background-color: var(--op019-paper); backface-visibility: visible; }
.op019-panel--l { left: 0; transform-origin: 0 50%;
  background-image: linear-gradient(90deg, rgba(255, 255, 255, .22), rgba(255, 255, 255, 0) 40%, rgba(74, 63, 53, .05) 94%, var(--op019-seam)); }
.op019-panel--r { right: 0; transform-origin: 100% 50%;
  background-image: linear-gradient(90deg, var(--op019-seam), rgba(74, 63, 53, .04) 6%, rgba(255, 255, 255, 0) 60%, rgba(74, 63, 53, .03)); }
/* the cotton grain: the skin's --k-grain noise used as a MASK over its own ink (rgb .23/.2/.19), the same look as a
   background layer, but a mask is never an LCP candidate (a full-height background image was: A1350 opening-check) */
.op019-panel::after { content: ""; position: absolute; inset: 0; background: rgb(59, 51, 48); -webkit-mask: var(--k-grain); mask: var(--k-grain); pointer-events: none; }
.op019-pt { position: absolute; width: 0; height: 0; }
.op019-pt--tl { left: 0; top: 0; } .op019-pt--tm { left: 50%; top: 0; } .op019-pt--tr { left: 100%; top: 0; }
.op019-pt--bl { left: 0; top: 100%; } .op019-pt--bm { left: 50%; top: 100%; } .op019-pt--br { left: 100%; top: 100%; }

/* ---- letterpress text on the front (pressed: a light edge below, a shade above) ---- */
.op019-text { position: absolute; left: 8%; right: 8%; top: 13%; text-align: center; }
.op019-text p { margin: 0; }
.op019-mono { font: 400 calc(var(--op019-h) * .028)/1 var(--k-font-display, serif); letter-spacing: .32em; text-indent: .32em;
  color: var(--op019-soft); text-shadow: 0 1px 0 var(--op019-press), 0 -1px 0 rgba(74, 63, 53, .12); }
.op019-kicker { margin-top: calc(var(--op019-h) * .085) !important; color: var(--op019-soft); font-size: .6875rem;
  text-shadow: 0 1px 0 var(--op019-press); }
/* one text block (inline names + <br>), so the whole name block is ONE LCP candidate: flex items each count alone (A1350) */
.op019-names { margin-top: .5em !important; line-height: 1.1; color: var(--op019-ink);
  --op019-avail: calc(var(--op019-w) * .84); text-shadow: 0 1px 0 var(--op019-press), 0 -1px 0 rgba(74, 63, 53, .14); }
.op019-name { font: 400 min(calc(var(--op019-h) * .058), calc(var(--op019-avail) / (var(--op019-len, 6) * .74)))/1.1 var(--k-font-display, serif);
  text-transform: uppercase; letter-spacing: .04em; white-space: nowrap; }
.op019-and { font: 400 calc(var(--op019-h) * .03)/1.5 var(--k-font-script, cursive); color: var(--op019-soft); text-shadow: none; }
.op019-date { margin-top: 1.1em !important; font: 500 calc(var(--op019-h) * .018)/1.4 var(--k-font-body, sans-serif); letter-spacing: .14em;
  text-transform: uppercase; color: var(--op019-soft); text-shadow: 0 1px 0 var(--op019-press); }

/* ---- the ribbon: a satin band across both panels, the bow over the seam (the open control, D-026) ---- */
.op019-band { position: absolute; left: 0; right: 0; top: calc(var(--op019-bandy) - var(--op019-band) / 2); height: var(--op019-band);
  filter: drop-shadow(0 2px 2px rgba(74, 63, 53, .22)); }
.op019-band__half { position: absolute; top: 0; bottom: 0; width: 50%;
  background: url("assets/band.webp") 0 0 / calc(var(--op019-w) + 2px) 100% no-repeat; }
.op019-band__half--l { left: 0; transform-origin: 0 50%; transform: rotate(var(--op019-bl, 0deg)); }
.op019-band__half--r { right: 0; background-position: 100% 0; transform-origin: 100% 50%; transform: rotate(var(--op019-br, 0deg)); }
.op019-bow { position: absolute; left: 50%; top: var(--op019-bandy); display: block; width: var(--op019-bow); min-width: 104px; aspect-ratio: 560 / 496;
  min-height: 0; padding: 0; margin: 0; border: 0; border-radius: 22%; background: none; color: inherit; cursor: grab;
  transform: translate(calc(-50% + var(--op019-px, 0px)), calc(-56% + var(--op019-py, 0px))) rotate(var(--op019-pr, 0deg));
  -webkit-tap-highlight-color: transparent; -webkit-user-select: none; user-select: none; }
.op019-bow:focus-visible { outline: 2px solid var(--op019-ink); outline-offset: 4px; }
.op019-bow__img, .op019-bow__shadow { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.op019-bow__shadow { transform: translate(3%, 5%); opacity: .55; }
.op019-band__half--l, .op019-band__half--r { will-change: transform; }

/* ---- the hint: after 2.5 s, or at once on a stray tap ---- */
.op019-hint { position: absolute; left: 0; right: 0; top: calc(var(--op019-bandy) + var(--op019-h) * .14); margin: 0; text-align: center;
  font: 600 .6875rem/1.4 var(--k-font-display, serif); letter-spacing: .2em; text-transform: uppercase; color: var(--op019-soft);
  opacity: 0; animation: op019-hint .6s ease 2.5s forwards; }
.op019-hint__click { display: none; }
@media (pointer: fine) { .op019-hint__tap { display: none; } .op019-hint__click { display: inline; } }
.op019.is-hint .op019-hint { animation: none; opacity: 1; transition: opacity .3s ease; }
@keyframes op019-hint { to { opacity: 1; } }
/* short landscape phones: tighter type */
@media (orientation: landscape) and (max-height: 480px) {
  .op019-kicker { margin-top: calc(var(--op019-h) * .05) !important; font-size: .5625rem; }
  .op019-hint { font-size: .5625rem; }
}

/* the live layer draws the panels (its twin); the DOM text, ribbon and bow stay on top */
.kjy-live .op019-fold { visibility: hidden; transition: visibility 0s linear 400ms; }

/* ---- the open. Ribbon + text: DOM in both modes. Panels: CSS only without the live layer. ---- */
.op019.is-opening { animation: op019-out 600ms ease 2700ms forwards; }
.op019.is-opening::before { opacity: 0; transition: opacity .9s ease .4s; }
.op019.is-opening .op019-text, .op019.is-opening .op019-hint { opacity: 0; transition: opacity .3s ease; animation: none; }
.op019.is-opening .op019-bow { animation: op019-untie 650ms cubic-bezier(.5, 0, .75, 0) both; outline-color: transparent; pointer-events: none; }
.op019.is-opening .op019-band__half--l { animation: op019-slip-l 700ms cubic-bezier(.55, .055, .675, .19) 150ms both; }
.op019.is-opening .op019-band__half--r { animation: op019-slip-r 700ms cubic-bezier(.55, .055, .675, .19) 150ms both; }
html:not(.kjy-live) .op019.is-opening .op019-panel--l { animation: op019-open-l 1800ms cubic-bezier(.45, 0, .3, 1) 500ms both; }
html:not(.kjy-live) .op019.is-opening .op019-panel--r { animation: op019-open-r 1800ms cubic-bezier(.45, 0, .3, 1) 500ms both; }
@keyframes op019-untie {
  0% { transform: translate(calc(-50% + var(--op019-px, 0px)), calc(-56% + var(--op019-py, 0px))) rotate(var(--op019-pr, 0deg)); opacity: 1; }
  35% { transform: translate(calc(-50% + var(--op019-px, 0px)), calc(-50% + var(--op019-py, 0px))) rotate(-9deg) scale(.96); opacity: 1; }
  100% { transform: translate(-46%, 40vh) rotate(-24deg) scale(.9); opacity: 0; }
}
@keyframes op019-slip-l { to { transform: translate(-105%, 6px) rotate(-2deg); opacity: .2; } }
@keyframes op019-slip-r { to { transform: translate(105%, 6px) rotate(2deg); opacity: .2; } }
@keyframes op019-open-l { from { transform: rotateY(0deg); } to { transform: rotateY(100deg); } }
@keyframes op019-open-r { from { transform: rotateY(0deg); } to { transform: rotateY(-100deg); } }
@keyframes op019-out { to { opacity: 0; } }

/* ---- tablet and desktop (A1369, owner 2026-10-14: "looks a bit weird just before the disappearance"): the card stands
   on a wide ground, so after the swing its panels stood edge-on as two thin strips across the hero for a second. Here the
   panels fade out during the last part of the swing (1300 -> 2000 ms, from about 45 degrees to about 95), gone before
   they turn edge-on. Phone keeps the full swing: there the hinges are the screen's own edges. gate.js does the same. */
@media (min-aspect-ratio: 10/16) {
  html:not(.kjy-live) .op019.is-opening .op019-panel--l { animation: op019-open-l 1800ms cubic-bezier(.45, 0, .3, 1) 500ms both, op019-leave 700ms ease-in 1300ms both; }
  html:not(.kjy-live) .op019.is-opening .op019-panel--r { animation: op019-open-r 1800ms cubic-bezier(.45, 0, .3, 1) 500ms both, op019-leave 700ms ease-in 1300ms both; }
}
@keyframes op019-leave { to { opacity: 0; } }

/* ---- reduced motion: a static poster, the hint always shown, a plain crossfade ---- */
html.motion-reduce .op019-hint { animation: none; opacity: 1; }
html.motion-reduce .op019.is-opening { animation: op019-out .4s ease forwards; }
html.motion-reduce .op019.is-opening *, html.motion-reduce .op019.is-opening::before { animation: none !important; transition: none !important; }
