/* Mahjong 2048: the game's name and its button across the top, and under them the game's own
   area, which mahjong-2048.js lays the board out in. The panel's size is game-layout.css's
   (data-ideal); the stage fills it, on a green table cloth. */

/* No `inset` in this file: iOS before 14.5 drops it, and the stage then has no size. */
.game-root[data-game="mahjong-2048"] {
  position: relative; display: block; padding: 0; overflow: hidden; text-align: left;
  background: radial-gradient(120% 100% at 50% 0%, #3d7a57 0%, #2f6146 55%, #264f39 100%);
  touch-action: manipulation;
  -webkit-user-select: none; user-select: none;
}
.m48-stage { position: absolute; top: 0; right: 0; bottom: 0; left: 0; }

/* --- the top row: the game's name at the left, its button at the right ------------------------ */
.m48-top {
  position: absolute; top: 14px; left: 18px; right: 18px; z-index: 2;
  display: flex; align-items: baseline; gap: 10px; pointer-events: none; text-align: left;
}
.m48-game { font-weight: 700; color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, .35); }
.m48-tools { position: absolute; top: 12px; right: 14px; z-index: 4; display: flex; gap: 8px; }
.m48-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 14px; border: 1px solid rgba(255, 255, 255, .6); border-radius: 999px;
  background: rgba(255, 255, 255, .86); color: #2f4a3a;
  font: inherit; font-size: .85rem; cursor: pointer; white-space: nowrap;
}
.m48-pill:hover:not(:disabled) { border-color: var(--c-primary); color: var(--c-text); }
.m48-pill .m48-icon { width: 16px; height: 16px; }

/* --- the game's own area -------------------------------------------------------------------
   The top padding clears the row above. */
.m48 {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0; display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 52px 8px 3px; box-sizing: border-box; overflow: hidden; text-align: left;
  -webkit-tap-highlight-color: transparent;
}
.m48 > .m48-ladder, .m48 > .m48-cap, .m48 > .m48-ctrl { flex: none; }

/* The ladder, as wide as the board (--bw) and moved down by the space the board leaves over
   (--slack), every tile on it --rw wide, all set by mahjong-2048.js. Its height is fixed: the board
   is laid out in what it leaves. A tile never made is a shadow, one made in an earlier game is
   faint, and one reached in this game is in colour; the biggest on the board has a ring. */
