/*
 * Taskbar landing-page CSS mockups.
 *
 * Primitives (.tb-*) compose into per-scene layouts below.
 * Loaded after style.css so it can override or extend palette tokens
 * (--bg, --surface, --text, --text-muted, --border, --accent) defined
 * there. No new color tokens are introduced.
 *
 * Sections:
 *   1. Local custom properties
 *   2. Primitives — atoms (tb-icon, tb-pill, tb-start, tb-divider, tb-clock)
 *   3. Primitives — composites (tb-bar, tb-popover, tb-window-frame, tb-desktop)
 *   4. Scene layouts (hero, grouping, pinned, multi, settings)
 */

/* --- 1. Local custom properties --- */
:root {
  --tb-bar-height: 44px;
  --tb-icon-size: 32px;
  --tb-icon-glyph-size: 18px;
  --tb-pill-height: 14px;
  --tb-wallpaper-light: linear-gradient(135deg, #d8e6f5 0%, #b9d2ec 100%);
  --tb-wallpaper-dark: linear-gradient(135deg, #1a2538 0%, #0d1827 100%);
}

:root { --tb-wallpaper: var(--tb-wallpaper-light); }
@media (prefers-color-scheme: dark) {
  :root { --tb-wallpaper: var(--tb-wallpaper-dark); }
}

/* --- 2. Primitives — atoms --- */

/* App-icon tile: rounded square + colored bg + inline glyph.
   Each instance sets --tb-icon-bg inline so colors vary without
   bloating the stylesheet. */
.tb-icon {
  position: relative;
  width: var(--tb-icon-size);
  height: var(--tb-icon-size);
  border-radius: 8px;
  background: var(--tb-icon-bg, #6e6e73);
  display: grid;
  place-items: center;
  flex: 0 0 auto;
}
.tb-icon svg {
  width: var(--tb-icon-glyph-size);
  height: var(--tb-icon-glyph-size);
  color: #ffffff;
}
/* Below-tile running-state dot. */
.tb-icon--running::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -6px;
  transform: translateX(-50%);
  width: 4px;
  height: 3px;
  border-radius: 1.5px;
  background: var(--accent);
}
/* Drag-in-progress affordance (used in Scene 3 only). */
.tb-icon--dragging {
  transform: rotate(-4deg) translateY(-2px);
  box-shadow: 0 8px 18px -6px rgba(0, 0, 0, 0.35);
  z-index: 1;
}

/* Accent pill — count badges, app badges, combined "5•3". */
.tb-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--tb-pill-height);
  height: var(--tb-pill-height);
  padding: 0 4px;
  border-radius: calc(var(--tb-pill-height) / 2);
  background: var(--accent);
  color: #ffffff;
  font-size: 9px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.01em;
  /* Static 40%-white halo (matches the real BadgeView from feat/app-badges). */
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.4);
}

/* Start button — the ▤ glyph at the left of the bar. */
.tb-start {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  display: grid;
  place-items: center;
  color: var(--accent);
  font-size: 18px;
  line-height: 1;
  flex: 0 0 auto;
}

/* Pinned-strip overflow chevron — sits at the trailing edge of the pinned
   zone when there are more pinned items than the visible cap. Same size as
   .tb-icon (32pt) but rendered as a muted chevron, not a colored tile.
   Mirrors the real Taskbar's `PinnedOverflowButton`. */
.tb-overflow {
  width: var(--tb-icon-size);
  height: var(--tb-icon-size);
  border-radius: 8px;
  display: grid;
  place-items: center;
  color: var(--text-muted);
  flex: 0 0 auto;
}
.tb-overflow svg {
  width: 18px;
  height: 18px;
}

/* Running-window button with a fixed width: small icon on the left,
   truncated title text on the right. Matches the real Taskbar's "fixed"
   window-button-width mode (default 150pt) — every running button has
   the same width regardless of title length, so the bar never shifts as
   window titles change. */
.tb-window-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: var(--tb-icon-size);
  width: 150px;
  padding: 0 8px 0 4px;
  border-radius: 8px;
  background: color-mix(in oklab, var(--text) 8%, transparent);
  font-size: 12px;
  color: var(--text);
  flex: 0 0 auto;
  position: relative;
}
.tb-window-btn .tb-icon {
  width: 22px;
  height: 22px;
  border-radius: 5px;
  --tb-icon-glyph-size: 14px;
}
.tb-window-btn__title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.tb-window-btn--running::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -6px;
  transform: translateX(-50%);
  width: 4px;
  height: 3px;
  border-radius: 1.5px;
  background: var(--accent);
}

