/* The shell's silver surface extends from the header and footer to meet at
   the viewport centre. Clip the sheet instead of stretching its texture. */
:root {
    --hps-shutter-wash: color-mix(in srgb, var(--paper) 32%, transparent);
    --hps-shutter-surface: linear-gradient(var(--hps-shutter-wash), var(--hps-shutter-wash)), var(--hps-shutter-image, url('../images/doors/silver.webp'));
    --hps-shutter-size: max(100vw, 117.31dvh) auto;
    --hps-door-shade: color-mix(in srgb, var(--hps-color-media-canvas) 24%, transparent);
}
.site-header, .site-footer {
    background-image: var(--hps-shutter-surface);
    background-size: auto, var(--hps-shutter-size);
    background-repeat: no-repeat;
}
.site-header { background-position: center top; }
.site-footer { background-position: center bottom; }
/* Keep pale photographic surfaces out of the dark navigation shell. */
:root[data-color-mode="dark"] :is(.site-header, .site-footer) { background-image: none; }
@media (prefers-color-scheme: dark) {
    :root[data-color-mode="auto"] :is(.site-header, .site-footer) { background-image: none; }
}
/* Clear the shell lettering briefly before its background becomes the cover. */
html.hps-doors-preparing :is(.site-header, .site-footer) > * {
    opacity: 0;
    transition: opacity 100ms ease;
}
html:is(.hps-doors-pending, .hps-doors-arrive, .hps-doors-close)::before,
html:is(.hps-doors-pending, .hps-doors-arrive, .hps-doors-close)::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 10001;
    pointer-events: none;
    background-color: var(--paper);
    background-image: linear-gradient(var(--hps-door-shade), var(--hps-door-shade)), var(--hps-shutter-image, url('../images/doors/silver.webp'));
    background-size: auto, var(--hps-shutter-size);
    background-repeat: no-repeat;
}
html:is(.hps-doors-pending, .hps-doors-arrive, .hps-doors-close)::before {
    background-position: center;
    clip-path: inset(0 0 50%);
}
html:is(.hps-doors-pending, .hps-doors-arrive, .hps-doors-close)::after {
    background-position: center;
    clip-path: inset(calc(50% - 1px) 0 0);
}
html.hps-doors-close::before { animation: hps-doors-top 640ms cubic-bezier(.65,0,.35,1) both; }
html.hps-doors-close::after { animation: hps-doors-bottom 640ms cubic-bezier(.65,0,.35,1) both; }
/* Keep the original, unornamented vertical transition as a selectable style. */
html[data-hps-door-style="plain"] { --hps-door-shade: var(--hps-shutter-wash); }
html[data-hps-door-style="plain"]::before { background-position: center top; }
html[data-hps-door-style="plain"]::after { background-position: center bottom; }
/* A quarter turn puts the stem on the horizontal join, matching the reference.
   Each wing moves as a whole with its panel; the artwork is never stretched. */
.hps-door-wings { display: none; }
html:is(.hps-doors-pending, .hps-doors-arrive, .hps-doors-close) .hps-door-wings {
    display: block; position: fixed; inset: 0; z-index: 10002;
    pointer-events: none; overflow: hidden;
    --hps-wing-length: min(80vw, 92dvh);
    --hps-wing-height: calc(var(--hps-wing-length) * .407857);
}
.hps-door-wings > span { position: absolute; inset: 0; }
.hps-door-wings > span::before {
    content: ''; position: absolute; left: 50%;
    width: var(--hps-wing-height); height: var(--hps-wing-length);
    transform: translate(-50%, -50%) rotate(90deg);
    background: center / 100% 100% no-repeat;
    filter: drop-shadow(2px 0 3px color-mix(in srgb, var(--hps-color-media-canvas) 45%, transparent));
}
.hps-door-wings > .hps-door-wing--top::before {
    top: calc(50% - var(--hps-wing-height) / 2);
    background-image: url('../images/doors/ornament-left.webp');
}
.hps-door-wings > .hps-door-wing--bottom::before {
    top: calc(50% + var(--hps-wing-height) / 2 - 1px);
    background-image: url('../images/doors/ornament-right.webp');
}
html.hps-doors-close .hps-door-wing--top { animation: hps-wing-top-in 640ms cubic-bezier(.65,0,.35,1) both; }
html.hps-doors-close .hps-door-wing--bottom { animation: hps-wing-bottom-in 640ms cubic-bezier(.65,0,.35,1) both; }
html.hps-doors-arrive .hps-door-wing--top { animation: hps-wing-top-out 760ms 100ms cubic-bezier(.65,0,.35,1) both; }
html.hps-doors-arrive .hps-door-wing--bottom { animation: hps-wing-bottom-out 760ms 100ms cubic-bezier(.65,0,.35,1) both; }
@keyframes hps-wing-top-in { from { transform: translateY(-50%); } to { transform: none; } }
@keyframes hps-wing-bottom-in { from { transform: translateY(50%); } to { transform: none; } }
@keyframes hps-wing-top-out { from { transform: none; } to { transform: translateY(-50%); } }
@keyframes hps-wing-bottom-out { from { transform: none; } to { transform: translateY(50%); } }
html.hps-doors-pending .hps-door-wings { animation: hps-doors-failsafe 0s 5s forwards; }
html.hps-doors-pending:not(.hps-doors-art) .hps-door-wings { visibility: hidden; }
/* Hold the destination shut until its content is ready. If JS fails, uncover it after five seconds. */
html.hps-doors-pending::before, html.hps-doors-pending::after { animation: hps-doors-failsafe 0s 5s forwards; }
@keyframes hps-doors-failsafe { to { visibility: hidden; } }
/* Decoding the artwork during the arriving document's first frame makes Vivaldi show an empty tab for a frame or two.
   The doors start plain, and doors.js adds the artwork once it is decoded, while the outgoing frame still covers them. */
