/* Light-novel feel for the dialogue box: typewriter, advance caret, reactions, choice beats, backlog. */

/* Typewriter: untyped text keeps its space so the box never jumps while a line types. */
#dialogue-text .untyped{color:transparent}
.next-caret{display:none;font-style:normal;font-size:.8em;line-height:1;margin-left:7px;color:#b58537}
#dialogue.awaiting .next-caret{display:inline-block;animation:caretBob .9s ease-in-out infinite}
#dialogue[data-ui="brain"] .next-caret{color:#f9ce69}
#dialogue[data-ui="text"] .next-caret,#dialogue[data-ui="draft"] .next-caret{display:none!important}
#dialogue[data-ui="draft"]:not(.line-done) #dialogue-text::after{content:none}
#dialogue[data-ui="draft"]:not(.line-done) .untyped::before{content:'|';color:#447b69}
#dialogue-text.bubble-in{animation:bubbleIn .26s cubic-bezier(.2,.9,.3,1.3) backwards;transform-origin:left bottom}
@keyframes caretBob{50%{transform:translateY(3px)}}
@keyframes bubbleIn{from{opacity:0;transform:scale(.86) translateY(6px)}}

/* Name plates: a colour per character, sliding in when the speaker changes. */
#dialogue[data-speaker="giulia"] #speaker{color:#b0506a}
#dialogue[data-speaker="mamma"] #speaker{color:#b3473a}
#dialogue[data-speaker="davide"] #speaker{color:#3a7a72}
#dialogue[data-speaker="nino"] #speaker{color:#7d6636}
#dialogue[data-speaker="luca"] #speaker{color:#8b5a2b}
#dialogue[data-speaker="sara"] #speaker{color:#3b7686}
#dialogue[data-speaker="marco"] #speaker{color:#56689c}
#dialogue[data-speaker="tourist"] #speaker{color:#6b7a4f}
#dialogue[data-speaker="narrator"] #speaker{color:#7b8570}
#speaker.name-in{animation:nameIn .24s ease-out backwards}
@keyframes nameIn{from{opacity:0;transform:translateX(-6px)}}

/* Portrait reactions stay opaque: fading a decoded face to zero looks like a loading failure.
   Backwards fill only, so social-hit scaling still applies afterwards. */
#dialogue-portrait.pm-enter{animation:pmEnter .32s cubic-bezier(.2,.9,.3,1.2) backwards}
#dialogue-portrait.pm-hop{animation:pmHop .34s ease-out}
#dialogue-portrait.pm-wobble{animation:pmWobble .42s ease-in-out}
#dialogue-portrait.pm-tilt{animation:pmTilt .4s ease-out}
#dialogue-portrait.pm-punch{animation:pmPunch .3s cubic-bezier(.2,.9,.3,1.4)}
#dialogue-portrait.pm-sag{animation:pmSag .5s ease-out}
#dialogue-portrait.pm-shift{animation:pmShift .25s ease-out}
@keyframes pmEnter{from{transform:translateY(6px) scale(.98)}}
@keyframes pmHop{35%{transform:translateY(-6px)}70%{transform:translateY(1px)}}
@keyframes pmWobble{25%{transform:rotate(-2.2deg)}55%{transform:rotate(1.6deg)}80%{transform:rotate(-.6deg)}}
@keyframes pmTilt{40%{transform:rotate(-3deg) translateX(-2px)}}
@keyframes pmPunch{30%{transform:scale(1.07)}}
@keyframes pmSag{45%{transform:translateY(5px) scaleY(.97)}}
@keyframes pmShift{from{transform:translateY(1px)}}

/* Choices: hidden (but still taking space) while the line types, then stagger in; the pick gets a beat. */
#choices.choices-typing{visibility:hidden}
#choices.choices-in button{animation:choiceIn .3s cubic-bezier(.2,.9,.25,1.1) backwards;animation-delay:calc(var(--i,0) * 60ms)}
#choices.choice-made button:not(.picked){opacity:.35;transition:opacity .15s}
#choices button.picked{background:var(--ink);color:var(--cream);border-color:var(--ink);animation:choicePick .17s ease-out}
#dialogue[data-ui="brain"] #choices button.picked{background:#fff4db;color:#173d3c;border-color:#fff4db}
@keyframes choiceIn{from{opacity:0;transform:translateY(8px)}}
@keyframes choicePick{40%{transform:scale(1.03)}}

/* Relationship toasts: warm or cold edge to match the chime. */
#toast.vibe.warm{border-color:#f2b49a;box-shadow:0 0 0 1px #f2b49a55,var(--shadow)}
#toast.vibe.cold{border-color:#86a7a3}

/* Big moments. */
#stage.moment-shake{animation:stageShake .45s cubic-bezier(.36,.07,.19,.97)}
#stage.moment-bloom #world-shade{animation:warmBloom 1.9s ease-out}
#stage.moment-glow #world-shade{animation:goldGlow 1.4s ease-out}
@keyframes stageShake{10%,90%{transform:translateX(-1px)}20%,80%{transform:translateX(3px)}30%,50%,70%{transform:translateX(-5px)}40%,60%{transform:translateX(5px)}}
@keyframes warmBloom{18%{background:#ffd9a64d}}
@keyframes goldGlow{25%{box-shadow:inset 0 0 140px #f9ce6977}}

/* Backlog. */
.meta-right{display:flex;align-items:center;gap:8px;min-width:0}
.log-button{background:none;font-size:9px;font-weight:800;letter-spacing:1.4px;color:#8c8e75;padding:2px 6px;border:1px solid #d7c9a4;border-radius:5px;flex-shrink:0}
.log-button:hover{background:#ebe3c8}
#skip-read{display:inline-flex;align-items:center;gap:6px;flex-shrink:0;min-height:32px;padding:4px 8px;background:none;border:1px solid #d7c9a4;border-radius:5px;color:#667463;font-size:11px;font-weight:700;white-space:nowrap;touch-action:none;user-select:none;-webkit-user-select:none;transform:none}
#skip-read kbd{margin:0;background:#e6dcbd;color:#3a6254;font-size:9px}
#skip-read:disabled{cursor:default;opacity:.55}
#skip-read[data-active="true"]{background:#173d3c;color:#fff4db;border-color:#173d3c}
#dialogue[data-ui="brain"] #skip-read{color:#dce8db;border-color:#3d6b63}
#dialogue[data-ui="brain"] #skip-read[data-active="true"]{background:#eef3e4;color:#173d3c;border-color:#eef3e4}
.touch-layout #skip-read{min-height:44px;font-size:12px}
.touch-layout #skip-read kbd{display:none}
/* Fast-forwarding familiar lines is a reading shortcut: no repeated portrait/name/bubble motion. */
#dialogue.skipping *,#dialogue.skipping *::after{animation:none!important;transition:none!important}
#dialogue[data-ui="brain"] .log-button{color:#9fbcb0;border-color:#3d6b63}
#game.social-danger .log-button{visibility:hidden}
#backlog{position:absolute;inset:0;z-index:13;display:flex;align-items:center;justify-content:center;background:#102e30b8;backdrop-filter:blur(4px);animation:fadeInOnly .18s}
.backlog-card{width:min(640px,92%);max-height:78%;display:flex;flex-direction:column;background:var(--cream);border:2px solid #e7c987;border-radius:16px;box-shadow:0 7px 0 #c6ad7c,var(--shadow);padding:16px 22px}
.backlog-head{display:flex;justify-content:space-between;align-items:center;font-size:11px;font-weight:800;letter-spacing:2px;color:#976624}
.backlog-head button{background:none;font-size:22px;line-height:1}
#backlog-lines{overflow:auto;overscroll-behavior:contain;padding-right:6px;margin-top:6px}
#backlog-lines p{margin:0;padding:9px 0;border-bottom:1px solid #eadcb9;font-size:14px;line-height:1.5;white-space:pre-line}
#backlog-lines b{display:block;font-size:10px;letter-spacing:1.6px;text-transform:uppercase;color:#a1602e}
#backlog-lines .brain{font-style:normal;font-family:'Fraunces',Georgia,serif;color:#35605a}
#backlog-lines .log-choice{color:#437a68;font-weight:700;font-size:13px;border-bottom-style:dashed}

/* Reading polish: a bounded reading measure, content-sized narration, and stable choice rows.
   The full unrevealed line still occupies space; nothing resizes as the typewriter advances. */
#game #dialogue{left:max(20px,calc((100% - 1080px)/2));right:max(20px,calc((100% - 1080px)/2));bottom:22px;min-height:0;max-height:calc(100% - 36px);overflow:auto;overscroll-behavior:contain;scrollbar-width:thin;outline:none}
#dialogue:focus,#backlog:focus,#phone:focus,#minigame:focus{outline:none}
#game #dialogue-portrait{width:144px;height:144px;min-height:144px;align-self:flex-start;margin:12px 0 12px 12px;border:1px solid #dcbf88;border-radius:10px;box-shadow:none;outline:none;overflow:hidden}
#dialogue .dialogue-content{min-height:0;padding:12px 20px;display:flex;flex-direction:column;gap:8px}
#dialogue .dialogue-meta{align-items:center;flex-wrap:wrap;row-gap:6px;min-height:32px}
#speaker{line-height:1.4;overflow-wrap:anywhere}
#dialogue .meta-right{margin-left:auto}
#dialogue #dialogue-text{overflow-wrap:anywhere;font-size:19px;line-height:1.5;font-weight:400;margin:0}
#dialogue-text .readable-line{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
/* Keep the end-of-line cue out of text flow: finishing a line must not create another line. */
#dialogue-text{position:relative;padding-right:18px}
#dialogue .next-caret{position:absolute;right:0;bottom:4px;display:block;visibility:hidden;margin:0}
#dialogue.awaiting .next-caret{visibility:visible}
#dialogue[data-ui="draft"]:not(.line-done) .untyped::before{content:none}
#dialogue #continue{width:112px;white-space:nowrap;min-height:32px;align-self:flex-end;margin:0;padding:4px 0;font-size:13px;line-height:1.4}
.touch-layout #dialogue #continue{min-height:44px}
#dialogue #choices:empty{display:none}
#dialogue #choice-timer{margin:18px 0 4px}
/* The bridge's timed beat is held breath, not social danger: a thin soft-gold timer with no label,
   and the log steps out as it does for every timed choice. */
#dialogue.tender-timed #choice-timer{height:3px;background:#efe0bf}
#dialogue.tender-timed #choice-timer div{background:linear-gradient(90deg,#d9a24e,#efc56e)}
#dialogue.tender-timed #choice-timer span{visibility:hidden}
#dialogue.tender-timed .log-button{visibility:hidden}
/* Only portraitless, non-choice narration gets the compact reading card. Portrait dialogue and
   every choice scene retain the established text-above-options stack. */
#game #dialogue:has(.no-portrait)[data-has-choices="false"]{bottom:36px;max-height:calc(100% - 40px)}
#dialogue:has(.no-portrait)[data-has-choices="false"] .dialogue-content{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px 24px;padding:18px 24px}
#dialogue:has(.no-portrait)[data-has-choices="false"] .dialogue-meta{grid-column:1/-1}
#dialogue:has(.no-portrait)[data-has-choices="false"] #dialogue-text{align-self:center;text-wrap:pretty;line-height:1.55}
#dialogue:has(.no-portrait)[data-has-choices="false"] #continue{align-self:center}
#dialogue[data-has-choices="true"] .dialogue-content{display:flex;flex-direction:column}
#dialogue[data-has-choices="true"] #choices{width:100%}
/* La giornata is a quieter narrator card; reduce only the internal gap so its line sits slightly higher. */
@media(min-width:761px) and (min-height:521px){
 #dialogue[data-speaker="narrator"]:has(.no-portrait)[data-has-choices="false"] .dialogue-content{gap:8px 24px;padding-bottom:22px}
 #dialogue[data-speaker="narrator"]:has(.no-portrait)[data-has-choices="false"] .dialogue-meta{min-height:28px}
}
#choices{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
#dialogue #choices button{display:grid;grid-template-columns:20px minmax(0,1fr);column-gap:10px;align-items:start;align-content:center;min-width:0;min-height:48px;padding:8px 14px;overflow-wrap:anywhere;font-size:16px;font-weight:600;line-height:1.4}
#dialogue #choices .choice-index{font-size:12px;line-height:22.4px;text-align:center;font-weight:500;opacity:.8}
/* Selection is color, not a permanent two-pixel lift that misaligns adjacent choices. */
#dialogue #choices button.selected,#dialogue #choices button:hover{transform:none}
/* At most 120ms of stagger plus 180ms of motion; JS waits the same 300ms before enabling. */
#choices.choices-in button{animation-duration:.18s;animation-delay:calc(var(--i,0) * 40ms)}
#choices button:disabled{opacity:1;cursor:default;transform:none}
#choices.choice-made button:not(.picked){opacity:.35}
#choices button:focus-visible{outline:2px solid #bb8330;outline-offset:2px}
.log-button{min-width:44px;min-height:32px;font-size:10px;color:#536e64}
.log-button:disabled{cursor:default}
#backlog-lines{min-height:0;overflow-wrap:anywhere;touch-action:pan-y}
.backlog-head button{min-width:44px;min-height:44px;flex-shrink:0}
#game.reading-paused #stage,#game.reading-paused #dialogue *,#game.reading-paused #dialogue *::after,#game.reading-paused #world-shade{animation-play-state:paused!important}
/* Don't spend a quarter of a phone screen on a disabled directional pad during a conversation. */
.touch-layout[data-mode="dialogue"] #touch-controls{min-height:64px;height:64px;padding-top:8px;padding-bottom:8px}
.touch-layout[data-mode="dialogue"] .dpad,.touch-layout[data-mode="dialogue"] #touch-phone,.touch-layout[data-mode="dialogue"] .touch-guidance .eyebrow{display:none}
.touch-layout[data-mode="dialogue"] .touch-guidance{display:flex;max-width:none;align-items:flex-start;text-align:left;gap:0}
.touch-layout[data-mode="dialogue"] #touch-hint{min-height:0;max-width:none;font-size:12px}
.touch-layout[data-mode="dialogue"] #touch-interact{width:96px;height:44px;border-radius:10px;border-bottom-width:3px;flex-direction:row;gap:8px}
.touch-layout[data-mode="dialogue"] #touch-action-icon{font-size:22px}
.touch-layout[data-mode="dialogue"] #touch-action-label{font-size:9px}
@media(max-width:760px){
 #game #dialogue{left:12px;right:12px;bottom:12px;max-height:calc(100% - 24px)}
 #game #dialogue:has(.no-portrait)[data-has-choices="false"]{bottom:12px;max-height:calc(100% - 24px)}
 #game #dialogue-portrait{width:112px;height:112px;min-height:112px}
 #dialogue:has(.no-portrait)[data-has-choices="false"] .dialogue-content{gap:10px 18px;padding:14px 18px}
 #choices{grid-template-columns:1fr}
 #dialogue .log-button{min-height:44px}
}
@media(max-width:520px){
 #game #dialogue-portrait{position:absolute;left:12px;top:12px;width:64px;height:64px;min-height:64px;margin:0}
 #dialogue .dialogue-meta{padding-left:76px;min-height:64px;align-content:center;gap:4px 8px}
 #dialogue #speaker{margin-left:0;min-height:0;font-size:11px;letter-spacing:1.2px}
 #dialogue #dialogue-context{max-width:none;font-size:9px;letter-spacing:.5px}
 #dialogue .meta-right{flex:1;justify-content:flex-end}
 /* Read-skip adds a second control: context gets a full row beside the portrait instead of a
    narrow column that can spill underneath it on small Italian phone layouts. */
 #dialogue:has(#skip-read:not([hidden])) .meta-right{flex-wrap:wrap;row-gap:4px}
 #dialogue:has(#skip-read:not([hidden])) #dialogue-context:not(:empty){flex-basis:100%;text-align:right}
 #dialogue:has(#skip-read:not([hidden])) #dialogue-context:empty{display:none}
 #dialogue #dialogue-text{padding-left:0;min-height:0;font-size:17px;line-height:1.5}
 #dialogue:has(.no-portrait) .dialogue-meta{padding-left:0;min-height:32px}
 #dialogue:has(.no-portrait)[data-has-choices="false"] .dialogue-content{grid-template-columns:minmax(0,1fr);gap:8px;padding:12px 14px}
 #dialogue:has(.no-portrait)[data-has-choices="false"] #continue{justify-self:end}
 #dialogue #choices button{font-size:15px;padding:10px 12px;column-gap:8px}
 #dialogue #choices .choice-index{line-height:21px}
 #dialogue .dialogue-content{padding:12px 14px}
 .backlog-card{padding:12px 16px;max-height:calc(100% - 32px)}
 #backlog-lines p{font-size:15px;line-height:1.55}
}
@media(max-height:520px) and (min-width:521px){#game #dialogue{bottom:20px}#game #dialogue:has(.no-portrait)[data-has-choices="false"]{bottom:20px}#game #dialogue-portrait{width:96px;height:96px;min-height:96px}#dialogue .dialogue-content{padding:10px 16px;gap:8px}#dialogue:has(.no-portrait)[data-has-choices="false"] .dialogue-content{padding:12px 16px;gap:8px}#dialogue #dialogue-text{font-size:17px}}
@media(prefers-reduced-motion:reduce){
 #dialogue *,#dialogue *::before,#dialogue *::after{animation:none!important;transition:none!important}
}
/* On phones the three held-breath answers sit in one compact row, so the couple stays visible
   above the box at the moment that matters. */
@media(max-width:560px){#dialogue.tender-timed #choices{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}#dialogue.tender-timed #choices button{grid-template-columns:minmax(0,1fr);column-gap:0;justify-items:center;min-height:0;padding:11px 6px;text-align:center;font-size:14px;overflow-wrap:normal;hyphens:none}#dialogue.tender-timed #choices .choice-index{display:none}}
