/* "Every tower changes the way through": the walled board exhibit (js/path-demo.js).
   Flat fields in the page's own tokens: grass, a sand road, ink outlines.
   Everything is prefixed .path; the layout answers to the width of its own
   column, not the window, because the column is narrow on desktop too. */

.path {
  container-type: inline-size;
  /* the one colour the page has no token for at this level: a refusal */
  --path-stop: var(--sm-red, #a5281f);
  --path-grass-alt: #8ad24f; /* leaf-spring, one step lighter, for the checker */
}

.path__frame {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.75rem;
  max-width: 26rem;
}

/* Readout */

.path__readout {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.75rem;
}

.path__walk {
  margin: 0;
  font-weight: 600;
  line-height: 1.1;
}

.path__steps {
  display: block;
  font-size: clamp(2.5rem, 12cqi, 4rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
}

.path__gain {
  margin: 0;
  font-weight: 600;
  color: var(--ink-soft);
}

/* Board */

.path__board {
  border: 3px solid var(--ink);
  border-radius: 12px;
  overflow: hidden;
  background: var(--leaf-spring);
  /* a double tap on a tile builds twice, it must not zoom the page */
  touch-action: manipulation;
}

.path__row {
  display: grid;
  grid-template-columns: repeat(var(--path-cols, 7), minmax(0, 1fr));
}

.path__cell {
  aspect-ratio: 1;
}

.path__tile {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  font: inherit;
  color: var(--ink);
  background: var(--leaf-spring);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* :where keeps the checker as weak as the plain tile, so a tile's kind always wins */
.path__tile:where(.path__row:nth-child(odd) .path__cell:nth-child(even) *),
.path__tile:where(.path__row:nth-child(even) .path__cell:nth-child(odd) *) {
  background: var(--path-grass-alt);
}

.path__tile[data-kind="road"] {
  background: var(--sand);
}

.path__tile[data-kind="in"] {
  background: var(--blue-light);
}

.path__tile[data-kind="out"] {
  background: var(--ink);
  color: var(--white);
}

.path__tile:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: -3px;
  box-shadow: inset 0 0 0 6px var(--white);
  z-index: 1;
}

.path__tile[data-kind="out"]:focus-visible {
  outline-color: var(--gold);
}

/* The label is the tile's one child: text for the entrance, the exit and the
   route map, and the body of a wall or a rock. */
.path__label {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.875rem;
  font-weight: 700;
  line-height: 1;
  pointer-events: none;
}

.path__tile[data-kind="wall"] .path__label {
  inset: 10%;
  background: var(--gold);
  border: 3px solid var(--ink);
  border-bottom-width: 7px; /* a thick foot makes the block read as standing */
  border-radius: 7px;
}

.path__tile[data-kind="rock"] {
  cursor: default;
}

.path__tile[data-kind="rock"] .path__label {
  inset: 14%;
  background: var(--rule);
  border: 3px solid var(--ink);
  border-bottom-width: 6px;
  border-radius: 46% 54% 42% 58% / 58% 46% 54% 42%;
}

.path__tile[data-hint] .path__label {
  inset: 8%;
  background: var(--white);
  border: 3px dashed var(--ink);
  border-radius: 7px;
}

@media (hover: hover) {
  .path__tile[data-kind="grass"]:not([data-hint]):hover .path__label,
  .path__tile[data-kind="road"]:not([data-hint]):hover .path__label {
    inset: 10%;
    border: 3px dashed var(--ink);
    border-radius: 7px;
  }
}

/* Route map: the pointer toward the next step sits on the edge it points at. */
.path__tile[data-dir]::after {
  content: "";
  position: absolute;
  width: 0;
  height: 0;
  border: 5px solid transparent;
}

.path__tile[data-dir="down"]::after {
  bottom: 2px;
  left: calc(50% - 5px);
  border-top-color: currentColor;
  border-bottom-width: 0;
}

.path__tile[data-dir="up"]::after {
  top: 2px;
  left: calc(50% - 5px);
  border-bottom-color: currentColor;
  border-top-width: 0;
}

.path__tile[data-dir="left"]::after {
  left: 2px;
  top: calc(50% - 5px);
  border-right-color: currentColor;
  border-left-width: 0;
}

.path__tile[data-dir="right"]::after {
  right: 2px;
  top: calc(50% - 5px);
  border-left-color: currentColor;
  border-right-width: 0;
}

/* A refused wall: a cross over the tile that stays until the next action. */
.path__tile[data-refused]::before,
.path__tile[data-refused] .path__label::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 80%;
  height: 6px;
  margin: -3px 0 0 -40%;
  border-radius: 3px;
  background: var(--path-stop);
  box-shadow: 0 0 0 2px var(--white);
  transform: rotate(45deg);
  z-index: 2;
}

.path__tile[data-refused] .path__label::before {
  /* the label can be inset (a rock), so its bar is sized in tile terms */
  width: 36px;
  margin-left: -18px;
  box-shadow: none;
  transform: rotate(-45deg);
  z-index: 3;
}

.path__tile[data-refused]::before {
  width: 36px;
  margin-left: -18px;
}

/* Status line */

.path__say {
  margin: 0;
  min-height: 4.6em; /* three lines, so the controls do not jump under a thumb */
  padding: 0.6rem 0.8rem;
  border: 2px solid var(--ink);
  border-radius: 12px;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.35;
  background: var(--white);
}

.path[data-refused] .path__say {
  background: var(--gold);
}

/* Panel */

.path__panel {
  display: grid;
  gap: 0.75rem;
}

.path__stock {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0;
  font-weight: 600;
}

.path__pips {
  display: flex;
  gap: 0.3rem;
}

.path__pip {
  width: 1.25rem;
  height: 1.25rem;
  background: var(--gold);
  border: 2px solid var(--ink);
  border-bottom-width: 4px;
  border-radius: 4px;
}

.path__pip[data-used] {
  background: transparent;
  border: 2px dashed var(--ink-soft);
}

.path__controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.path__button {
  min-height: 2.75rem;
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--ink);
  background: var(--white);
  border: 2px solid var(--ink);
  border-radius: 999px;
  padding: 0.5rem 1rem;
  cursor: pointer;
}

