/*
 * Play (js/ui/play.js): the status bar, the tools, the number pad and the hint card in the side panel, and
 * the overlay layer drawn into the board SVG. Only var(--...) tokens are used; a translucent tint is the
 * token colour with fill-opacity (SVG) or opacity (a pseudo-element), so the three themes need no extra
 * tokens and no colour function is written here.
 *
 * Board overlay (inside the board's <svg class="sgb">): one <g class="pl-cell"> per cell holding two rects
 * (.pl-bg: selection, neighbours, same symbol, conflict, mistake; .pl-hint: hint region, cells and targets)
 * and, when the cell has something to show, .pl-content (the value, or the candidate notes). The state of a
 * cell is a class of its group: is-sel is-peer is-same is-conflict is-wrong is-hint-region is-hint-cell
 * is-hint-target.
 */

/* ---- Panel ---- */
.play {
  display: flex;
  flex-direction: column;
  gap: var(--sg-space-3);
}

.play__panel {
  display: flex;
  flex-direction: column;
  gap: var(--sg-space-3);
  padding: var(--sg-space-3);
  border: 1px solid var(--sg-color-divider);
  border-radius: var(--sg-radius-3);
  background: var(--sg-color-surface);
  box-shadow: var(--sg-shadow-1);
}

.play__more-toggle {
  align-self: center;
  gap: var(--sg-space-1);
  color: var(--sg-color-text-muted);
}

.play__keys {
  display: flex;
  flex-direction: column;
  gap: var(--sg-space-3);
}

.play__status {
  display: flex;
  flex-direction: column;
  gap: var(--sg-space-2);
  padding: var(--sg-space-2) var(--sg-space-3);
  border: 1px solid var(--sg-color-divider);
  border-radius: var(--sg-radius-2);
  background: var(--sg-color-surface);
}

.play__status-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sg-space-2) var(--sg-space-3);
}

.play__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: var(--sg-space-2);
}

/* The status line inside the box: no frame of its own, a rule above it. */
.play__status .status-row {
  min-height: 0;
  padding: var(--sg-space-2) 0 0;
  border: 0;
  border-top: 1px solid var(--sg-color-divider);
  border-radius: 0;
  background: transparent;
}

.play__time {
  display: inline-flex;
  align-items: baseline;
  gap: var(--sg-space-2);
}

.play__clock {
  font-size: var(--sg-font-size-lg);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.play__progress {
  color: var(--sg-color-text-muted);
  font-size: var(--sg-font-size-sm);
  font-variant-numeric: tabular-nums;
}

/* The key word of a solved Wordoku and what it means. */
.play__word {
  display: flex;
  flex-direction: column;
  gap: var(--sg-space-1);
  padding: var(--sg-space-2) var(--sg-space-3);
  border: 1px solid var(--sg-color-success);
  border-radius: var(--sg-radius-2);
  background: var(--sg-color-success-bg);
}

.play__word-title {
  color: var(--sg-color-text-muted);
  font-size: var(--sg-font-size-sm);
}

.play__word-text {
  color: var(--sg-color-success);
  font-size: var(--sg-font-size-xl);
  font-weight: 700;
  overflow-wrap: anywhere;
}

.play__word-other {
  color: var(--sg-color-text-muted);
  font-size: var(--sg-font-size-sm);
}

.play__pause {
  min-height: 2.75rem;
  font-weight: 700;
}

.play__reset {
  min-height: 2.75rem;
}

.play__reset.is-armed {
  border-color: var(--sg-color-danger);
  background: var(--sg-color-danger-bg);
  color: var(--sg-color-danger);
}

/* ---- Tools and number pad: touch targets of at least 44 px ---- */
.play__tools {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--sg-space-2);
}

.play__tool,
.play__key {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: var(--sg-space-1);
  border: 1px solid var(--sg-color-border);
  border-radius: var(--sg-radius-2);
  background: var(--sg-color-surface-2);
  color: var(--sg-color-text);
  font-weight: 600;
  line-height: 1.15;
  text-align: center;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  transition:
    background-color var(--sg-motion-fast) ease,
    border-color var(--sg-motion-fast) ease,
    color var(--sg-motion-fast) ease;
}

.play__tool {
  font-size: 0.75rem;
}

.play__tool .icon {
  width: 1.25rem;
  height: 1.25rem;
}

.play__tool-label {
  overflow-wrap: anywhere;
}

