/* The board: its squares, the pieces on them, the connectors between scoring pieces, and the walls.

   A square's state is shown with attributes and classes set by board-view.js:
     data-owner              1, 2 or 3 on a played square
     .in-scoring-line        the piece is part of a scoring line (full color instead of the dark shade)
     .has-check-mark         a ✓ has been put on the piece (the slab on its right)
     .check-mark-in-line     ...and that ✓ is part of a ✓ scoring line
     .bonus-square           one of the four star squares
     .selectable             a square the person can pick right now (.selectable-piece when it holds a piece to steal or mark)
     .latest                 a player's latest square (data-latest-by says whose, .latest-fresh when it's the very latest move)
     .latest-is-check-mark   ...and it was a ✓ put on a piece, so the dashes go around the slab */

symbol { overflow: visible; }
.symbol { width: 1.15em; height: 1.15em; vertical-align: -0.22em; }

.board-box { position: relative; }
.board { position: relative; display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--board-gap); --my-color: var(--player-1-color); }

.square {
  --square-fill: var(--panel-background);
  --check-green: var(--player-3-color);
  --check-green-dark: color-mix(in srgb, var(--player-3-color) 42%, #1f1f23);
  /* where the slab's slanted edge meets the top and the bottom of the square (keep the dashed outline's points in step) */
  --slab-top: 68%;
  --slab-bottom: 46%;
  --piece-shift: -34%;
  aspect-ratio: 1; position: relative; padding: 0;
  border: 2px solid var(--line-color); border-radius: var(--square-radius);
  background: var(--square-fill); color: var(--text-color);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  transition: background-color 0.35s ease, border-color 0.35s ease;   /* the squares you can pick fade in (and out) rather than snapping */
}
.square[aria-disabled="true"] { cursor: default; }
.square .piece { width: 50%; height: 50%; display: block; pointer-events: none; }

/* a played square: a white symbol on a darker shade of its player's color; once it's part of a scoring line it takes the full color */
.square[data-owner="1"] { --player-color: var(--player-1-color); --dark-fill: color-mix(in srgb, var(--player-1-color) 42%, #1f1f23); color: var(--player-1-color); }
.square[data-owner="2"] { --player-color: var(--player-2-color); --dark-fill: color-mix(in srgb, var(--player-2-color) 42%, #1f1f23); color: var(--player-2-color); }
.square[data-owner="3"] { --player-color: var(--player-3-color); --dark-fill: color-mix(in srgb, var(--player-3-color) 42%, #1f1f23); color: var(--player-3-color); }
.square[data-owner] { --square-fill: var(--dark-fill); background: var(--square-fill); border-color: var(--square-fill); }
.square[data-owner].in-scoring-line { --square-fill: var(--player-color); }
.square[data-owner] svg { --player-1-color: #fff; --player-2-color: #fff; --player-3-color: #fff; }
.square.bonus-square { background: var(--bonus-square-background); border-color: rgba(232, 185, 60, 0.5); }   /* the gold edge stays even when the green tint of a selectable square takes over the fill */
.square.bonus-square[data-owner] { background: var(--square-fill); border-color: var(--bonus-color); }   /* a bonus square keeps its gold edge once it's played */

/* the squares you can pick are lit in a shade of your color */
.square.selectable { background: color-mix(in srgb, var(--my-color) 30%, var(--panel-background)); }
.square.selectable:not(.bonus-square, [data-owner]) { border-color: color-mix(in srgb, var(--my-color) 60%, var(--panel-background)); }
.square.selectable[data-owner] { box-shadow: inset 0 0 0 3px rgba(255, 255, 255, 0.55); }   /* a piece you can steal or put a ✓ on */
.square.in-scoring-line { box-shadow: none; }

.square .bonus-star { position: absolute; inset: 0; margin: auto; width: 40%; height: 40%; color: var(--bonus-color); pointer-events: none; }
.star-inline { color: var(--bonus-color); }

/* a faint copy of your piece fades in on the empty squares you can pick, when you point at one */
.square .ghost-piece { color: var(--my-color); opacity: 0; transition: opacity 0.25s ease; }
@media (hover: hover) {
  .square.selectable:hover, .square.selectable:focus-visible { background: color-mix(in srgb, var(--my-color) 42%, var(--panel-background)); }
  .square.selectable:not(.bonus-square, [data-owner]):hover, .square.selectable:not(.bonus-square, [data-owner]):focus-visible {
    border-color: color-mix(in srgb, var(--my-color) 75%, var(--panel-background));
  }
  .square.selectable:hover .ghost-piece, .square.selectable:focus-visible .ghost-piece { opacity: 0.4; }
  /* picking a piece to put a ✓ on: it lightens in its own color, not in the green of the ✓ (a piece in a scoring line is
     already at full color, so it lightens toward white instead) */
  .square.selectable-piece[data-owner="1"] { --hover-fill: color-mix(in srgb, var(--player-1-color) 58%, #1f1f23); }
  .square.selectable-piece[data-owner="2"] { --hover-fill: color-mix(in srgb, var(--player-2-color) 58%, #1f1f23); }
  .square.selectable-piece[data-owner="3"] { --hover-fill: color-mix(in srgb, var(--player-3-color) 58%, #1f1f23); }
  .square.selectable-piece[data-owner="1"].in-scoring-line { --hover-fill: color-mix(in srgb, var(--player-1-color) 78%, #fff); }
  .square.selectable-piece[data-owner="2"].in-scoring-line { --hover-fill: color-mix(in srgb, var(--player-2-color) 78%, #fff); }
  .square.selectable-piece[data-owner="3"].in-scoring-line { --hover-fill: color-mix(in srgb, var(--player-3-color) 78%, #fff); }
  .square.selectable-piece:hover, .square.selectable-piece:focus-visible { --square-fill: var(--hover-fill); background: var(--hover-fill); }
}

/* ---- a ✓ put on a piece: shoved in from the right ----
   A slanted green slab takes the right part of the square, and the piece, which doesn't shrink, is pushed left so it's cramped
   against the slab. The slab is the dark green of a ✓ square, or full green when that ✓ is part of a ✓ line. */
.square.has-check-mark .piece, .square.has-check-mark .stolen-from { translate: var(--piece-shift) 0; }
.square .check-slab-clip { position: absolute; inset: -2px; border-radius: var(--square-radius); overflow: hidden; pointer-events: none; }   /* as big as the square, border included, so the slab covers the border too */
.square.bonus-square .check-slab-clip { inset: 0; border-radius: 8px; }   /* a bonus square keeps its gold edge all the way round */
.square .check-slab {
  position: absolute; inset: 0; background: var(--check-green-dark); transition: background-color 0.35s ease;
  clip-path: polygon(var(--slab-top) 0, 100% 0, 100% 100%, var(--slab-bottom) 100%);
}
.square.check-mark-in-line .check-slab { background: var(--check-green); }
.square .check-slab .check-slab-symbol { position: absolute; width: 44%; height: 44%; right: -3%; top: 28%; }
.square .check-slab .check-slab-outline { position: absolute; inset: 0; width: 100%; height: 100%; }
/* a stolen square: the thief's piece on top, the original symbol small and faded in its center */
.square .stolen-from { position: absolute; inset: 0; margin: auto; width: 20%; height: 20%; opacity: 0.4; pointer-events: none; }

/* ---- each player's latest square is dashed ----
   The very latest move on the board has plain white dashes (::before); once another player has moved they cross-fade to dashes
   in that player's own color (::after). Each case has a fixed color: the player's bright color on a dark fill, and a pale tint
   of it on the full-color fill of a square in a line. */
.square[data-latest-by="1"] { --dash-color: #e8314a; } .square[data-latest-by="1"].in-scoring-line { --dash-color: color-mix(in srgb, #e8314a 50%, #fff); }
.square[data-latest-by="2"] { --dash-color: #2e9efa; } .square[data-latest-by="2"].in-scoring-line { --dash-color: color-mix(in srgb, #2e9efa 50%, #fff); }
.square[data-latest-by="3"] { --dash-color: #01ca58; } .square[data-latest-by="3"].in-scoring-line { --dash-color: color-mix(in srgb, #01ca58 50%, #fff); }
.square.latest::before, .square.latest::after {
  content: ""; position: absolute; box-sizing: border-box; inset: clamp(3px, calc(100% / 6 - 5px), 6px);   /* 6px in from the edge on a big square, down to 3px on a small one */
  border: 2px dashed #fff; border-radius: 6px; pointer-events: none;
  transition: opacity 0.6s ease, border-color 0.35s ease;
}
.square.latest::before { opacity: 0; }
.square.latest.latest-fresh::before { opacity: 0.95; }
.square.latest::after { border-color: var(--dash-color, #fff); }
.square.latest.latest-fresh::after { opacity: 0; }
/* when the latest move was a ✓ put on a piece, the dashes go around the green slab (an SVG outline with the same white-then-color
   cross-fade) instead of the whole square */
.square.latest-is-check-mark::before, .square.latest-is-check-mark::after { display: none; }
.square .check-slab-outline polygon {
  fill: none; stroke-width: 2; stroke-dasharray: 5 3.5; stroke-linejoin: round; vector-effect: non-scaling-stroke; opacity: 0;
  transition: opacity 0.6s ease, stroke 0.35s ease;
}
.square .check-slab-outline .outline-white { stroke: #fff; }
.square .check-slab-outline .outline-colored { stroke: var(--dash-color, #fff); }
.square.latest-is-check-mark .outline-colored { opacity: 1; }
.square.latest-is-check-mark.latest-fresh .outline-white { opacity: 0.95; }
.square.latest-is-check-mark.latest-fresh .outline-colored { opacity: 0; }
/* the slab is always the ✓'s, whatever piece it sits on, so its dashes are the ✓'s bright green */
.square.latest-is-check-mark, .square.latest-is-check-mark.in-scoring-line { --dash-color: #01ca58; }

/* ---- what each player would score by playing on an empty square (the small colored chips) ---- */
.gain-chips {
  position: absolute; left: 0; right: 0; bottom: 4px; display: flex; flex-wrap: wrap; gap: 3px; justify-content: center; pointer-events: none;
  font: 800 13px/1 var(--display-font); font-feature-settings: "case"; letter-spacing: 0.5px;
}
.gain-chip { padding: 3px 5px 3px; border-radius: 6px; color: #fff; }
.gain-chip.blocks-an-opponent { box-shadow: 0 0 0 2px var(--text-color); }
.gain-chip[data-player="1"] { background: var(--player-1-color); }
.gain-chip[data-player="2"] { background: var(--player-2-color); }
.gain-chip[data-player="3"] { background: var(--player-3-color); }

/* ---- connectors between the squares of a scoring line ----
   Dark shades of the line's color, drawn under the squares (so only the part across the gaps shows) and under the walls. */
.links { position: absolute; inset: 0; pointer-events: none; }
.link { position: absolute; border-radius: 2px; transition: opacity 0.3s ease; }
.link.pending { opacity: 0; }   /* waiting for the square to land; fades in afterwards */
.link[data-player="1"] { background: color-mix(in srgb, var(--player-1-color) 55%, #000); }
.link[data-player="2"] { background: color-mix(in srgb, var(--player-2-color) 55%, #000); }
.link[data-player="3"] { background: color-mix(in srgb, var(--player-3-color) 55%, #000); }

/* ---- walls ---- */
.walls { position: absolute; inset: 0; pointer-events: none; }
.wall { position: absolute; border-radius: 4px; background: var(--wall-color); box-shadow: 0 0 0 2px var(--page-background); }

/* the tappable strips along every link between squares: only used while building, taking over or looking at a wall */
.wall-target { position: absolute; padding: 0; border: 0; background: none; pointer-events: none; transform: translate(-50%, -50%); z-index: 2; }   /* above the built walls, so a wall's hover light shows on top of it */
.wall-target::after { content: ""; position: absolute; inset: 0; margin: auto; border-radius: 4px; background: var(--muted-text-color); opacity: 0; }
.wall-target.vertical::after { width: var(--wall-thickness); height: 100%; }
.wall-target.horizontal::after { height: var(--wall-thickness); width: 100%; }   /* 8px thick, the same as a built wall */
.wall-target.vertical:not(.diagonal)::after { height: 80%; }
.wall-target.horizontal:not(.diagonal)::after { width: 80%; }   /* the preview is as long as the wall will be */
.wall-target.live { pointer-events: auto; }
.wall-target.buildable { pointer-events: auto; cursor: pointer; }
.wall-target.takeable { pointer-events: auto; cursor: pointer; }
.wall-target.inspectable { pointer-events: auto; cursor: help; }   /* a built wall: tap it to see what it is */
/* ...but only on the wall itself, very tight (8px wide, 0.8 of a square long, like the wall that's drawn), so a tap next to a wall
   still lands on the square. (The strips are 20px wide and a whole square long, so they're cut down to the wall.) */
.wall-target.vertical.inspectable:not(.diagonal) { clip-path: inset(10% 6px); }
.wall-target.horizontal.inspectable { clip-path: inset(6px 10%); }
.wall-target.buildable::after { opacity: 0.35; }
.wall-target.diagonal.buildable::after { opacity: 0.2; }
/* the link you're about to build on is shown as the wall will look: a lighter version of X's red, with the thin dark border a built wall has */
.wall-target.buildable:hover::after, .wall-target.buildable:focus-visible::after {
  opacity: 1; background: color-mix(in srgb, var(--player-1-color) 55%, #fff); box-shadow: 0 0 0 2px var(--page-background);
}
/* pointing at a wall that O's steal can take lights it up in its owner's color, lighter */
.wall-target.takeable:hover::after, .wall-target.takeable:focus-visible::after {
  opacity: 1; background: color-mix(in srgb, var(--wall-owner-color, #d4394d) 55%, #fff); box-shadow: 0 0 0 2px var(--page-background);
}
/* The two slashes at a corner cross in the middle. Only a slash's .hit-area can be tapped, and it's cut along the horizontal and
   vertical lines through the crossing, so a tap near the middle goes to the slash it is nearer to ("/" for up-right or down-left
   of the crossing, "\" for the other two) instead of always to whichever slash is on top. */
.wall-target.diagonal .hit-area {
  position: absolute; inset: 0; pointer-events: none; cursor: pointer;
  clip-path: polygon(0 0, 100% 0, 100% calc(50% - 8px), 50% 50%, 100% calc(50% + 8px), 100% 100%, 0 100%, 0 calc(50% + 8px), 50% 50%, 0 calc(50% - 8px));
}
.wall-target.diagonal.inspectable .hit-area { inset: 0 4px; clip-path: none; }
.wall-target.diagonal.live, .wall-target.diagonal.buildable, .wall-target.diagonal.takeable, .wall-target.diagonal.inspectable { pointer-events: none; }
.wall-target.diagonal.live .hit-area, .wall-target.diagonal.buildable .hit-area, .wall-target.diagonal.takeable .hit-area,
.wall-target.diagonal.inspectable .hit-area { pointer-events: auto; }
