/*! © 2026 JuJu Games — https://juju.games */
/* Fruit Slide. The tray's whole geometry is one number, `--c` (a cell's width in CSS pixels),
   set by fruit-slide.js on .fsl-stage along with the tray's size in cells (--w, --h) and its
   rim (--rim). Nothing here states one of those numbers of its own.

   Nothing here states a panel size either: mode 2 belongs to game-layout.css and the game
   only declares 'fill'. */

.game-root[data-game="fruit-slide"] {
  padding: clamp(12px, 2.4vw, 24px);
  background: linear-gradient(180deg, #ffe7d2 0%, #fff4e2 55%, #f6e5c6 100%);
}

/* width:100% is load-bearing: the filling panel is a flex container, so without it .fsl is a
   flex item that shrinks to its contents — and its contents are sized from it. */
.fsl { position: relative; display: flex; flex-direction: column; align-items: center; gap: 8px; width: 100%; container-type: inline-size; }
/* Only the tray's box may take the slack, or the end of a run shrinks the tray. */
.fsl > :not(.g-fit) { flex: none; }

/* The chain: eighteen across where there is room, two rows of nine where there is not. The
   arrow belongs to the fruit before it, so a row that ends still points on to the next. */
.fsl-chain {
  display: grid; grid-template-columns: repeat(18, auto); justify-content: center; gap: 4px 12px;
  margin: 0; padding: 6px 12px; list-style: none;
  border-radius: 14px; background: rgba(255, 250, 238, .75); box-shadow: 0 2px 8px rgba(92, 60, 26, .1);
}
@container (max-width: 760px) {
  .fsl-chain { grid-template-columns: repeat(9, auto); }
}
/* Block, not grid: in an auto-sized grid row a tall picture's 100% height resolves to its own
   height at this width, and the banana spills three icons down. */
.fsl-link { position: relative; display: block; width: 28px; height: 28px; }
.fsl-link img {
  position: relative; display: block; width: 100%; height: 100%; object-fit: contain;
  filter: brightness(0) opacity(.16);
}
.fsl-link.is-found img { filter: none; }
.fsl-link:not(:last-child)::after {
  content: ''; position: absolute; right: -8px; top: 50%;
  width: 5px; height: 5px; margin-top: -3px;
  border-top: 2px solid #d19a5c; border-right: 2px solid #d19a5c; transform: rotate(45deg);
}
.fsl-link.is-best::before {
  content: ''; position: absolute; inset: -4px; border-radius: 50%;
  background: rgba(255, 207, 90, .45); box-shadow: 0 0 0 2px #f2b53a;
}
.fsl-link.is-pop img { animation: fsl-link-pop .6s cubic-bezier(.3, 1.8, .5, 1); }
@keyframes fsl-link-pop { from { transform: scale(.2); } to { transform: scale(1); } }

.fsl-status { min-height: 1.45em; color: #4d4236; font-size: .93rem; text-align: center; line-height: 1.45; }
.fsl-status.is-note { color: #b35d14; font-weight: 700; animation: fsl-say .45s ease-out; }
@keyframes fsl-say { 0% { transform: scale(.85); opacity: 0; } 60% { transform: scale(1.06); opacity: 1; } 100% { transform: scale(1); } }

/* --- the tray --------------------------------------------------------------------------- */
.fsl-stage {
  --c: 50px;
  --r: calc(var(--c) * .14);
  position: relative; flex: none;
  border-radius: calc(var(--c) * .24);
  background: linear-gradient(160deg, #d7a86e 0%, #c28e55 55%, #a8743f 100%);
  box-shadow: 0 10px 26px rgba(92, 60, 26, .28), inset 0 2px 0 rgba(255, 236, 200, .55),
              inset 0 -3px 0 rgba(90, 56, 22, .35);
  touch-action: none; user-select: none; -webkit-user-select: none;
}
.fsl-layer {
  position: absolute;
  left: calc(var(--rim) * var(--c)); top: calc(var(--rim) * var(--c));
  width: calc(var(--w) * var(--c)); height: calc(var(--h) * var(--c));
  border-radius: var(--r);
  background-color: #efd3a6;
  background-image:
    linear-gradient(to right, rgba(120, 80, 40, .14) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(120, 80, 40, .14) 1px, transparent 1px);
  background-size: var(--c) var(--c);
  box-shadow: inset 0 3px 8px rgba(110, 70, 30, .28);
}
.fsl-layer::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: calc(var(--c) * 2.2);
  border-radius: var(--r) var(--r) 0 0; pointer-events: none; opacity: 0;
  background: linear-gradient(to bottom, rgba(228, 70, 58, .34), rgba(228, 70, 58, 0));
  transition: opacity .3s;
}
.fsl-stage.is-high .fsl-layer::before { opacity: 1; animation: fsl-warn 1.2s ease-in-out infinite; }
@keyframes fsl-warn { 50% { opacity: .45; } }

/* A piece is positioned by its transform alone, so everything that animates it — the pop, the
   fade, the lift — runs on the child, never on the piece: two animations on one transform
   cancel each other. */
.fsl-piece {
  position: absolute; left: 0; top: 0; z-index: 2;
  width: calc(var(--pw) * var(--c)); height: calc(var(--ph) * var(--c));
  transform: translate(calc(var(--x) * var(--c)), calc(var(--y) * var(--c)));
  cursor: grab; touch-action: none;
}
.fsl-stage.is-live .fsl-piece { transition: transform var(--t, 0ms) var(--ease, ease-out); }
.fsl-stage.is-resizing .fsl-piece { transition: none; }
/* Two layers: the jelly (--sx/--sy, driven by springs in fruit-slide.js) on .fsl-art, and the
   picture, its shadow, its breathing and its fade on .fsl-img. One element carrying both would
   have the keyframes overwrite the springs' transform. */
.fsl-art {
  position: absolute; inset: calc(var(--c) * .03);
  transform: scale(var(--sx, 1), var(--sy, 1)); transform-origin: 50% 92%;
}
.fsl-img {
  position: absolute; inset: 0;
  background: center / contain no-repeat;
  filter: drop-shadow(0 calc(var(--c) * .05) calc(var(--c) * .05) rgba(84, 52, 20, .32));
  transform-origin: 50% 95%;
  animation: fsl-idle 2.6s ease-in-out infinite;
}
@keyframes fsl-idle { 0%, 100% { transform: scale(1, 1); } 50% { transform: scale(1.018, .978); } }
.fsl-piece.is-held { z-index: 5; cursor: grabbing; }
.fsl-piece.is-held .fsl-img { filter: drop-shadow(0 calc(var(--c) * .12) calc(var(--c) * .1) rgba(84, 52, 20, .34)); }
.fsl-piece.is-gone { z-index: 4; pointer-events: none; }
.fsl-piece.is-gone .fsl-img { animation: fsl-gone .24s ease-in forwards; }
@keyframes fsl-gone { to { transform: scale(.55); opacity: 0; } }
.fsl-piece.is-cleared { z-index: 4; pointer-events: none; }
.fsl-piece.is-cleared .fsl-img { animation: fsl-cleared .3s ease-in forwards; }
@keyframes fsl-cleared { 40% { transform: scale(1.2); opacity: 1; } 100% { transform: scale(.2); opacity: 0; } }
.fsl-piece.is-born { z-index: 6; }
.fsl-stage.is-over .fsl-img { filter: saturate(.5) drop-shadow(0 calc(var(--c) * .05) calc(var(--c) * .05) rgba(84, 52, 20, .25)); }

/* The ring is the piece's own child, so it never meets the animations on the art. */
.fsl-halo {
  position: absolute; inset: calc(var(--c) * -.04); border-radius: calc(var(--c) * .28);
  border: max(2px, calc(var(--c) * .06)) solid #ffcf5a; opacity: 0; pointer-events: none;
}
.fsl-piece.is-coach .fsl-halo { animation: fsl-breathe 1.6s ease-in-out infinite; }
@keyframes fsl-breathe {
  0%, 100% { transform: scale(1); opacity: .35; }
  50% { transform: scale(1.18); opacity: .95; }
}
.fsl-piece.is-born .fsl-halo { animation: fsl-ring .62s ease-out; }
@keyframes fsl-ring { 0% { transform: scale(.6); opacity: .95; } 100% { transform: scale(1.45); opacity: 0; } }

.fsl-juice { position: absolute; z-index: 7; border-radius: 50%; pointer-events: none; }

/* A column the tray has just gained, lit up for a moment. */
.fsl-newcol {
  position: absolute; top: 0; bottom: 0; z-index: 1; pointer-events: none;
  left: calc(var(--x) * var(--c)); width: var(--c);
  background: linear-gradient(to bottom, rgba(255, 236, 170, 0), rgba(255, 214, 110, .75));
  box-shadow: inset 0 0 0 2px rgba(255, 207, 90, .9);
  animation: fsl-newcol 1.4s ease-out forwards;
}
@keyframes fsl-newcol { 0% { opacity: 0; } 20% { opacity: 1; } 100% { opacity: 0; } }

/* The next fruit, shown faintly where it will come in. */
.fsl-tell {
  position: absolute; left: 0; top: 0; z-index: 1; pointer-events: none;
  width: calc(var(--pw) * var(--c)); height: calc(var(--ph) * var(--c));
  transform: translateX(calc(var(--x) * var(--c)));
  border-radius: calc(var(--c) * .2);
  background: rgba(255, 255, 255, .3); box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .75);
  animation: fsl-tell .4s ease-in-out infinite alternate;
}
.fsl-tell-img { position: absolute; inset: 10%; background: center / contain no-repeat; opacity: .5; }
@keyframes fsl-tell { from { opacity: .55; } to { opacity: 1; } }

/* Start, carry on and resume: over the tray only, so the chain and controls stay readable. */
.fsl-cover {
  position: absolute; inset: 0; z-index: 30; display: grid; place-items: center;
  border-radius: calc(var(--c) * .24); background: rgba(255, 246, 230, .5); cursor: pointer;
}
.fsl-cover[hidden] { display: none; }
.fsl-go { padding: 12px 36px; font-size: 1.15rem; }
.fsl-go.btn-primary, .fsl-card .btn-primary { background: #55a446; border-color: #46893a; color: #fff5e8; }
.fsl-go.btn-primary:hover, .fsl-card .btn-primary:hover { background: #4b9a3d; border-color: #3d7a33; }

/* --- controls ------------------------------------------------------------------------------ */
.fsl-controls { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.fsl-btn { background: #fffaf0; color: #3e2f20; border: 1px solid rgba(90, 64, 38, .25); }
.fsl-btn:disabled { opacity: .45; }
.fsl-fs { display: inline-flex; align-items: center; gap: 7px; }
/* Two nested corners read as "expand" at any size; U+26F6 tofus on Windows and Android. */
.fsl-fsicon {
  position: relative; display: inline-block; width: .85em; height: .72em;
  border: 2px solid currentColor; border-radius: 2px;
}
.fsl-fsicon::before {
  content: ''; position: absolute; inset: 2px;
  border-top: 2px solid currentColor; border-bottom: 2px solid currentColor; opacity: .45;
}

/* --- the result card ----------------------------------------------------------------------- */
.fsl-end {
  position: absolute; inset: 0; z-index: 60; display: grid; place-items: center;
  background: rgba(62, 44, 26, .22); border-radius: 12px;
}
.fsl-end:empty { display: none; }
.fsl-card {
  max-width: min(92%, 360px); max-height: calc(100% - 24px); overflow-y: auto;
  padding: 18px 22px 20px; border-radius: 18px; text-align: center;
  background: #fffaf0; color: #3e2f20; box-shadow: 0 18px 44px rgba(62, 44, 26, .35);
}
.fsl-card .result-done { color: #b35d14; font-size: .95rem; }
.fsl-card-img {
  display: block; width: 96px; height: 96px; margin: 10px auto 0; object-fit: contain;
  animation: fsl-card-pop .6s .15s cubic-bezier(.3, 1.8, .5, 1) both;
}
@keyframes fsl-card-pop { from { transform: scale(.2); } to { transform: scale(1); } }
.fsl-card-name { margin: 6px 0 2px; font-size: 1.3rem; line-height: 1.25; }
.fsl-card-line { margin: 0; color: #5b4a38; font-size: .95rem; line-height: 1.5; }
.fsl-card-stat { margin: 10px 0 0; color: #9d968c; font-size: .88rem; }
.fsl-card-new {
  display: inline-block; margin: 10px 0 0; padding: 3px 12px; border-radius: 999px;
  background: #fdecc8; color: #8a5a17; font-size: .85rem; font-weight: 700;
}
.fsl-card-btns { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 16px; }

/* --- Mode 1: page-embedded ------------------------------------------------------------------- */
/* The tray takes what the window leaves, capped at an absolute 820px: a viewport share here
   would be no cap at all. */
.fsl .g-fit {
  position: relative; display: grid; place-items: center; width: 100%;
  height: clamp(320px, calc(100svh - 250px), 820px);
}

/* --- Mode 3: phone ------------------------------------------------------------------------- */
@media (max-width: 640px) {
  /* Full bleed: on a phone the width is what binds the tray, so the page’s own gutter
     is what the cells would otherwise pay for. */
  .game-root[data-game="fruit-slide"] { border: 0; padding: 10px 0 12px; margin-inline: -16px; }
  .fsl .g-fit { height: calc(100svh - 270px); min-height: 300px; }
  /* Two lines held open whatever the text, or every message that wraps moves the tray. */
  .fsl-status { height: 2.9em; display: flex; align-items: center; justify-content: center; padding: 0 12px; }
  .fsl-link { width: 26px; height: 26px; }
  .fsl-controls { gap: 6px; flex-wrap: nowrap; }
  .fsl-btn { padding: 6px 10px; font-size: .82rem; white-space: nowrap; }}

/* --- Mode 2: page-filling ------------------------------------------------------------------ */
/* Only what goes INSIDE the panel. :not(.fsl-full) on every page-mode rule: full screen is a
   separate mode with its own sizing and these selectors outrank its own. */
html.fills-window .fsl:not(.fsl-full) { height: 100%; justify-content: center; }
html.fills-window .fsl:not(.fsl-full) .g-fit { flex: 1 1 0; min-height: 0; height: auto; }

/* --- Mode 4: full screen ------------------------------------------------------------------- */
/* Written outside every media query: mode 2's copy lives inside a window-height query and
   full screen on a tall monitor falls outside it. */
body.fsl-locked { overflow: hidden; }
.fsl.fsl-full {
  position: fixed; inset: 0; z-index: 200; margin: 0; padding: 12px;
  background: linear-gradient(180deg, #ffe7d2 0%, #fff4e2 55%, #f6e5c6 100%);
  justify-content: center;
}
.fsl.fsl-full .g-fit { flex: 1 1 0; min-height: 0; height: auto; }
.fsl.fsl-full .fsl-end { border-radius: 0; }
