/* === OnlyBun VN player — ADV presentation ======================= */
/* Reading model is a visual novel, not a comic page: the art is the set,
   and every line is read from one steady text box docked at the bottom.
   Narration bookends switch to full-screen prose (NVL). */

* { box-sizing: border-box; }

/* Custom display rules (flex/inline-flex) would otherwise override the UA's
   [hidden] { display:none } — keep the hidden attribute authoritative. */
[hidden] { display: none !important; }

html, body { height: 100%; }

body.vnp-body {
    margin: 0;
    background: #05080d;
    color: #f2f5fa;
    font-family: "Noto Sans KR", ui-sans-serif, system-ui, sans-serif;
    overflow: hidden;
    -webkit-tap-highlight-color: transparent;
}

.vnp-stage {
    /* Height reserved at the bottom for the text box; the art sits above it. */
    --box-space: clamp(186px, 25vh, 258px);
    --frost: rgba(202, 228, 255, .18);

    position: relative;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
    cursor: pointer;
    user-select: none;
}

/* ── Backdrop: the same art, blurred, so the frame is lit by the scene ── */
.vnp-backdrop {
    position: absolute;
    inset: -6%;
    background-position: center;
    background-size: cover;
    /* Blur cost climbs fast with radius, so scale the art up and blur less:
       the enlargement does most of the softening for a fraction of the paint.
       translateZ keeps it on its own layer, painted once per scene. */
    filter: blur(22px) brightness(.4) saturate(1.2);
    transform: translateZ(0) scale(1.22);
}

.vnp-backdrop::after {
    content: "";
    position: absolute;
    inset: 0;
    background:
        radial-gradient(120% 80% at 50% 0%, transparent 40%, rgba(3, 6, 12, .72) 100%),
        linear-gradient(180deg, rgba(5, 8, 13, .35), rgba(5, 8, 13, .8));
}

/* ── Art ────────────────────────────────────────────────── */
.vnp-art {
    position: absolute;
    inset: 0;
    display: flex;
    /* Sit the art on top of the text box. On wide windows the art is
       height-bound and fills its area anyway; on phones, where portrait art
       leaves slack, this keeps art and text together instead of stranding a
       band of backdrop between them. */
    align-items: flex-end;
    justify-content: center;
    padding: 8px 8px calc(var(--box-space) - 8px);
}

.vnp-stage[data-mode="nvl"] .vnp-art {
    align-items: center;
    padding-bottom: 8px;
}

#vnp-image {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: 4px;
    box-shadow: 0 16px 44px rgba(0, 0, 0, .55);
    opacity: 1;
    transition-property: opacity;
    transition-timing-function: ease;
}

#vnp-image.is-changing { opacity: .3; }

/* ── Weather / screen effects (over the whole frame) ────── */
.vnp-overlay,
.vnp-screenfx {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.vnp-overlay { opacity: var(--fx-intensity, 0); }
.vnp-overlay[data-effect="none"] { display: none; }

/* Weather scrolls by moving a composited layer, never by animating
   background-position — that repainted the whole frame every tick and was a
   large part of the stutter. The layer is grown by exactly the distance it
   travels, and the travel is a whole number of tiles, so the loop is seamless. */
.vnp-overlay[data-effect="snow"] {
    top: -680px;
    height: calc(100% + 680px);
    background-image:
        radial-gradient(2.4px 2.4px at 22% 18%, rgba(255,255,255,.95) 45%, transparent 55%),
        radial-gradient(1.8px 1.8px at 64% 42%, rgba(255,255,255,.85) 45%, transparent 55%),
        radial-gradient(2px 2px at 84% 12%, rgba(255,255,255,.9) 45%, transparent 55%),
        radial-gradient(1.5px 1.5px at 38% 66%, rgba(255,255,255,.8) 45%, transparent 55%),
        radial-gradient(2.2px 2.2px at 8% 44%, rgba(255,255,255,.85) 45%, transparent 55%),
        radial-gradient(1.6px 1.6px at 52% 88%, rgba(255,255,255,.8) 45%, transparent 55%);
    background-size: 240px 340px;
    animation: vnp-snow 11s linear infinite;
    will-change: transform;
}

@keyframes vnp-snow {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-240px, 680px, 0); }
}

