/* =====================================================================
   🗑️ Trash Easter Egg
   ===================================================================== */

/* --- Animations --- */
@keyframes dramaticReveal {
  from { opacity: 0; transform: scale(0.95); }
  to   { opacity: 1; transform: scale(1); }
}
@keyframes blink { 50% { border-color: transparent; } }

/* --- Main Secret Container --- */
#trash .secret-content.revealed {
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  align-items: center;
  flex: 1 1 auto;
  padding: 20px 20px 0;
  box-sizing: border-box;
  background-color: #0d2a0d;
  color: #e0e0e0;
  animation: dramaticReveal 0.5s ease-out;
  overflow: hidden;
}

/* pre-wrap, not pre. The hand-broken dialogue is not what `pre` was protecting:
   typewriterEffect() writes every "\n" out as a <br>, so the authored breaks are
   already elements and survive any white-space value. All `pre` contributed was
   "never wrap" — and this panel is overflow: hidden, so a line one character too
   long for the window neither scrolled nor wrapped. It silently lost characters
   off both ends, the wrapping single quotes first, which turned narration into
   what looked like corruption. pre-wrap keeps both guarantees the copy relies on
   (hard breaks, and runs of spaces if a line ever wants them) and turns the one
   failure mode into a wrap. .final-message-text below has been pre-wrap since it
   was written, in this same panel and this same font, which is the precedent. */
