/* ==========================================================================
   Cúpla Score: map (inlined map.svg + route + nodes), node sheet.
   Builds on tokens.css and base.css. Node positions come from levels.json
   via --x / --y custom properties (set with CSSOM, allowed by the CSP).
   ========================================================================== */

.cs-map {
  position: relative;
  width: 100%;
  aspect-ratio: 771 / 1000;
  margin-inline: auto;
  user-select: none;
  -webkit-user-select: none;
}

.cs-map__svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* ---- Island ---- */
.cs-map .land {
  color: var(--land);
  fill: var(--land);
}

.cs-map .coast {
  color: var(--coast);
  stroke: var(--coast);
  stroke-width: 2.5;
}

/* Soft province regions: hairline divisions inside the island, no national border. */
.cs-map .province {
  fill: transparent;
  stroke: var(--line);
  stroke-width: 2;
  stroke-dasharray: 1 7;
  stroke-linecap: round;
  transition: fill-opacity var(--dur-slow) var(--ease-out);
}

.cs-map .province.is-complete,
.cs-map .province.is-tinting {
  fill-opacity: var(--tint-alpha);
}
.cs-map .province-laighin.is-complete,
.cs-map .province-laighin.is-tinting { fill: var(--tint-laighin); }
.cs-map .province-mumhain.is-complete,
.cs-map .province-mumhain.is-tinting { fill: var(--tint-mumhain); }
.cs-map .province-connachta.is-complete,
.cs-map .province-connachta.is-tinting { fill: var(--tint-connachta); }
.cs-map .province-ulaidh.is-complete,
.cs-map .province-ulaidh.is-tinting { fill: var(--tint-ulaidh); }

/* The province reward: the tint washes in (province complete screen). */
.cs-map .province.is-tinting {
  animation: cs-tint-in 1400ms var(--ease-out) 300ms both;
}

@keyframes cs-tint-in {
  from { fill-opacity: 0; }
  to { fill-opacity: calc(var(--tint-alpha) * 1.6); }
}

/* ---- Route (dotted) ---- */
.cs-route__line,
.cs-route__done {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 0 17;
}

.cs-route__line {
  stroke: var(--route);
  stroke-width: 6;
  opacity: 0.75;
}

.cs-route__done {
  stroke: var(--atlantic);
  stroke-width: 8;
}

/* Landing: the route draws across the island once (the orchestrated moment). */
.cs-route__mask {
  fill: none;
  stroke: #fff;
  stroke-width: 40;
  stroke-linecap: round;
  stroke-dasharray: 1 1;
  stroke-dashoffset: 1;
  animation: cs-route-draw var(--dur-route) var(--ease-in-out) 350ms forwards;
}

@keyframes cs-route-draw {
  to { stroke-dashoffset: 0; }
}

/* ---- Nodes ---- */
.cs-map__nodes {
  position: absolute;
  inset: 0;
}

.cs-node {
  --dot: 14px;
  --hit: 40px;
  position: absolute;
  left: var(--x);
  top: var(--y);
  display: grid;
  place-items: center;
  width: var(--hit);
  height: var(--hit);
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--text);
  transform: translate(-50%, -50%);
  -webkit-appearance: none;
  appearance: none;
  touch-action: manipulation;
}

button.cs-node:not([disabled]) {
  cursor: pointer;
}

.cs-node__dot {
  position: relative;
  display: block;
  width: var(--dot);
  height: var(--dot);
  border-radius: 50%;
  background: var(--surface);
  border: 2.5px solid var(--line-strong);
  transition: transform var(--dur-fast) var(--ease-spring);
}

.cs-node.is-boss {
  --dot: 22px;
  --hit: 46px;
}

.cs-node.is-boss .cs-node__dot {
  border-color: var(--heather);
  border-width: 3px;
}

.cs-node.is-final .cs-node__dot {
  border-color: var(--heather);
  box-shadow: 0 0 0 3px var(--surface), 0 0 0 5.5px var(--gorse);
}

/* locked: muted */
.cs-node.is-locked .cs-node__dot {
  background: var(--sea-mist);
  border-color: var(--line);
}
.cs-node.is-locked.is-boss .cs-node__dot {
  border-color: color-mix(in srgb, var(--heather) 45%, var(--line));
}

/* open: solid atlantic ring, filled centre, pulsing ring once on unlock */
.cs-node.is-open { --dot: 18px; }
.cs-node.is-open.is-boss { --dot: 24px; }

