/* The board. Design option 2b: near-black surface, accent spent on line and
   glow, matched pairs lit from behind. The grid is sized to the viewport so
   even an 88-tile board never scrolls. */

.game {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* The board no longer grows past a 128px cell, so on a wide screen the HUD
     would drift to the far edge and leave the board marooned. Holding the whole
     game to one measure keeps HUD, board and hint reading as a single unit —
     the proportions the design was drawn at. */
  width: 100%;
  max-width: var(--measure);
  margin-inline: auto;
}

.game-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 20px calc(clamp(16px, 4vw, 32px) + 52px) 0 clamp(16px, 4vw, 32px);
  flex-wrap: wrap;
}
.game-bar .spacer { margin-left: auto; }

/* — turn clock ——————————————————————————————————— */

.clock-row {
  display: flex;
  align-items: center;
  gap: 14px;
  /* Same right reservation as the bar above it: once the viewport is no wider
     than the measure, the clock would otherwise run under the fixed sound
     toggle — which is exactly what happens on a phone held sideways. */
  padding: 14px calc(clamp(16px, 4vw, 32px) + 52px) 0 clamp(16px, 4vw, 32px);
}
.clock-rail {
  flex: 1;
  height: 3px;
  background: rgba(0, 0, 0, 0.55);
  overflow: hidden;
}
.clock-fill {
  display: block;
  height: 100%;
  background: linear-gradient(to right, transparent, var(--color-accent) 12%, var(--color-accent));
  transition: width 1s linear;
}
.clock-value {
  min-width: 2.2ch;
  text-align: right;
  font: 500 clamp(30px, 4vw, 46px)/1 var(--font-mono);
  font-variant-numeric: tabular-nums;
  /* White above 15s, then the warn/hot/danger bands below. */
  color: var(--color-text);
  text-shadow: 0 0 22px rgba(255, 255, 255, 0.4);
}
/* The clock heats up as it runs down — the Android build's timer colours. */
.clock-value[data-heat='warn']   { color: var(--color-warn);   text-shadow: 0 0 22px rgba(255, 210, 74, 0.5); }
.clock-value[data-heat='hot']    { color: var(--color-hot);    text-shadow: 0 0 22px rgba(255, 138, 61, 0.55); }
.clock-value[data-heat='danger'] { color: var(--color-danger); text-shadow: 0 0 26px rgba(255, 95, 95, 0.6); }
.clock-value[data-heat='danger'] { animation: clock-pulse 1s ease-in-out infinite; }
@keyframes clock-pulse {
  0%, 100% { transform: scale(1); }
  18% { transform: scale(1.16); }
}
.clock-rail[data-heat='danger'] .clock-fill {
  background: linear-gradient(to right, transparent, var(--color-danger) 12%, var(--color-danger));
}

/* — board area ——————————————————————————————————— */

.game-body {
  flex: 1;
  display: flex;
  align-items: center;
  gap: clamp(16px, 3vw, 44px);
  padding: 12px clamp(16px, 4vw, 32px) 24px;
  min-height: 0;
}

.hud {
  flex: none;
  width: 170px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}
.hud-block .kicker { display: block; }

.pips { display: flex; gap: 6px; margin-top: 9px; }
.pips > i {
  width: 30px;
  height: 7px;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.5);
  transition: background-color 200ms ease, box-shadow 200ms ease;
}
/* The pips take the colour the phone gives the tries counter: white at three,
   then yellow, orange and red as they run out. */
.pips > i.lit { background: var(--color-text); box-shadow: 0 0 10px rgba(255, 255, 255, 0.5); }
.pips[data-lives='2'] > i.lit { background: var(--color-warn); box-shadow: 0 0 10px rgba(255, 255, 0, 0.5); }
.pips[data-lives='1'] > i.lit { background: var(--color-hot); box-shadow: 0 0 10px rgba(255, 102, 0, 0.6); }
.pips[data-lives='0'] > i.lit { background: var(--color-danger); box-shadow: 0 0 10px rgba(255, 0, 0, 0.6); }