.secret-content { font-family: monospace; white-space: pre-wrap; font-size: 12px; line-height: 1.2; overflow: auto; padding: 5px; }
.secret-content .highlight { color: #32cd32; font-weight: bold; }

.secret-main { display: flex; flex-direction: column; align-items: center; text-align: center; width: 100%; }

/* The width and the centring live here rather than being inherited from
   .secret-main, because the pills scene is the one scene with no .secret-main:
   there this element is a direct child of a centring flex column, so it used to
   shrink-wrap to its longest line and overhang both sides equally — which meant
   only the short lines lost anything, and they lost it off the left. 'Good.'
   rendered as .' on a phone. */
.guardian-text {
  width: 100%;
  text-align: center;
  font-family: "VT323", monospace;
  font-size: 20px;
  line-height: 1.5;
  min-height: 50px;
}
.highlight { color: #32cd32; font-weight: bold; }

/* A line only invites a click while it is still typing, when that click
   finishes it early. Morphy himself stays pokeable either way. */
.guardian-text.typing,
.final-message-text.typing { cursor: pointer; }

/* --- Game Options --- */
/* Both option rows are drawn at opacity: 0 and faded in by showOptions() once
   the line above them has finished typing, so until that happens they must not
   be clickable either. Without this an invisible "Kill the dog" sat over the
   panel through the whole opening line, and a click landing there fired the one
   irreversible ending in the OS before a word of it had been read. showOptions()
   hands the pointer back with the opacity. */
.game-options-container {
  margin-top: 20px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  pointer-events: none;
}
.game-option {
  display: inline-block;
  padding: 6px 14px;
  min-width: 120px;
  border: 2px solid #32cd32;
  background: transparent;
  color: #32cd32;
  font-family: "VT323", monospace;
  font-size: 18px;
  text-align: center;
  cursor: pointer;
  transition: all 0.2s ease-out;
}
.game-option:hover  { background-color: #32cd32; color: #0d2a0d; }
.game-option:active { transform: scale(0.95); }

/* --- The Kill Switch ---
   "Kill the dog" is not one of the machine's own options — it was planted, and
   it is drawn as something planted. Every declaration below is one control
   failing to match the one beside it:

     - the wrong typeface (browser Courier, not VT323), which is the single most
       convincing thing here: different metrics, different stroke weight, and
       nothing else in Retrium OS is set in it;
     - the wrong metrics and no 120px slot, so it is a different size in the row;
     - a dead grey-mauve fill and a default-widget bevel, off this panel's
       palette entirely, as if it were drawn by something with no stylesheet;
     - uneven borders (1px / 3px) where every OS control is even, so the bevel
       it is imitating does not even come out square;
     - three pixels of vertical drift and one horizontal, out of register;
     - padding that does not match the box it was given;
     - a hover that snaps, where the option beside it fades over 0.2s;
     - and no press response at all, which the option beside it has and this one
       never learned.

   What it deliberately no longer does is glitch. It carried a cyan ::before
   ghost, a red text-shadow and a cyan/red box-shadow, which together made a
   chromatic aberration — and chromatic aberration is a *style*. It says a
   designer chose it, and a program capable of an RGB split has a stylesheet.
   Software with no stylesheet draws something plain and wrong: a default button,
   a bad bevel, the wrong grey. Cheap is what "not drawn by this machine" looks
   like, and cheap is also legible, which the animated version stopped being the
   moment the pointer touched it — the one control in the OS with an irreversible
   consequence must not become harder to read when you point at it.

   Red went with the paint, and that is the point rather than a loss. Red is not
   foreign here: .ctrl-close is red, SYSTEM WARNING is red, the whole Devil theme
   is red. A red button reads as this machine's own danger state, which is the
   opposite of what this control is.

   Being wider than the slot beside it means the pair wraps a little sooner than
   it used to on a narrow window. That is not a regression to chase: this row is
   already flex-wrap: wrap and already stacks on a phone, and a control that does
   not fit the row it was dropped into is the point rather than a side effect.

   Marking it is deliberate: a visitor who takes it anyway made a real choice,
   which is what entitles the ending to call them a monster for it. The mark is
   the drawing, and only the drawing — nothing announces it, because a caption
   explaining that the button is wrong spends the noticing on the player's
   behalf. */
.game-option.kill {
  font-family: "Courier New", Courier, monospace;
  font-size: 15px;
  min-width: 0;
  padding: 4px 11px 8px 8px;
  border-style: solid;
  /* A raised bevel lit from the top left, drawn at four different widths, so it
     is recognisably the default-widget idiom and recognisably botched. */
  border-color: #d9d5cc #4b4842 #4b4842 #d9d5cc;
  border-width: 1px 3px 2px 1px;
  color: #1c1c1c;
  background: #b3aeb4;
  letter-spacing: 0.6px;
  position: relative;
  top: 3px;
  left: -1px;
  transition: none;
}
.game-option.kill:hover {
  background: #c8c4c9;
  color: #000;
}
/* The sibling presses; this one does not. Only the inherited scale is cancelled
   — there is nothing here to replace it with. */
.game-option.kill:active {
  transform: none;
}

/* --- Guardian Dog Image --- */
.guardian-dog-image { max-width: 250px; width: 60%; height: auto; margin-top: 20px; align-self: center; cursor: pointer; }
.guardian-dog-image.wise { width: auto; height: 230px; object-fit: contain; margin: 0; }

/* --- Finder Icon Fixes inside Trash --- */
#trash .finder-icon          { user-select: none; -webkit-user-select: none; }
#trash .finder-icon img      { pointer-events: none; }

/* --- Utility --- */
.no-padding { padding: 0 !important; }

/* --- Pill Stage ---
   Minimum content for this row is about 404px: a 79px pill, the 233px wise dog,
   a 72px pill and the container's own 20px of padding, none of which shrink.
   The desktop panel clips at 404px exactly, so the row fits and has nothing
   spare — do not add a gap here without widening #trash to match. Narrower than
   that and space-between throws the surplus symmetrically outward into the
   panel's overflow: hidden, which is what used to put the Blue Pill's centre off
   the left of a 320px viewport. The phone block below reflows it instead. */
.pill-buttons-container {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  max-width: 420px;
  /* Same gap the game options keep below the dialogue. */
  margin-top: 20px;
  padding: 0 10px;
  box-sizing: border-box;
  /* Same reason as .game-options-container above: invisible until showOptions()
     fades it in, so untouchable until then. The wise dog rides inside this row
     rather than beside it, so the rule below hands him straight back — the line
     itself is outside the container and hurries a click either way. */
  pointer-events: none;
}

/* Morphy is not one of the options he is sitting between. Clicking him hurries
   the line, which is only worth doing while that line is still typing — which
   is precisely the window the rule above closes. In the five .secret-main
   scenes he is a sibling of the options row and never lost the click; this is
   the one scene where he is a child of it, so he takes it back on his own. The
   two .pill-option children go on waiting for showOptions(), which is the whole
   point of the rule above and is not weakened by this. */
.pill-buttons-container .guardian-dog-image {
  pointer-events: auto;
}
.pill-option {
  padding: 8px;
  margin: 0;
  border: 3px solid black;
  font-family: "VT323", monospace;
  font-size: 16px;
  text-align: center;
  border-radius: 30px;
  cursor: pointer;
  flex-shrink: 0;
  transition: all 0.2s ease;
}
.pill-option:hover       { transform: scale(1.05); box-shadow: 0 0 25px rgba(255,255,255,0.6); }
.pill-option.blue        { background-color: #4a90e2; color: white; }
.pill-option.red         { background-color: #ff5f57; color: white; }

/* --- Final Messages --- */
.final-message-container { flex: 1 1 auto; width: 100%; padding: 15px; display: flex; justify-content: center; align-items: center; }
.final-message-text { font-family: "VT323", monospace; font-size: 20px; line-height: 1.6; white-space: pre-wrap; }
.final-message-text.monster  { color: red; }
.final-message-text.redpill  { color: black; }
.final-message-text.bluepill { color: rgb(0, 68, 255); }

/* --- Blue Pill Ending: Morphy Asleep --- */
.guardian-dog-image.sleeping { margin-top: 0; }

/* --- The conversation on a phone ---
   Three things are being bought here, and all three are measured rather than
   picked. #trash is 94% wide at this breakpoint (css/responsive.css), so at the
   narrowest viewport the OS supports the panel's clip box is
   300.8 - 6 borders - 20 padding = 274.8px. VT323 advances exactly 0.4em, so
   18px lands 38 characters inside that box — which is the figure the dialogue
   was written to, and it is now true at 320px rather than only on a large
   phone. Longer copy wraps rather than vanishing, because .secret-content is
   pre-wrap; this only keeps the shipped lines off the wrap.

   The dog is capped so the tallest scene still clears the dock. `pressing` is
   the long one — six lines, two options and the dog — and at 60% of the panel
   it ran the window under the dock by about a dog's head.

   And the pill row reflows. The dog takes its own row via order: -1 and a
   full-width box, which is also what forces the wrap; the two pills then sit
   under it, centred, both wholly on screen and both tappable. That is the whole
   fix for the blue pill: at 320px it used to be 13% visible with its centre at
   x = -8, so a real click on the hesitation branch could not land at all. */
@media (max-width: 600px) {
  #trash .secret-content.revealed {
    padding: 16px 10px 0;
  }

  .guardian-text {
    font-size: 18px;
  }

  .guardian-dog-image:not(.wise) {
    max-height: 120px;
    width: auto;
  }

  /* The endings are the one thing in this window that is a paragraph rather
     than hand-broken lines, so they are the one thing whose height depends on
     how narrowly it wraps. At 20px the blue pill's three paragraphs came to
     more than `.window`'s 80vh cap allows, and because #trash is content-sized
     the overflow had nothing to scroll — the window's own overflow: hidden simply
     took the last line off. The same 18px the dialogue uses here fits all three
     endings whole, red pill included, which matters most of all: its last lines
     are the two secret words. */
  .final-message-text {
    font-size: 18px;
  }

  .pill-buttons-container {
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px 28px;
    padding: 0;
  }

  .pill-buttons-container .guardian-dog-image.wise {
    order: -1;
    width: 100%;
    height: 160px;
  }
}

/* --- Window Overrides --- */
/* #trash has no fixed height: it is as tall as whichever scene is loaded, so
   nothing here may pin one. The floor keeps the short states reading as a
   window rather than a strip, and because .content is a column the scene
   stretches into that floor — otherwise the leftover would expose the white
   window background below the dark green panel. */
#trash.window            { background: #fff; }
#trash.window .content   { display: flex; flex-direction: column; min-height: 220px; }

/* --- Guardian Prompt --- */
/* Same bubble as the music prompt in css/music.css, but ambient rather than
   clickable, so it takes no pointer events at all like Morphy's own bubble. */
.trash-prompt {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 5050;
  max-width: 260px;
  padding: 8px 12px;
  border: 3px solid #000;
  background: #fffdf2;
  color: #000;
  box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.9);
  font-family: "VT323", monospace;
  font-size: 20px;
  line-height: 1.1;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.4s ease, visibility 0s 0.4s;
}

.trash-prompt.visible {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.4s ease, visibility 0s 0s;
}

.trash-prompt::after {
  content: "";
  position: absolute;
  left: var(--dock-bubble-tail-x, 22px);
  bottom: -13px;
  width: 18px;
  height: 18px;
  border-right: 3px solid #000;
  border-bottom: 3px solid #000;
  background: #fffdf2;
  transform: rotate(45deg);
}

body.has-fullscreen-window .trash-prompt {
  display: none !important;
}

/* --- Morphy Desktop Companion --- */
#morphy-cursor {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 8900;
  pointer-events: none;
  image-rendering: pixelated;
  transform-origin: top left;
}
#morphy-speech-bubble {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 8901;
  max-width: 260px;
  padding: 8px 12px;
  border: 3px solid #000;
  background: #fffdf2;
  color: #000;
  box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.9);
  font-family: "VT323", monospace;
  font-size: 20px;
  line-height: 1.1;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.12s steps(2, end), visibility 0.12s steps(2, end);
}
#morphy-speech-bubble.visible {
  opacity: 1;
  visibility: visible;
}
#morphy-speech-bubble::after {
  content: "";
  position: absolute;
  left: 22px;
  bottom: -13px;
  width: 18px;
  height: 18px;
  border-right: 3px solid #000;
  border-bottom: 3px solid #000;
  background: #fffdf2;
  transform: rotate(45deg);
}
.morphy-paw-print {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 8899;
  width: 32px;
  height: 32px;
  image-rendering: pixelated;
  pointer-events: none;
  opacity: 0;
}
.morphy-paw-print.visible {
  animation: morphyPawPrint 1.275s steps(4, end) forwards;
}

