diff --git a/api/pexels.php b/api/pexels.php new file mode 100644 index 0000000..9816ad1 --- /dev/null +++ b/api/pexels.php @@ -0,0 +1,29 @@ + 'assets/images/pexels/'.$p['id'].'.jpg', + 'photographer' => $p['photographer'] ?? 'Unknown', + 'photographer_url' => $p['photographer_url'] ?? '', + ]; + } else { + // Fallback: Picsum + $out[] = [ + 'src' => 'https://picsum.photos/600?random=' . rand(1,1000), + 'photographer' => 'Random Picsum', + 'photographer_url' => 'https://picsum.photos/' + ]; + } +} +echo json_encode($out); +?> \ No newline at end of file diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..c926c75 --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,188 @@ +@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&family=Roboto:wght@300;400&display=swap'); + +:root { + --primary-color: #BDE0FE; /* Baby Blue Eyes */ + --accent-color: #FFC8B2; /* Pastel Peach */ + --background-color: #FFFBF7; /* Very light, warm off-white */ + --text-color: #6D6875; /* Muted, soft gray */ + --surface-color: #FFFFFF; + --board-bg: #A3C4F3; + --cell-bg: #EAF4F4; + --border-radius: 1rem; +} + +body { + background-color: var(--background-color); + color: var(--text-color); + font-family: 'Roboto', sans-serif; + font-weight: 300; +} + +h1, h2, h3, h4, h5, h6 { + font-family: 'Poppins', sans-serif; + font-weight: 700; + color: var(--text-color); +} + +.navbar { + background-color: var(--surface-color) !important; + box-shadow: 0 2px 10px rgba(0,0,0,0.05) !important; +} + +.navbar-brand { + font-family: 'Poppins', sans-serif; + font-weight: 700; + color: var(--primary-color) !important; +} + +.hero { + background: linear-gradient(135deg, var(--primary-color) 0%, var(--accent-color) 100%); + color: white; + padding: 6rem 0; + text-align: center; + border-bottom-left-radius: var(--border-radius); + border-bottom-right-radius: var(--border-radius); +} + +.hero h1 { + font-size: 3.5rem; + font-weight: 700; + color: white; + text-shadow: 1px 1px 3px rgba(0,0,0,0.1); +} + +.btn-primary { + background-color: var(--accent-color); + border-color: var(--accent-color); + border-radius: var(--border-radius); + padding: 0.75rem 1.5rem; + font-weight: 700; + color: white; + transition: all 0.3s ease; + box-shadow: 0 4px 15px rgba(0,0,0,0.1); +} + +.btn-primary:hover { + background-color: white; + border-color: white; + color: var(--accent-color); + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(0,0,0,0.15); +} + +#game-section { + padding: 4rem 0; +} + +.game-board { + display: grid; + gap: 10px; + width: 100%; + max-width: 500px; + margin: 2rem auto; + background-color: var(--board-bg); + border: 5px solid var(--board-bg); + border-radius: var(--border-radius); + padding: 10px; +} + +.game-cell { + width: 100%; + padding-bottom: 100%; + position: relative; + background-color: var(--cell-bg); + border-radius: 0.75rem; + cursor: pointer; + transition: all 0.3s ease; +} + +.game-cell:hover { + transform: scale(1.05); + box-shadow: 0 4px 10px rgba(0,0,0,0.1); +} + +.game-cell .symbol { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 1rem; /* Default for large boards */ + font-weight: 400; + user-select: none; +} + +/* Board-size specific adjustments */ +.game-board.size-5 { + gap: 10px; +} +.game-board.size-5 .game-cell .symbol { + font-size: 2.5rem; +} + +.game-board.size-18, +.game-board.size-36 { + gap: 2px; + padding: 2px; + border-width: 2px; +} + +#gallery-section { + padding: 4rem 0; + background-color: var(--primary-color-light); +} + +.cat-gallery { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 1.5rem; +} + +.cat-gallery-item { + border-radius: var(--border-radius); + overflow: hidden; + box-shadow: 0 4px 15px rgba(0,0,0,0.1); + transition: all 0.3s ease; + position: relative; +} + +.cat-gallery-item:hover { + transform: translateY(-5px) scale(1.03); + box-shadow: 0 8px 25px rgba(0,0,0,0.15); +} + +.cat-gallery-item img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.cat-gallery-item .photographer-credit { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: rgba(0,0,0,0.5); + color: white; + padding: 0.5rem; + text-align: center; + font-size: 0.8rem; + opacity: 0; + transition: opacity 0.3s ease; +} + +.cat-gallery-item:hover .photographer-credit { + opacity: 1; +} + +.cat-gallery-item .photographer-credit a { + color: var(--accent-color); + text-decoration: none; +} + + + +footer { + background-color: var(--text-color); + color: white; + padding: 2rem 0; +} \ No newline at end of file diff --git a/assets/images/pexels/10914511.jpg b/assets/images/pexels/10914511.jpg new file mode 100644 index 0000000..6fd30b6 Binary files /dev/null and b/assets/images/pexels/10914511.jpg differ diff --git a/assets/images/pexels/11163348.jpg b/assets/images/pexels/11163348.jpg new file mode 100644 index 0000000..49ec1aa Binary files /dev/null and b/assets/images/pexels/11163348.jpg differ diff --git a/assets/images/pexels/11497291.jpg b/assets/images/pexels/11497291.jpg new file mode 100644 index 0000000..0ad69c4 Binary files /dev/null and b/assets/images/pexels/11497291.jpg differ diff --git a/assets/images/pexels/12692139.jpg b/assets/images/pexels/12692139.jpg new file mode 100644 index 0000000..cb83e46 Binary files /dev/null and b/assets/images/pexels/12692139.jpg differ diff --git a/assets/images/pexels/12915730.jpg b/assets/images/pexels/12915730.jpg new file mode 100644 index 0000000..c59bc97 Binary files /dev/null and b/assets/images/pexels/12915730.jpg differ diff --git a/assets/images/pexels/14603745.jpg b/assets/images/pexels/14603745.jpg new file mode 100644 index 0000000..7a119c7 Binary files /dev/null and b/assets/images/pexels/14603745.jpg differ diff --git a/assets/images/pexels/14852082.jpg b/assets/images/pexels/14852082.jpg new file mode 100644 index 0000000..6405fcd Binary files /dev/null and b/assets/images/pexels/14852082.jpg differ diff --git a/assets/images/pexels/14904690.jpg b/assets/images/pexels/14904690.jpg new file mode 100644 index 0000000..b2d3728 Binary files /dev/null and b/assets/images/pexels/14904690.jpg differ diff --git a/assets/images/pexels/15208769.jpg b/assets/images/pexels/15208769.jpg new file mode 100644 index 0000000..5783a52 Binary files /dev/null and b/assets/images/pexels/15208769.jpg differ diff --git a/assets/images/pexels/160722.jpg b/assets/images/pexels/160722.jpg new file mode 100644 index 0000000..f5f73df Binary files /dev/null and b/assets/images/pexels/160722.jpg differ diff --git a/assets/images/pexels/160839.jpg b/assets/images/pexels/160839.jpg new file mode 100644 index 0000000..d9fea27 Binary files /dev/null and b/assets/images/pexels/160839.jpg differ diff --git a/assets/images/pexels/16282655.jpg b/assets/images/pexels/16282655.jpg new file mode 100644 index 0000000..79c5cb5 Binary files /dev/null and b/assets/images/pexels/16282655.jpg differ diff --git a/assets/images/pexels/16482823.jpg b/assets/images/pexels/16482823.jpg new file mode 100644 index 0000000..400992c Binary files /dev/null and b/assets/images/pexels/16482823.jpg differ diff --git a/assets/images/pexels/16575029.jpg b/assets/images/pexels/16575029.jpg new file mode 100644 index 0000000..57cb693 Binary files /dev/null and b/assets/images/pexels/16575029.jpg differ diff --git a/assets/images/pexels/16577552.jpg b/assets/images/pexels/16577552.jpg new file mode 100644 index 0000000..1e5af78 Binary files /dev/null and b/assets/images/pexels/16577552.jpg differ diff --git a/assets/images/pexels/17596619.jpg b/assets/images/pexels/17596619.jpg new file mode 100644 index 0000000..2c6264d Binary files /dev/null and b/assets/images/pexels/17596619.jpg differ diff --git a/assets/images/pexels/179222.jpg b/assets/images/pexels/179222.jpg new file mode 100644 index 0000000..c6ceea3 Binary files /dev/null and b/assets/images/pexels/179222.jpg differ diff --git a/assets/images/pexels/18002652.jpg b/assets/images/pexels/18002652.jpg new file mode 100644 index 0000000..9bd0e5f Binary files /dev/null and b/assets/images/pexels/18002652.jpg differ diff --git a/assets/images/pexels/18159266.jpg b/assets/images/pexels/18159266.jpg new file mode 100644 index 0000000..23780da Binary files /dev/null and b/assets/images/pexels/18159266.jpg differ diff --git a/assets/images/pexels/18168507.jpg b/assets/images/pexels/18168507.jpg new file mode 100644 index 0000000..e246af7 Binary files /dev/null and b/assets/images/pexels/18168507.jpg differ diff --git a/assets/images/pexels/18533500.jpg b/assets/images/pexels/18533500.jpg new file mode 100644 index 0000000..ec99d3e Binary files /dev/null and b/assets/images/pexels/18533500.jpg differ diff --git a/assets/images/pexels/19012985.jpg b/assets/images/pexels/19012985.jpg new file mode 100644 index 0000000..dde29fc Binary files /dev/null and b/assets/images/pexels/19012985.jpg differ diff --git a/assets/images/pexels/19500831.jpg b/assets/images/pexels/19500831.jpg new file mode 100644 index 0000000..8e5ed5e Binary files /dev/null and b/assets/images/pexels/19500831.jpg differ diff --git a/assets/images/pexels/20782645.jpg b/assets/images/pexels/20782645.jpg new file mode 100644 index 0000000..fad2de4 Binary files /dev/null and b/assets/images/pexels/20782645.jpg differ diff --git a/assets/images/pexels/24018314.jpg b/assets/images/pexels/24018314.jpg new file mode 100644 index 0000000..8ed282a Binary files /dev/null and b/assets/images/pexels/24018314.jpg differ diff --git a/assets/images/pexels/24600235.jpg b/assets/images/pexels/24600235.jpg new file mode 100644 index 0000000..9c924cc Binary files /dev/null and b/assets/images/pexels/24600235.jpg differ diff --git a/assets/images/pexels/2646483.jpg b/assets/images/pexels/2646483.jpg new file mode 100644 index 0000000..d962c19 Binary files /dev/null and b/assets/images/pexels/2646483.jpg differ diff --git a/assets/images/pexels/29235341.jpg b/assets/images/pexels/29235341.jpg new file mode 100644 index 0000000..d31b1ad Binary files /dev/null and b/assets/images/pexels/29235341.jpg differ diff --git a/assets/images/pexels/29983805.jpg b/assets/images/pexels/29983805.jpg new file mode 100644 index 0000000..61e57e8 Binary files /dev/null and b/assets/images/pexels/29983805.jpg differ diff --git a/assets/images/pexels/30247451.jpg b/assets/images/pexels/30247451.jpg new file mode 100644 index 0000000..ab3d511 Binary files /dev/null and b/assets/images/pexels/30247451.jpg differ diff --git a/assets/images/pexels/30374205.jpg b/assets/images/pexels/30374205.jpg new file mode 100644 index 0000000..1353a38 Binary files /dev/null and b/assets/images/pexels/30374205.jpg differ diff --git a/assets/images/pexels/30389394.jpg b/assets/images/pexels/30389394.jpg new file mode 100644 index 0000000..c09d5c0 Binary files /dev/null and b/assets/images/pexels/30389394.jpg differ diff --git a/assets/images/pexels/32552958.jpg b/assets/images/pexels/32552958.jpg new file mode 100644 index 0000000..a754be2 Binary files /dev/null and b/assets/images/pexels/32552958.jpg differ diff --git a/assets/images/pexels/32849279.jpg b/assets/images/pexels/32849279.jpg new file mode 100644 index 0000000..b6b9026 Binary files /dev/null and b/assets/images/pexels/32849279.jpg differ diff --git a/assets/images/pexels/34368085.jpg b/assets/images/pexels/34368085.jpg new file mode 100644 index 0000000..30d02d0 Binary files /dev/null and b/assets/images/pexels/34368085.jpg differ diff --git a/assets/images/pexels/3652805.jpg b/assets/images/pexels/3652805.jpg new file mode 100644 index 0000000..7e36a95 Binary files /dev/null and b/assets/images/pexels/3652805.jpg differ diff --git a/assets/images/pexels/3780890.jpg b/assets/images/pexels/3780890.jpg new file mode 100644 index 0000000..202a6b4 Binary files /dev/null and b/assets/images/pexels/3780890.jpg differ diff --git a/assets/images/pexels/4612722.jpg b/assets/images/pexels/4612722.jpg new file mode 100644 index 0000000..a94c754 Binary files /dev/null and b/assets/images/pexels/4612722.jpg differ diff --git a/assets/images/pexels/4790612.jpg b/assets/images/pexels/4790612.jpg new file mode 100644 index 0000000..a3b999b Binary files /dev/null and b/assets/images/pexels/4790612.jpg differ diff --git a/assets/images/pexels/51439.jpg b/assets/images/pexels/51439.jpg new file mode 100644 index 0000000..8654f77 Binary files /dev/null and b/assets/images/pexels/51439.jpg differ diff --git a/assets/images/pexels/8597460.jpg b/assets/images/pexels/8597460.jpg new file mode 100644 index 0000000..ca98a4b Binary files /dev/null and b/assets/images/pexels/8597460.jpg differ diff --git a/assets/images/pexels/8861204.jpg b/assets/images/pexels/8861204.jpg new file mode 100644 index 0000000..77e6318 Binary files /dev/null and b/assets/images/pexels/8861204.jpg differ diff --git a/assets/images/pexels/8935989.jpg b/assets/images/pexels/8935989.jpg new file mode 100644 index 0000000..67eb4eb Binary files /dev/null and b/assets/images/pexels/8935989.jpg differ diff --git a/assets/images/pexels/9195549.jpg b/assets/images/pexels/9195549.jpg new file mode 100644 index 0000000..dac9eec Binary files /dev/null and b/assets/images/pexels/9195549.jpg differ diff --git a/assets/images/pexels/9195629.jpg b/assets/images/pexels/9195629.jpg new file mode 100644 index 0000000..cae3991 Binary files /dev/null and b/assets/images/pexels/9195629.jpg differ diff --git a/assets/images/pexels/9660361.jpg b/assets/images/pexels/9660361.jpg new file mode 100644 index 0000000..51d285f Binary files /dev/null and b/assets/images/pexels/9660361.jpg differ diff --git a/assets/images/pexels/9787888.jpg b/assets/images/pexels/9787888.jpg new file mode 100644 index 0000000..722b168 Binary files /dev/null and b/assets/images/pexels/9787888.jpg differ diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..376979b --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,363 @@ +document.addEventListener('DOMContentLoaded', function() { + const playNowButton = document.querySelector('.btn-primary'); + if (playNowButton) { + playNowButton.addEventListener('click', function(e) { + e.preventDefault(); + document.querySelector('#game-section').scrollIntoView({ behavior: 'smooth' }); + }); + } + + const gameBoard = document.getElementById('game-board'); + const resetButton = document.getElementById('reset-button'); + const gameStatus = document.getElementById('game-status'); + const boardSizeSelect = document.getElementById('board-size-select'); + const aiDifficultySelect = document.getElementById('ai-difficulty-select'); + + const WIN_CONDITION = 4; + const PLAYER_SYMBOL = '🐾'; + const AI_SYMBOL = '🧶'; + + let BOARD_SIZE = 5; + let boardState; + let currentPlayer; + let gameActive; + let cells; + + function createBoard(size) { + BOARD_SIZE = size; + gameBoard.innerHTML = ''; + gameBoard.className = 'game-board'; + gameBoard.classList.add(`size-${size}`); + + gameBoard.style.gridTemplateColumns = `repeat(${size}, 1fr)`; + gameBoard.style.gridTemplateRows = `repeat(${size}, 1fr)`; + + cells = []; + for (let i = 0; i < size * size; i++) { + const cell = document.createElement('div'); + cell.classList.add('game-cell'); + const row = Math.floor(i / BOARD_SIZE); + const col = i % BOARD_SIZE; + cell.addEventListener('click', () => handleCellClick(row, col)); + gameBoard.appendChild(cell); + cells.push(cell); + } + } + + function handleCellClick(row, col) { + if (!gameActive || boardState[row][col] !== null || currentPlayer !== 'PLAYER') { + return; + } + + boardState[row][col] = 'PLAYER'; + renderBoard(); + + if (checkWin('PLAYER')) { + endGame('Player'); + return; + } + + if (isDraw()) { + endGame('Draw'); + return; + } + + currentPlayer = 'AI'; + updateStatus("AI's turn..."); + setTimeout(makeAIMove, 500); + } + + function makeAIMove() { + if (!gameActive) return; + + const difficulty = aiDifficultySelect.value; + let move; + + if (difficulty === 'easy') { + move = findRandomMove(); + } else if (difficulty === 'medium') { + move = findBestMoveMedium(); + } else { // Hard + move = findBestMoveHard(); + } + + if (move) { + boardState[move.row][move.col] = 'AI'; + renderBoard(); + + if (checkWin('AI')) { + endGame('AI'); + return; + } + + if (isDraw()) { + endGame('Draw'); + return; + } + } + + currentPlayer = 'PLAYER'; + updateStatus("Your turn!"); + } + + function findRandomMove() { + let availableCells = []; + for (let i = 0; i < BOARD_SIZE; i++) { + for (let j = 0; j < BOARD_SIZE; j++) { + if (boardState[i][j] === null) { + availableCells.push({ row: i, col: j }); + } + } + } + if (availableCells.length > 0) { + return availableCells[Math.floor(Math.random() * availableCells.length)]; + } + return null; + } + + function findBestMoveMedium() { + // 1. Check if AI can win + for (let i = 0; i < BOARD_SIZE; i++) { + for (let j = 0; j < BOARD_SIZE; j++) { + if (boardState[i][j] === null) { + boardState[i][j] = 'AI'; + if (checkWin('AI')) { + boardState[i][j] = null; // Reset + return { row: i, col: j }; + } + boardState[i][j] = null; // Reset + } + } + } + + // 2. Check if Player is about to win and block + for (let i = 0; i < BOARD_SIZE; i++) { + for (let j = 0; j < BOARD_SIZE; j++) { + if (boardState[i][j] === null) { + boardState[i][j] = 'PLAYER'; + if (checkWin('PLAYER')) { + boardState[i][j] = null; // Reset + return { row: i, col: j }; + } + boardState[i][j] = null; // Reset + } + } + } + + // 3. Otherwise, make a random move + return findRandomMove(); + } + + function findBestMoveHard() { + let bestScore = -Infinity; + let move = null; + + for (let i = 0; i < BOARD_SIZE; i++) { + for (let j = 0; j < BOARD_SIZE; j++) { + if (boardState[i][j] === null) { + boardState[i][j] = 'AI'; + let score = evaluateBoard(); + boardState[i][j] = null; + if (score > bestScore) { + bestScore = score; + move = { row: i, col: j }; + } + } + } + } + return move || findRandomMove(); // Fallback to random if no good move + } + + function evaluateBoard() { + let score = 0; + // Prioritize winning moves + if (checkWin('AI')) return 10000; + // Prioritize blocking player's winning moves + if (checkWin('PLAYER')) return -9000; + + // Evaluate lines for potential + score += evaluateLinesForPlayer('AI'); + score -= evaluateLinesForPlayer('PLAYER'); + + return score; + } + + function evaluateLinesForPlayer(player) { + let score = 0; + const symbol = player; + + for (let i = 0; i < BOARD_SIZE; i++) { + for (let j = 0; j < BOARD_SIZE; j++) { + // Horizontal + if (j + WIN_CONDITION <= BOARD_SIZE) { + score += evaluateLine(i, j, 0, 1, symbol); + } + // Vertical + if (i + WIN_CONDITION <= BOARD_SIZE) { + score += evaluateLine(i, j, 1, 0, symbol); + } + // Diagonal (down-right) + if (i + WIN_CONDITION <= BOARD_SIZE && j + WIN_CONDITION <= BOARD_SIZE) { + score += evaluateLine(i, j, 1, 1, symbol); + } + // Diagonal (down-left) + if (i + WIN_CONDITION <= BOARD_SIZE && j - WIN_CONDITION + 1 >= 0) { + score += evaluateLine(i, j, 1, -1, symbol); + } + } + } + return score; + } + + function evaluateLine(row, col, dr, dc, player) { + let playerCount = 0; + let emptyCount = 0; + for (let k = 0; k < WIN_CONDITION; k++) { + const current = boardState[row + k * dr][col + k * dc]; + if (current === player) { + playerCount++; + } else if (current === null) { + emptyCount++; + } + } + + // If the line is blocked by the opponent, it has no potential. + if (playerCount + emptyCount < WIN_CONDITION) { + return 0; + } + + // Assign scores based on the number of pieces in a line + if (playerCount === 3 && emptyCount === 1) return 100; + if (playerCount === 2 && emptyCount === 2) return 10; + if (playerCount === 1 && emptyCount === 3) return 1; + return 0; + } + + + function checkWin(player) { + const symbol = player; + + for (let i = 0; i < BOARD_SIZE; i++) { + for (let j = 0; j < BOARD_SIZE; j++) { + // Horizontal + if (j + WIN_CONDITION <= BOARD_SIZE) { + let count = 0; + for (let k = 0; k < WIN_CONDITION; k++) { + if (boardState[i][j + k] === symbol) count++; + } + if (count === WIN_CONDITION) return true; + } + // Vertical + if (i + WIN_CONDITION <= BOARD_SIZE) { + let count = 0; + for (let k = 0; k < WIN_CONDITION; k++) { + if (boardState[i + k][j] === symbol) count++; + } + if (count === WIN_CONDITION) return true; + } + // Diagonal (down-right) + if (i + WIN_CONDITION <= BOARD_SIZE && j + WIN_CONDITION <= BOARD_SIZE) { + let count = 0; + for (let k = 0; k < WIN_CONDITION; k++) { + if (boardState[i + k][j + k] === symbol) count++; + } + if (count === WIN_CONDITION) return true; + } + // Diagonal (down-left) + if (i + WIN_CONDITION <= BOARD_SIZE && j - WIN_CONDITION + 1 >= 0) { + let count = 0; + for (let k = 0; k < WIN_CONDITION; k++) { + if (boardState[i + k][j - k] === symbol) count++; + } + if (count === WIN_CONDITION) return true; + } + } + } + return false; + } + + function isDraw() { + return boardState.every(row => row.every(cell => cell !== null)); + } + + function endGame(winner) { + gameActive = false; + if (winner === 'Draw') { + updateStatus("It's a draw!"); + } else { + updateStatus(`${winner} wins!`); + } + } + + function resetGame() { + const size = parseInt(boardSizeSelect.value); + createBoard(size); + boardState = Array(BOARD_SIZE).fill(null).map(() => Array(BOARD_SIZE).fill(null)); + currentPlayer = 'PLAYER'; + gameActive = true; + renderBoard(); + updateStatus("Your turn!"); + } + + function renderBoard() { + cells.forEach((cell, index) => { + const row = Math.floor(index / BOARD_SIZE); + const col = index % BOARD_SIZE; + const state = boardState[row][col]; + + if (state === 'PLAYER') { + cell.innerHTML = `
${PLAYER_SYMBOL}
`; + } else if (state === 'AI') { + cell.innerHTML = `
${AI_SYMBOL}
`; + } else { + cell.innerHTML = ''; + } + }); + } + + function updateStatus(message) { + gameStatus.textContent = message; + } + + if (resetButton) { + resetButton.addEventListener('click', resetGame); + } + + if (boardSizeSelect) { + boardSizeSelect.addEventListener('change', resetGame); + } + + if(aiDifficultySelect) { + aiDifficultySelect.addEventListener('change', resetGame); + } + + resetGame(); + + const catGallery = document.getElementById('cat-gallery'); + if (catGallery) { + fetch('api/pexels.php') + .then(response => response.json()) + .then(images => { + images.forEach(image => { + const galleryItem = document.createElement('div'); + galleryItem.className = 'cat-gallery-item'; + + const img = document.createElement('img'); + img.src = image.src; + img.alt = 'A cute cat'; + + const credit = document.createElement('div'); + credit.className = 'photographer-credit'; + credit.innerHTML = `Photo by ${image.photographer}`; + + galleryItem.appendChild(img); + galleryItem.appendChild(credit); + catGallery.appendChild(galleryItem); + }); + }) + .catch(error => { + console.error('Error fetching cat images:', error); + catGallery.innerHTML = '

Could not load cat pictures. Meow-be later?

'; + }); + } +}); \ No newline at end of file diff --git a/includes/pexels.php b/includes/pexels.php new file mode 100644 index 0000000..ff50279 --- /dev/null +++ b/includes/pexels.php @@ -0,0 +1,26 @@ + 0 ? $k : 'Vc99rnmOhHhJAbgGQoKLZtsaIVfkeownoQNbTj78VemUjKh08ZYRbf18'; +} +function pexels_get($url) { + $ch = curl_init(); + curl_setopt_array($ch, [ + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HTTPHEADER => [ 'Authorization: '. pexels_key() ], + CURLOPT_TIMEOUT => 15, + ]); + $resp = curl_exec($ch); + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + if ($code >= 200 && $code < 300 && $resp) return json_decode($resp, true); + return null; +} +function download_to($srcUrl, $destPath) { + $data = @file_get_contents($srcUrl); + if ($data === false) return false; + if (!is_dir(dirname($destPath))) mkdir(dirname($destPath), 0775, true); + return file_put_contents($destPath, $data) !== false; +} +?> \ No newline at end of file diff --git a/index.php b/index.php index 7205f3d..0480bd8 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,84 @@ - - + - - - New Style - - - - - - - - - - - - - - - - - - - + + + Cute-Cat-Toe + + + + + + + + + + + + + + + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

-
-
- + + + +
+
+
+

Welcome to Cute-Cat-Toe!

+

The cutest Tic Tac Toe game on the web. Play with paws and yarn!

+ Play a Game +
+
+ +
+

Let's Play!

+
+ + + + +
+
+
+ +
+ +
+ + +
+ + + + + - + \ No newline at end of file