/* ========================================================= 🔧 Controls (tweak these) ========================================================= */ :root { --cell-size: 96px; --cell-font-size: 48px; --grid-gap: 6px; --box-separator: 9px; } /* ========================================================= Container & Grid Base ========================================================= */ #sudoku_container { position: relative; margin: 1em auto; width: fit-content; } #sudoku { position: relative; background-color: var(--card, #1e2030); border-radius: 0.5rem; box-shadow: 0 0 10px rgba(27, 29, 43, 0.6), inset 0 0 6px rgba(130, 170, 255, 0.05); padding: 0.5rem; width: fit-content; } /* ========================================================= Grid Layout ========================================================= */ #sudoku .sudoku-grid { display: grid; grid-template-columns: var(--cell-size) var(--cell-size) var(--cell-size) var(--cell-size) var(--cell-size) var(--cell-size) var(--cell-size) var(--cell-size) var(--cell-size); grid-template-rows: var(--cell-size) var(--cell-size) var(--cell-size) var(--cell-size) var(--cell-size) var(--cell-size) var(--cell-size) var(--cell-size) var(--cell-size); column-gap: var(--grid-gap); row-gap: var(--grid-gap); user-select: none; } /* ========================================================= Cell Base Styles ========================================================= */ #sudoku .sudoku-cell { width: var(--cell-size); height: var(--cell-size); display: flex; align-items: center; justify-content: center; border-radius: 4px; font-family: "Fira Code", monospace; font-size: var(--cell-font-size); background: var(--muted, #2f334d); color: var(--foreground, #c8d3f5); transition: all 0.15s ease; box-shadow: inset 0 0 3px rgba(27, 29, 43, 0.4); } /* ========================================================= 3x3 Box Separators ========================================================= */ /* Right borders (end of each 3x3 box horizontally) */ #sudoku .sudoku-cell[data-c="2"], #sudoku .sudoku-cell[data-c="5"], #sudoku .sudoku-cell[data-c="8"] { border-right: 2px solid color-mix(in srgb, var(--primary, #82aaff) 30%, transparent); } /* Left borders (start of each 3x3 box horizontally) */ #sudoku .sudoku-cell[data-c="0"], #sudoku .sudoku-cell[data-c="3"], #sudoku .sudoku-cell[data-c="6"] { border-left: 2px solid color-mix(in srgb, var(--primary, #82aaff) 30%, transparent); } /* Bottom borders (end of each 3x3 box vertically) */ #sudoku .sudoku-cell[data-r="2"], #sudoku .sudoku-cell[data-r="5"], #sudoku .sudoku-cell[data-r="8"] { border-bottom: 2px solid color-mix(in srgb, var(--primary, #82aaff) 30%, transparent); } /* Top borders (start of each 3x3 box vertically) */ #sudoku .sudoku-cell[data-r="0"], #sudoku .sudoku-cell[data-r="3"], #sudoku .sudoku-cell[data-r="6"] { border-top: 2px solid color-mix(in srgb, var(--primary, #82aaff) 30%, transparent); } /* ========================================================= User-Entered Cells ========================================================= */ #sudoku .sudoku-cell.user-entered { color: var(--primary, #82aaff); font-weight: 600; } /* ========================================================= Active Cell Highlight (Navigation Mode) ========================================================= */ #sudoku .sudoku-cell.active { outline: 2px solid var(--primary, #82aaff); outline-offset: -2px; background: color-mix(in srgb, var(--primary, #82aaff) 20%, var(--muted, #2f334d)); box-shadow: 0 0 8px color-mix(in srgb, var(--primary, #82aaff) 40%, transparent), 0 0 12px color-mix(in srgb, var(--primary, #82aaff) 20%, transparent), inset 0 0 6px color-mix(in srgb, var(--primary, #82aaff) 15%, transparent); } /* ========================================================= Editing Cell Highlight (Edit Mode) ========================================================= */ #sudoku .sudoku-cell.editing { outline: 2px solid var(--accent, #ffc777); outline-offset: -2px; background: color-mix(in srgb, var(--accent, #ffc777) 15%, var(--muted, #2f334d)); box-shadow: 0 0 16px color-mix(in srgb, var(--accent, #ffc777) 70%, transparent), 0 0 24px color-mix(in srgb, var(--accent, #ffc777) 40%, transparent), inset 0 0 12px color-mix(in srgb, var(--accent, #ffc777) 30%, transparent); animation: editing-cell-glow 1.5s ease-in-out infinite; } @keyframes editing-cell-glow { 0%, 100% { box-shadow: 0 0 16px color-mix(in srgb, var(--accent, #ffc777) 70%, transparent), 0 0 24px color-mix(in srgb, var(--accent, #ffc777) 40%, transparent), inset 0 0 12px color-mix(in srgb, var(--accent, #ffc777) 30%, transparent); } 50% { box-shadow: 0 0 20px color-mix(in srgb, var(--accent, #ffc777) 90%, transparent), 0 0 32px color-mix(in srgb, var(--accent, #ffc777) 60%, transparent), inset 0 0 16px color-mix(in srgb, var(--accent, #ffc777) 40%, transparent); } } /* ========================================================= Visual Feedback Effects ========================================================= */ /* Invalid move effect */ #sudoku .sudoku-cell.invalid-move { animation: sudoku-invalid-pulse 180ms ease-out; box-shadow: 0 0 12px color-mix(in srgb, var(--destructive, #c53b53) 85%, transparent), 0 0 24px color-mix(in srgb, var(--destructive, #c53b53) 45%, transparent); } @keyframes sudoku-invalid-pulse { 0% { transform: scale(1.05); box-shadow: 0 0 16px color-mix(in srgb, var(--destructive, #c53b53) 95%, transparent), 0 0 28px color-mix(in srgb, var(--destructive, #c53b53) 55%, transparent); } 100% { transform: none; box-shadow: none; } } /* Locked cell effect (pre-filled clues) */ #sudoku .sudoku-cell.locked-cell { animation: sudoku-locked-pulse 300ms ease-out; } @keyframes sudoku-locked-pulse { 0% { transform: scale(1.08); background: rgba(255, 85, 85, 0.3); box-shadow: 0 0 20px rgba(255, 85, 85, 0.9), 0 0 32px rgba(255, 85, 85, 0.6), inset 0 0 16px rgba(255, 85, 85, 0.4); } 50% { transform: scale(1.05); background: rgba(255, 85, 85, 0.2); box-shadow: 0 0 16px rgba(255, 85, 85, 0.8), 0 0 28px rgba(255, 85, 85, 0.5), inset 0 0 12px rgba(255, 85, 85, 0.3); } 100% { transform: none; background: transparent; box-shadow: none; } } /* Trail effect for moves */ #sudoku .sudoku-cell.trail { box-shadow: inset 0 0 6px color-mix(in srgb, var(--primary, #82aaff) 60%, transparent), 0 0 6px color-mix(in srgb, var(--primary, #82aaff) 35%, transparent); animation: sudoku-trail-fade 220ms ease-out; } @keyframes sudoku-trail-fade { from { background-color: color-mix(in srgb, var(--primary, #82aaff) 25%, transparent); } to { background-color: transparent; } } /* Valid move flash */ #sudoku .sudoku-cell.valid-move { animation: sudoku-valid-flash 300ms ease-out; } @keyframes sudoku-valid-flash { 0% { background: color-mix(in srgb, var(--success, #4fd6be) 40%, transparent); box-shadow: 0 0 12px color-mix(in srgb, var(--success, #4fd6be) 80%, transparent), 0 0 20px color-mix(in srgb, var(--success, #4fd6be) 50%, transparent), inset 0 0 8px color-mix(in srgb, var(--success, #4fd6be) 35%, transparent); } 100% { background: transparent; box-shadow: none; } } /* Conflict highlighting */ #sudoku .sudoku-cell.conflict { outline: 2px solid var(--destructive, #c53b53); outline-offset: -2px; background: color-mix(in srgb, var(--destructive, #c53b53) 25%, var(--muted, #2f334d)); box-shadow: 0 0 10px color-mix(in srgb, var(--destructive, #c53b53) 70%, transparent), 0 0 18px color-mix(in srgb, var(--destructive, #c53b53) 40%, transparent), inset 0 0 8px color-mix(in srgb, var(--destructive, #c53b53) 30%, transparent); animation: sudoku-conflict-pulse 1s ease-in-out infinite; } @keyframes sudoku-conflict-pulse { 0%, 100% { box-shadow: 0 0 10px color-mix(in srgb, var(--destructive, #c53b53) 70%, transparent), 0 0 18px color-mix(in srgb, var(--destructive, #c53b53) 40%, transparent), inset 0 0 8px color-mix(in srgb, var(--destructive, #c53b53) 30%, transparent); } 50% { box-shadow: 0 0 14px color-mix(in srgb, var(--destructive, #c53b53) 85%, transparent), 0 0 24px color-mix(in srgb, var(--destructive, #c53b53) 55%, transparent), inset 0 0 12px color-mix(in srgb, var(--destructive, #c53b53) 40%, transparent); } }