.play__tool:hover:not(:disabled),
.play__key:hover:not(:disabled) {
  background: var(--sg-color-hover);
}

.play__tool:active:not(:disabled),
.play__key:active:not(:disabled) {
  background: var(--sg-color-accent-soft);
}

.play__tool[aria-pressed="true"],
.play__key[aria-pressed="true"] {
  border-color: var(--sg-color-accent);
  background: var(--sg-color-accent);
  color: var(--sg-color-accent-text);
}

.play__tool:disabled,
.play__key:disabled {
  border-color: var(--sg-color-divider);
  color: var(--sg-color-text-muted);
  opacity: 0.6;
  cursor: not-allowed;
}

.play__pad {
  display: grid;
  grid-template-columns: repeat(var(--play-pad-cols, 9), minmax(0, 1fr));
  gap: var(--sg-space-2);
}

.play__key {
  font-size: 1.375rem;
  font-variant-numeric: tabular-nums;
}

/* Notes mode: the pad is dashed, so the mode shows without relying on colour alone. */
.play__pad.is-notes .play__key {
  border-style: dashed;
  font-size: 1.125rem;
  font-weight: 500;
}

.play__key .sgb-sw {
  width: 1.75rem;
  height: 1.75rem;
}

/* ---- Hints ---- */
.play__hint {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  gap: var(--sg-space-2);
  padding: var(--sg-space-3);
  border: 1px solid var(--sg-board-technique);
  border-radius: var(--sg-radius-2);
  background: var(--sg-color-surface);
}

/* The tint of the hint card is a translucent layer of the technique colour behind the content. */
.play__hint::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--sg-board-technique);
  opacity: 0.09;
  pointer-events: none;
}

.play__hint-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sg-space-2);
  padding-inline-end: 1.75rem;
}

.play__hint-close {
  position: absolute;
  top: var(--sg-space-1);
  inset-inline-end: var(--sg-space-1);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  border-radius: var(--sg-radius-2);
  background: transparent;
  color: var(--sg-color-text-muted);
  cursor: pointer;
}

.play__hint-close .icon {
  width: 0.875rem;
  height: 0.875rem;
}

.play__hint-close:hover {
  background: var(--sg-color-hover);
  color: var(--sg-color-text);
}

.play__hint-title {
  font-size: var(--sg-font-size-lg);
}

.play__hint-desc {
  color: var(--sg-color-text-muted);
  font-size: var(--sg-font-size-sm);
}

.play__hint-line {
  font-size: var(--sg-font-size-sm);
}

.play__hint-action {
  font-weight: 700;
}

.play__hint-note {
  color: var(--sg-color-warning);
  font-size: var(--sg-font-size-sm);
}

.play__hint-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sg-space-2);
}

.play__hint-buttons .btn {
  min-height: 2.75rem;
}

/* ---- Options frame (side panel): a disclosure, closed at first ---- */
.play__options {
  border-radius: var(--sg-radius-3);
  background: var(--sg-color-surface);
  box-shadow: var(--sg-shadow-1);
}

.play__options-body {
  gap: var(--sg-space-4);
}

/* Choice groups of the frame (symbols, check mode): no frame of their own, one radio per line. */
.play__options .field-group {
  gap: var(--sg-space-2);
  padding: 0;
  border: 0;
}

.play__options .field-group__legend {
  float: left;
  width: 100%;
  margin-bottom: var(--sg-space-2);
  padding: 0;
}

.play__choices {
  display: flex;
  flex-direction: column;
  gap: var(--sg-space-2);
}

.play__choices .checkbox {
  min-height: 2rem;
  align-items: center;
}

.play__option-buttons {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--sg-space-2);
}

.play__option-buttons .btn {
  min-height: 2.75rem;
}

/* ---- The popup over the board: keys, Notes, Erase, Close, next to the selected cell ---- */
.play__popup {
  position: absolute;
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: var(--sg-space-2);
  padding: var(--sg-space-2);
  border: 1px solid var(--sg-color-border);
  border-radius: var(--sg-radius-3);
  background: var(--sg-color-surface);
  box-shadow: var(--sg-shadow-2);
}

.play__popup-pad {
  display: grid;
  grid-template-columns: repeat(var(--play-pad-cols, 3), minmax(2.75rem, 1fr));
  gap: var(--sg-space-1);
}

.play__popup-tools {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sg-space-1);
}