@keyframes morphyPawPrint {
  0% {
    opacity: 0;
  }
  15% {
    opacity: 1;
  }
  70% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

/* --- Morphy's House --- */
/* The follower's on/off switch, and the one part of Morphy that takes pointer
   events. He cannot be dragged into it: #morphy-cursor must stay
   pointer-events: none or he would intercept every click on the desktop, since
   he is always sitting on the pointer. So the house works with his follow
   behaviour instead — the visitor leads him here and waits with him at the
   door while the meter fills.

   z-index 5 is the desktop's own furniture layer: above the wallpaper and the
   grain, below every window (those start at 1000 via zTop), the dock (5000),
   the dock bubbles (5050), and both of Morphy's layers, so he walks in front
   of the house he is about to enter and a dragged window covers it the way it
   would cover a desktop icon. */
#morphy-house {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 5;
  width: 150px;
  height: 114px;
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s ease, visibility 0s 0.25s;
}
#morphy-house.unlocked {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.25s ease, visibility 0s 0s;
}
/* The art is 50x38 pixels and the file ships it at 6x, so a 2x display gets
   real pixels rather than the browser's upscaler. Every box below is a whole
   multiple of 50x38 — 3x here, 2x on a phone — which is what keeps one art
   pixel on a whole number of device pixels at every ratio, in both directions.
   That is also why pixelated is right on what is nominally a downscale: the
   file is flat 6x6 blocks, so dropping pixels out of it is exact. */
