/* ------------------------------------------------------------------
   Phase E.1 — desktop windowed layout.

   Adds two new windows (Solitaire background, Episodes chrome wrapper)
   and repositions the hero on desktop viewports (≥880px).
   Below 880px every desktop rule is reverted: Solitaire is hidden and
   the Episodes wrapper collapses to display:contents so today's
   flat-grid layout is byte-for-byte preserved on mobile.
   ------------------------------------------------------------------ */


/* --- Shared Win98 chrome (--w98-* vars are duplicated from index.html;
       worth extracting if a fourth file needs them) ----------------- */

.desktop-window {
  --w98-face: #c0c0c0;
  --w98-shadow: #808080;
  --w98-hilite: #ffffff;
  --w98-title: #000080;
  --w98-title-text: #ffffff;
  --w98-text: #000000;

  background: var(--w98-face);
  border: 2px solid var(--w98-hilite);
  box-shadow:
    inset -2px -2px 0 var(--w98-shadow),
    inset  2px  2px 0 var(--w98-hilite),
    2px 2px 0 #000;
  font-family: "MS Sans Serif", Tahoma, Verdana, Arial, sans-serif;
  color: var(--w98-text);
}

.dw-titlebar {
  background: var(--w98-title);
  color: var(--w98-title-text);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 8px;
  font-weight: 700;
  font-size: 11px;            /* dialled down from 13px so 'Solitaire' /
                                  'Episodes' read as small chrome labels
                                  rather than headline text */
  user-select: none;
}

.dw-title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dw-titlebar-controls {
  display: flex;
  gap: 6px;
}

.dw-ctrl {
  position: relative;
  width: 22px;
  height: 22px;
  background: var(--w98-face);
  border: 2px solid var(--w98-hilite);
  box-shadow:
    inset -2px -2px 0 var(--w98-shadow),
    inset  2px  2px 0 var(--w98-hilite);
}

/* Invisible hit-target extension. Pseudo-element sits 6px outside the
   visible button in every direction, so the clickable area is ~34px even
   though the chrome still looks 22px. Clicks on the pseudo bubble to the
   parent button. Compensates for the FAFO cursor's hotspot at (0,0) —
   the visible cursor body extends down-right of where clicks actually
   register, so users tend to click slightly above-left of where they're
   aiming. */
.dw-ctrl::before {
  content: '';
  position: absolute;
  inset: -6px;
}

/* Glyph inside the close button. Selecting via [data-close] (not nth-child)
   so adding/removing other controls doesn't shift the glyph rule. */
.dw-titlebar-controls .dw-ctrl::after {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
  color: #000;
  line-height: 1;
}
.dw-titlebar-controls .dw-ctrl[data-close]::after {
  content: '\00D7';   /* multiplication sign as the X */
  font-size: 16px;
}

/* Small program icon next to the title text. */
.dw-title {
  display: flex;
  align-items: center;
  gap: 5px;
}
.dw-title::before {
  content: '';
  display: inline-block;
  width: 14px;
  height: 14px;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  flex: 0 0 14px;
}
.solitaire-window .dw-title::before {
  /* mini playing card with spade */
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14"><rect x="2" y="1" width="10" height="12" fill="white" stroke="black"/><text x="7" y="11" font-family="serif" font-size="11" font-weight="bold" text-anchor="middle" fill="black">%E2%99%A0</text></svg>');
}
.episodes-window .dw-title::before {
  /* folder */
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 12"><path d="M1 3 L5 3 L6 2 L13 2 L13 11 L1 11 Z" fill="%23e8c44a" stroke="black" stroke-width="0.5"/></svg>');
  height: 12px;
}

.dw-menubar {
  display: flex;
  gap: 14px;
  padding: 3px 10px;
  font-size: 12px;
  border-bottom: 1px solid var(--w98-shadow);
  user-select: none;
}

.dw-menu-item::first-letter {
  text-decoration: underline; /* Win98 Alt-shortcut hint */
}

/* --- Toolbar (between menubar and content) ------------------------- */

.dw-toolbar {
  display: flex;
  gap: 2px;
  padding: 3px 6px;
  background: var(--w98-face);
  border-top: 1px solid var(--w98-hilite);
  border-bottom: 1px solid var(--w98-shadow);
  user-select: none;
  align-items: center;
}