.play__pkey,
.play__ptool {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: var(--sg-space-1);
  border: 1px solid var(--sg-color-border);
  border-radius: var(--sg-radius-2);
  background: var(--sg-color-surface-2);
  color: var(--sg-color-text);
  font-size: 1.25rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}

.play__ptool {
  font-size: 1rem;
}

.play__ptool .icon {
  width: 1.25rem;
  height: 1.25rem;
}

.play__pkey .sgb-sw {
  width: 1.5rem;
  height: 1.5rem;
}

.play__pkey:hover:not(:disabled),
.play__ptool:hover:not(:disabled) {
  background: var(--sg-color-hover);
}

.play__pkey[aria-pressed="true"],
.play__ptool[aria-pressed="true"] {
  border-color: var(--sg-color-accent);
  background: var(--sg-color-accent);
  color: var(--sg-color-accent-text);
}

.play__popup-pad.is-notes .play__pkey {
  border-style: dashed;
  font-weight: 500;
}

.play__pkey:disabled,
.play__ptool:disabled {
  border-color: var(--sg-color-divider);
  color: var(--sg-color-text-muted);
  opacity: 0.6;
  cursor: not-allowed;
}

/* ---- Overlay layer inside the board SVG ---- */
.sgb.play-on {
  cursor: pointer;
}

.sgb .layer-play,
.sgb .layer-play * {
  pointer-events: none;
}

.sgb .layer-play .pl-bg,
.sgb .layer-play .pl-hint {
  fill: transparent;
  fill-opacity: 1;
  stroke: none;
}

.sgb .layer-play .is-peer .pl-bg {
  fill: var(--sg-board-selected);
  fill-opacity: 0.07;
}

.sgb .layer-play .is-same .pl-bg {
  fill: var(--sg-board-selected);
  fill-opacity: 0.2;
}

.sgb .layer-play .is-sel .pl-bg {
  fill: var(--sg-board-selected-fill);
  fill-opacity: 1;
}

.sgb .layer-play .is-conflict .pl-bg {
  fill: var(--sg-color-danger);
  fill-opacity: 0.22;
  stroke: var(--sg-color-danger);
  stroke-width: 2;
  stroke-dasharray: 5 3;
}

.sgb .layer-play .is-wrong .pl-bg {
  fill: var(--sg-color-danger);
  fill-opacity: 0.34;
  stroke: var(--sg-color-danger);
  stroke-width: 2.5;
  stroke-dasharray: none;
}

/* After the conflict rules: a selected conflict keeps its red fill but shows the selection outline. */
.sgb .layer-play .is-sel .pl-bg {
  stroke: var(--sg-board-selected);
  stroke-width: 3;
  stroke-dasharray: none;
}

.sgb .layer-play .is-hint-region .pl-hint {
  fill: var(--sg-board-technique);
  fill-opacity: 0.09;
}

.sgb .layer-play .is-hint-cell .pl-hint {
  fill: var(--sg-board-technique-fill);
  fill-opacity: 1;
  stroke: var(--sg-board-technique);
  stroke-width: 2;
}

.sgb .layer-play .is-hint-target .pl-hint {
  fill: var(--sg-board-technique);
  fill-opacity: 0.32;
  stroke: var(--sg-board-technique);
  stroke-width: 3.5;
}

.sgb .layer-play .pl-val {
  fill: var(--sg-board-ink-placed);
  font-family: var(--sg-font-family);
  font-weight: var(--sg-board-weight-placed);
  text-anchor: middle;
}

.sgb .layer-play .pl-val--l2 { font-size: 0.78em; }
.sgb .layer-play .pl-val--l3 { font-size: 0.6em; }

.sgb .layer-play .is-conflict .pl-val,
.sgb .layer-play .is-wrong .pl-val {
  fill: var(--sg-color-danger);
  font-weight: 700;
}

.sgb .layer-play .is-conflict .sym--placed,
.sgb .layer-play .is-wrong .sym--placed {
  fill: var(--sg-color-danger);
}

.sgb .layer-play .pl-note {
  fill: var(--sg-board-ink-coord);
  font-family: var(--sg-font-family);
  font-weight: 600;
  text-anchor: middle;
}

.sgb .layer-play .pl-note-sym {
  fill: var(--sg-board-ink-coord);
}

.sgb .layer-play .pl-note.is-elim {
  fill: var(--sg-color-danger);
  text-decoration: line-through;
}