#morphy-house img {
  display: block;
  width: 100%;
  height: 100%;
  image-rendering: pixelated;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}
/* Armed, by hovering it or by clicking it open. No scale hover — the state
   change is a flat brightening plus the hard shadow the rest of the OS uses. */
#morphy-house.armed img {
  filter: brightness(1.12) drop-shadow(4px 4px 0 rgba(0, 0, 0, 0.55));
}
.morphy-house-label {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 26px);
  transform: translateX(-50%);
  padding: 3px 9px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  font-family: "VT323", monospace;
  font-size: 18px;
  line-height: 1.1;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
}
#morphy-house.armed .morphy-house-label {
  opacity: 1;
  visibility: visible;
}
/* The dwell meter. The empty track appears with the label so the visitor can
   see there is something to fill before Morphy has finished walking over. */
.morphy-house-meter {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 6px);
  transform: translateX(-50%);
  width: 96px;
  height: 12px;
  border: 3px solid #000;
  background: #fffdf2;
  box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.9);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
}
#morphy-house.armed:not(.occupied) .morphy-house-meter {
  opacity: 1;
  visibility: visible;
}
.morphy-house-meter-fill {
  display: block;
  width: 0;
  height: 100%;
  background: #000;
}
/* HOUSE_DWELL in js/apps/morphy.js must stay in step with this duration: the
   script decides when he is in, this only has to finish at the same moment.
   Stepped rather than smooth, so it reads as a chunky retro gauge, and the
   snap back to zero on cancel is deliberately untransitioned. */