/* Vertical divider between pinned and running zones. */
.tb-divider {
  flex: 0 0 1px;
  height: 60%;
  margin: 0 8px;
  background: color-mix(in oklab, var(--text) 18%, transparent);
  align-self: center;
}

/* Right-side static clock. */
.tb-clock {
  margin-left: auto;
  padding: 0 6px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  white-space: nowrap;
  align-self: center;
}

/* --- 3. Primitives — composites --- */

/* The taskbar strip. Translucent surface, flex row. */
.tb-bar {
  display: flex;
  align-items: center;
  gap: 4px;
  height: var(--tb-bar-height);
  padding: 0 8px;
  border-radius: 10px;
  background: color-mix(in oklab, var(--surface) 70%, transparent);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid color-mix(in oklab, var(--text) 8%, transparent);
  box-shadow: 0 4px 16px -6px rgba(0, 0, 0, 0.18);
}
.tb-bar__zone {
  display: flex;
  align-items: center;
  gap: 4px;
}
/* Running zone with a count pill anchored top-right of an icon. */
.tb-bar__group {
  position: relative;
}
.tb-bar__group .tb-pill {
  position: absolute;
  top: -3px;
  right: -4px;
}

/* Group popover — a floating card above an anchor tile. */
.tb-popover {
  position: absolute;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 14px 40px -10px rgba(0, 0, 0, 0.35);
  padding: 6px;
  min-width: 240px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.tb-popover__row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--text);
}
.tb-popover__row:hover { background: color-mix(in oklab, var(--text) 6%, transparent); }
.tb-popover__row .tb-icon {
  width: 22px;
  height: 22px;
  border-radius: 5px;
  --tb-icon-glyph-size: 14px;
}
.tb-popover__row-title {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tb-popover__row-close {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  display: grid;
  place-items: center;
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1;
}
.tb-popover__tail {
  position: absolute;
  left: 50%;
  bottom: -6px;
  transform: translateX(-50%) rotate(45deg);
  width: 10px;
  height: 10px;
  background: var(--surface);
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

/* Fake macOS window frame — used by Scene 4 (snapped above bar) and Scene 5 (Settings). */
.tb-window-frame {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 14px 40px -12px rgba(0, 0, 0, 0.3);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.tb-window-frame__titlebar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
  color: var(--text-muted);
  background: color-mix(in oklab, var(--surface) 92%, var(--text) 8%);
}
.tb-window-frame__lights {
  display: flex;
  gap: 6px;
  margin-right: 8px;
}
.tb-window-frame__light {
  width: 11px;
  height: 11px;
  border-radius: 50%;
}
.tb-window-frame__light--red    { background: #ff5f57; }
.tb-window-frame__light--yellow { background: #febc2e; }
.tb-window-frame__light--green  { background: #28c840; }
.tb-window-frame__body {
  flex: 1 1 auto;
  padding: 16px;
  font-size: 13px;
  color: var(--text-muted);
}

/* Desktop wrapper — soft gradient wallpaper, bar pinned to its bottom. */
.tb-desktop {
  position: relative;
  width: 100%;
  height: 100%;
  aspect-ratio: 16 / 10;
  background: var(--tb-wallpaper);
  border-radius: var(--radius-hero);
  overflow: hidden;
  box-shadow: var(--shadow-hero);
}
.tb-desktop > .tb-bar {
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 12px;
}

/* --- 4. Scene layouts --- */

/* Scene 3: pinned-strip close-up. Bare bar (no desktop wrapper), with a
   soft fade-out on the right so the running icons trail off the edge.
   The third pinned icon (.tb-icon--dragging) animates in a loop: lifts,
   slides leftward, slides back, sets down — demonstrating drag-to-
   reorder without actually swapping any neighbors. Pure CSS, 5s cycle. */
.scene-pinned {
  width: 100%;
  display: grid;
  place-items: center;
  position: relative;
}
.scene-pinned .tb-bar {
  width: 100%;
  max-width: 480px;
  -webkit-mask-image: linear-gradient(to right, #000 0%, #000 85%, transparent 100%);
          mask-image: linear-gradient(to right, #000 0%, #000 85%, transparent 100%);
}
.scene-pinned .tb-icon--dragging {
  /* Override the static lifted state from the atom primitive; the
     animation manages all of these properties across the cycle. */
  transform: rotate(0) translate(0, 0);
  box-shadow: none;
  animation: pinnedDrag 5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
@keyframes pinnedDrag {
  0%, 10%   { transform: rotate(0)     translate(0,     0);    box-shadow: none; }
  22%, 28%  { transform: rotate(-4deg) translate(0,    -8px);  box-shadow: 0 8px 18px -6px rgba(0, 0, 0, 0.35); }
  45%, 55%  { transform: rotate(-4deg) translate(-72px,-8px);  box-shadow: 0 8px 18px -6px rgba(0, 0, 0, 0.35); }
  72%, 78%  { transform: rotate(-4deg) translate(0,    -8px);  box-shadow: 0 8px 18px -6px rgba(0, 0, 0, 0.35); }
  90%, 100% { transform: rotate(0)     translate(0,     0);    box-shadow: none; }
}

/* Empty pinning slot — sits between the 3 visible pinned apps and the
   divider with a dashed outline, suggesting "free space to pin into".
   When the animation deposits something here, the dashed outline fills
   solid and the glyph inside fades in. */
.scene-pinned__slot {
  width: var(--tb-icon-size);
  height: var(--tb-icon-size);
  border-radius: 8px;
  border: 1.5px dashed color-mix(in oklab, var(--text) 22%, transparent);
  background: transparent;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
}
.scene-pinned__slot svg {
  width: var(--tb-icon-glyph-size);
  height: var(--tb-icon-glyph-size);
  color: #ffffff;
  opacity: 0;
}

/* Right-click pin demo: the pink chat icon (last running tile) lifts,
   slides leftward into the chat slot's empty position, and fades out as
   the slot fills with the chat color + icon. 8s cycle, out of phase
   with the 5s drag-reorder so the scene feels alive. */
.scene-pinned .scene-pinned__chat-source {
  animation: pinFromTaskbar 8s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  z-index: 2;
}
@keyframes pinFromTaskbar {
  0%, 8%    { transform: translate(0,     0)    rotate(0);    opacity: 1; }
  16%       { transform: translate(0,    -6px)  rotate(-3deg);opacity: 1; }
  38%       { transform: translate(-129px,-6px) rotate(-3deg);opacity: 1; }   /* arrives over chat slot */
  48%       { transform: translate(-129px, 0)   rotate(0);    opacity: 0.4; } /* settling, fading */
  56%, 80%  { transform: translate(-129px, 0)   rotate(0);    opacity: 0; }   /* faded; slot is now visible */
  92%       { transform: translate(0,     0)    rotate(0);    opacity: 0; }   /* invisible at home */
  100%      { transform: translate(0,     0)    rotate(0);    opacity: 1; }
}

/* Chat slot fills as the chat-source arrives. */
.scene-pinned__slot--chat {
  animation: pinSlotChatFill 8s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
.scene-pinned__slot--chat svg {
  animation: pinSlotChatGlyph 8s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
@keyframes pinSlotChatFill {
  0%, 44%   { background: transparent; border: 1.5px dashed color-mix(in oklab, var(--text) 22%, transparent); }
  54%, 80%  { background: #e84393;     border: 1.5px solid  #e84393; }
  90%, 100% { background: transparent; border: 1.5px dashed color-mix(in oklab, var(--text) 22%, transparent); }
}
@keyframes pinSlotChatGlyph {
  0%, 48%   { opacity: 0; }
  56%, 80%  { opacity: 1; }
  88%, 100% { opacity: 0; }
}

/* Folder drop demo: a yellow Finder-style folder appears above the bar,
   descends onto the folder slot, and fades out as the slot fills with
   the folder color + glyph. 7s cycle (out of phase with chat). */
.scene-pinned__folder-floater {
  position: absolute;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: #fdcb6e;
  display: grid;
  place-items: center;
  color: #ffffff;
  /* Anchor over the folder slot (5th pinned position from the bar's
     left padding). The bar is centered with max-width 480px; the
     folder slot's center is at x=168 from the bar's left, which is
     -72 from the bar's horizontal center. */
  top: 50%;
  left: 50%;
  margin-top: -16px;
  margin-left: -88px;
  box-shadow: 0 8px 22px -6px rgba(0, 0, 0, 0.5);
  opacity: 0;
  z-index: 3;
  animation: pinFromFolderDrop 7s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  pointer-events: none;
}
.scene-pinned__folder-floater svg {
  width: 18px;
  height: 18px;
}
@keyframes pinFromFolderDrop {
  0%, 30%   { opacity: 0; transform: translateY(-60px); }
  40%       { opacity: 1; transform: translateY(-44px); }
  60%       { opacity: 1; transform: translateY(0); }       /* landed on slot */
  68%       { opacity: 0; transform: translateY(0); }       /* fades into slot */
  100%      { opacity: 0; transform: translateY(-60px); }
}

/* Folder slot fills as the floater lands. */
.scene-pinned__slot--folder {
  animation: pinSlotFolderFill 7s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
.scene-pinned__slot--folder svg {
  animation: pinSlotFolderGlyph 7s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
@keyframes pinSlotFolderFill {
  0%, 56%   { background: transparent; border: 1.5px dashed color-mix(in oklab, var(--text) 22%, transparent); }
  66%, 85%  { background: #fdcb6e;     border: 1.5px solid  #fdcb6e; }
  95%, 100% { background: transparent; border: 1.5px dashed color-mix(in oklab, var(--text) 22%, transparent); }
}
@keyframes pinSlotFolderGlyph {
  0%, 60%   { opacity: 0; }
  68%, 85%  { opacity: 1; }
  95%, 100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .scene-pinned .tb-icon--dragging,
  .scene-pinned .scene-pinned__chat-source,
  .scene-pinned__folder-floater,
  .scene-pinned__slot--chat,
  .scene-pinned__slot--folder,
  .scene-pinned__slot svg {
    animation: none;
  }
  .scene-pinned .tb-icon--dragging {
    transform: rotate(-4deg) translateY(-2px);
    box-shadow: 0 8px 18px -6px rgba(0, 0, 0, 0.35);
  }
  .scene-pinned__folder-floater {
    opacity: 1;
    transform: translateY(-30px);
  }
  /* Show both slots in their filled state so the metaphor still reads. */
  .scene-pinned__slot--chat   { background: #e84393; border-color: #e84393; border-style: solid; }
  .scene-pinned__slot--folder { background: #fdcb6e; border-color: #fdcb6e; border-style: solid; }
  .scene-pinned__slot svg     { opacity: 1; }
}

/* Scene: grouping animation. The popover opens and closes in a 5s loop
   anchored to the grouped button below. The grouped button briefly
   "presses" (scales down 7%) right before the popover appears, suggesting
   the click that opened it. Pure CSS @keyframes, infinite. */
.scene-grouping .tb-popover {
  opacity: 0;
  transform: translateX(0) translateY(8px) scale(0.95);
  transform-origin: bottom center;
  animation: groupingPopover 5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
@keyframes groupingPopover {
  0%, 15%  { opacity: 0; transform: translateX(0) translateY(8px) scale(0.95); }
  25%, 80% { opacity: 1; transform: translateX(0) translateY(0)   scale(1); }
  90%, 100%{ opacity: 0; transform: translateX(0) translateY(8px) scale(0.95); }
}
.scene-grouping .tb-bar__group {
  animation: groupingPress 5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  transform-origin: center;
}
@keyframes groupingPress {
  0%, 14%, 24%, 100% { transform: scale(1); }
  18%, 20%           { transform: scale(0.93); }
}

@media (prefers-reduced-motion: reduce) {
  .scene-grouping .tb-popover,
  .scene-grouping .tb-bar__group {
    animation: none;
  }
  .scene-grouping .tb-popover {
    opacity: 1;
    transform: translateX(0) translateY(0) scale(1);
  }
}

/* Scene: multi-display. Side-by-side external monitor (with stand) and
   laptop (with keyboard base). Each display shows its own Taskbar with
   a different running-icon set, communicating "windows filter by which
   display they live on". A small window slides between the two displays
   on a loop, showing cross-display window movement. */
.scene-displays {
  width: 100%;
  aspect-ratio: 4 / 3;
  display: grid;
  place-items: center;
  padding: 20px;
  overflow: hidden;
}
.scene-displays__stage {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: end;
  justify-content: center;
  gap: 28px;
}

/* External monitor on the left */
.scene-displays__monitor {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 0 0 auto;
}
.scene-displays__monitor-screen {
  width: 280px;
  height: 175px;
  border-radius: 8px;
  background: var(--tb-wallpaper);
  border: 5px solid #2a2a2e;
  box-shadow: 0 4px 12px -4px rgba(0, 0, 0, 0.3);
  position: relative;
  overflow: hidden;
}
.scene-displays__monitor-neck {
  width: 50px;
  height: 22px;
  background: #2a2a2e;
  border-radius: 0 0 4px 4px;
}
.scene-displays__monitor-base {
  width: 140px;
  height: 5px;
  background: #2a2a2e;
  border-radius: 3px;
}

/* Laptop on the right */
.scene-displays__laptop {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 0 0 auto;
}
.scene-displays__laptop-screen {
  width: 220px;
  height: 138px;
  border-radius: 6px 6px 2px 2px;
  background: var(--tb-wallpaper);
  border: 4px solid #2a2a2e;
  border-bottom: 2px solid #2a2a2e;
  box-shadow: 0 4px 12px -4px rgba(0, 0, 0, 0.3);
  position: relative;
  overflow: hidden;
}
.scene-displays__laptop-base {
  width: 248px;
  height: 8px;
  background: linear-gradient(180deg, #3a3a3e 0%, #2a2a2e 60%, #1a1a1e 100%);
  border-radius: 1px 1px 6px 6px;
  clip-path: polygon(6px 0, calc(100% - 6px) 0, 100% 100%, 0 100%);
}

/* The bars inside each display — pinned to the bottom of the screen */
.scene-displays__bar {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 8px;
  height: 26px;
  padding: 0 4px;
  gap: 3px;
}
.scene-displays__bar .tb-icon {
  width: 18px;
  height: 18px;
  border-radius: 4px;
  --tb-icon-glyph-size: 11px;
}
.scene-displays__bar .tb-start {
  font-size: 12px;
  width: 16px;
  height: 16px;
}
.scene-displays__bar .tb-divider {
  margin: 0 4px;
}

/* The floating window that slides between the two displays */
.scene-displays__floating {
  position: absolute;
  width: 90px;
  height: 58px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 8px 22px -6px rgba(0, 0, 0, 0.45);
  z-index: 3;
  /* Start position: centered over the laptop screen.
     The laptop is on the right of the stage; offset from center accordingly. */
  bottom: 60px;
  left: 50%;
  margin-left: 70px;
  margin-top: -29px;
  transform-origin: center;
  animation: displaysMove 6s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
.scene-displays__floating-titlebar {
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 5px 6px;
  border-bottom: 1px solid var(--border);
}
.scene-displays__floating-light {
  width: 5px;
  height: 5px;
  border-radius: 50%;
}
.scene-displays__floating-light:nth-child(1) { background: #ff5f57; }
.scene-displays__floating-light:nth-child(2) { background: #febc2e; }
.scene-displays__floating-light:nth-child(3) { background: #28c840; }

/* Window slides leftward from over the laptop to over the monitor, then
   slides back. The travel distance is ~290px (monitor center is to the
   left of laptop center by roughly the sum of half the monitor width +
   gap + half the laptop width = 140 + 28 + 110 = 278; round to 280). */
@keyframes displaysMove {
  0%, 20%   { transform: translate(0, 0)      scale(1); }
  35%       { transform: translate(-140px, -8px) scale(1.04); }  /* mid-flight, slight lift */
  50%, 70%  { transform: translate(-280px, 0)  scale(1); }       /* over monitor */
  85%       { transform: translate(-140px, -8px) scale(1.04); }
  100%      { transform: translate(0, 0)      scale(1); }
}

/* The "moving window" icon appears in whichever bar the window is over.
   Both bars contain a folder/purple tile representing the same window;
   one is visible at a time, fading in/out in sync with the floating
   window's flight (6s cycle, same easing). */
.scene-displays__moving-icon {
  transform-origin: center;
}
.scene-displays__moving-icon--laptop {
  animation: displaysLaptopIcon 6s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
.scene-displays__moving-icon--monitor {
  animation: displaysMonitorIcon 6s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
/* Timing reference (displaysMove cycle):
     0%, 20%  → window at laptop
     35%      → mid-flight leftward
     50%, 70% → window at monitor
     85%      → mid-flight rightward
     100%     → window back at laptop
   Icons fade IN once the window has arrived at their display, and fade
   OUT once the window starts leaving — never visible during flight. */
@keyframes displaysLaptopIcon {
  0%, 20%  { opacity: 1; transform: scale(1); }    /* window at laptop */
  28%, 90% { opacity: 0; transform: scale(0.4); }  /* window away */
  100%     { opacity: 1; transform: scale(1); }    /* window returned */
}
@keyframes displaysMonitorIcon {
  0%, 42%  { opacity: 0; transform: scale(0.4); }  /* window away */
  50%, 70% { opacity: 1; transform: scale(1); }    /* window at monitor */
  78%, 100%{ opacity: 0; transform: scale(0.4); }  /* window flying back */
}

@media (prefers-reduced-motion: reduce) {
  .scene-displays__floating,
  .scene-displays__moving-icon--laptop,
  .scene-displays__moving-icon--monitor {
    animation: none;
  }
  .scene-displays__floating {
    /* Park the window over the monitor */
    transform: translate(-280px, 0);
  }
  .scene-displays__moving-icon--monitor { opacity: 1; transform: scale(1); }
  .scene-displays__moving-icon--laptop  { opacity: 0; transform: scale(0.4); }
}

/* Scene 5: Settings window with sidebar tabs + an Appearance pane. */
.scene-settings {
  width: 100%;
  aspect-ratio: 4 / 3;
  display: grid;
  place-items: center;
  padding: 12px;
}
.scene-settings .tb-window-frame {
  width: 100%;
  height: 100%;
}
.scene-settings__inner {
  display: grid;
  grid-template-columns: 140px 1fr;
  height: 100%;
}
.scene-settings__sidebar {
  border-right: 1px solid var(--border);
  padding: 12px 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: color-mix(in oklab, var(--surface) 94%, var(--text) 6%);
}
.scene-settings__tab {
  padding: 7px 10px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--text-muted);
  white-space: nowrap;
}
.scene-settings__tab[aria-current="true"] {
  background: color-mix(in oklab, var(--accent) 18%, transparent);
  color: var(--text);
  font-weight: 500;
}
.scene-settings__pane {
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow: hidden;
}
.scene-settings__row {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: 12px;
  align-items: center;
  font-size: 13px;
}
.scene-settings__row > .scene-settings__label {
  color: var(--text-muted);
}
.scene-settings__slider {
  position: relative;
  height: 4px;
  background: var(--border);
  border-radius: 2px;
}
.scene-settings__slider::before {
  content: "";
  position: absolute;
  inset: 0 60% 0 0;
  background: var(--accent);
  border-radius: 2px;
}
.scene-settings__slider::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 40%;
  transform: translate(-50%, -50%);
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}
.scene-settings__swatches {
  display: flex;
  gap: 8px;
}
.scene-settings__swatch {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1px solid color-mix(in oklab, var(--text) 12%, transparent);
}
.scene-settings__swatch[data-selected="true"] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.scene-settings__segments {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
}
.scene-settings__segment {
  padding: 4px 10px;
  font-size: 12px;
  color: var(--text-muted);
  border-right: 1px solid var(--border);
}
.scene-settings__segment:last-child { border-right: none; }
.scene-settings__segment[aria-current="true"] {
  background: var(--surface);
  color: var(--text);
  font-weight: 500;
}
.scene-settings__preview {
  margin-top: 8px;
  padding: 14px;
  border-radius: 8px;
  background: var(--tb-wallpaper);
}
.scene-settings__preview .tb-bar { width: 100%; }

/* Below 480px, collapse the sidebar into a top tab strip so the pane gets full width. */
@media (max-width: 480px) {
  .scene-settings__inner {
    grid-template-columns: 1fr;
  }
  .scene-settings__sidebar {
    flex-direction: row;
    overflow-x: auto;
    border-right: none;
    border-bottom: 1px solid var(--border);
    padding: 8px;
  }
  .scene-settings__tab { white-space: nowrap; }
}

/* Scene: Drop files (animated drag-and-drop demo). A file icon loops:
   enters from the right, drags across the bar, hovers over a running
   window tile, a window frame rises above the bar, then the file drops
   into the window. Pure CSS @keyframes, 5s cycle, infinite. Respects
   prefers-reduced-motion (no animation; static parked state). */
.scene-dragdrop {
  width: 100%;
  aspect-ratio: 4 / 3;
  position: relative;
  display: grid;
  place-items: stretch;
  padding: 24px;
  overflow: hidden;
}
.scene-dragdrop__stage {
  position: relative;
  width: 100%;
  height: 100%;
  display: grid;
  align-items: end;
}
.scene-dragdrop__bar {
  width: 100%;
  position: relative;
  z-index: 1;
}
/* Window frame that rises above the bar — anchored over the target tile
   (the 2nd running icon, marked .scene-dragdrop__target in the HTML). */
.scene-dragdrop__window {
  position: absolute;
  bottom: calc(var(--tb-bar-height) + 16px);
  left: 50%;
  width: 60%;
  max-width: 260px;
  height: 110px;
  transform: translate(-50%, 18px) scale(0.92);
  transform-origin: bottom center;
  opacity: 0;
  z-index: 2;
  animation: dragdropWindow 5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
.scene-dragdrop__window-lines {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 4px;
}
.scene-dragdrop__window-lines span {
  display: block;
  height: 6px;
  border-radius: 3px;
  background: color-mix(in oklab, var(--text) 12%, transparent);
}
.scene-dragdrop__window-lines span:nth-child(1) { width: 70%; }
.scene-dragdrop__window-lines span:nth-child(2) { width: 90%; }
.scene-dragdrop__window-lines span:nth-child(3) { width: 50%; }

@keyframes dragdropWindow {
  0%, 35%   { opacity: 0; transform: translate(-50%, 18px) scale(0.92); }
  50%, 82%  { opacity: 1; transform: translate(-50%, 0)    scale(1); }
  95%, 100% { opacity: 0; transform: translate(-50%, 10px) scale(0.95); }
}

/* File icon — animated across the bar. Enters from the right edge of the
   stage, slides leftward to hover over the target tile, then lifts up
   into the rising window and fades out. */
.scene-dragdrop__file {
  position: absolute;
  width: 32px;
  height: 40px;
  bottom: calc(var(--tb-bar-height) + 12px);
  /* Starts at the right edge; animation translates leftward via X. */
  right: 8px;
  display: grid;
  place-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 5px;
  color: var(--accent);
  box-shadow: 0 6px 18px -6px rgba(0, 0, 0, 0.4);
  opacity: 0;
  z-index: 3;
  animation: dragdropFile 5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
.scene-dragdrop__file svg { width: 18px; height: 22px; }

/* The file's X target is the horizontal center of the stage (where the
   rising window is anchored). Using % of the stage's width via translateX
   on a right-anchored element: -100% would move left by the file's own
   width; we need a much larger leftward movement. Use a calc that's
   approximately "(stage-width / 2) - 30px" but expressed via translate. */
@keyframes dragdropFile {
  0%, 5%    { opacity: 0; transform: translate(0, 0); }
  15%       { opacity: 1; transform: translate(0, 0); }
  45%, 65%  { opacity: 1; transform: translate(calc(-50cqi + 30px), 0); }
  78%       { opacity: 0.7; transform: translate(calc(-50cqi + 30px), -60px); }
  85%, 100% { opacity: 0; transform: translate(calc(-50cqi + 30px), -50px); }
}
/* Container query unit fallback: older browsers without `cqi` support
   will silently fail the calc and the file won't translate. Provide a
   pixel-based fallback that's close enough for typical stage widths. */
@supports not (width: 1cqi) {
  @keyframes dragdropFile {
    0%, 5%    { opacity: 0; transform: translate(0, 0); }
    15%       { opacity: 1; transform: translate(0, 0); }
    45%, 65%  { opacity: 1; transform: translate(-180px, 0); }
    78%       { opacity: 0.7; transform: translate(-180px, -60px); }
    85%, 100% { opacity: 0; transform: translate(-180px, -50px); }
  }
}
.scene-dragdrop__stage {
  container-type: inline-size;
}

/* Reduced motion: skip the animation entirely. Render the file parked at
   its hover position with the window already visible — a frozen "this is
   what's happening" snapshot rather than a loop. */
@media (prefers-reduced-motion: reduce) {
  .scene-dragdrop__file,
  .scene-dragdrop__window {
    animation: none;
    opacity: 1;
  }
  .scene-dragdrop__file {
    transform: translate(calc(-50cqi + 30px), 0);
  }
  .scene-dragdrop__window {
    transform: translate(-50%, 0) scale(1);
  }
  @supports not (width: 1cqi) {
    .scene-dragdrop__file { transform: translate(-180px, 0); }
  }
}

/* --- Hero menubar + sticky Taskbar --- */

/* Top-edge bar. The default .tb-bar implements a bottom-edge bar; this
   modifier handles the top-edge variant for the hero scene. Flush against
   the desktop's top edge, no top radius, shadow falls downward. */
.tb-bar--top {
  border-radius: 0 0 10px 10px;
  box-shadow: 0 6px 16px -8px rgba(0, 0, 0, 0.25);
}

/* Pins any .tb-bar--top to the top of its parent .tb-desktop, overriding
   the default bottom-pin in section 3. Used by the hero (where the menubar
   sits at the top of the desktop and a separate Taskbar sits at the
   bottom — both via the default + this override). */
.tb-desktop > .tb-bar--top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: auto;
}

/* Menubar layer — absolute-positioned full-bleed inside the bar. Starts
   fully visible (opacity driven by --progress = 0); fades out as --progress
   approaches 1. Dark-translucent regardless of system mode because the real
   macOS menu bar is dark-by-default. */
.tb-bar__menubar {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 12px;
  background: color-mix(in oklab, #1d1d1f 70%, transparent);
  color: rgba(255, 255, 255, 0.85);
  font-size: 13px;
  border-radius: inherit;
}
.tb-bar__menubar-apple {
  display: inline-flex;
  width: 14px;
  height: 14px;
  color: rgba(255, 255, 255, 0.95);
  flex: 0 0 auto;
}
.tb-bar__menubar-apple svg {
  width: 100%;
  height: 100%;
}
.tb-bar__menubar-appname {
  font-weight: 600;
  flex: 0 0 auto;
}
.tb-bar__menubar-menus {
  display: flex;
  gap: 12px;
  flex: 0 0 auto;
  font-weight: 400;
  color: rgba(255, 255, 255, 0.85);
}
.tb-bar__menubar-status {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
}
.tb-bar__menubar-status svg {
  width: 14px;
  height: 14px;
  color: rgba(255, 255, 255, 0.85);
  display: block;
}
.tb-bar__menubar-clock {
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.95);
  white-space: nowrap;
}

/* Taskbar layer — absolute-positioned full-bleed inside the same bar as
   the menubar. Starts invisible (opacity 0); fades in via --inline-progress
   as the visitor scrolls. Layered on top of the menubar at the top of the
   hero desktop card. */
.tb-bar__taskbar {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 8px;
}

/* Hero scroll-driven transformation. The top-edge bar holds both the
   menubar layer (initial state) and the taskbar layer (after scroll),
   stacked via absolute positioning. As the visitor scrolls, the JS in
   script.js sets --inline-progress (0..1) on .scene-hero-animated from
   window.scrollY (fully transformed after 200px of scroll). Bar height
   grows from 26px (menubar) to 44px (taskbar); menubar fades out as
   taskbar fades in. */
.scene-hero-animated {
  --inline-progress: 0;
}
.scene-hero-animated .tb-bar--top {
  height: calc(26px + 18px * var(--inline-progress));
}
.scene-hero-animated .tb-bar__menubar {
  opacity: calc(1 - var(--inline-progress));
}
.scene-hero-animated .tb-bar__taskbar {
  opacity: var(--inline-progress);
  pointer-events: none;
}
.scene-hero-animated.is-fully-visible .tb-bar__taskbar {
  pointer-events: auto;
}

/* Reduced motion: skip the scroll-driven crossfade; render the final
   Taskbar state (bar at 44px, taskbar layer fully visible, menubar
   layer hidden). Visitor sees the Taskbar on page load with no scroll-
   dependent behavior. */
@media (prefers-reduced-motion: reduce) {
  .scene-hero-animated .tb-bar--top { height: 44px; }
  .scene-hero-animated .tb-bar__menubar { display: none; }
  .scene-hero-animated .tb-bar__taskbar { opacity: 1; }
}