.cs-node.is-open .cs-node__dot {
  background: var(--surface);
  border-color: var(--atlantic);
  border-width: 4px;
}
.cs-node.is-open.is-boss .cs-node__dot {
  border-color: var(--heather);
  border-width: 5px;
}

.cs-node.is-open::before {
  content: "";
  position: absolute;
  inset: calc((var(--hit) - var(--dot)) / 2 - 4px);
  border-radius: 50%;
  border: 2px solid var(--atlantic);
  opacity: 0;
  pointer-events: none;
}
.cs-node.is-open.is-boss::before { border-color: var(--heather); }

.cs-node.is-open.is-new::before {
  animation: cs-node-pulse 1300ms var(--ease-out) 500ms 2 both;
}

@keyframes cs-node-pulse {
  0% { opacity: 0.9; transform: scale(0.7); }
  100% { opacity: 0; transform: scale(2.1); }
}

/* done: filled */
.cs-node.is-done .cs-node__dot {
  background: var(--atlantic);
  border-color: var(--atlantic-edge);
}
.cs-node.is-done.is-boss .cs-node__dot {
  background: var(--heather);
  border-color: var(--heather-edge);
}

@media (hover: hover) {
  button.cs-node:not([disabled]):hover .cs-node__dot {
    transform: scale(1.25);
  }
}

.cs-node:focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: -4px;
}

/* tiny stars under completed nodes */
.cs-node__stars.cs-stars {
  position: absolute;
  top: calc(50% + var(--dot) / 2 + 1px);
  left: 50%;
  transform: translateX(-50%);
  font-size: 7px;
  gap: 0.5px;
  pointer-events: none;
}

/* Hero (landing): small neutral nodes appear as the route reaches them */
.cs-map--hero .cs-node {
  --dot: 10px;
  --hit: 10px;
}
.cs-map--hero .cs-node.is-boss { --dot: 15px; --hit: 15px; }
.cs-map--hero .cs-node__dot {
  border-width: 2px;
  border-color: var(--atlantic);
}
.cs-map--hero .cs-node.is-boss .cs-node__dot { border-color: var(--heather); border-width: 3px; }
.cs-map--hero .cs-node.is-final .cs-node__dot { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--gorse); }

.cs-map--hero.is-drawing .cs-node {
  animation: cs-pop-in var(--dur-base) var(--ease-spring) both;
  animation-delay: calc(350ms + var(--i) * (var(--dur-route) / 24));
}

/* Province screen: nodes decorative */
.cs-map--province .cs-node { --hit: 16px; }

/* ---- Node sheet ---- */
.cs-nodesheet {
  position: fixed;
  inset: 0;
  z-index: var(--z-sheet);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: var(--backdrop);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}

.cs-nodesheet.is-open { opacity: 1; }

.cs-nodesheet__panel {
  position: relative;
  width: 100%;
  max-width: var(--content-max);
  display: grid;
  gap: var(--space-2);
  padding: var(--space-5) var(--gutter) calc(var(--space-5) + env(safe-area-inset-bottom, 0px));
  border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
  box-shadow: 0 -2px 0 var(--tile-edge);
  transform: translateY(24px);
  transition: transform var(--dur-base) var(--ease-out);
}

.cs-nodesheet.is-open .cs-nodesheet__panel { transform: none; }

.cs-nodesheet__panel.is-boss {
  box-shadow: 0 -4px 0 var(--heather);
}

.cs-nodesheet__close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
}

.cs-nodesheet__step {
  color: var(--muted);
  font-size: var(--step--1);
  font-weight: var(--weight-bold);
}

.cs-nodesheet__place {
  font-size: var(--step-4);
  font-weight: var(--weight-heavy);
  padding-right: var(--tap);
}

.cs-nodesheet__en {
  color: var(--muted);
  margin-top: calc(-1 * var(--space-1));
}

.cs-nodesheet__theme {
  font-size: var(--step-1);
  font-weight: var(--weight-bold);
  margin-top: var(--space-2);
}

.cs-nodesheet__best {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--muted);
  margin-bottom: var(--space-3);
}

.cs-nodesheet__best .cs-stars { font-size: 1.25rem; }

@media (min-width: 48rem) {
  .cs-nodesheet { align-items: center; }
  .cs-nodesheet__panel {
    max-width: 26rem;
    border-radius: var(--radius-sheet);
    box-shadow: 0 2px 0 var(--tile-edge);
  }
}