#morphy-house.filling .morphy-house-meter-fill {
  width: 100%;
  transition: width 1400ms steps(8, end);
}
/* He is in there. Hidden while the label is up so the two never collide. */
.morphy-house-sleep {
  position: absolute;
  right: 8px;
  bottom: calc(100% + 2px);
  color: #fffdf2;
  font-family: "VT323", monospace;
  font-size: 22px;
  line-height: 1;
  letter-spacing: 2px;
  text-shadow: 2px 2px 0 #000;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
}
#morphy-house.occupied:not(.armed) .morphy-house-sleep {
  opacity: 1;
  visibility: visible;
}
/* Same rule the dock and its bubbles follow: a maximized window owns the
   screen, and the house is desktop furniture underneath it. */
body.has-fullscreen-window #morphy-house {
  display: none !important;
}
/* The dock is centred, so it only reaches this corner once the viewport is
   narrow enough. Past that the house sits above the dock rather than under it.
   The desktop dock stands 128px tall from the bottom, the mobile one 104px. */
@media (max-width: 900px) {
  #morphy-house {
    bottom: 136px;
  }
}
@media (max-width: 768px) {
  #morphy-house {
    right: 16px;
    bottom: 112px;
    width: 100px;
    height: 76px;
  }
  .morphy-house-meter {
    width: 84px;
  }
}

/* =====================================================================
   💀 Dead Dog Skull (Draggable Remains)
   ===================================================================== */
.skull-icon { display: flex; flex-direction: column; align-items: center; cursor: grab; user-select: none; -webkit-user-select: none; }
.skull-icon:active { cursor: grabbing; }
.skull-icon img    { width: 80px; height: auto; filter: drop-shadow(0 0 6px rgba(255,165,0,0.6)); transition: filter 0.3s ease; pointer-events: none; }
.skull-icon:hover img { filter: drop-shadow(0 0 12px rgba(255,165,0,0.9)); }
.skull-icon span   { font-family: "VT323", monospace; font-size: 14px; margin-top: 6px; color: #333; }
.skull-icon.skull-on-desktop { z-index: 9999; }
.skull-icon.skull-on-desktop span { color: #fff; text-shadow: 1px 1px 2px rgba(0,0,0,0.8); }
