/* Hungry Little Snake: the game's name and its buttons across the top, and under them the round's own area:
   the level and the count, the board, the caption and the row of buttons, which hungry-little-snake.js lays
   out. The panel's size is game-layout.css's (data-ideal); the stage fills it. */

/* No `inset` in this file: iOS before 14.5 drops it, and the stage then has no size. */
.game-root[data-game="hungry-little-snake"] {
  position: relative; display: block; padding: 0; overflow: hidden; text-align: left;
  background: #10231a;
  touch-action: manipulation;
  -webkit-user-select: none; user-select: none;
}
/* The forest behind the board: the upright picture, or the wide one on a stage wider than it is
   tall (is-wide, set by hungry-little-snake.js). Bump ?v= when a picture is installed again. */
.onl-stage {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0;
  background: url(/assets/img/hungry-little-snake/backdrop-tall.webp?v=1) center / cover no-repeat;
}
.onl-stage.is-wide { background-image: url(/assets/img/hungry-little-snake/backdrop-wide.webp?v=1); }

/* --- the top row: the game's name at the left, its buttons at the right ----------------------- */
.onl-top {
  position: absolute; top: 14px; left: 18px; right: 18px; z-index: 2;
  display: flex; align-items: baseline; pointer-events: none; text-align: left;
}
.onl-game { font-weight: 800; color: #fff; text-shadow: 0 1px 2px rgba(15, 60, 30, .45); white-space: nowrap; }
.onl-tools { position: absolute; top: 10px; right: 14px; z-index: 4; display: flex; align-items: center; gap: 8px; }
.onl-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 14px; border: 1px solid rgba(255, 255, 255, .8); border-radius: 999px;
  background: rgba(255, 255, 255, .85); color: #1f5e34;
  font: inherit; font-size: .85rem; font-weight: 600; cursor: pointer; white-space: nowrap;
  box-shadow: 0 1px 4px rgba(15, 60, 30, .2);
}
.onl-pill:hover:not(:disabled) { background: #fff; }
.onl-pill .onl-icon { width: 16px; height: 16px; }
/* The topic page's How to play button, moved into the tools row by the game's script. No
   `display` here: common.css hides it with .topic-howto[hidden], which this would outrank. */
.onl-tools .topic-howto {
  position: static; height: auto; margin: 0; gap: 0;
  padding: 6px 14px; border: 1px solid rgba(255, 255, 255, .8); border-radius: 999px;
  background: rgba(255, 255, 255, .85); color: #1f5e34; box-shadow: 0 1px 4px rgba(15, 60, 30, .2);
  font-size: .85rem; font-weight: 600; text-decoration: none; white-space: nowrap; cursor: pointer;
}
.onl-tools .topic-howto:hover { background: #fff; color: #1f5e34; }
.onl-tools .topic-howto-text { margin-left: 5px; }

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

/* The level at the board's left edge and the count at its right. --bw is the board's width, set
   by hungry-little-snake.js. */
.onl-hud {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: max(var(--bw, 100%), min(100%, 300px)); max-width: 100%; height: 2rem; padding: 0 2px; box-sizing: border-box;
}
.onl-level, .onl-count {
  flex: none; margin: 0; white-space: nowrap;
  color: #fff; font-size: .95rem; font-weight: 800; text-shadow: 0 1px 2px rgba(15, 60, 30, .45);
}
.onl-count { display: flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; }
.onl-count .onl-icon { width: 20px; height: 20px; stroke-width: 2.4; filter: drop-shadow(0 1px 1px rgba(15, 60, 30, .45)); }

.onl-fit { flex: 1 1 0; min-height: 0; width: 100%; display: grid; place-items: center; }

/* --- the board -------------------------------------------------------------------------------
   Three layers, hungry-little-snake.js sizing the board and placing each cell's tile and picture: the
   tiles, the snake over them, and the pictures over the snake. A press is read off the board, so
   nothing on it takes the pointer, and a finger on it draws instead of scrolling. A tile draws
   nothing of its own but a room's colour; it carries the pointer, the shakes and the bridge. */
.onl-board { position: relative; z-index: 0; cursor: pointer; touch-action: none; }
.onl-tiles, .onl-pics { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; }
.onl-svg { position: absolute; top: 0; left: 0; overflow: visible; pointer-events: none; }
.onl-tile {
  position: absolute; box-sizing: border-box; border-radius: 18%;
  transition: background-color .15s ease;
}
/* The lesson's pointer: a soft glow round the next tile. */
.onl-tile.is-hint { animation: onl-hint 1.3s ease-in-out infinite; }
@keyframes onl-hint {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 216, 77, 0); }
  50% { box-shadow: 0 0 0 4px #f1e2a6, 0 0 18px 4px rgba(241, 226, 166, .7); }
}
/* A dead end: the tile at the line's end rings red and shakes. */
.onl-tile.is-stuck { animation: onl-stuck .5s ease-in-out; }
@keyframes onl-stuck {
  15% { transform: translateX(-6%); box-shadow: 0 0 0 3px #d77b86; }
  35% { transform: translateX(5%); }
  55% { transform: translateX(-3%); box-shadow: 0 0 0 3px #d77b86; }
  75% { transform: translateX(2%); }
}

/* A step a rule refuses: the tile it would have gone to rings red and shakes. */
.onl-tile.is-no { animation: onl-no .42s ease-in-out; }
@keyframes onl-no {
  15% { transform: translateX(-5%); box-shadow: 0 0 0 3px #d77b86; }
  35% { transform: translateX(4%); box-shadow: 0 0 0 3px #d77b86; }
  60% { transform: translateX(-2%); }
}

/* Rooms: each room ringed in its own colour (hungry-little-snake.js draws the outline); a room
   filled lights up all at once. */
.onl-edge.is-a { stroke: #f0c46e; }
.onl-edge.is-b { stroke: #ef9a95; }
.onl-edge.is-c { stroke: #c3a6ee; }
.onl-edge.is-d { stroke: #86c4ec; }
.onl-tile.is-full { animation: onl-full .55s ease-out; }
@keyframes onl-full { 35% { box-shadow: 0 0 0 4px #fff, 0 0 16px 4px rgba(255, 255, 255, .9); } }

/* A bridge: two plank bands crossing, each lit once the line has gone over it that way. */
.onl-band {
  position: absolute; border-radius: 4px;
  background: repeating-linear-gradient(90deg, #bca88f 0 22%, #a99379 22% 25%);
  box-shadow: 0 1px 0 rgba(80, 60, 30, .3);
}
.onl-band.is-x { left: 4%; right: 4%; top: 34%; height: 32%; }
.onl-band.is-y {
  top: 4%; bottom: 4%; left: 34%; width: 32%;
  background: repeating-linear-gradient(0deg, #bca88f 0 22%, #a99379 22% 25%);
}
.onl-band.is-on { background: #b4e09f; }

/* Fences, between the tiles and the line. */
.onl-wall { stroke: #f1ebdc; }

/* A mark in a tile's top left corner: a flag, a number, a key or a lock. hungry-little-snake.js sizes and
   places each; it rides over the pictures. A lock opens (is-open) once its key is on the line. */
.onl-badge {
  position: absolute; z-index: 1; box-sizing: border-box; display: grid; place-items: center;
  border-radius: 50%; background: #fff; color: #1f5e34; border: 2px solid #1f5e34;
  font-weight: 900; line-height: 1; font-variant-numeric: tabular-nums;
  box-shadow: 0 1px 3px rgba(15, 60, 30, .35); pointer-events: none;
}
.onl-badge.is-num { background: #1f5e34; color: #fff; border-color: #fff; }
.onl-badge.is-num.is-on { background: #6fbf5e; }
.onl-badge.is-pair1 { border-color: #b8963e; }
.onl-badge.is-pair2 { border-color: #8d7cbf; }
.onl-mark { display: block; width: 78%; height: 78%; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.onl-pole { stroke: #4d4031; stroke-width: 2.2; }
.onl-flag-go { fill: #79b48a; stroke: #4f8a62; stroke-width: 1.2; }
.onl-flag-end { fill: #fff; stroke: #333; stroke-width: 1.2; }
.onl-check { fill: #333; }
.onl-keyring, .onl-keybit { stroke-width: 2.6; }
.onl-shackle, .onl-shackle-open { stroke-width: 2.4; }
.onl-lockbody { stroke: none; }
.is-pair1 .onl-keyring, .is-pair1 .onl-keybit, .is-pair1 .onl-shackle, .is-pair1 .onl-shackle-open { stroke: #b8963e; }
.is-pair2 .onl-keyring, .is-pair2 .onl-keybit, .is-pair2 .onl-shackle, .is-pair2 .onl-shackle-open { stroke: #8d7cbf; }
.is-pair1 .onl-lockbody { fill: #cdb066; }
.is-pair2 .onl-lockbody { fill: #a395cc; }
.onl-shackle-open { display: none; }
.onl-badge.is-open .onl-shackle { display: none; }
.onl-badge.is-open .onl-shackle-open { display: inline; }
.onl-badge.is-open { opacity: .7; }
/* The marks wiggle as a level opens, to be seen; they bounce when the line reaches them. */
.onl-badge.is-intro { animation: onl-wiggle .5s ease-in-out .5s 2; }
@keyframes onl-wiggle { 25% { transform: rotate(-14deg) scale(1.12); } 75% { transform: rotate(12deg) scale(1.12); } }
.onl-badge.is-pop { animation: onl-pop .3s cubic-bezier(.2, .9, .3, 1.4); }

/* The snake: a green body on a white rim with paler spots down its back, its head with eyes and a
   tongue, a bite each time it reaches a thing, and a light run along it when the board is cleared. */
.onl-rim { stroke: rgba(255, 255, 255, .85); }
.onl-core { stroke: #6fbf5e; }
.onl-spot { fill: #b4e09f; }
.onl-face { fill: #6fbf5e; stroke: rgba(255, 255, 255, .85); }
.onl-eye { fill: #fff; }
.onl-pupil { fill: #2b3a4a; }
.onl-tongue { fill: none; stroke: #e07a86; stroke-width: .13; stroke-linecap: round; stroke-linejoin: round; animation: onl-tongue 2.6s ease-in-out infinite; }
@keyframes onl-tongue { 0%, 18%, 100% { transform: scaleX(0); } 6%, 12% { transform: scaleX(1); } }
.onl-chomp.is-chomp { animation: onl-chomp .22s ease-out; }
@keyframes onl-chomp { 45% { transform: scale(1.18, 1.1); } }
.onl-glint { stroke: #effae6; opacity: 0; }
.onl-board.is-done .onl-glint { opacity: 1; }
.onl-board.is-done .onl-core { stroke: #5aad4b; }
.onl-board.is-done .onl-face { fill: #5aad4b; }
.onl-board.is-done .onl-chomp { animation: onl-happy .45s ease-in-out 3; }
@keyframes onl-happy { 50% { transform: scale(1.2); } }

.onl-item { position: absolute; display: block; }
/* The pictures are shown muted: the filter is the whole of it, the files stay as drawn. */
.onl-pic {
  display: block; width: 100%; height: 100%; object-fit: contain; pointer-events: none; -webkit-user-drag: none;
  filter: saturate(.4) brightness(1.1) contrast(.9);
}
.onl-pic.onl-emoji { display: grid; place-items: center; line-height: 1; }

/* The board comes on: each thing grows in, its delay set by hungry-little-snake.js; 0.38s is POP_MS there. */
.onl-item.is-in .onl-pic { animation: onl-in .38s cubic-bezier(.2, .9, .3, 1.3) both; }
@keyframes onl-in {
  from { opacity: 0; transform: scale(.2) rotate(-12deg); }
  to { opacity: 1; transform: none; }
}
@keyframes onl-pop { 40% { transform: scale(1.2); } }
/* A thing the snake lets go of grows back; one it reaches is swallowed and stays gone. This
   comes after is-back: a thing keeps that class once it has come back. */
.onl-item.is-back .onl-pic { animation: onl-in .25s cubic-bezier(.2, .9, .3, 1.3) both; }
.onl-item.is-on .onl-pic { animation: onl-gulp .2s ease-in both; }
@keyframes onl-gulp { to { opacity: 0; transform: scale(.3); } }

/* Over the stage: the paper that falls on a clear. */
.onl-fx { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 4; overflow: hidden; }

/* Two lines tall whatever it says, empty included: the board is laid out in what this leaves. */
.onl-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: #fff; font-size: .86rem; font-weight: 700; text-align: center;
  text-shadow: 0 1px 2px rgba(15, 60, 30, .5);
}
.onl-cap.is-new { animation: onl-say .4s ease-out; }
@keyframes onl-say { from { opacity: 0; transform: translateY(4px); } }
/* The row under the board: Start over with an arrow each side of it. */
.onl-foot { display: flex; align-items: center; justify-content: center; min-height: 44px; }
.onl-arrow {
  flex: none; display: grid; place-items: center; width: 36px; height: 36px; margin: 0 8px; padding: 0;
  border: 0; border-radius: 50%; background: rgba(255, 255, 255, .62); color: #1f5e34; cursor: pointer;
  box-shadow: 0 1px 4px rgba(15, 60, 30, .2);
}
.onl-arrow:hover { background: #fff; }
.onl-arrow .onl-icon { width: 24px; height: 24px; stroke-width: 2.6; opacity: .55; }
.onl-arrow:hover .onl-icon { opacity: 1; }
/* An arrow with no level that way keeps its place, so Start over does not move. */
.onl-arrow[hidden] { display: block; visibility: hidden; }

/* The speaker beside Full screen, 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 downward. */
.onl-round {
  width: 36px; height: 36px; padding: 0;
  display: grid; place-items: center; border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .7); color: #1f5e34; cursor: pointer;
  box-shadow: 0 1px 4px rgba(15, 60, 30, .18);
}
.onl-round:hover { background: #fff; }
.onl-round .onl-sicon { width: 22px; height: 22px; }
.onl-audio { position: relative; display: flex; align-items: center; }
.onl-more {
  display: grid; place-items: center; width: 0; height: 36px; padding: 0; overflow: hidden;
  border: 0; background: none; color: rgba(255, 255, 255, .85); cursor: pointer; opacity: 0;
  transition: opacity .15s ease;
}
.onl-audio:hover .onl-more, .onl-audio:focus-within .onl-more, .onl-audio.is-open .onl-more { width: 30px; opacity: 1; }
@media (hover: none) { .onl-more { width: 26px; opacity: .7; } }
.onl-more .onl-sicon { width: 22px; height: 22px; }
.onl-ellipsis { stroke-width: 3.4; }
.onl-menu {
  position: absolute; right: 0; top: 44px; 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(50, 40, 20, .18);
}
.onl-menu[hidden] { display: none; }
.onl-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;
}
.onl-opt:hover, .onl-opt:focus-visible { background: rgba(77, 64, 49, .07); }
.onl-sw { position: relative; flex: none; width: 34px; height: 20px; border-radius: 999px; background: rgba(77, 64, 49, .22); transition: background .15s ease; }
.onl-sw::after {
  content: ''; position: absolute; left: 2px; top: 2px; width: 16px; height: 16px; border-radius: 50%;
  background: #fff; transition: transform .15s ease;
}
.onl-opt[aria-checked="true"] .onl-sw { background: #4fb878; }
.onl-opt[aria-checked="true"] .onl-sw::after { transform: translateX(14px); }
.onl-sicon { display: block; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.onl-cone { fill: currentColor; stroke: none; }
.onl-sound.off .onl-waves { display: none; }
.onl-sound:not(.off) .onl-slash { display: none; }
.onl-icon { width: 18px; height: 18px; flex: none; }

/* A stage too narrow for the game's name beside the buttons (hungry-little-snake.js sets the class). */
.onl-tight .onl-game { visibility: hidden; }

/* --- over the stage: the panel dims it, and a sheet in its middle holds the card -------------- */
.onl-win { position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 5; }
.onl-win:empty { pointer-events: none; }
.onl-panel {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0;
  display: flex; flex-direction: column; align-items: center;
  padding: 20px; text-align: center; overflow-y: auto;
  background: rgba(15, 60, 30, .5);
  animation: onl-fade .35s ease-out;
}
@keyframes onl-fade { 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. */
.onl-panel > * { flex: none; }
.onl-panel > :first-child { margin-top: auto; margin-bottom: auto; }
.onl-sheet {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 14px; width: min(440px, 100%); box-sizing: border-box;
  padding: 26px 18px; border-radius: 20px; background: #fffdf8;
  box-shadow: 0 10px 0 rgba(77, 64, 49, .08);
}
.onl-sheet .onl-title { margin: 0; font-size: 1.6rem; font-weight: 700; color: #4d4031; }
/* Each letter's delay is set by hungry-little-snake.js. */
.onl-word { white-space: nowrap; }
.onl-ch { display: inline-block; animation: onl-wave .5s ease-in-out both; }
@keyframes onl-wave { 40% { transform: translateY(-.35em); } }
.onl-sheet > p { margin: 0; }
.onl-line { color: #4d4031; }
.onl-choices { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }
.onl-choices .btn { display: inline-flex; align-items: center; gap: 8px; }
.onl-choices .onl-icon { stroke-width: 2.2; }

/* The review build's tools, under the game panel and outside it. */
.onl-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;
}
.onl-review select, .onl-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.onl-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.onl-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 .onl-tools > * + * { margin-left: 8px; }
  #game-root .onl-pill > * + * { margin-left: 6px; }
  #game-root .onl > * + * { margin-top: 6px; }
  #game-root .onl-hud > * + * { margin-left: 10px; }
  #game-root .onl-count > * + * { margin-left: 6px; }
  #game-root .onl-opt > * + * { margin-left: 16px; }
  #game-root .onl-sheet > * + * { margin-top: 14px; }
  #game-root .onl-choices > * { margin: 6px 6px; }
  #game-root .onl-choices .btn > * + * { margin-left: 8px; }
  #game-root .onl-review > * { margin: 4px 4px; }
}