/* The digit a hint puts in a cell (Help page examples, and the notes of that cell). */
.sgb .layer-play .pl-note.is-keep {
  fill: var(--sg-board-technique);
  font-weight: 800;
}

.sgb .layer-play .pl-note-fill {
  stroke: var(--sg-board-sym-edge);
  stroke-width: 0.6;
}

.sgb .layer-play .pl-note-fill.is-elim {
  stroke: var(--sg-color-danger);
  stroke-width: 1.4;
}

.sgb .layer-play.is-paused .pl-content {
  visibility: hidden;
}

/*
 * Small screens (the breakpoint of Sudoku Generator): smaller buttons, and the tools and the pad are always
 * on screen, fixed to the bottom. There is no popup over the board. Last, so it wins over the rules above.
 */
@media (max-width: 767.98px) {
  /* The frame would be empty (the keys are fixed to the bottom): it is only the toggle, the actions and the
     hint card in the flow. */
  .play__panel:not([hidden]) {
    display: contents;
  }

  .play__keys {
    position: fixed;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 50;
    gap: var(--sg-space-2);
    padding: var(--sg-space-2) var(--sg-space-3) calc(var(--sg-space-2) + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--sg-color-border);
    background: var(--sg-color-surface);
    box-shadow: var(--sg-shadow-2);
  }

  .play__tools {
    gap: var(--sg-space-1);
  }

  .play__pad {
    grid-template-columns: repeat(var(--play-pad-cols-mobile, 9), minmax(0, 1fr));
    gap: var(--sg-space-1);
  }

  .play__tool,
  .play__key {
    min-width: 0;
    min-height: 2.25rem;
    padding: 2px;
  }

  .play__tool {
    gap: 0;
    font-size: 0.625rem;
  }

  .play__tool .icon {
    width: 1rem;
    height: 1rem;
  }

  .play__key {
    font-size: 1.125rem;
  }

  .play__pad.is-notes .play__key {
    font-size: 1rem;
  }

  .play__key .sgb-sw {
    width: 1.25rem;
    height: 1.25rem;
  }

  .play__pause,
  .play__reset,
  .play__hint-buttons .btn,
  .play__option-buttons .btn {
    min-height: 2.25rem;
  }

  .play__more .play__option-buttons {
    flex-direction: row;
  }

  .play__more .play__option-buttons .btn {
    flex: 1 1 0;
    min-width: 0;
  }

  .play__popup {
    display: none;
  }

  /* The game buttons sit on the left of the row of Share and Import (play.js moves them there, see
     placeStatus); the status box is the next line. */
  .main-actions .play__controls {
    margin-inline-end: auto;
  }

  .main-head > .play__status {
    order: -1;
    flex: 1 1 100%;
    margin-block-end: var(--sg-space-2);
  }

  /* The status box above the puzzle: time, progress and the status line, small and without a frame. */
  .play__status {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0 var(--sg-space-3);
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
  }

  .play__clock {
    font-size: var(--sg-font-size-base);
  }

  .play__progress,
  .play__status .status-row,
  .play__status .status-row__label {
    font-size: var(--sg-font-size-sm);
  }

  .play__status .status-row {
    flex: 1 1 100%;
    padding: 0;
    border-top: 0;
  }
}

/* ---- Forced colours: system colours for the states the tints would lose ---- */
@media (forced-colors: active) {
  .play__tool,
  .play__key,
  .play__hint {
    border-color: ButtonText;
  }

  .play__tool[aria-pressed="true"],
  .play__key[aria-pressed="true"],
  .play__pause[aria-pressed="true"] {
    border-color: Highlight;
    background: Highlight;
    color: HighlightText;
    forced-color-adjust: none;
  }

  .play__tool:disabled,
  .play__key:disabled {
    border-color: GrayText;
    color: GrayText;
    opacity: 1;
  }

  .sgb .layer-play .is-sel .pl-bg {
    fill: Highlight;
    fill-opacity: 0.35;
    stroke: Highlight;
  }

  .sgb .layer-play .is-conflict .pl-bg,
  .sgb .layer-play .is-wrong .pl-bg {
    stroke: LinkText;
  }

  .sgb .layer-play .is-hint-cell .pl-hint,
  .sgb .layer-play .is-hint-target .pl-hint {
    stroke: Mark;
  }

  .sgb .layer-play .pl-val,
  .sgb .layer-play .pl-note {
    fill: CanvasText;
  }
}