.vnp-overlay[data-effect="sparkles"] {
    background-image:
        radial-gradient(2.6px 2.6px at 30% 30%, rgba(255,236,170,.95) 40%, transparent 60%),
        radial-gradient(2px 2px at 70% 22%, rgba(214,240,255,.9) 40%, transparent 60%),
        radial-gradient(2.4px 2.4px at 52% 62%, rgba(255,246,214,.9) 40%, transparent 60%),
        radial-gradient(1.8px 1.8px at 16% 74%, rgba(255,255,255,.85) 40%, transparent 60%),
        radial-gradient(2.2px 2.2px at 86% 58%, rgba(255,236,170,.9) 40%, transparent 60%);
    background-size: 260px 260px;
    animation: vnp-sparkle 2.6s ease-in-out infinite alternate;
}

@keyframes vnp-sparkle {
    from { opacity: calc(var(--fx-intensity, 0) * .4); }
    to   { opacity: var(--fx-intensity, 0); }
}

/* Static: this fires on a single scene alongside the flash, and scrolling it
   cost a full-frame repaint for something on screen a couple of seconds. */
.vnp-overlay[data-effect="speed-lines"] {
    background: repeating-linear-gradient(
        104deg,
        transparent 0 26px,
        rgba(255, 255, 255, .25) 26px 28px,
        transparent 28px 60px);
}

.vnp-screenfx { opacity: 0; }

.vnp-screenfx.is-flash {
    background: #fff;
    animation-name: vnp-flash;
    animation-timing-function: ease-out;
}

@keyframes vnp-flash {
    0%   { opacity: .9; }
    100% { opacity: 0; }
}

/* ── Top bar ────────────────────────────────────────────── */
.vnp-bar {
    position: absolute;
    inset: 0 0 auto;
    z-index: 6;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px 30px;
    background: linear-gradient(180deg, rgba(4, 7, 12, .8), transparent);
    cursor: default;
}

.vnp-bar-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 34px;
    height: 34px;
    padding: 0 11px;
    border-radius: 999px;
    border: 1px solid var(--frost);
    background: rgba(8, 13, 22, .55);
    color: rgba(238, 245, 255, .86);
    font: 500 12.5px/1 "Noto Sans KR", sans-serif;
    text-decoration: none;
    cursor: pointer;
    flex: 0 0 auto;
}

