/* ───────────────────────────────────────────────────────────────
   Bento engine — shared layout, phases and ghost cursor.
   Every style page links this first, then overrides freely.
   Stage is a fixed 1920×1080 (landscape) or 1080×1920 (portrait)
   canvas scaled to fit, so all style CSS can use plain px.
   ─────────────────────────────────────────────────────────────── */
*,
*::before,
*::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --pad: 40px;          /* stage inset */
  --gap: 20px;          /* tile gap */
  --in-name: tile-in;   /* keyframes used for entrance */
  --out-name: tile-out; /* keyframes used for exit */
  --in-ms: 800;         /* unitless ms — engine reads these */
  --in-stagger: 55;
  --out-ms: 520;
  --out-stagger: 28;
  --in-ease: cubic-bezier(.22, 1, .36, 1);
  --out-ease: cubic-bezier(.55, 0, .9, .4);
  --ring: rgba(255, 255, 255, .9); /* click ring colour */
}

html, body { height: 100%; overflow: hidden; }
body { -webkit-font-smoothing: antialiased; user-select: none; -webkit-user-select: none; }
button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }
input { font: inherit; color: inherit; border: 0; background: none; outline: 0; user-select: text; -webkit-user-select: text; }

.viewport { position: fixed; inset: 0; overflow: hidden; }
.stage {
  position: absolute; left: 50%; top: 50%;
  width: 1920px; height: 1080px; overflow: hidden;
  transform: translate(-50%, -50%) scale(var(--scale, 1));
  transform-origin: center;
}
body.portrait .stage { width: 1080px; height: 1920px; }
.backdrop { position: absolute; inset: 0; overflow: hidden; }

/* ── the bento: 14 slots, same spans in both orientations ──────── */
.bento {
  position: absolute; inset: var(--pad);
  display: grid; gap: var(--gap);
  grid-template-columns: repeat(8, minmax(0, 1fr));
  grid-template-rows: repeat(4, minmax(0, 1fr));
  grid-template-areas:
    "a a b c c c d d"
    "a a e c c c f g"
    "h i i j j k k g"
    "h l l j j m n n";
}
body.portrait .bento {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-template-rows: repeat(8, minmax(0, 1fr));
  grid-template-areas:
    "a a d d"
    "a a b e"
    "c c c g"
    "c c c g"
    "h j j f"
    "h j j m"
    "i i k k"
    "l l n n";
}
.tile { position: relative; min-width: 0; min-height: 0; overflow: hidden; opacity: 0; }
.tile[data-slot="a"] { grid-area: a; } .tile[data-slot="b"] { grid-area: b; }
.tile[data-slot="c"] { grid-area: c; } .tile[data-slot="d"] { grid-area: d; }
.tile[data-slot="e"] { grid-area: e; } .tile[data-slot="f"] { grid-area: f; }
.tile[data-slot="g"] { grid-area: g; } .tile[data-slot="h"] { grid-area: h; }
.tile[data-slot="i"] { grid-area: i; } .tile[data-slot="j"] { grid-area: j; }
.tile[data-slot="k"] { grid-area: k; } .tile[data-slot="l"] { grid-area: l; }
.tile[data-slot="m"] { grid-area: m; } .tile[data-slot="n"] { grid-area: n; }

/* ── phases: .in → .live → .out (engine swaps the classes) ─────── */
.tile.in {
  animation: var(--in-name) calc(var(--in-ms) * 1ms) var(--in-ease) both;
  animation-delay: calc(var(--i, 0) * var(--in-stagger) * 1ms);
}
.tile.live { opacity: 1; }
.tile.out {
  animation: var(--out-name) calc(var(--out-ms) * 1ms) var(--out-ease) both;
  animation-delay: calc(var(--o, 0) * var(--out-stagger) * 1ms);
}
@keyframes tile-in  { from { opacity: 0; transform: translateY(40px) scale(.94); } to { opacity: 1; transform: none; } }
@keyframes tile-out { from { opacity: 1; } to { opacity: 0; transform: translateY(-24px) scale(.96); } }

/* ── ghost cursor (override --cursor-img / --ring per style) ───── */
.cursor {
  position: absolute; left: 0; top: 0; z-index: 999; pointer-events: none;
  opacity: 0; transition: opacity .35s; will-change: transform;
}
.cursor.show { opacity: 1; }
.cursor i {
  display: block; width: 34px; height: 34px; transform-origin: 0 0; transition: transform .12s;
  background: var(--cursor-img, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath d='M4 2v23l6.2-5.6 4 9.2 4-1.7-4-9.1 8.3-.3z' fill='%23111' stroke='%23fff' stroke-width='1.8' stroke-linejoin='round'/%3E%3C/svg%3E")) no-repeat 0 0 / contain;
  filter: drop-shadow(0 3px 5px rgba(0, 0, 0, .35));
}
.cursor.down i { transform: scale(.86); }
.cursor-ring {
  position: absolute; left: 0; top: 0; z-index: 998; pointer-events: none;
  width: 46px; height: 46px; margin: -23px 0 0 -23px; border-radius: 50%;
  border: 2px solid var(--ring);
  animation: cursor-ring .55s cubic-bezier(.2, .7, .2, 1) forwards;
}
@keyframes cursor-ring { from { transform: scale(.3); opacity: 1; } to { transform: scale(1.5); opacity: 0; } }

/* ?snap=1|2 — settled state for screenshots: no transitions, animations jump to their end */
body.snap *, body.snap *::before, body.snap *::after {
  transition: none !important;
  animation-delay: 0s !important; animation-duration: 1ms !important; animation-iteration-count: 1 !important;
}
