<div>
  <h1>Sudoku Fun with CSS</h1>
  <p>Figuring out how to select similar cells with just CSS.</p>
  <p>Long live :has</p>
  <p>Click on a cell to see it in action. (not playable yet, since this really was just to try and setup the CSS grid and blocking out non-viable cells.)</p>
</div>
<!-- static -->
<div class="sudoku">
  <div class="cell original" data-sudoku-row="1" data-sudoku-box="1" data-sudoku-col="1" data-sudoku-cell-is-number="1">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">1</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="1" data-sudoku-box="1" data-sudoku-col="2" data-sudoku-cell-is-number="7">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">7</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="1" data-sudoku-box="1" data-sudoku-col="3" data-sudoku-cell-is-number="8">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">8</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="1" data-sudoku-box="2" data-sudoku-col="4">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value"></span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="1" data-sudoku-box="2" data-sudoku-col="5">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value"></span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="1" data-sudoku-box="2" data-sudoku-col="6" data-sudoku-cell-is-number="3">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">3</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="1" data-sudoku-box="3" data-sudoku-col="7" data-sudoku-cell-is-number="2">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">2</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="1" data-sudoku-box="3" data-sudoku-col="8" data-sudoku-cell-is-number="6">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">6</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="1" data-sudoku-box="3" data-sudoku-col="9" data-sudoku-cell-is-number="9">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">9</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="2" data-sudoku-box="1" data-sudoku-col="1" data-sudoku-cell-is-number="4">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">4</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="2" data-sudoku-box="1" data-sudoku-col="2" data-sudoku-cell-is-number="2">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">2</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="2" data-sudoku-box="1" data-sudoku-col="3" data-sudoku-cell-is-number="6">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">6</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="2" data-sudoku-box="2" data-sudoku-col="4" data-sudoku-cell-is-number="1">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">1</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="2" data-sudoku-box="2" data-sudoku-col="5">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value"></span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="2" data-sudoku-box="2" data-sudoku-col="6" data-sudoku-cell-is-number="9">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">9</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="2" data-sudoku-box="3" data-sudoku-col="7" data-sudoku-cell-is-number="7">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">7</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="2" data-sudoku-box="3" data-sudoku-col="8" data-sudoku-cell-is-number="5">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">5</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="2" data-sudoku-box="3" data-sudoku-col="9" data-sudoku-cell-is-number="3">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">3</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="3" data-sudoku-box="1" data-sudoku-col="1" data-sudoku-cell-is-number="5">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">5</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="3" data-sudoku-box="1" data-sudoku-col="2" data-sudoku-cell-is-number="3">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">3</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="3" data-sudoku-box="1" data-sudoku-col="3" data-sudoku-cell-is-number="9">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">9</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="3" data-sudoku-box="2" data-sudoku-col="4" data-sudoku-cell-is-number="6">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">6</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="3" data-sudoku-box="2" data-sudoku-col="5" data-sudoku-cell-is-number="2">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">2</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="3" data-sudoku-box="2" data-sudoku-col="6" data-sudoku-cell-is-number="7">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">7</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="3" data-sudoku-box="3" data-sudoku-col="7" data-sudoku-cell-is-number="8">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">8</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="3" data-sudoku-box="3" data-sudoku-col="8" data-sudoku-cell-is-number="1">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">1</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="3" data-sudoku-box="3" data-sudoku-col="9" data-sudoku-cell-is-number="4">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">4</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="4" data-sudoku-box="4" data-sudoku-col="1" data-sudoku-cell-is-number="3">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">3</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="4" data-sudoku-box="4" data-sudoku-col="2" data-sudoku-cell-is-number="8">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">8</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="4" data-sudoku-box="4" data-sudoku-col="3" data-sudoku-cell-is-number="1">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">1</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="4" data-sudoku-box="5" data-sudoku-col="4" data-sudoku-cell-is-number="7">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">7</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="4" data-sudoku-box="5" data-sudoku-col="5" data-sudoku-cell-is-number="5">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">5</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="4" data-sudoku-box="5" data-sudoku-col="6" data-sudoku-cell-is-number="4">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">4</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="4" data-sudoku-box="6" data-sudoku-col="7" data-sudoku-cell-is-number="9">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">9</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="4" data-sudoku-box="6" data-sudoku-col="8" data-sudoku-cell-is-number="2">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">2</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="4" data-sudoku-box="6" data-sudoku-col="9" data-sudoku-cell-is-number="6">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">6</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="5" data-sudoku-box="4" data-sudoku-col="1" data-sudoku-cell-is-number="7">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">7</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="5" data-sudoku-box="4" data-sudoku-col="2" data-sudoku-cell-is-number="6">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">6</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="5" data-sudoku-box="4" data-sudoku-col="3" data-sudoku-cell-is-number="5">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">5</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="5" data-sudoku-box="5" data-sudoku-col="4" data-sudoku-cell-is-number="2">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">2</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="5" data-sudoku-box="5" data-sudoku-col="5" data-sudoku-cell-is-number="9">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">9</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="5" data-sudoku-box="5" data-sudoku-col="6" data-sudoku-cell-is-number="8">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">8</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="5" data-sudoku-box="6" data-sudoku-col="7" data-sudoku-cell-is-number="4">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">4</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="5" data-sudoku-box="6" data-sudoku-col="8" data-sudoku-cell-is-number="3">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">3</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="5" data-sudoku-box="6" data-sudoku-col="9" data-sudoku-cell-is-number="1">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">1</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="6" data-sudoku-box="4" data-sudoku-col="1" data-sudoku-cell-is-number="2">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">2</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="6" data-sudoku-box="4" data-sudoku-col="2" data-sudoku-cell-is-number="9">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">9</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="6" data-sudoku-box="4" data-sudoku-col="3" data-sudoku-cell-is-number="4">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">4</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="6" data-sudoku-box="5" data-sudoku-col="4" data-sudoku-cell-is-number="3">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">3</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="6" data-sudoku-box="5" data-sudoku-col="5" data-sudoku-cell-is-number="6">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">6</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="6" data-sudoku-box="5" data-sudoku-col="6" data-sudoku-cell-is-number="1">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">1</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="6" data-sudoku-box="6" data-sudoku-col="7">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value"></span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="6" data-sudoku-box="6" data-sudoku-col="8" data-sudoku-cell-is-number="8">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">8</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="6" data-sudoku-box="6" data-sudoku-col="9" data-sudoku-cell-is-number="7">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">7</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="7" data-sudoku-box="7" data-sudoku-col="1" data-sudoku-cell-is-number="9">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">9</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="7" data-sudoku-box="7" data-sudoku-col="2" data-sudoku-cell-is-number="4">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">4</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="7" data-sudoku-box="7" data-sudoku-col="3" data-sudoku-cell-is-number="2">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">2</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="7" data-sudoku-box="8" data-sudoku-col="4" data-sudoku-cell-is-number="8">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">8</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="7" data-sudoku-box="8" data-sudoku-col="5">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value"></span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="7" data-sudoku-box="8" data-sudoku-col="6" data-sudoku-cell-is-number="6">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">6</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="7" data-sudoku-box="9" data-sudoku-col="7" data-sudoku-cell-is-number="1">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">1</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="7" data-sudoku-box="9" data-sudoku-col="8" data-sudoku-cell-is-number="7">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">7</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="7" data-sudoku-box="9" data-sudoku-col="9" data-sudoku-cell-is-number="5">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">5</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="8" data-sudoku-box="7" data-sudoku-col="1" data-sudoku-cell-is-number="8">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">8</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="8" data-sudoku-box="7" data-sudoku-col="2">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value"></span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="8" data-sudoku-box="7" data-sudoku-col="3">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value"></span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="8" data-sudoku-box="8" data-sudoku-col="4" data-sudoku-cell-is-number="9">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">9</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="8" data-sudoku-box="8" data-sudoku-col="5" data-sudoku-cell-is-number="7">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">7</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="8" data-sudoku-box="8" data-sudoku-col="6" data-sudoku-cell-is-number="5">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">5</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="8" data-sudoku-box="9" data-sudoku-col="7">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value"></span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="8" data-sudoku-box="9" data-sudoku-col="8" data-sudoku-cell-is-number="4">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">4</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="8" data-sudoku-box="9" data-sudoku-col="9" data-sudoku-cell-is-number="2">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">2</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="9" data-sudoku-box="7" data-sudoku-col="1" data-sudoku-cell-is-number="6">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">6</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="9" data-sudoku-box="7" data-sudoku-col="2" data-sudoku-cell-is-number="5">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">5</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="9" data-sudoku-box="7" data-sudoku-col="3" data-sudoku-cell-is-number="7">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">7</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="9" data-sudoku-box="8" data-sudoku-col="4" data-sudoku-cell-is-number="4">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">4</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="9" data-sudoku-box="8" data-sudoku-col="5" data-sudoku-cell-is-number="1">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">1</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="9" data-sudoku-box="8" data-sudoku-col="6" data-sudoku-cell-is-number="2">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">2</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="9" data-sudoku-box="9" data-sudoku-col="7" data-sudoku-cell-is-number="3">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">3</span>
    </label>
  </div>
  <div class="cell solution" data-sudoku-row="9" data-sudoku-box="9" data-sudoku-col="8" data-sudoku-cell-is-number="9">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden">
      <span class="value">9</span>
    </label>
  </div>
  <div class="cell original" data-sudoku-row="9" data-sudoku-box="9" data-sudoku-col="9" data-sudoku-cell-is-number="8">
    <label>
      <input type="number" aria-hidden="true" class="visually-hidden" readonly="">
      <span class="value">8</span>
    </label>
  </div>
