diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 1170717..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,136 +0,0 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-lerna-debug.log*
-.pnpm-debug.log*
-
-# Diagnostic reports (https://nodejs.org/api/report.html)
-report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-*.lcov
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# Snowpack dependency directory (https://snowpack.dev/)
-web_modules/
-
-# TypeScript cache
-*.tsbuildinfo
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Optional stylelint cache
-.stylelintcache
-
-# Microbundle cache
-.rpt2_cache/
-.rts2_cache_cjs/
-.rts2_cache_es/
-.rts2_cache_umd/
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variable files
-.env
-.env.development.local
-.env.test.local
-.env.production.local
-.env.local
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-.parcel-cache
-
-# Next.js build output
-.next
-out
-
-# Nuxt.js build / generate output
-.nuxt
-dist
-
-# Gatsby files
-.cache/
-# Comment in the public line in if your project uses Gatsby and not Next.js
-# https://nextjs.org/blog/next-9-1#public-directory-support
-# public
-
-# vuepress build output
-.vuepress/dist
-
-# vuepress v2.x temp and cache directory
-.temp
-.cache
-
-# vitepress build output
-**/.vitepress/dist
-
-# vitepress cache directory
-**/.vitepress/cache
-
-# Docusaurus cache and generated files
-.docusaurus
-
-# Serverless directories
-.serverless/
-
-# FuseBox cache
-.fusebox/
-
-# DynamoDB Local files
-.dynamodb/
-
-# TernJS port file
-.tern-port
-
-# Stores VSCode versions used for testing VSCode extensions
-.vscode-test
-
-# yarn v2
-.yarn/cache
-.yarn/unplugged
-.yarn/build-state.yml
-.yarn/install-state.gz
-.pnp.*
diff --git a/cloudy.png b/cloudy.png
new file mode 100644
index 0000000..4f162e4
Binary files /dev/null and b/cloudy.png differ
diff --git a/fog.png b/fog.png
new file mode 100644
index 0000000..f67ec82
Binary files /dev/null and b/fog.png differ
diff --git a/index.html b/index.html
index 09c6dc0..92c1821 100644
--- a/index.html
+++ b/index.html
@@ -1,13 +1,98 @@
+
- Simple HTML Page
-
-
+
+ Weather Forecast App
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
Today
+
+
23°C
+
14°C
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..453b7f8
--- /dev/null
+++ b/main.js
@@ -0,0 +1,119 @@
+const API_KEY = 'FF7ZYNQQ68ZK9BB677FAW6CTX';
+const BASE_URL = 'https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/';
+
+const searchBtn = document.querySelector('.search-btn');
+const cityInput = document.getElementById('cityInput');
+const cityElem = document.querySelector('.city');
+const countryElem = document.querySelector('.country');
+const tempElem = document.querySelector('.temp h1');
+const conditionElem = document.querySelector('.condition');
+const windElem = document.querySelector('.extra-info p:nth-child(1)');
+const humidityElem = document.querySelector('.extra-info p:nth-child(2)');
+const forecastCarousel = document.querySelector('.forecast-carousel');
+const weatherIcon = document.querySelector('.current-weather-icon img');
+
+// Створення та приховування попапу
+const popup = document.createElement('div');
+popup.classList.add('popup');
+document.body.appendChild(popup);
+popup.style.display = 'none';
+
+async function fetchWeather(city) {
+ const url = `${BASE_URL}${city}?unitGroup=metric&key=${API_KEY}&contentType=json&include=days`;
+
+ // Відправляється асинхронний запит на сервер, отримується відповідь і перетворюється в об'єкт JSON.
+ const res = await fetch(url);
+ const data = await res.json();
+ forecastData = data.days.slice(0, 10); // Зберігається тільки перших 10 днів прогнозу
+
+ // Збереження прогнозу і назви міста
+ localStorage.setItem('weatherForecast', JSON.stringify(forecastData));
+ localStorage.setItem('forecastCity', data.resolvedAddress);
+
+ updateMainWeather(data);
+ updateForecast();
+}
+
+function updateMainWeather(data, dayIndex = 0) {
+ const day = forecastData[dayIndex]; // Вибирається день (за замовчуванням -- сьогодні)
+ cityElem.textContent = data.resolvedAddress.split(',')[0];
+ countryElem.textContent = data.resolvedAddress.split(',')[1]?.trim() || '';
+ tempElem.textContent = `${Math.round(day.temp)}°C`;
+ conditionElem.textContent = day.conditions;
+ windElem.textContent = `Wind: ${day.windspeed} km/h`;
+ humidityElem.textContent = `Humidity: ${day.humidity}%`;
+ weatherIcon.src = getIcon(day.icon);
+}
+
+function updateForecast() {
+ forecastCarousel.innerHTML = '';
+ forecastData.forEach((day, index) => {
+ const forecastDay = document.createElement('div');
+ forecastDay.classList.add('forecast-day');
+ forecastDay.innerHTML = `
+ ${index === 0 ? 'Today' : new Date(day.datetime).toLocaleDateString('en-US', { weekday: 'short' })}
+
+ ${Math.round(day.temp)}°C
+ ${Math.round(day.tempmin)}°C
+ `;
+
+ // Оновлює головну панель з погодою на вибраний день
+ forecastDay.addEventListener('click', () => {
+ updateMainWeather({ resolvedAddress: `${cityElem.textContent}, ${countryElem.textContent}` }, index);
+ });
+
+ // Клік по температурі відкриває попап з деталями дня
+ forecastDay.querySelector('.temp-click').addEventListener('click', (e) => {
+ e.stopPropagation();
+ const idx = e.target.dataset.index;
+ showPopup(forecastData[idx]);
+ });
+
+ forecastCarousel.appendChild(forecastDay);
+ });
+}
+
+function getIcon(condition) {
+ const icons = {
+ 'clear-day': 'sunny.png',
+ 'rain': 'rainy.png',
+ 'cloudy': 'cloudy.png',
+ 'partly-cloudy-day': 'cloudy.png',
+ 'snow': 'snow.png',
+ 'fog': 'fog.png',
+ 'wind': 'windy.png'
+ };
+ return icons[condition] || 'sunny.png';
+}
+
+// Відображення попапу з деталями про день
+function showPopup(day) {
+ popup.innerHTML = `
+
+ `;
+ popup.style.display = 'block';
+}
+
+searchBtn.addEventListener('click', () => {
+ const city = cityInput.value.trim();
+ if (city) fetchWeather(city);
+});
+
+cityInput.addEventListener('keydown', (e) => {
+ if (e.key === 'Enter'){
+ const city = cityInput.value.trim();
+ if (city) fetchWeather(city);
+ }
+});
+
+// Load default city
+fetchWeather('Kyiv');
\ No newline at end of file
diff --git a/rainy.png b/rainy.png
new file mode 100644
index 0000000..e758f99
Binary files /dev/null and b/rainy.png differ
diff --git a/report.html b/report.html
new file mode 100644
index 0000000..43a60ea
--- /dev/null
+++ b/report.html
@@ -0,0 +1,56 @@
+
+
+
+
+
+ Weather Report
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/snow.png b/snow.png
new file mode 100644
index 0000000..ad94c7f
Binary files /dev/null and b/snow.png differ
diff --git a/src/main.js b/src/main.js
deleted file mode 100644
index e69de29..0000000
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..b067c21
--- /dev/null
+++ b/style.css
@@ -0,0 +1,343 @@
+:root {
+ --background-color: #f0f0f0;
+
+ --box-background-color: #ffffff;
+ --box-shadow-color: #0000001a;
+
+ --cityInput-border-color: #cccccc;
+ --cityInput-border-color-focus: #306cdb;
+ --cityInput-text-color-focus: #000000;
+
+ --search-btn-background-color: #306cdb;
+ --search-btn-text-color: #ffffff;
+ --search-btn-background-color-hover: #477de2;
+
+ --country-text-color: #2b3a40;
+ --extra-info-text-color: #000000;
+
+ --forecast-day-border-color: #cccccc;
+ --forecast-day-background-color: #ffffff;
+
+ --popup-background-color: #ffffff;
+ --popup-border-color: #cccccc;
+ --popup-content-btn-background-color: #306cdb;
+ --popup-content-btn-text-color: #ffffff;
+ --popup-content-btn-background-color-hover: #477de2;
+}
+
+* {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
+}
+
+body {
+ background: var(--background-color);
+ display: flex;
+ justify-content: center;
+ padding: 20px;
+}
+
+/* -------------------------------------- */
+.box {
+ background: var(--box-background-color);
+ padding: 20px;
+ border-radius: 10px;
+ max-width: 500px;
+ width: 100%;
+ box-shadow: 0 0 20px var(--box-shadow-color);
+}
+
+/* SEARCH ROW---------------------------- */
+.search-row {
+ display: flex;
+ gap: 5px;
+ margin-bottom: 20px;
+}
+
+#cityInput {
+ flex: 1;
+ padding: 0 10px;
+ border: 1px solid var(--cityInput-border-color);
+ border-radius: 8px;
+ transition: border-color 0.2s;
+}
+
+#cityInput:focus {
+ outline: none;
+ border-color: var(--cityInput-border-color-focus);
+ color: var(--cityInput-text-color-focus);
+}
+
+.search-btn {
+ padding: 8px 20px;
+ background: var(--search-btn-background-color);
+ color: var(--search-btn-text-color);
+ border: none;
+ border-radius: 8px;
+ cursor: pointer;
+}
+
+.search-btn:hover {
+ background: var(--search-btn-background-color-hover);
+}
+
+/* MAIN ABOUT WEATHER-------------------- */
+.weather-main {
+ display: grid;
+ grid-template-columns: 1fr auto;
+ grid-template-areas:
+ "left icon"
+ "left right";
+ gap: 20px;
+ align-items: start;
+}
+
+.left-panel {
+ grid-area: left;
+}
+
+.city {
+ font-size: 24px;
+ font-weight: 500;
+}
+
+.country {
+ color: var(--country-text-color);
+ font-size: 16px;
+}
+
+.temp h1 {
+ font-size: 36px;
+ font-weight: 500;
+}
+
+.condition {
+ margin-bottom: 5px;
+ font-size: 16px;
+}
+
+.right-panel {
+ grid-area: right;
+ margin-bottom: 15px;
+}
+
+.current-weather-icon img {
+ width: 80px;
+ height: 80px;
+ float: right;
+ object-fit: contain;
+}
+
+.current-weather-icon {
+ grid-area: icon;
+}
+
+.right-panel,
+.current-weather-icon img {
+ margin-right: 50px;
+}
+
+.extra-info {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+ font-size: 14px;
+ font-weight: 400;
+ color: var(--extra-info-text-color);
+ align-items: left;
+}
+
+/* CAROUSEL------------------------------ */
+.forecast-carousel {
+ display: flex;
+ flex-direction: row;
+ gap: 20px;
+ overflow-x: auto; /*дозволяє горизонтальну прокрутку, якщо вміст ширший за контейнер*/
+ scroll-snap-type: x mandatory; /*snap (прилипання) працює по осі X*/
+ scroll-padding: 1rem;
+ position: relative;
+ block-size: auto;
+ padding-bottom: 12px;
+}
+
+.forecast-day {
+ scroll-snap-align: start; /*цей елемент має "прилипнути" до початку області прокрутки (start — це край каруселі)*/
+ flex: 0 0 calc(100% / 4 - 1rem); /*показує 4 елементи на екрані */
+ border: 1px solid var(--forecast-day-border-color);
+ background-color: var(--forecast-day-background-color);
+ padding: 10px;
+ border-radius: 10px;
+ text-align: center;
+ min-width: 0; /* без цього елементи можуть не стискатися як треба, і прокрутка буде працювати неправильно */
+}
+
+.forecast-day .icon img {
+ width: 35px;
+ height: 35px;
+ object-fit: contain;
+ margin: 5px;
+}
+
+.low-temp {
+ color: #666;
+ font-size: 14px;
+}
+
+/* POPUP----------------------------- */
+.popup {
+ position: fixed;
+ top: 20%;
+ left: 50%;
+ transform: translateX(-50%);
+ background-color: var(--popup-background-color);
+ border: 1px solid var(--popup-border-color);
+ padding: 20px;
+ z-index: 9999;
+ box-shadow: 0 0 15px var(--box-shadow-color);
+ border-radius: 10px;
+ max-width: 300px;
+}
+
+.popup-content-btn {
+ margin-top: 10px;
+ padding: 6px 12px;
+ background: var(--popup-content-btn-background-color);
+ color: var(--popup-content-btn-text-color);
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+}
+
+.popup-content-btn:hover {
+ background-color: var(--popup-content-btn-background-color-hover);
+}
+
+/* REPORT----------------------------- */
+.report {
+ text-align: center;
+ margin-top: 20px;
+}
+
+.report-backward {
+ display: inline-block;
+ margin-top: 10px;
+ padding: 8px 16px;
+ background-color: var(--search-btn-background-color);
+ color: white;
+ border-radius: 8px;
+ text-decoration: none;
+ font-weight: 500;
+}
+
+.report-backward:hover {
+ background-color: var(--search-btn-background-color-hover);
+}
+
+#reportTitle{
+ text-align: center;
+}
+
+#pivot-table-container{
+ margin-top:20px;
+}
+
+/* MEDIA----------------------------- */
+@media (max-width: 768px) {
+ body {
+ background: var(--box-background-color);
+ }
+
+ .box {
+ box-shadow: none;
+ }
+
+ .city {
+ font-size: 30px;
+ font-weight: 600;
+ }
+
+ .country {
+ font-size: 18px;
+ }
+
+ .temp h1 {
+ font-size: 38px;
+ }
+
+ .condition {
+ font-size: 18px;
+ }
+
+ .weather-main {
+ display: grid;
+ grid-template-columns: 1fr auto;
+ grid-template-areas:
+ "left icon"
+ "left ."
+ "right .";
+ gap: 10px;
+ }
+
+ .left-panel {
+ align-items: flex-start;
+ }
+
+ .right-panel {
+ align-items: flex-start;
+ }
+
+ .current-weather-icon {
+ justify-self: end;
+ }
+
+ .current-weather-icon img {
+ width: 90px;
+ height: 90px;
+ object-fit: contain;
+ }
+
+ .extra-info {
+ margin-top: 10px;
+ font-size: 14px;
+ }
+
+ .forecast-day {
+ flex: 0 0 calc(100% / 3 - 1rem);
+ }
+}
+
+@media (max-width: 371px) {
+ body {
+ min-width: 350px;
+ overflow-x: auto;
+ }
+
+ .box {
+ min-width: 350px;
+ }
+
+ .search-row {
+ flex-direction: column;
+ }
+
+ #cityInput {
+ padding: 5px 10px;
+ }
+
+ .extra-info {
+ margin-top: 10px;
+ font-size: 14px;
+ }
+
+ .forecast-day p {
+ font-size: 16px;
+ }
+
+ .forecast-day .icon img {
+ width: 30px;
+ height: 30px;
+ object-fit: contain;
+ }
+}
\ No newline at end of file
diff --git a/style/style.css b/style/style.css
deleted file mode 100644
index e69de29..0000000
diff --git a/sunny.png b/sunny.png
new file mode 100644
index 0000000..74feb0e
Binary files /dev/null and b/sunny.png differ
diff --git a/windy.png b/windy.png
new file mode 100644
index 0000000..972b98a
Binary files /dev/null and b/windy.png differ