/* only where a pointer can hover: on a phone the gold would stick after a tap */
@media (hover: hover) {
  .path__button:not([aria-pressed="true"]):hover {
    background: var(--gold);
  }
}

.path__button[aria-pressed="true"] {
  background: var(--ink);
  color: var(--white);
}

.path__button[aria-disabled="true"],
.path__button[aria-disabled="true"]:hover {
  color: var(--ink-soft);
  background: var(--wash);
  border-color: var(--rule);
  cursor: default;
}

.path__button:focus-visible {
  outline: 3px solid var(--blue);
  outline-offset: 2px;
}

.path__note {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.4;
  color: var(--ink-soft);
  max-width: var(--measure);
}

/* Beside the board once the column is wide enough for both. */
@container (min-width: 38rem) {
  .path__frame {
    grid-template-columns: minmax(0, 23rem) minmax(0, 1fr);
    grid-template-rows: auto auto 1fr;
    column-gap: clamp(1.25rem, 4cqi, 2.5rem);
    max-width: none;
  }

  .path__board {
    grid-column: 1;
    grid-row: 1 / span 3;
    align-self: start;
  }

  .path__readout,
  .path__say,
  .path__panel {
    grid-column: 2;
  }

  .path__readout {
    display: block;
  }

  .path__gain {
    margin-top: 0.25rem;
  }

  .path__panel {
    align-self: start;
  }
}

/* Movement only answers an action, and only for visitors who have not asked for less. */
@media (prefers-reduced-motion: no-preference) {
  .path__tile[data-pop] .path__label {
    animation: path-pop 180ms ease-out;
  }

  .path__tile[data-refused] {
    animation: path-shake 240ms ease-in-out;
  }
}

@keyframes path-pop {
  from {
    transform: scale(0.6);
  }
  70% {
    transform: scale(1.08);
  }
  to {
    transform: scale(1);
  }
}

@keyframes path-shake {
  25% {
    transform: translateX(-3px);
  }
  75% {
    transform: translateX(3px);
  }
}

/* On a narrow column the sentence sits above the board, so a refusal is read where the thumb is. */
.path__readout {
  order: 0;
}

.path__say {
  order: 1;
}

.path__board {
  order: 2;
}

.path__panel {
  order: 3;
}

/* ====================================================================
   2026-11-14: the board wears the game's own ground and models, a raider
   walks whatever route stands, and the longest possible route is met with
   a trophy.
   ==================================================================== */
.path__board {
  position: relative;
  background: #7ccf3f url("../../media/world/meadow-lawn.webp") center / 42% auto;
}

.path__tile,
.path__tile:where(.path__row:nth-child(odd) .path__cell:nth-child(even) *),
.path__tile:where(.path__row:nth-child(even) .path__cell:nth-child(odd) *) {
  background: transparent;
}

/* the checker stays, as a light wash over the lawn */
.path__tile:where(.path__row:nth-child(odd) .path__cell:nth-child(even) *),
.path__tile:where(.path__row:nth-child(even) .path__cell:nth-child(odd) *) {
  background: rgb(255 255 255 / 0.1);
}

.path__tile[data-kind="road"],
.path__tile[data-kind="in"],
.path__tile[data-kind="out"] {
  background: #e3c88c url("../../media/world/meadow-road.webp") center / 240% auto;
  box-shadow: inset 0 0 0 1px rgb(60 40 10 / 0.18);
}

