diff --git a/index.html b/index.html
index 5971bf7d..4d25bee8 100644
--- a/index.html
+++ b/index.html
@@ -1,16 +1,88 @@
-
-
+
+
- My Page
-
-
-
+
+ BuyList
+
+
-
- Apple
- 4
-
+
+
+
+ Кошик покупок
+
+
+
+
+ -
+
Помідори
+
+
+
+
+ -
+
Печиво
+
+
+
+
+
+ -
+
Сир
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/main.css b/main.css
index 00bc872e..25a3f765 100644
--- a/main.css
+++ b/main.css
@@ -1,17 +1,423 @@
-.product-item {
- background-color: gray;
- display: inline-block;
- height: 25px;
- padding: 5px;
- border-radius: 5px;
+* {
+ box-sizing: border-box;
+}
+
+body {
+ margin: 0;
+ min-height: 100vh;
+ font-family: Arial, sans-serif;
+ background-color: #d9d9d9;
+ color: #111;
+}
+
+.page {
+ width: min(100%, 980px);
+ margin: 0 auto;
+ padding: 28px 20px;
+ display: grid;
+ grid-template-columns: minmax(0, 1.45fr) minmax(180px, 0.75fr);
+ gap: 18px;
+ align-items: start;
+}
+
+.products-card, .summary-card {
+ background-color: white;
+ border-radius: 5px;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12);
+}
+
+.products-card {
+ overflow: visible;
+}
+
+.summary-card {
+ overflow: hidden;
+}
+
+.add-form {
+ padding: 14px;
+ display: flex;
+}
+
+.add-form input {
+ flex: 1;
+ min-width: 0;
+ padding: 10px 14px;
+ font-size: 16px;
+ border: 1px solid #d7d7d7;
+ border-radius: 5px 0 0 5px;
+}
+
+.add-form button {
+ padding: 0 40px;
+ border: none;
+ border-radius: 0 5px 5px 0;
+ background: linear-gradient(#3498db, #2b84c6);
+ color: white;
+ font-size: 16px;
+ font-weight: bold;
+ min-height: 46px;
+ transform: none;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 2px 0 #21679c, 0 2px 4px rgba(0, 0, 0, 0.16);
+}
+
+.product>button:not(.delete), .product.product-bought>button:not(.delete) {
+ background: linear-gradient(#ffffff, #e7e7e7);
+ border: 1px solid #d4d4d4;
+ color: #555;
+ font-weight: bold;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9), 0 3px 0 #c4c4c4, 0 3px 6px rgba(0, 0, 0, 0.14);
+}
+
+.products-list {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.product {
+ min-height: 72px;
+ padding: 16px;
+ border-top: 1px solid #ececec;
+ display: grid;
+ grid-template-columns: minmax(65px, 1fr) minmax(0, 0.5fr) 118px minmax(0, 0.5fr) 110px 34px;
+ column-gap: 8px;
+ row-gap: 8px;
+ align-items: center;
+ justify-items: stretch;
+}
+
+.product-bought {
+ grid-template-columns: minmax(65px, 1fr) minmax(0, 0.5fr) 118px minmax(0, 0.5fr) 110px 34px;
+}
+
+.product-name {
+ grid-column: 1;
+ margin: 0;
+ font-size: 16px;
+}
+
+.product-bought .product-name {
+ text-decoration: line-through;
+}
+
+.product-bought .counter {
+ grid-column: 3;
+ justify-self: center;
+}
+
+.editable {
+ width: 100%;
+ max-width: 160px;
+ min-width: 65px;
+ padding: 7px 10px;
+ border: 1px solid #58aef7;
+ border-radius: 4px;
+ background-color: white;
+ box-shadow: 0 0 0 2px rgba(88, 174, 247, 0.18), 0 0 8px rgba(88, 174, 247, 0.45);
+}
+
+.editable:focus {
+ outline: none;
+ border-color: #58aef7;
+ box-shadow: 0 0 0 2px rgba(88, 174, 247, 0.18), 0 0 8px rgba(88, 174, 247, 0.45);
+}
+
+.controls {
+ grid-column: 3;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ display: grid;
+ grid-template-columns: 34px 30px 34px;
+ gap: 10px;
+ justify-content: center;
+ align-items: center;
+}
+
+.counter {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 30px;
+ height: 30px;
+ background-color: #e8e8e8;
+ border-radius: 5px;
+ font-size: 15px;
+ font-weight: bold;
+ color: #555;
+}
+
+button {
+ position: relative;
+ min-height: 34px;
+ cursor: pointer;
+ border: 1px solid #d7d7d7;
+ border-radius: 5px;
+ font-size: 14px;
+ background-color: #f5f5f5;
+ appearance: none;
+ box-shadow: none;
+}
+
+.product>button:not(.delete) {
+ grid-column: 5;
+ justify-self: end;
+ width: auto;
+ min-width: 120px;
+ padding: 0 12px;
+ height: 40px;
+ white-space: nowrap;
+}
+
+.product.product-bought>button:not(.delete) {
+ grid-column: 5 / 7;
+ justify-self: end;
+ width: auto;
+ min-width: 120px;
+ padding: 0 12px;
+ height: 40px;
+ white-space: nowrap;
+}
+
+.product .delete {
+ grid-column: 6;
+}
+
+.minus, .plus, .delete {
+ width: 34px;
+ height: 34px;
+ border: none;
+ border-radius: 50%;
+ color: white;
+ font-size: 20px;
+ font-weight: bold;
+}
+
+.minus {
+ background: linear-gradient(#ef3434, #d71920);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 3px 0 #a9161b, 0 3px 6px rgba(0, 0, 0, 0.18);
+}
+
+.minus.disabled {
+ background: linear-gradient(#f7b0b0, #ef9999);
+ box-shadow: none;
+ opacity: 0.75;
+ cursor: not-allowed;
+}
+
+.plus {
+ background: linear-gradient(#25c858, #18a83f);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 3px 0 #128332, 0 3px 6px rgba(0, 0, 0, 0.18);
+}
+
+.delete {
+ border-radius: 5px;
+ background: linear-gradient(#ef3434, #d71920);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 3px 0 #a9161b, 0 3px 6px rgba(0, 0, 0, 0.18);
+}
+
+.summary-card {
+ overflow: hidden;
+}
+
+.summary-section {
+ padding: 0;
+ border-bottom: 1px solid #e5e5e5;
+}
+
+.summary-section:last-child {
+ border-bottom: none;
+}
+
+.summary-section h2 {
+ margin: 0;
+ padding: 20px 16px 22px;
+ border-bottom: 1px solid #e5e5e5;
+ font-size: 24px;
+}
+
+.summary-list {
+ margin: 0;
+ padding: 20px 16px 22px;
+ list-style: none;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ align-items: center;
+}
+
+.summary-list strong {
+ color: #555;
+ font-weight: bold;
+}
+
+.summary-list li {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 10px 12px;
+ background-color: #e8e8e8;
+ border-radius: 6px;
+ font-size: 14px;
}
.amount {
- background-color: yellow;
- border-radius: 10px;
-
- display: inline-block;
- height: 20px;
- width: 20px;
- text-align: center;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-width: 22px;
+ height: 22px;
+ padding: 0 7px;
+ background-color: #ff6f1a;
+ color: white;
+ border-radius: 50%;
+ font-size: 13px;
+ font-weight: bold;
+ position: relative;
+}
+
+.bought-label strong {
+ text-decoration: line-through;
+}
+
+.bought-label .amount::before {
+ content: "";
+ position: absolute;
+ left: 7px;
+ right: 7px;
+ top: 50%;
+ height: 1.5px;
+ background-color: white;
+ transform: translateY(-50%);
+}
+
+button[data-tooltip]::after {
+ content: attr(data-tooltip);
+ position: absolute;
+ left: 50%;
+ bottom: calc(100% + 8px);
+ transform: translateX(-50%) translateY(10px) scale(0.85);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-width: 130px;
+ min-height: 32px;
+ padding: 4px 12px;
+ background-color: #4b148c;
+ color: white;
+ border-radius: 12px;
+ text-align: center;
+ font-size: 11px;
+ line-height: 1.1;
+ white-space: normal;
+ opacity: 0;
+ visibility: hidden;
+ pointer-events: none;
+ transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s ease;
+ z-index: 20;
+}
+
+button[data-tooltip]:hover::after {
+ opacity: 1;
+ visibility: visible;
+ font-weight: bold;
+ transform: translateX(-50%) translateY(0) scale(1);
+}
+
+.author-badge {
+ position: fixed;
+ left: 18px;
+ bottom: 0;
+ width: 155px;
+ height: 92px;
+ padding: 12px 10px;
+ text-align: center;
+ background-color: #4b148c;
+ color: white;
+ border-radius: 12px 12px 0 0;
+ transform: translateY(42px);
+ transition: 0.35s ease;
+ z-index: 20;
+}
+
+.author-badge:hover {
+ transform: translateY(0);
+ background-color: #6d20c7;
+}
+
+.badge-title, .badge-author {
+ margin: 0;
+ font-weight: bold;
+}
+
+.badge-title {
+ font-size: 26px;
+ margin-bottom: 12px;
+}
+
+.badge-author {
+ font-size: 14px;
+ line-height: 1.2;
+}
+
+.visually-hidden {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ overflow: hidden;
+ clip-path: inset(50%);
+ white-space: nowrap;
+}
+
+@media (max-width: 650px) {
+
+ .page {
+ grid-template-columns: 1fr;
+ padding: 16px;
+ }
+
+ .add-form {
+ flex-direction: column;
+ gap: 10px;
+ }
+
+ .add-form input, .add-form button {
+ width: 100%;
+ border-radius: 5px;
+ }
+
+ .product, .product-bought {
+ grid-template-columns: minmax(65px, 1fr) minmax(0, 0.5fr) 118px minmax(0, 0.5fr) 110px 34px;
+ }
+
+ .controls {
+ justify-content: center;
+ }
+}
+
+@media print {
+
+ body {
+ background-color: white;
+ }
+
+ .author-badge {
+ background-color: white;
+ color: #4b148c;
+ border: 2px solid #4b148c;
+ transform: none;
+ }
+
+ .badge-title {
+ display: none;
+ }
+
+ .add-form button, .minus, .plus, .delete, .product button {
+ box-shadow: none !important;
+ }
+
+ .add-form button {
+ transform: none;
+ }
}
\ No newline at end of file
diff --git a/main.js b/main.js
new file mode 100644
index 00000000..16d8fbfd
--- /dev/null
+++ b/main.js
@@ -0,0 +1,218 @@
+const form = document.querySelector(".add-form");
+const input = document.querySelector("#product-name");
+const productsList = document.querySelector(".products-list");
+const summarySections = document.querySelectorAll(".summary-section");
+
+const STORAGE_KEY = "buy-list-products";
+let products = loadProducts();
+
+render();
+
+form.addEventListener("submit", (event) => {
+ event.preventDefault();
+ const name = input.value.trim();
+ if (!name) {
+ input.focus();
+ return;
+ }
+ products.push({
+ id: Date.now(),
+ name: name,
+ count: 1,
+ bought: false
+ });
+ input.value = "";
+ input.focus();
+ saveAndRender();
+});
+
+productsList.addEventListener("click", (event) => {
+ const button = event.target.closest("button");
+ const name = event.target.closest(".product-name");
+ if (name) {
+ startEditingName(name);
+ return;
+ }
+ if (!button) {
+ return;
+ }
+
+ const productElement = button.closest(".product");
+ const id = Number(productElement.dataset.id);
+ const product = products.find(item => item.id === id);
+
+ if (!product) return;
+ if (button.classList.contains("delete")) products = products.filter(item => item.id !== id);
+ if (button.classList.contains("plus")) product.count++;
+ if (button.classList.contains("minus") && product.count > 1) product.count--;
+ if (button.dataset.action === "buy") product.bought = true;
+ if (button.dataset.action === "unbuy") product.bought = false;
+
+ saveAndRender();
+});
+
+function render() {
+ productsList.textContent = "";
+ products.forEach(product => {
+ productsList.append(createProductElement(product));
+ });
+ renderSummary();
+}
+
+function createProductElement(product) {
+ const li = document.createElement("li");
+ li.classList.add("product");
+ li.dataset.id = product.id;
+ if (product.bought) {
+ li.classList.add("product-bought");
+ }
+ const name = document.createElement("p");
+ name.classList.add("product-name");
+ name.textContent = product.name;
+
+ const counter = document.createElement("output");
+ counter.classList.add("counter");
+ counter.textContent = product.count;
+
+ if (product.bought) {
+ const unbuyButton = document.createElement("button");
+ unbuyButton.type = "button";
+ unbuyButton.textContent = "Не куплено";
+ unbuyButton.dataset.action = "unbuy";
+ unbuyButton.dataset.tooltip = "Повернути до покупок";
+ li.append(name, counter, unbuyButton);
+ return li;
+ }
+
+ const controls = document.createElement("menu");
+ controls.classList.add("controls");
+
+ const minusLi = document.createElement("li");
+ const minusButton = document.createElement("button");
+ minusButton.type = "button";
+ minusButton.textContent = "-";
+ minusButton.classList.add("minus");
+ minusButton.dataset.tooltip = "Зменшити кількість";
+
+ if (product.count === 1) {
+ minusButton.classList.add("disabled");
+ minusButton.disabled = true;
+ minusButton.dataset.tooltip = "Мінімальна кількість";
+ }
+
+ minusLi.append(minusButton);
+
+ const counterLi = document.createElement("li");
+ counterLi.append(counter);
+
+ const plusLi = document.createElement("li");
+ const plusButton = document.createElement("button");
+ plusButton.type = "button";
+ plusButton.textContent = "+";
+ plusButton.classList.add("plus");
+ plusButton.dataset.tooltip = "Збільшити кількість";
+ plusLi.append(plusButton);
+ controls.append(minusLi, counterLi, plusLi);
+
+ const buyButton = document.createElement("button");
+ buyButton.type = "button";
+ buyButton.textContent = "Куплено";
+ buyButton.dataset.action = "buy";
+ buyButton.dataset.tooltip = "Позначити як куплене";
+
+ const deleteButton = document.createElement("button");
+ deleteButton.type = "button";
+ deleteButton.textContent = "×";
+ deleteButton.classList.add("delete");
+ deleteButton.dataset.tooltip = "Видалити товар";
+
+ li.append(name, controls, buyButton, deleteButton);
+
+ return li;
+}
+
+function startEditingName(nameElement) {
+ const productElement = nameElement.closest(".product");
+ const id = Number(productElement.dataset.id);
+ const product = products.find(item => item.id === id);
+
+ if (!product || product.bought) return;
+
+ const editInput = document.createElement("input");
+ editInput.classList.add("editable");
+ editInput.value = product.name;
+
+ nameElement.replaceWith(editInput);
+ editInput.focus();
+
+ editInput.addEventListener("blur", () => {
+ const newName = editInput.value.trim();
+ if (newName) product.name = newName;
+ saveAndRender();
+ });
+
+ editInput.addEventListener("keydown", (event) => {
+ if (event.key === "Enter") editInput.blur();
+ });
+}
+
+function renderSummary() {
+ const notBoughtList = summarySections[0].querySelector(".summary-list");
+ const boughtList = summarySections[1].querySelector(".summary-list");
+ notBoughtList.textContent = "";
+ boughtList.textContent = "";
+ products.forEach(product => {
+ const item = createSummaryItem(product);
+ if (product.bought) {
+ item.classList.add("bought-label");
+ boughtList.append(item);
+ } else {
+ notBoughtList.append(item);
+ }
+ });
+}
+
+function createSummaryItem(product) {
+ const li = document.createElement("li");
+ const name = document.createElement("strong");
+ name.textContent = product.name;
+ const amount = document.createElement("output");
+ amount.classList.add("amount");
+ amount.textContent = product.count;
+ li.append(name, amount);
+ return li;
+}
+
+function saveAndRender() {
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(products));
+ render();
+}
+
+function loadProducts() {
+ const savedProducts = localStorage.getItem(STORAGE_KEY);
+
+ if (savedProducts) {
+ return JSON.parse(savedProducts);
+ }
+
+ return [
+ {
+ id: 1,
+ name: "Помідори",
+ count: 2,
+ bought: true
+ },
+ {
+ id: 2,
+ name: "Печиво",
+ count: 2,
+ bought: false
+ },
+ {
+ id: 3,
+ name: "Сир",
+ count: 1,
+ bought: false
+ }
+ ];
+}
\ No newline at end of file