.dw-tool-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  font-size: 13px;
  background: var(--w98-face);
  border: 1px solid;
  border-color: var(--w98-hilite) var(--w98-shadow) var(--w98-shadow) var(--w98-hilite);
}

.dw-tool-sep {
  width: 0;
  height: 18px;
  border-left: 1px solid var(--w98-shadow);
  border-right: 1px solid var(--w98-hilite);
  margin: 0 4px;
}

.dw-content {
  padding: 8px;
  background: var(--w98-face);
  /* recessed/sunken bevel: dark on top+left, light on bottom+right
     (inverse of the raised window chrome above). Adds an inner border
     that reads as a Win98 "list view" / "client area" panel. */
  border-style: solid;
  border-width: 2px;
  border-color: var(--w98-shadow) var(--w98-hilite) var(--w98-hilite) var(--w98-shadow);
  margin: 3px;
}

/* --- Status bar (bottom of each window) ----------------------------- */

.dw-statusbar {
  display: flex;
  gap: 4px;
  padding: 3px 4px 4px;
  font-size: 11px;
  user-select: none;
  align-items: stretch;
  border-top: 1px solid var(--w98-hilite);
}

.dw-status-cell {
  flex: 1;
  padding: 1px 6px;
  border-style: solid;
  border-width: 1px;
  border-color: var(--w98-shadow) var(--w98-hilite) var(--w98-hilite) var(--w98-shadow);
}

.dw-status-grip {
  width: 14px;
  height: 14px;
  align-self: flex-end;
  /* three diagonal lines in the bottom-right — the Win98 sizing grip */
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14"><path d="M0 14 L14 0" stroke="%23808080" stroke-width="1.5"/><path d="M5 14 L14 5" stroke="%23808080" stroke-width="1.5"/><path d="M10 14 L14 10" stroke="%23808080" stroke-width="1.5"/></svg>');
  background-repeat: no-repeat;
}

/* Solitaire green felt — Phase E.2 <video>. Falls back to flat #008000
   before the video paints or if it fails to load. */
.solitaire-felt {
  background: #008000;
  width: 100%;
  height: 100%;
  min-height: 200px;
  display: block;
  object-fit: cover; /* fill area, crop slight excess (source is 1500x700 ~2.14:1, container ~2.2:1) */
}

/* --- Win98-style scrollbar inside Episodes' content area ----------
   WebKit only; Firefox gets a basic scrollbar-color treatment below. */