.streak-row { display: flex; align-items: baseline; gap: 7px; margin-top: 6px; }
.streak-now {
  font: 500 30px/1 var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
}
.hud-stats {
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 12px;
  color: var(--color-text-muted);
}
.hud-stats div { display: flex; justify-content: space-between; }
.hud-stats b { color: var(--color-text); font-weight: 400; font-variant-numeric: tabular-nums; }
.hud-stats .bonus b { color: var(--color-accent); }

.board-wrap {
  flex: 1;
  /* The row is centre-aligned, which would otherwise size this box to its own
     content — and the content is sized *from* this box. Stretching breaks the
     circle so the measured height is the space actually available. */
  align-self: stretch;
  min-width: 0;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.board {
  display: grid;
  /* --cell is measured in JS from the space actually available, so the whole
     board fits without scrolling at any difficulty. */
  grid-template-columns: repeat(var(--cols, 4), var(--cell, 64px));
  gap: clamp(4px, 0.7vmin, 10px);
}

.hud-hint {
  flex: none;
  width: 150px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: flex-end;
  text-align: right;
  font-size: 13px;
  color: var(--color-text-muted);
}

/* — tiles ————————————————————————————————————————— */

.tile {
  position: relative;
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: var(--color-tile-back);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14);
  cursor: pointer;
  /* The Compose build shrinks a card to zero width, swaps the art, and grows
     it back; the same trick reads as a flip here. */
  transition: transform 150ms ease, box-shadow 200ms ease, background-color 200ms ease;
  transform: scaleX(1);
}
.tile:disabled { cursor: default; }
.tile.flipping { transform: scaleX(0); }
.tile { display: flex; align-items: center; justify-content: center; }

/* The four faces carry the whole read of the board, so they are deliberately
   far apart in value — the Android build's own language:
     UNOPENED  dark, marked with a question mark  → unknown
     HIDDEN    white and blank                    → seen, still in play
     SHOWN     white, carrying the meme art       → face up right now
     FINISHED  dark and receded                   → matched, out of play
   Android drew these as unopened.png (a "?"), hidden.png (white with a black
   frame) and finished.png (fully transparent, so the tile drops to the board).
   The question mark is set in the app's own bundled Courier Bold rather than
   pulled from the 106px bitmap, so it stays crisp at any cell size. */
.tile::before {
  content: '?';
  font: 700 clamp(14px, calc(var(--cell, 64px) * 0.44), 60px) / 1 var(--font-mono);
  color: var(--color-accent);
  transition: color 200ms ease;
  pointer-events: none;
}

/* Seen once and back down: white, the strongest signal on the board — the
   tiles you are meant to remember are the ones that stand out. */
.tile[data-face='HIDDEN'] {
  background: var(--color-tile-face);
  box-shadow: inset 0 0 0 1px rgba(13, 14, 23, 0.55);
}
.tile[data-face='HIDDEN']::before { content: none; }

.tile[data-face='SHOWN'] {
  background: var(--color-tile-face);
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
}

/* Matched and spent: darker than the board's own tile back, no glow, so a
   cleared pair recedes instead of competing with what is still in play. */
.tile[data-face='FINISHED'] {
  /* Transparent on the phone, so a cleared tile drops to the wallpaper. Same
     here: the dimmed collage showing through reads as the darkest face. */
  background: transparent;
  box-shadow: inset 0 0 0 1px rgba(255, 215, 0, 0.22);
}
.tile[data-face='SHOWN']::before,
.tile[data-face='FINISHED']::before { content: none; }

/* The design's signature glow on a matched pair, kept as the moment of the
   match rather than its resting state. Removed with the confetti burst.
   Scoped to FINISHED so it cannot wash over the white SHOWN face during the
   150ms flip that sits between the match resolving and the face changing. */