html.hps-doors-pending:not(.hps-doors-art)::before,
html.hps-doors-pending:not(.hps-doors-art)::after { background-image: none; }
/* Preserve the outgoing artwork: the incoming snapshot can be taken before background images decode. */
html:is(.hps-doors-close, .hps-doors-pending)::view-transition-group(root),
html:is(.hps-doors-close, .hps-doors-pending)::view-transition-old(root),
html:is(.hps-doors-close, .hps-doors-pending)::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
html.hps-doors-pending::view-transition-old(root) { animation: hps-doors-snapshot-hold 4s linear both; }
html.hps-doors-pending::view-transition-new(root) { display: none; }
@keyframes hps-doors-snapshot-hold { from { opacity: 1; } to { opacity: 1; } }

/* Reverse the vertical motion after the destination is ready. */
html.hps-doors-arrive::before { animation: hps-doors-open-top 760ms 100ms cubic-bezier(.65,0,.35,1) both; }
html.hps-doors-arrive::after { animation: hps-doors-open-bottom 760ms 100ms cubic-bezier(.65,0,.35,1) both; }
@keyframes hps-doors-top {
    from { clip-path: inset(0 0 calc(100% - var(--hps-door-header, 0px))); }
    to { clip-path: inset(0 0 50%); }
}
@keyframes hps-doors-bottom {
    from { clip-path: inset(calc(100% - var(--hps-door-footer, 0px)) 0 0); }
    to { clip-path: inset(calc(50% - 1px) 0 0); }
}
@keyframes hps-doors-open-top {
    from { clip-path: inset(0 0 50%); }
    to { clip-path: inset(0 0 100%); }
}
@keyframes hps-doors-open-bottom {
    from { clip-path: inset(calc(50% - 1px) 0 0); }
    to { clip-path: inset(100% 0 0); }
}
@media (prefers-reduced-motion: reduce) {
    html:is(.hps-doors-pending, .hps-doors-arrive, .hps-doors-close) .hps-door-wings { display: none; }
    html.hps-doors-preparing :is(.site-header, .site-footer) > * { opacity: 1; transition: none; }
    html:is(.hps-doors-pending, .hps-doors-arrive, .hps-doors-close)::before,
    html:is(.hps-doors-pending, .hps-doors-arrive, .hps-doors-close)::after { content: none; }
}

/* Third option: branches unfold in the page margins, then a short paper fade
   bridges the document change. No silver cover or moving shutter is used. */
.hps-door-vines { display: none; }
html[data-hps-door-style="vines"]:is(.hps-doors-close,.hps-doors-pending,.hps-doors-arrive) .hps-door-vines {
    display: block; position: fixed; inset: 0; z-index: 10002; pointer-events: none;
    overflow: hidden;
    --vine-width: clamp(56px, 13vw, 180px);
    --vine-height: calc(var(--vine-width) * 2.45);
}
.hps-door-vine {
    position: absolute; bottom: 15%; width: var(--vine-width); height: var(--vine-height);
    filter: drop-shadow(0 1px 1px color-mix(in srgb, var(--hps-color-media-canvas) 18%, transparent));
}
.hps-door-vine--left { left: -8px; --vine-image: url('../images/doors/ornament-right.webp'); --vine-origin: left; }
.hps-door-vine--right { right: -8px; --vine-image: url('../images/doors/ornament-left.webp'); --vine-origin: right; }
.hps-door-vine > i {
    position: absolute; inset: 0;
    background: var(--vine-image) center / 100% 100% no-repeat;
    /* Six contiguous sections bloom from the stem, bottom to top. */
    clip-path: inset(calc((5 - var(--branch)) * 100% / 6) 0 calc(var(--branch) * 100% / 6));
    transform-origin: var(--vine-origin) calc((6 - var(--branch)) * 100% / 6);
}
html.hps-doors-close .hps-door-vine > i {
    animation: hps-vine-bloom 520ms calc(var(--branch) * 120ms) cubic-bezier(.22,.7,.3,1) both;
}
html.hps-doors-close .hps-door-vine--right > i { animation-delay: calc(80ms + var(--branch) * 120ms); }
@keyframes hps-vine-bloom {
    from { transform: scale(.03, .4); opacity: 0; }
    25% { opacity: 1; }
    to { transform: none; opacity: 1; }
}
html[data-hps-door-style="vines"]:is(.hps-doors-close,.hps-doors-pending,.hps-doors-arrive)::before { content: none; }
html[data-hps-door-style="vines"]:is(.hps-doors-close,.hps-doors-pending,.hps-doors-arrive)::after {
    background: var(--paper); clip-path: none;
}
html[data-hps-door-style="vines"].hps-doors-close::after { animation: hps-doors-vine-cover 240ms 1160ms ease-in-out both; }
html[data-hps-door-style="vines"].hps-doors-arrive::after { animation: hps-doors-vine-reveal 420ms ease-out both; }
html.hps-doors-arrive .hps-door-vines { animation: hps-vines-release 420ms ease-out both; }
html.hps-doors-pending .hps-door-vines { animation: hps-doors-failsafe 0s 5s forwards; }
html.hps-doors-pending:not(.hps-doors-art) .hps-door-vines { visibility: hidden; }
@keyframes hps-doors-vine-cover { from { opacity: 0; } to { opacity: 1; } }
@keyframes hps-doors-vine-reveal { from { opacity: 1; } to { opacity: 0; } }
@keyframes hps-vines-release { to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
    html[data-hps-door-style="vines"]:is(.hps-doors-close,.hps-doors-pending,.hps-doors-arrive) .hps-door-vines { display: none; }
}