.episodes-window .dw-content::-webkit-scrollbar {
  width: 16px;
}
.episodes-window .dw-content::-webkit-scrollbar-track {
  background-color: var(--w98-face);
  background-image:
    repeating-linear-gradient(0deg,  #aaa 0 1px, transparent 1px 2px),
    repeating-linear-gradient(90deg, #aaa 0 1px, transparent 1px 2px);
}
.episodes-window .dw-content::-webkit-scrollbar-thumb {
  background: var(--w98-face);
  border: 2px solid;
  border-color: var(--w98-hilite) var(--w98-shadow) var(--w98-shadow) var(--w98-hilite);
  box-shadow: inset -1px -1px 0 var(--w98-shadow), inset 1px 1px 0 var(--w98-hilite);
}
.episodes-window .dw-content::-webkit-scrollbar-button {
  height: 16px;
  background-color: var(--w98-face);
  border: 2px solid;
  border-color: var(--w98-hilite) var(--w98-shadow) var(--w98-shadow) var(--w98-hilite);
  background-repeat: no-repeat;
  background-position: center;
}
.episodes-window .dw-content::-webkit-scrollbar-button:vertical:start:decrement {
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 8"><path d="M5 1 L1 6 L9 6 Z" fill="black"/></svg>');
}
.episodes-window .dw-content::-webkit-scrollbar-button:vertical:end:increment {
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 8"><path d="M5 7 L1 2 L9 2 Z" fill="black"/></svg>');
}
.episodes-window .dw-content::-webkit-scrollbar-button:vertical:start:increment,
.episodes-window .dw-content::-webkit-scrollbar-button:vertical:end:decrement {
  display: none;   /* hide the "double" buttons WebKit reserves */
}

/* Firefox fallback */
.episodes-window .dw-content {
  scrollbar-width: auto;
  scrollbar-color: var(--w98-face) #aaa;
}


/* ------------------------------------------------------------------
   Phase F — stylised desktop sim.

   The page becomes a Win98 desktop: ambient spinning logo centred as a
   "wallpaper" element, icons in the top-left, and three app windows
   (.app-window) that the user opens by clicking icons. In Phase 1 all
   three windows are visible by default at preset positions so the
   layout can be reviewed; Phase 2 hides them and wires click-to-open.
   ------------------------------------------------------------------ */

/* --- Mobile (<880px): scroll-stack, no desktop sim ----------------- */
@media (max-width: 879.98px) {
  /* The desktop wrapper vanishes from layout so its children flow
     normally. Icons + ambient logo are hidden; Solitaire window is
     hidden; Welcome and Episodes flatten into the document flow. */
  .desktop {
    display: contents;
  }
  .desktop-icons,
  .ambient-logo,
  .app-window[data-window="solitaire"] {
    display: none;
  }
  .app-window {
    position: static;
    margin: 16px;
    box-shadow: 2px 2px 0 #000;
  }
  .app-window[data-window="episodes"] {
    display: contents;
  }
  .app-window[data-window="episodes"] .dw-titlebar,
  .app-window[data-window="episodes"] .dw-menubar,
  .app-window[data-window="episodes"] .dw-toolbar,
  .app-window[data-window="episodes"] .dw-statusbar {
    display: none;
  }

  /* Welcome — same trick: wrapper vanishes so the intro paragraphs flow
     into the document above the Episodes grid. The higher specificity
     of this selector overrides the [hidden] attribute on the HTML
     element (UA stylesheet specificity 0,0,1,0 vs ours 0,0,2,0), which
     is critical because desktop.js bails on mobile and never unhides
     Welcome itself. */
  .app-window[data-window="welcome"] {
    display: contents;
  }
  .app-window[data-window="welcome"] .dw-titlebar {
    display: none;
  }
  /* Win98 content panel for the intro on mobile: grey face + black border
     + 2px drop shadow. Matches the visual language of the episode portrait
     boxes below so the intro reads as an intentional widget on the teal
     desktop rather than floating prose. */
  .app-window[data-window="welcome"] .dw-content {
    background: var(--w98-face);
    border: 2px solid #000;
    box-shadow: 2px 2px 0 #000;
    margin: 16px;
    padding: 14px 18px;
  }
  /* Centre the intro on mobile, like the old .hero copy. */
  .app-window[data-window="welcome"] .intro {
    text-align: center;
  }
}

/* --- Desktop (≥880px): the windowed layout ------------------------- */
@media (min-width: 880px) {
  /* Desktop fills the viewport; no page-level scrolling. App windows
     handle their own internal scrolling via .dw-content overflow. */
  html, body {
    height: 100%;
    overflow: hidden;
  }

  .desktop {
    position: fixed;
    /* 16px inset leaves a teal frame at the viewport edge where body
       (with no cursor of its own, inheriting `auto` from html) shows
       the system cursor. Lets the browser's window-resize cursor take
       over cleanly when sliding toward the Chrome tab edge. The teal
       bg matches --w98-bg so the frame is invisible. 16px chosen to
       give room for the 32px FAFO cursor body to clear out before the
       user crosses into the resize zone. */
    inset: 16px;
    z-index: 0;
  }

  /* Ambient spinning FAFO logo — wallpaper element, centred behind the
     icons and windows. Transparent VP8 alpha webm. Sized via vmin so the
     logo dominates the desktop at any viewport without overflowing.
     Full opacity — the logo is the hero of the desktop. */
  .ambient-logo {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 80vmin;
    height: auto;
    display: block;
    z-index: 1;
    pointer-events: none;
    opacity: 1;
  }

  /* --- Intro choreography (first arrival after login) ------------------
     Inline head script in index.html adds .fafo-intro to <html> when
     sessionStorage.fafo_just_logged_in is set, BEFORE first paint, so
     the logo and icons start at opacity 0 without flashing. desktop.js
     then adds the *-in classes to trigger the transitions. ----------- */
  html.fafo-intro .ambient-logo {
    opacity: 0;
    transition: opacity 3s ease-out;
  }
  html.fafo-intro.fafo-intro-logo-in .ambient-logo {
    opacity: 1;
  }
  html.fafo-intro .desktop-icons {
    opacity: 0;
    transition: opacity 0.4s ease-out;
  }
  html.fafo-intro.fafo-intro-icons-in .desktop-icons {
    opacity: 1;
  }

  /* Vertical icon strip in the top-left, Win98 style. */
  .desktop-icons {
    position: absolute;
    top: 16px;
    left: 16px;
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 14px;
    z-index: 2;
  }

  .desktop-icon {
    background: none;
    border: 0;
    color: #fff;
    font-family: inherit;
    font-size: 12px;
    padding: 6px;
    width: 94px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    cursor: inherit;
    text-align: center;
    /* 1px black outline so the white label reads on any background. */
    text-shadow:
      -1px -1px 0 #000,
       1px -1px 0 #000,
      -1px  1px 0 #000,
       1px  1px 0 #000;
    user-select: none;
  }

  /* Click target gets a dotted focus rectangle on keyboard nav, à la
     Win98 selected-icon state. */
  .desktop-icon:focus-visible {
    outline: 1px dotted #fff;
    outline-offset: 2px;
  }

  .desktop-icon-glyph {
    width: 54px;
    height: 54px;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
  }
  .desktop-icon-glyph[data-glyph="folder"] {
    background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44 44" shape-rendering="crispEdges"><path d="M3 14 L13 14 L15 11 L24 11 L24 14 L41 14 L41 36 L3 36 Z" fill="%23e8c44a" stroke="black" stroke-width="1.5"/><line x1="3" y1="18" x2="41" y2="18" stroke="black" stroke-width="0.6"/></svg>');
  }
  .desktop-icon-glyph[data-glyph="cards"] {
    background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44 44" shape-rendering="crispEdges"><rect x="6" y="10" width="22" height="28" fill="white" stroke="black" stroke-width="1.5" transform="rotate(-10 17 24)"/><rect x="14" y="8" width="22" height="28" fill="white" stroke="black" stroke-width="1.5"/><text x="25" y="29" font-family="serif" font-size="20" font-weight="bold" text-anchor="middle" fill="black">%E2%99%A0</text></svg>');
  }
  /* Win98 info circle — matches the icon shown in the Welcome titlebar. */
  .desktop-icon-glyph[data-glyph="info"] {
    background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44 44" shape-rendering="crispEdges"><circle cx="22" cy="22" r="18" fill="white" stroke="black" stroke-width="1.5"/><text x="22" y="32" font-family="serif" font-size="28" font-weight="bold" font-style="italic" text-anchor="middle" fill="black">i</text></svg>');
  }

  /* --- App windows --------------------------------------------------
     Common chrome (border, bg, shadow) comes from the existing .dw-*
     rules above; .app-window adds positioning + the layered raised
     bevel. position:absolute so the desktop wrapper anchors them. */
  .app-window {
    position: absolute;
    background: var(--w98-face);
    border: 2px solid var(--w98-hilite);
    box-shadow:
      inset -2px -2px 0 var(--w98-shadow),
      inset  2px  2px 0 var(--w98-hilite),
      2px 2px 0 #000;
    display: flex;
    flex-direction: column;
    z-index: 10;
    color: var(--w98-text);
    font-family: "MS Sans Serif", Tahoma, Verdana, Arial, sans-serif;
    /* Hard edge: nothing inside the window can bleed past its border,
       no matter how big the inner content tries to be. Episodes' inner
       scroll still works because its overflow:auto is on .dw-content. */
    overflow: hidden;
    /* Phase E — open/close zoom. transform-origin set in JS to the
       originating icon's centre. Duration must match ANIM_MS in JS. */
    transform: scale(1);
    opacity: 1;
    transition: transform 180ms ease-out, opacity 180ms ease-out;
  }
  /* Re-assert the UA default — without this, the .app-window's explicit
     display:flex wins over [hidden]'s display:none. */
  .app-window[hidden] {
    display: none;
  }

  /* While a window is being dragged: suppress text selection across the
     whole window (otherwise text inside the content area highlights as the
     mouse passes over). Cursor stays the custom FAFO cursor — no override. */
  .app-window.is-dragging {
    user-select: none;
  }

  /* Phase D — inactive (not-focused) titlebar: Win98 flat grey, low-contrast
     text. Only ONE window has .is-focused at a time, set by desktop.js.
     The default .dw-titlebar (navy) shows on the focused window. */
  .app-window:not(.is-focused) .dw-titlebar {
    background: var(--w98-shadow);    /* #808080 */
  }
  .app-window:not(.is-focused) .dw-title {
    color: #c0c0c0;
  }

  /* Phase E — closed/closing/opening start state: small + transparent.
     .is-opening additionally disables the transition for that one frame
     so the window APPEARS in this state instantly (then JS removes the
     class on the next rAF and the transition runs back to default). */
  .app-window.is-opening,
  .app-window.is-closing {
    transform: scale(0.08);
    opacity: 0;
  }
  .app-window.is-opening {
    transition: none;
  }

  /* Phase 1 preset positions. Phase 2 JS will own these and reset on
     open. Welcome top-right of centre, Episodes left-of-centre, Solitaire
     bottom-right. */
  .app-window[data-window="welcome"] {
    top: 70px;
    right: 80px;
    width: 360px;
  }
  /* Squeeze-resilient defaults — at the 1440px design target these
     resolve to the original fixed values; at narrower viewports they
     scale down so windows don't crowd the viewport edge.

     Episodes width: clamp(420, 80vw, 720). At 880 viewport → 704; at
     1440+ → 720 (original). left clamp(40, 10vw, 140): at 880 → 88,
     at 1440+ → 140 (original). Net: right margin grows from 16px
     (cramped, original) to 88px at 880 viewport. */
  .app-window[data-window="episodes"] {
    left: clamp(40px, 10vw, 140px);
    top: 200px;
    /* +20% from previous 420/720 width range and 420 height. */
    width: clamp(504px, 80vw, 864px);
    height: 504px;
  }
  /* Solitaire right-pinned, so it auto-distances from the right edge —
     no width adjustment needed in the 880-1440 range. Sized to fit the
     solitaire.webm aspect ratio (1500×700 ≈ 2.14:1) inside the content
     area so the video fills without cropping. */
  .app-window[data-window="solitaire"] {
    right: 120px;
    bottom: 80px;
    width: 520px;
    height: 330px;
  }

  /* Welcome window — text-only content, no menubar/toolbar/statusbar.
     dw-content overrides the sunken inner panel for a cleaner reading
     surface (just window face, no recessed border). */
  .app-window[data-window="welcome"] .dw-content {
    padding: 14px 18px;
    background: var(--w98-face);
    border: 0;
    margin: 0;
  }
  .app-window[data-window="welcome"] .intro {
    font-size: 13px;
    font-weight: 500;
    line-height: 1.5;
    margin: 0 0 10px;
    text-align: left;
  }
  .app-window[data-window="welcome"] .intro:last-child {
    margin-bottom: 0;
  }
  /* Title icon: little speech-bubble "i" for "info / readme". */
  .app-window[data-window="welcome"] .dw-title::before {
    background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14"><circle cx="7" cy="7" r="6" fill="white" stroke="black" stroke-width="1"/><text x="7" y="11" font-family="serif" font-size="11" font-weight="bold" text-anchor="middle" fill="black">i</text></svg>');
  }

  /* Episodes content — internal scroll, three-column card grid. */
  .app-window[data-window="episodes"] .dw-content {
    flex: 1;
    overflow-y: auto;
    padding: 10px;
  }
  /* 4-column grid inside the Episodes window. Cards end up narrower than
     the page-level grid so a second row peeks at the bottom of the window
     content area, signalling "scroll for more". */
  .app-window[data-window="episodes"] .episodes-grid {
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
    margin: 0;
    padding: 0;
  }

  /* Solitaire content — video fills via object-fit:cover (same as before). */
  .app-window[data-window="solitaire"] .dw-content {
    flex: 1;
    min-height: 0;
    overflow: hidden;
    padding: 4px;
    display: flex;
  }
}