.m48-ladder {
  display: flex; align-items: center; justify-content: space-between;
  width: var(--bw, 100%); max-width: 100%; height: 44px; margin-top: var(--slack, 0px);
}
.m48-rung {
  position: relative; display: grid; place-items: center; flex: none; box-sizing: border-box;
  width: var(--rw, 22px); height: calc(var(--rw, 22px) * 4 / 3); border-radius: 4px;
  background: rgba(255, 255, 255, .28); border-right: 2px solid rgba(0, 0, 0, .18);
}
.m48-rung img { display: block; width: 84%; height: 84%; object-fit: contain; filter: brightness(0) opacity(.3); }
.m48-rung.is-known { background: rgba(255, 253, 245, .6); }
.m48-rung.is-known img { filter: opacity(.5); }
.m48-rung.is-here { background: #fbf7ea; border-right-color: #2e9b5e; }
.m48-rung.is-here img { filter: none; }
.m48-rung.is-top { box-shadow: 0 0 0 2px #fff, 0 0 0 4px #ffb703; }
.m48-rung.is-new { animation: m48-rung-new .7s cubic-bezier(.2, .9, .3, 1.35); }
@keyframes m48-rung-new {
  0% { transform: scale(1); }
  35% { transform: scale(1.7) rotate(-10deg); }
  70% { transform: scale(.9) rotate(4deg); }
  100% { transform: scale(1); }
}

.m48-fit { flex: 1 1 0; min-height: 0; width: 100%; display: grid; place-items: start center; }
.m48-board { position: relative; }
/* A swipe on the board moves the tiles, so the page must not take it as a scroll. */
.m48-canvas {
  display: block; width: 100%; height: 100%; cursor: grab; touch-action: none;
  user-select: none; -webkit-user-select: none;
}

/* Two lines tall whatever it says, empty included: the board is laid out in what this leaves, so
   a caption that changed height would move the board as words come and go. */
.m48-cap {
  display: flex; align-items: center; justify-content: center; box-sizing: border-box;
  height: 3em; overflow: hidden; line-height: 1.5; margin: 0; width: 100%; max-width: 560px; padding: 0 8px;
  color: #fffbea; font-size: .86rem; font-weight: 700; text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .45);
}

/* The lesson's hand: mahjong-2048.js puts the fingertip's start and end in --x0 --y0 --x1 --y1.
   It presses, swipes, lifts, then rests for about two seconds before the next pass. */
.m48-hand {
  position: absolute; left: 0; top: 0; z-index: 2; pointer-events: none;
  width: 46px; height: 48.875px; opacity: 0;
}
.m48-hand[hidden] { display: none; }
.m48-hand svg { display: block; width: 100%; height: 100%; filter: drop-shadow(0 2px 2px rgba(0, 0, 0, .35)); }
.m48-hand.is-on { animation: m48-swipe 3.8s ease-in-out infinite; }
@keyframes m48-swipe {
  0% { opacity: 0; transform: translate(var(--x0), var(--y0)) scale(1.08); }
  8% { opacity: 1; transform: translate(var(--x0), var(--y0)) scale(1); }
  14% { opacity: 1; transform: translate(var(--x0), var(--y0)) scale(.92); }
  38% { opacity: 1; transform: translate(var(--x1), var(--y1)) scale(.92); }
  46% { opacity: 0; transform: translate(var(--x1), var(--y1)) scale(1.05); }
  100% { opacity: 0; transform: translate(var(--x1), var(--y1)) scale(1.05); }
}

/* New game, under the caption in the middle; once pressed it asks again, in amber. */
.m48-ctrl {
  position: relative; z-index: 2; display: flex; align-items: center; justify-content: center;
  width: var(--bw, 100%); max-width: 100%; min-height: 46px;
}
.m48-new { padding: 8px 18px; font-weight: 700; }
.m48-new.is-sure { background: #ffcf4a; border-color: #fff; color: #5a3b00; }

/* The speaker, and the dots beside it that open the menu. The dots take no room until shown
   (hover, focus, or the menu open); a screen that cannot hover shows them always, dimmer. The
   menu opens upward. */
.m48-round {
  width: 38px; height: 38px; padding: 0;
  display: grid; place-items: center; border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .7); color: #2f4a3a; cursor: pointer;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .22);
}
.m48-round:hover { background: #fff; }
.m48-round .m48-sicon { width: 22px; height: 22px; }
.m48-audio { position: absolute; right: 12px; bottom: 10px; z-index: 3; display: flex; align-items: center; }
.m48-more {
  display: grid; place-items: center; width: 0; height: 38px; padding: 0; overflow: hidden;
  border: 0; background: none; color: rgba(255, 255, 255, .75); cursor: pointer; opacity: 0;
  transition: opacity .15s ease;
}
.m48-audio:hover .m48-more, .m48-audio:focus-within .m48-more, .m48-audio.is-open .m48-more { width: 30px; opacity: 1; }
@media (hover: none) { .m48-more { width: 26px; opacity: .6; } }
.m48-more .m48-sicon { width: 22px; height: 22px; }
.m48-ellipsis { stroke-width: 3.4; }
.m48-menu {
  position: absolute; right: 0; bottom: 46px; min-width: 200px; padding: 6px; box-sizing: border-box;
  border: 1px solid rgba(77, 64, 49, .18); border-radius: 12px; background: #fffdf8;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .22);
}
.m48-menu[hidden] { display: none; }
.m48-opt {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; width: 100%; padding: 9px 10px;
  border: 0; border-radius: 8px; background: none; color: #4d4031; font: inherit; font-size: .88rem; font-weight: 600; cursor: pointer; text-align: left;
}
.m48-opt:hover, .m48-opt:focus-visible { background: rgba(77, 64, 49, .07); }
.m48-sw { position: relative; flex: none; width: 34px; height: 20px; border-radius: 999px; background: rgba(77, 64, 49, .22); transition: background .15s ease; }
.m48-sw::after {
  content: ''; position: absolute; left: 2px; top: 2px; width: 16px; height: 16px; border-radius: 50%;
  background: #fff; transition: transform .15s ease;
}
.m48-opt[aria-checked="true"] .m48-sw { background: #4fb878; }
.m48-opt[aria-checked="true"] .m48-sw::after { transform: translateX(14px); }
.m48-sicon { display: block; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.m48-cone { fill: currentColor; stroke: none; }
.m48-sound.off .m48-waves { display: none; }
.m48-sound:not(.off) .m48-slash { display: none; }
.m48-icon { width: 18px; height: 18px; flex: none; }

/* --- over the stage: the panel dims it, and a sheet in its middle holds the card -------------- */
.m48-win { position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 5; }
.m48-win:empty { pointer-events: none; }
.m48-panel {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0;
  display: flex; flex-direction: column; align-items: center; gap: 18px;
  padding: 20px 12px; text-align: center; overflow-y: auto;
  background: rgba(14, 46, 30, .6);
  animation: m48-in .35s ease-out;
}
@keyframes m48-in { from { opacity: 0; } }
/* Centred with auto margins rather than justify-content: a sheet taller than the stage scrolls
   from its top instead of losing it. */
.m48-panel > * { flex: none; }
.m48-panel > :first-child { margin-top: auto; margin-bottom: auto; }
.m48-sheet {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 14px; width: min(440px, 100%); box-sizing: border-box;
  padding: 24px 14px; border-radius: 20px; background: #fffdf8;
  box-shadow: 0 10px 0 rgba(0, 0, 0, .1);
}
/* The tile on the card: an ivory face, its green back showing at the right. */
.m48-card-tile {
  display: grid; place-items: center; box-sizing: border-box; width: 66px; height: 88px; margin-bottom: -4px;
  border-radius: 9px; background: linear-gradient(135deg, #fffefa, #efe6d0);
  border: 1px solid rgba(120, 104, 76, .4); border-right: 4px solid #2e9b5e;
  box-shadow: 0 3px 6px rgba(0, 0, 0, .18);
  animation: m48-tile-in .6s cubic-bezier(.2, .9, .3, 1.35) .1s both;
}
.m48-card-tile img { display: block; width: 82%; height: 82%; object-fit: contain; }
@keyframes m48-tile-in { from { opacity: 0; transform: scale(.4) rotate(-20deg); } to { opacity: 1; transform: none; } }
.m48-sheet .m48-title { margin: 0; font-size: 1.6rem; font-weight: 700; color: #4d4031; }
/* The choices stay on one row down to a 360px-wide phone. */
.m48-choices .btn { padding: 10px 14px; font-size: .9rem; }
/* Each letter's delay is set by mahjong-2048.js. */
.m48-word { white-space: nowrap; }
.m48-ch { display: inline-block; animation: m48-wave .5s ease-in-out both; }
@keyframes m48-wave { 40% { transform: translateY(-.35em); } }
.m48-view { display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center; }
.m48-view p { margin: 0; }
.m48-view-line { color: #4d4031; font-weight: 600; }
.m48-view-small { font-size: .8rem; color: #9a8c78; }
.m48-ask { display: flex; flex-direction: column; align-items: center; gap: 10px; color: #6a5a44; }
.m48-ask p { margin: 0; }
.m48-moods { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.m48-mood {
  display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px;
  border: 1px solid var(--c-border); border-radius: 999px; background: #fff; color: var(--c-text);
  font: inherit; cursor: pointer;
}
.m48-mood:hover { border-color: var(--c-primary); }
.m48-mood.on { background: var(--c-primary); border-color: var(--c-primary); color: #fff; }
.m48-mood .m48-icon { width: 22px; height: 22px; }
.m48-ask .m48-note { min-height: 1.3em; margin: 0; font-size: .9rem; color: var(--c-text-soft); }
.m48-key {
  display: inline-block; min-width: 1.6em; padding: 1px 6px; margin: 0 1px;
  border: 1px solid #c9ced8; border-bottom-width: 2px; border-radius: 5px; background: #fff;
  font: inherit; font-size: .85em; font-weight: 700; line-height: 1.4; text-align: center; color: var(--c-text);
}
.m48-choices { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.m48-choices .btn { display: inline-flex; align-items: center; gap: 8px; }
.m48-choices .m48-icon { stroke-width: 2.2; }

/* The review build's tools, under the game panel and outside it. */
.m48-review {
  display: flex; gap: 8px; justify-content: center; align-items: center; flex-wrap: wrap;
  margin: 10px auto 0; padding: 8px; font-size: .85rem; color: #4a5766;
}
.m48-review button { font: inherit; padding: 4px 8px; border-radius: 8px; border: 1px solid #ccc; background: #fff; }

/* #game-root itself is the element that goes full screen; these same rules are the
   fixed-position fallback for a browser without the Fullscreen API. game-layout.css gives a
   [data-ideal] panel an explicit width and height, which would beat the fallback's inset. */
#game-root.m48-fs {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 200; margin: 0; padding: 0;
  width: auto; height: auto; max-width: none;
  border: 0; border-radius: 0; box-shadow: none; min-height: 0; overflow: hidden;
}
body.m48-locked { overflow: hidden; }

/* iOS before 14.5 ignores `gap` on a flex box, and `inset` came in the same release, so this
   reaches only those browsers. The margins stand in for each gap above, and must change with it.
   #game-root lifts them over the `margin: 0` the children set. */
@supports not (inset: 0) {
  #game-root .m48-top > * + * { margin-left: 10px; }
  #game-root .m48-tools > * + * { margin-left: 8px; }
  #game-root .m48-pill > * + * { margin-left: 6px; }
  #game-root .m48 > * + * { margin-top: 8px; }
  #game-root .m48-opt > * + * { margin-left: 16px; }
  #game-root .m48-panel > * + * { margin-top: 18px; }
  #game-root .m48-sheet > * + * { margin-top: 14px; }
  #game-root .m48-view > * + * { margin-top: 4px; }
  #game-root .m48-ask > * + * { margin-top: 10px; }
  #game-root .m48-moods > * { margin: 5px 5px; }
  #game-root .m48-mood > * + * { margin-left: 8px; }
  #game-root .m48-choices > * { margin: 4px 4px; }
  #game-root .m48-choices .btn > * + * { margin-left: 8px; }
  #game-root .m48-review > * { margin: 4px 4px; }
}