.tile[data-face='FINISHED'].just-matched {
  background: rgba(255, 215, 0, 0.16);
  box-shadow: inset 0 0 0 1.5px var(--color-accent), var(--glow-accent);
}

/* The art box is 84% of the cell — what inset:8% used to give it — but never
   wider than the image's own pixel count, which JS publishes per tile as
   --art-px from naturalWidth. CSS therefore only ever scales a tile *down*.
   That one rule is what lets the cell grow past the old 128px ceiling: a 512px
   custom face fills the larger cell and is still downsampled, while the 106px
   built-in art draws at its own size inside that cell rather than being
   magnified into mush. Without --art-px it falls back to the old 84%. */
.tile-art {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(84%, var(--art-px, 84%));
  /* Sized from width alone. Every face is square — the built-in set is 106x106
     and the store rejects anything that is not — so an aspect ratio beats a
     percentage height, which would have to resolve against a cell height that
     is itself derived from aspect-ratio. */
  aspect-ratio: 1;
  background-position: center;
  background-size: contain;
  background-repeat: no-repeat;
}

.tile:not(:disabled):hover {
  box-shadow: inset 0 0 0 1px var(--color-accent), 0 0 14px rgba(255, 215, 0, 0.25);
}
.tile[data-face='UNOPENED']:not(:disabled):hover::before { color: var(--color-accent-bright); }
.tile[data-face='HIDDEN']:not(:disabled):hover {
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.65), 0 0 16px rgba(255, 215, 0, 0.4);
}

/* — narrow screens ————————————————————————————————— */

@media (max-width: 760px) {
  /* Drop the wordmark so the tag and the two buttons stay on one row next to
     the fixed sound toggle, instead of wrapping and stealing board height. */
  .game-bar .wordmark { display: none; }
  .game-bar { gap: 8px; padding-top: 14px; }
}

/* — phone portrait: clock on top, board in the middle, HUD in a thumb bar ——
   Portrait only. Stacking the HUD under the board costs about 90px of height,
   which is affordable when height is the plentiful axis and ruinous when it is
   not — a phone on its side has barely 300px to give the tiles. */

@media (max-width: 760px) and (orientation: portrait) {
  .game-body {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding-inline: 16px;
  }
  .board-wrap { flex: 1; padding: 12px 0; }
  .hud {
    order: 2;
    width: auto;
    flex-direction: row;
    align-items: center;
    gap: 18px;
    padding: 14px 6px calc(14px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--color-divider);
    background: rgba(0, 0, 0, 0.55);
  }
  .hud-block:nth-child(2) { margin-left: auto; text-align: right; }
  .hud-block:nth-child(2) .streak-row { justify-content: flex-end; }
  .hud-stats {
    flex-direction: row;
    gap: 14px;
    font-size: 11px;
  }
  .hud-stats div { flex-direction: column; gap: 2px; align-items: flex-end; }
  .hud-hint { display: none; }
  .streak-now { font-size: 24px; }
  .pips > i { width: 26px; height: 6px; }
}

/* — short landscape (a phone on its side) ————————————————
   Keep the HUD beside the board so every spare pixel of height goes to tiles,
   and shrink the chrome that would otherwise eat the top of the screen. */

@media (orientation: landscape) and (max-height: 560px) {
  .game-bar { padding-top: 10px; }
  .clock-row { padding-top: 8px; }
  .game-bar, .clock-row { padding-right: calc(clamp(12px, 3vw, 32px) + 48px); }
  .clock-value { font-size: 26px; }
  .game-body { padding: 6px clamp(12px, 3vw, 32px) 10px; }
  .hud { width: 108px; gap: 10px; }
  .hud-hint { display: none; }
  .streak-now { font-size: 20px; }
  .pips > i { width: 20px; height: 5px; }
  .hud-stats { gap: 4px; font-size: 11px; }
}

@media (prefers-reduced-motion: reduce) {
  .tile.flipping { transform: none; }
  .clock-value[data-heat='danger'] { animation: none; }
}