.path__tile[data-kind="in"]::before,
.path__tile[data-kind="out"]::before {
  content: "";
  position: absolute;
  inset: -18% -6% 6%;
  background: url("../../media/models/raid_gate.webp") center bottom / contain no-repeat;
  pointer-events: none;
}

.path__tile[data-kind="out"]::before {
  inset: -30% -12% 4%;
  background-image: url("../../media/models/town_hall.webp");
}

.path__tile[data-kind="in"] .path__label,
.path__tile[data-kind="out"] .path__label {
  inset: auto 8% 6%;
  padding: 0.15em 0;
  border-radius: 0.5em;
  background: rgb(37 34 45 / 0.85);
  color: #fff;
  font-size: 0.75rem;
}

.path__tile[data-kind="wall"] .path__label {
  inset: -22% -8% 2%;
  border: 0;
  border-radius: 0;
  background: url("../../media/models/wall.webp") center bottom / contain no-repeat;
  filter: drop-shadow(0 3px 2px rgb(0 0 0 / 0.35));
}

.path__tile[data-kind="rock"] .path__label {
  inset: -30% -4% 6%;
  border: 0;
  border-radius: 0;
  background: url("../../media/models/tree_round.webp") center bottom / contain no-repeat;
  filter: drop-shadow(0 3px 2px rgb(0 0 0 / 0.3));
}

/* later rows stand in front of earlier ones, so a wall overlaps the tile behind it */
.path__row {
  position: relative;
}

.path__raider {
  position: absolute;
  z-index: 3;
  left: 50%;
  top: 0;
  width: calc(100% / var(--path-cols, 7) * 1.05);
  height: auto;
  transform: translate(-50%, -72%);
  filter: drop-shadow(0 3px 2px rgb(0 0 0 / 0.4));
  pointer-events: none;
}

.path__trophy {
  position: absolute;
  z-index: 5;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 0.4rem;
  padding: 1rem;
  border: 0;
  background: rgb(37 34 45 / 0.82);
  color: #fff;
  font: inherit;
  text-align: center;
  cursor: pointer;
  animation: path-trophy-in 0.35s ease-out both;
}

.path__trophy img {
  width: min(42%, 9rem);
  height: auto;
  animation: path-trophy-cup 0.9s cubic-bezier(0.2, 1.6, 0.4, 1) both;
}

.path__trophy-stars {
  display: flex;
  gap: 0.35rem;
}

.path__trophy-stars span {
  width: 2.25rem;
  height: 2.25rem;
  background: url("../../media/models/star.webp") center / contain no-repeat;
  animation: path-trophy-star 0.6s cubic-bezier(0.2, 1.8, 0.4, 1) both;
}

.path__trophy-stars span:nth-child(1) {
  animation-delay: 0.45s;
}

.path__trophy-stars span:nth-child(2) {
  animation-delay: 0.65s;
}

.path__trophy-stars span:nth-child(3) {
  animation-delay: 0.85s;
}

.path__trophy strong {
  font-size: 1.5rem;
  line-height: 1.1;
}

.path__trophy small {
  max-width: 16rem;
  font-size: 0.875rem;
  line-height: 1.35;
  opacity: 0.9;
}

/* gold sparks thrown out from the cup */
.path__trophy::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 38%;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  color: #f6bd35;
  box-shadow: 0 0 currentcolor, 0 0 currentcolor, 0 0 currentcolor, 0 0 currentcolor, 0 0 currentcolor, 0 0 currentcolor, 0 0 currentcolor, 0 0 currentcolor;
  animation: path-trophy-sparks 1.1s 0.3s ease-out both;
  pointer-events: none;
}

@keyframes path-trophy-in {
  from {
    opacity: 0;
  }
}

@keyframes path-trophy-cup {
  from {
    transform: translateY(60%) scale(0.3) rotate(-20deg);
    opacity: 0;
  }
}

@keyframes path-trophy-star {
  from {
    transform: scale(0) rotate(-90deg);
  }
}

@keyframes path-trophy-sparks {
  to {
    box-shadow: -6rem -4rem 0 -0.1rem transparent, 6rem -4rem 0 -0.1rem transparent, -7rem 1rem 0 -0.1rem transparent, 7rem 1rem 0 -0.1rem transparent,
      -3rem -7rem 0 -0.1rem transparent, 3rem -7rem 0 -0.1rem transparent, -4rem 5rem 0 -0.1rem transparent, 4rem 5rem 0 -0.1rem transparent;
  }
}

@media (prefers-reduced-motion: reduce) {
  .path__trophy,
  .path__trophy img,
  .path__trophy-stars span,
  .path__trophy::before {
    animation: none;
  }
}