.vnp-bar-btn:hover:not(:disabled),
.vnp-bar-btn:focus-visible { border-color: rgba(214, 240, 255, .5); color: #fff; }
.vnp-bar-btn:disabled { opacity: .32; cursor: default; }
.vnp-bar-btn.is-on { background: rgba(214, 240, 255, .88); color: #08111d; border-color: transparent; }

.vnp-bar-mid {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    margin-right: auto;
}

.vnp-bar-title {
    font-size: 12.5px;
    font-weight: 500;
    letter-spacing: .04em;
    color: rgba(238, 245, 255, .9);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.vnp-bar-scene {
    font: 400 10.5px/1 Inter, sans-serif;
    letter-spacing: .18em;
    color: rgba(169, 200, 232, .7);
}

.vnp-bar-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

.vnp-stats { display: flex; gap: 6px; }

.vnp-stat {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 11px;
    border-radius: 999px;
    background: rgba(8, 13, 22, .78);
    border: 1px solid var(--frost);
    font-size: 11px;
    color: rgba(238, 245, 255, .9);
    white-space: nowrap;
}

.vnp-stat i {
    width: 7px;
    height: 7px;
    border-radius: 999px;
    display: inline-block;
}

/* ── The text box (ADV) ─────────────────────────────────── */
.vnp-textbox {
    position: absolute;
    left: 50%;
    bottom: 20px;
    transform: translateX(-50%);
    z-index: 4;
    /* Kept near the art's visual weight, and short enough that Korean lines
       stay in a comfortable reading measure. */
    width: min(860px, calc(100% - 28px));
    min-height: 128px;
    max-height: calc(var(--box-space) - 34px);
    padding: 26px 30px 28px;
    border-radius: 16px;
    border: 1px solid var(--frost);
    /* No backdrop-filter here: this box repaints on every typed character, and
       re-blurring what is behind it each time is what made the reveal stutter.
       An almost-opaque fill reads the same over the darkened backdrop. */
    background:
        linear-gradient(180deg, rgba(12, 20, 33, .95), rgba(6, 11, 19, .97));
    box-shadow:
        0 -6px 40px rgba(0, 0, 0, .5),
        inset 0 1px 0 rgba(214, 240, 255, .16);
    transition: opacity .25s ease;
}

.vnp-textbox.is-hidden { opacity: 0; pointer-events: none; }

/* Nameplate straddling the box edge */
.vnp-speaker {
    position: absolute;
    top: 0;
    left: 26px;
    transform: translateY(-52%);
    margin: 0;
    padding: 6px 17px;
    border-radius: 999px;
    border: 1px solid rgba(214, 240, 255, .26);
    border-left: 3px solid var(--speaker-color, #a9ddff);
    background: rgba(9, 15, 25, .96);
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--speaker-color, #a9ddff) 30%, rgba(9, 15, 25, .96)),
        rgba(9, 15, 25, .96));
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .05em;
    white-space: nowrap;
    box-shadow: 0 8px 22px rgba(0, 0, 0, .45);
}

.vnp-text {
    margin: 0;
    max-height: 100%;
    overflow-y: auto;
    font-size: clamp(15px, 1.15vw, 17.5px);
    line-height: 1.95;
    letter-spacing: .01em;
    color: rgba(238, 245, 255, .96);
    white-space: pre-wrap;
    word-break: keep-all;
}

/* Typewriter caret while a line is still revealing */
.vnp-textbox.is-typing .vnp-text::after {
    content: "";
    display: inline-block;
    width: 2px;
    height: 1.05em;
    margin-left: 2px;
    vertical-align: -.16em;
    background: rgba(214, 240, 255, .9);
    animation: vnp-caret .7s steps(1) infinite;
}

@keyframes vnp-caret {
    0%, 50% { opacity: 1; }
    51%, 100% { opacity: 0; }
}

.vnp-cue {
    position: absolute;
    right: 18px;
    bottom: 12px;
    font-size: 10px;
    color: rgba(169, 221, 255, .8);
    animation: vnp-cue 1.5s ease-in-out infinite;
}

@keyframes vnp-cue {
    0%, 100% { transform: translateY(0); opacity: .45; }
    50% { transform: translateY(3px); opacity: 1; }
}

/* ── NVL: the narration bookends take the whole frame ───── */
.vnp-stage[data-mode="nvl"] .vnp-textbox {
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    width: auto;
    max-width: none;
    max-height: none;
    transform: none;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 14vh clamp(24px, 8vw, 130px) 16vh;
    border: 0;
    border-radius: 0;
    /* Full-screen scrim, no backdrop-filter: this layer repaints on every
       typed character and the two narration scenes are the first and last
       thing anyone reads. */
    background: linear-gradient(180deg, rgba(4, 8, 14, .66), rgba(4, 8, 14, .9));
    box-shadow: none;
}

.vnp-stage[data-mode="nvl"] .vnp-text {
    max-width: 620px;
    font-family: "Gowun Batang", serif;
    font-size: clamp(16px, 1.35vw, 19px);
    line-height: 2.15;
    text-align: left;
    overflow: visible;
}

.vnp-stage[data-mode="nvl"] .vnp-cue { right: 50%; transform: translateX(50%); bottom: 8vh; }

/* ── Choices: centred over the set, box stays put ───────── */
.vnp-choices {
    position: absolute;
    inset: 0 0 var(--box-space) 0;
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 40px 20px 0;
    background: radial-gradient(80% 60% at 50% 50%, rgba(4, 8, 14, .5), rgba(4, 8, 14, .78));
    cursor: default;
    animation: vnp-fade .28s ease both;
}

@keyframes vnp-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

.vnp-choices-title {
    margin: 0;
    font-size: 11.5px;
    letter-spacing: .34em;
    color: rgba(169, 200, 232, .8);
}

.vnp-choice-list {
    display: flex;
    flex-direction: column;
    gap: 11px;
    width: min(560px, 100%);
}

.vnp-choice {
    display: flex;
    flex-direction: column;
    gap: 5px;
    width: 100%;
    padding: 15px 22px;
    border-radius: 12px;
    border: 1px solid rgba(214, 240, 255, .28);
    background: rgba(10, 17, 28, .93);
    color: #f2f5fa;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color .2s ease, background-color .2s ease, transform .2s ease;
}

.vnp-choice:hover:not(:disabled),
.vnp-choice:focus-visible:not(:disabled) {
    border-color: rgba(214, 240, 255, .7);
    background: rgba(22, 34, 52, .92);
    transform: translateY(-1px);
}

.vnp-choice.is-locked { opacity: .5; cursor: default; }

.vnp-choice-text {
    font-size: 15px;
    font-weight: 500;
    line-height: 1.6;
    word-break: keep-all;
}

.vnp-choice-sub {
    font-size: 11.5px;
    color: rgba(169, 200, 232, .72);
}

/* ── Backlog ────────────────────────────────────────────── */
.vnp-backlog {
    position: absolute;
    inset: 0;
    z-index: 8;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: rgba(3, 6, 11, .88);
    cursor: default;
}

.vnp-backlog-panel {
    display: flex;
    flex-direction: column;
    width: min(720px, 100%);
    max-height: 82%;
    border-radius: 18px 18px 0 0;
    border: 1px solid var(--frost);
    border-bottom: 0;
    background: rgba(8, 13, 22, .96);
    animation: vnp-rise .3s cubic-bezier(.33, 1, .48, 1) both;
}

@keyframes vnp-rise {
    from { transform: translateY(18px); opacity: 0; }
    to { transform: none; opacity: 1; }
}

.vnp-backlog-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px 12px;
    border-bottom: 1px solid rgba(214, 240, 255, .12);
}

.vnp-backlog-head h2 {
    margin: 0;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .22em;
    color: rgba(169, 200, 232, .9);
}

.vnp-backlog-list {
    list-style: none;
    margin: 0;
    padding: 8px 20px 26px;
    overflow-y: auto;
}

.vnp-backlog-list li {
    padding: 13px 0;
    border-bottom: 1px solid rgba(214, 240, 255, .08);
}

.vnp-backlog-list li:last-child { border-bottom: 0; }

.vnp-log-who {
    display: block;
    margin-bottom: 5px;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .06em;
    color: var(--speaker-color, #a9ddff);
}

.vnp-log-text {
    display: block;
    font-size: 13.5px;
    line-height: 1.85;
    color: rgba(226, 236, 248, .84);
    word-break: keep-all;
}

.vnp-log-empty {
    padding: 26px 0;
    text-align: center;
    color: rgba(169, 200, 232, .6);
    font-size: 13px;
}

/* ── Ending card ────────────────────────────────────────── */
.vnp-ending {
    position: absolute;
    inset: 0;
    z-index: 9;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 40px 28px;
    text-align: center;
    background: rgba(4, 8, 14, .95);
    cursor: default;
}

.vnp-ending-label {
    margin: 0;
    font-size: 11px;
    letter-spacing: .5em;
    color: rgba(169, 200, 232, .6);
}

.vnp-ending-title {
    margin: 0;
    font-family: "Gowun Batang", serif;
    font-size: clamp(25px, 5vw, 34px);
    font-weight: 700;
    letter-spacing: .04em;
}

.vnp-ending-desc {
    margin: 0;
    max-width: 460px;
    font-size: 14.5px;
    line-height: 1.95;
    color: rgba(238, 245, 255, .82);
    word-break: keep-all;
}

.vnp-ending-stats {
    display: flex;
    gap: 16px;
    margin-top: 8px;
    font-size: 12.5px;
    color: rgba(238, 245, 255, .75);
}

.vnp-ending-stats i {
    width: 8px;
    height: 8px;
    border-radius: 999px;
    display: inline-block;
    margin-right: 6px;
}

.vnp-ending-actions {
    display: flex;
    gap: 12px;
    margin-top: 20px;
}

.vnp-ending-btn {
    padding: 12px 26px;
    border-radius: 999px;
    border: 0;
    background: linear-gradient(120deg, #d6f0ff, #a9ddff 55%, #c9bcff);
    color: #08111d;
    font: 500 14px/1 "Noto Sans KR", sans-serif;
    text-decoration: none;
    cursor: pointer;
}

.vnp-ending-quiet {
    background: transparent;
    border: 1px solid rgba(214, 240, 255, .4);
    color: rgba(238, 245, 255, .88);
}

/* ── Small screens ──────────────────────────────────────── */
@media (max-width: 560px) {
    .vnp-stage { --box-space: clamp(176px, 30vh, 240px); }
    .vnp-stats { display: none; }
    .vnp-textbox { padding: 22px 20px 24px; bottom: 12px; min-height: 118px; }
    .vnp-speaker { left: 18px; font-size: 12.5px; }
    .vnp-text { font-size: 15px; line-height: 1.9; }
    .vnp-stage[data-mode="nvl"] .vnp-textbox { padding: 16vh 22px 14vh; }
    .vnp-backlog-panel { max-height: 88%; }
}

@media (prefers-reduced-motion: reduce) {
    .vnp-overlay,
    .vnp-cue,
    .vnp-choices,
    .vnp-backlog-panel,
    .vnp-textbox.is-typing .vnp-text::after { animation: none !important; }
    #vnp-image { transition: none !important; }
}