</div>

<template id="sudokuCellTemplate">
  <div class="cell">
    <label>
      <input type="number" aria-hidden=true class="visually-hidden">
      <span class="value"></span>
    </label>
  </div>
</template>
<div class="sudoku" data-sudoku></div>
@layer page, sudoku;

:root {
  --c-text-input: blue;
  --c-selected: red;
  --c-selected--secondary: color-mix(in srgb, var(--c-selected) 15%, white);
  --c-selected--same-num: color-mix(in srgb, var(--c-selected) 30%, white);
  --num-font-size: 3rem;
  --s-grid-height: 80vh;
  --s-grid-line: 1px;
  --s-grid-line--bold: 5px;
}

@layer sudoku {
  .value {
    display: block;
    text-align: center;
    width: 100%;
    background: var(--_c-cell-bg, white);
    font-size: var(--num-font-size);
    height: 100%;
    align-content: center;
  }

  .sudoku {
    display: grid;
    grid-template-columns: repeat(9, 1fr);
    grid-template-rows: repeat(9, 1fr);
    aspect-ratio: 1/1;
    max-width: var(--s-grid-height);
    gap: var(--s-grid-line);
    background: black;
    padding: var(--s-grid-line--bold);
  }

  .cell {
    box-sizing: border-box;
    width: 100%;

    &:nth-of-type(3n):not(:nth-of-type(9n)) {
      padding-right: calc(var(--s-grid-line--bold) - var(--s-grid-line));
    }
    &:nth-child(n + 19):nth-child(-n + 27) {
      padding-bottom: calc(var(--s-grid-line--bold) - var(--s-grid-line));
    }
    &:nth-child(n + 55):nth-child(-n + 63) {
      padding-top: calc(var(--s-grid-line--bold) - var(--s-grid-line));
    }

    label:focus-within {
      --_c-cell-bg: var(--c-selected);
    }
  }

  @mixin secondary-select-highlight($data-attr, $cell-bg) {
    .sudoku:has(.cell[#{$data-attr}] label:focus-within) {
      [#{$data-attr}] {
        label:not(:focus-within) {
          --_c-cell-bg: #{$cell-bg};
        }
      }
    }
  }

  @for $i from 1 through 9 {
    @include secondary-select-highlight(
      'data-sudoku-row="#{$i}"',
      var(--c-selected--secondary)
    );
    @include secondary-select-highlight(
      'data-sudoku-col="#{$i}"',
      var(--c-selected--secondary)
    );
    @include secondary-select-highlight(
      'data-sudoku-box="#{$i}"',
      var(--c-selected--secondary)
    );
    @include secondary-select-highlight(
      'data-sudoku-cell-is-number="#{$i}"',
      var(--c-selected--same-num)
    );
  }

  .solution {
    color: var(--c-text-input);
  }
}

// demo stuff
@layer page {
  * {
    box-sizing: border-box;
  }

  body {
    padding: 5vh;
    font-family: Arial, sans-serif;
    font-weight: bold;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
    gap: 30px;
  }

  label {
    height: 100%;
    display: block;
  }

  .visually-hidden {
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    height: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
    width: 1px;
  }
}
View Compiled
// currently not playable, as it's just solving so far and highlighting stuff.

// empty cell
const x = null;

const emptySudoku = [
  [x, x, x, x, x, x, x, x, x],
  [x, x, x, x, x, x, x, x, x],
  [x, x, x, x, x, x, x, x, x],
  [x, x, x, x, x, x, x, x, x],
  [x, x, x, x, x, x, x, x, x],
  [x, x, x, x, x, x, x, x, x],
  [x, x, x, x, x, x, x, x, x],
  [x, x, x, x, x, x, x, x, x],
  [x, x, x, x, x, x, x, x, x]
];

// easy from NYT
const sampleSudoku = [
  [1, 7, 8, x, x, 3, 2, 6, x],
  [4, 2, x, 1, x, x, 7, x, x],
  [x, 3, x, 6, x, 7, 8, 1, x],
  [x, x, x, x, 5, 4, x, 2, 6],
  [7, x, 5, x, x, 8, 4, 3, x],
  [x, x, 4, x, 6, x, x, 8, x],
  [9, x, 2, x, x, x, 1, x, 5],
  [8, x, x, 9, 7, x, x, x, x],
  [x, 5, 7, x, 1, x, x, x, 8]
];

function isValid(sudoku, row, col, num) {
  for (let x = 0; x < 9; x++) {
    const boxRow = 3 * Math.floor(row / 3) + Math.floor(x / 3);
    const boxCol = 3 * Math.floor(col / 3) + (x % 3);
    if (
      sudoku[row][x] === num ||
      sudoku[x][col] === num ||
      sudoku[boxRow][boxCol] === num
    ) {
      return false;
    }
  }
  return true;
}

function deepCopySudoku(sudoku) {
  return sudoku.map((row) => [...row]);
}

function solveSudoku(sudoku) {
  for (let row = 0; row < 9; row++) {
    for (let col = 0; col < 9; col++) {
      if (sudoku[row][col] === null) {
        for (let num = 1; num <= 9; num++) {
          if (isValid(sudoku, row, col, num)) {
            sudoku[row][col] = num;
            if (solveSudoku(sudoku)) {
              return sudoku;
            }
            sudoku[row][col] = null;
          }
        }
        return null;
      }
    }
  }
  return sudoku;
}

const sudokuCopy = deepCopySudoku(sampleSudoku);
const solution = solveSudoku(sudokuCopy);

function getBoxIndex(row, col) {
  return Math.floor(row / 3) * 3 + Math.floor(col / 3);
}

const sudokuContainer = document.querySelector("[data-sudoku]");
const template = document.getElementById("sudokuCellTemplate");

solution.forEach((row, rowIndex) => {
  row.forEach((cell, cellIndex) => {
    const isOriginal = sampleSudoku[rowIndex][cellIndex] !== null;

    // Clone the template content
    const cellElement = template.content.cloneNode(true).querySelector("div");

    const inputElement = cellElement.querySelector("input");
    const labelElement = cellElement.querySelector("label");

    const gridBox =
      Math.floor(rowIndex / 3) * 3 + Math.floor(cellIndex / 3) + 1;
    const gridRow = rowIndex + 1;
    const gridCol = cellIndex + 1;

    if (isOriginal) {
      cellElement.classList.add("original");
    } else {
      cellElement.classList.add("solution");
    }

    cellElement.setAttribute("data-sudoku-row", gridRow);
    cellElement.setAttribute("data-sudoku-box", gridBox);
    cellElement.setAttribute("data-sudoku-col", gridCol);
    cellElement.setAttribute("data-sudoku-cell-is-number", cell);

    labelElement.querySelector(".value").innerText = cell;
    inputElement.value = cell;
    inputElement.readOnly = isOriginal;

    sudokuContainer.appendChild(cellElement);
  });
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.