diff --git a/.paul/HANDOFF-2026-03-16.md b/.paul/HANDOFF-2026-03-16.md
new file mode 100644
index 0000000..df45811
--- /dev/null
+++ b/.paul/HANDOFF-2026-03-16.md
@@ -0,0 +1,91 @@
+# PAUL Handoff
+
+**Date:** 2026-03-16
+**Status:** paused — checkpoint human-verify in progress
+
+---
+
+## READ THIS FIRST
+
+You have no prior context. This document tells you everything.
+
+**Project:** orderPRO — aplikacja do zarządzania zamówieniami z wielu platform
+**Core value:** Sprzedawca może obsługiwać zamówienia ze wszystkich kanałów sprzedaży i nadawać przesyłki bez przełączania się między platformami.
+
+---
+
+## Current State
+
+**Milestone:** v0.4 Moduł E-mail
+**Phase:** 14 of 3 (in milestone) — Szablony wiadomości e-mail
+**Plan:** 14-01 — APPLY in progress (checkpoint human-verify)
+
+**Loop Position:**
+```
+PLAN ──▶ APPLY ──▶ UNIFY
+ ✓ ◐ ○ [APPLY in progress — Task 1+2 done, Task 3 checkpoint awaiting approval]
+```
+
+---
+
+## What Was Done
+
+- Task 1: Created `EmailTemplateRepository` + `EmailTemplateController` + routes (6 endpoints)
+- Task 2: Created view `email-templates.php` with Quill.js CDN editor, variable panel, preview modal, AJAX toggle
+- Added sidebar link "Szablony e-mail" in `layouts/app.php`
+- Compiled SCSS (modal-overlay, email-tpl-editor styles)
+- Fixed 2 bugs discovered during deploy:
+ - `AuthService` namespace: `App\Core\Auth\AuthService` → `App\Modules\Auth\AuthService`
+ - `Flash` namespace: `App\Core\Session\Flash` → `App\Core\Support\Flash`
+
+---
+
+## What's In Progress
+
+- **Task 3 checkpoint:human-verify** — user was testing the deployed page when session paused
+- User reported 2 namespace errors which were fixed, needs to re-test
+
+---
+
+## What's Next
+
+**Immediate:** User re-tests `/settings/email-templates` after namespace fixes. If approved → APPLY complete.
+
+**After that:** Run `sonar-scanner` (required skill), then `/paul:unify .paul/phases/14-email-templates/14-01-PLAN.md`
+
+---
+
+## Key Files
+
+| File | Purpose |
+|------|---------|
+| `.paul/STATE.md` | Live project state |
+| `.paul/ROADMAP.md` | Phase overview |
+| `.paul/phases/14-email-templates/14-01-PLAN.md` | Current plan |
+| `src/Modules/Settings/EmailTemplateController.php` | Controller (CRUD + preview + variables) |
+| `src/Modules/Settings/EmailTemplateRepository.php` | Repository (DB operations) |
+| `resources/views/settings/email-templates.php` | View (list + form + Quill.js + variable panel) |
+| `routes/web.php` | Routes (6 new endpoints) |
+| `resources/views/layouts/app.php` | Sidebar link added |
+| `resources/scss/app.scss` | Styles (modal-overlay, email-tpl-editor) |
+
+---
+
+## Namespace Fixes Applied
+
+These were wrong in the initial controller and have been corrected:
+- `use App\Core\Auth\AuthService` → `use App\Modules\Auth\AuthService`
+- `use App\Core\Session\Flash` → `use App\Core\Support\Flash`
+
+---
+
+## Resume Instructions
+
+1. Read `.paul/STATE.md` for latest position
+2. Check loop position — APPLY in progress, Task 3 checkpoint
+3. Run `/paul:resume` or ask user to re-test `/settings/email-templates`
+4. On approval → finalize APPLY → sonar-scanner → `/paul:unify`
+
+---
+
+*Handoff created: 2026-03-16*
diff --git a/.paul/ROADMAP.md b/.paul/ROADMAP.md
index 5819821..d6d812e 100644
--- a/.paul/ROADMAP.md
+++ b/.paul/ROADMAP.md
@@ -13,7 +13,7 @@ Skrzynki pocztowe SMTP, szablony wiadomości z systemem zmiennych (Quill.js), wy
| Phase | Name | Plans | Status |
|-------|------|-------|--------|
| 13 | DB + Skrzynki pocztowe | 1/1 | Complete ✓ |
-| 14 | Szablony wiadomości | TBD | Not started |
+| 14 | Szablony wiadomości | 0/1 | Planning |
| 15 | Wysyłka e-mail z zamówień | TBD | Not started |
## Completed Milestones
diff --git a/.paul/STATE.md b/.paul/STATE.md
index 7f5a982..b1c935b 100644
--- a/.paul/STATE.md
+++ b/.paul/STATE.md
@@ -10,10 +10,10 @@ See: .paul/PROJECT.md (updated 2026-03-12)
## Current Position
Milestone: v0.4 Moduł E-mail
-Phase: [1] of [3] (DB + Skrzynki pocztowe) — Complete
-Plan: 13-01 complete
-Status: Phase 13 complete, ready for Phase 14
-Last activity: 2026-03-15 — UNIFY 13-01 complete, phase transition done
+Phase: [2] of [3] (Szablony wiadomości) — Planning
+Plan: 14-01 created, awaiting approval
+Status: PLAN created, ready for APPLY
+Last activity: 2026-03-16 — Created .paul/phases/14-email-templates/14-01-PLAN.md
Progress:
- v0.1 Initial Release: [██████████] 100% ✓
@@ -21,7 +21,7 @@ Progress:
- v0.3 Moduł Paragonów: [██████████] 100% ✓
- v0.4 Moduł E-mail: [███░░░░░░░] 33%
- Phase 13: [██████████] 100% ✓
- - Phase 14: [░░░░░░░░░░] 0%
+ - Phase 14: [░░░░░░░░░░] 0% ← planning
- Phase 15: [░░░░░░░░░░] 0%
## Loop Position
@@ -29,7 +29,7 @@ Progress:
Current loop state:
```
PLAN ──▶ APPLY ──▶ UNIFY
- ✓ ✓ ✓ [Loop complete — Phase 13 done, ready for Phase 14]
+ ✓ ◐ ○ [APPLY in progress — Task 3 checkpoint awaiting approval]
```
## Accumulated Context
@@ -147,7 +147,7 @@ PLAN ──▶ APPLY ──▶ UNIFY
- **Delivery mapping "Szukaj..." layout** — JS `attachSelectFilter()` w allegro.php tworzy input search dla InPost/Apaczka selectów, wizualnie wygląda jakby należał do wiersza powyżej. Pre-existing bug, do naprawy osobno.
### Git State
-Last commit: 22fc330 (feat(11-12-accounting): phases 11-12 complete — milestone v0.3 done)
+Last commit: 3223aac (feat(13-email-mailboxes): phase 13 complete — email DB foundation + SMTP mailbox CRUD)
Branch: main
Feature branches merged: none
@@ -156,16 +156,17 @@ Brak.
## Session Continuity
-Last session: 2026-03-15
-Stopped at: Phase 13 complete
-Next action: /paul:plan for Phase 14 (Szablony wiadomości)
-Resume file: .paul/phases/13-email-mailboxes/13-01-SUMMARY.md
+Last session: 2026-03-16
+Stopped at: APPLY 14-01 in progress — Task 3 checkpoint human-verify (2 namespace bugs fixed, awaiting re-test)
+Next action: User re-tests /settings/email-templates → if approved → finalize APPLY → sonar-scanner → /paul:unify
+Resume file: .paul/HANDOFF-2026-03-16.md
Resume context:
- v0.1: COMPLETE ✓ (6 phases, 15 plans)
- v0.2: COMPLETE ✓ (1 phase, 5 plans)
- v0.3: COMPLETE ✓ (5 phases, 5 plans) — Moduł Paragonów
-- v0.4: IN PROGRESS — Phase 13 complete, Phase 14 next
+- v0.4: IN PROGRESS — Phase 13 complete, Phase 14 APPLY checkpoint
- Faza 0 (nieaktywne przyciski) zrobiona poza planem
+- 2 namespace fixes applied: AuthService, Flash
---
*STATE.md — Updated after every significant action*
diff --git a/.paul/phases/14-email-templates/14-01-PLAN.md b/.paul/phases/14-email-templates/14-01-PLAN.md
new file mode 100644
index 0000000..6a00f4d
--- /dev/null
+++ b/.paul/phases/14-email-templates/14-01-PLAN.md
@@ -0,0 +1,319 @@
+---
+phase: 14-email-templates
+plan: 01
+type: execute
+wave: 1
+depends_on: ["13-01"]
+files_modified:
+ - src/Modules/Settings/EmailTemplateController.php
+ - src/Modules/Settings/EmailTemplateRepository.php
+ - resources/views/settings/email-templates.php
+ - resources/views/settings/email-template-form.php
+ - routes/web.php
+ - resources/views/layouts/app.php
+ - resources/scss/app.scss
+ - public/assets/css/app.css
+autonomous: false
+---
+
+
+## Goal
+CRUD szablonów wiadomości e-mail z edytorem rich-text (Quill.js) i systemem zmiennych do personalizacji treści (np. {{order.number}}, {{buyer.name}}).
+
+## Purpose
+Użytkownik musi mieć możliwość tworzenia i zarządzania szablonami e-mail, które w fazie 15 będą używane do wysyłki wiadomości z poziomu zamówień. Szablony muszą obsługiwać zmienne dynamiczne rozwiązywane z danych zamówienia.
+
+## Output
+- EmailTemplateController + EmailTemplateRepository (CRUD)
+- Widok listy szablonów + formularz edycji z Quill.js
+- System zmiennych: definicja dostępnych zmiennych, wstawianie z UI, podgląd
+- Link w sidebarze Settings
+
+
+
+## Project Context
+@.paul/PROJECT.md
+@.paul/ROADMAP.md
+@.paul/STATE.md
+
+## Prior Work
+@.paul/phases/13-email-mailboxes/13-01-SUMMARY.md
+- email_templates table already created (Phase 13)
+- EmailMailboxRepository::listActive() ready for mailbox select
+- Pattern: EmailMailboxController CRUD (same structure to follow)
+
+## Source Files
+@database/migrations/20260315_000055_create_email_templates_table.sql
+@src/Modules/Settings/EmailMailboxController.php
+@src/Modules/Settings/EmailMailboxRepository.php
+@resources/views/settings/email-mailboxes.php
+@routes/web.php
+@resources/views/layouts/app.php
+
+
+
+## Required Skills (from SPECIAL-FLOWS.md)
+
+| Skill | Priority | When to Invoke | Loaded? |
+|-------|----------|----------------|---------|
+| sonar-scanner | required | Po APPLY, przed UNIFY | ○ |
+
+## Skill Invocation Checklist
+- [ ] sonar-scanner uruchomiony po APPLY
+
+
+
+
+## AC-1: Lista szablonów
+```gherkin
+Given użytkownik jest zalogowany i przechodzi do Ustawienia > Szablony e-mail
+When strona się ładuje
+Then widzi tabelę z kolumnami: Nazwa, Temat, Skrzynka, Status, Akcje
+And każdy szablon ma przyciski: Edytuj, Włącz/Wyłącz, Usuń
+```
+
+## AC-2: Tworzenie i edycja szablonu
+```gherkin
+Given użytkownik jest na stronie szablonów e-mail
+When wypełnia formularz (nazwa, temat, skrzynka, treść HTML) i zapisuje
+Then szablon jest zapisany w bazie z poprawnym body_html z Quill.js
+And po edycji istniejącego szablonu treść Quill jest załadowana poprawnie
+```
+
+## AC-3: Edytor Quill.js z toolbarem
+```gherkin
+Given użytkownik edytuje treść szablonu
+When korzysta z edytora
+Then dostępne są: bold, italic, underline, listy, linki, nagłówki, kolory, wyrównanie
+And treść jest zapisywana jako HTML w polu body_html
+```
+
+## AC-4: System zmiennych — wstawianie
+```gherkin
+Given użytkownik edytuje szablon
+When klika przycisk "Wstaw zmienną" i wybiera zmienną z listy (np. {{zamowienie.numer}})
+Then zmienna jest wstawiana do treści edytora w miejscu kursora
+And zmienne są wizualnie wyróżnione w edytorze (np. badge/tag)
+```
+
+## AC-5: System zmiennych — definicja
+```gherkin
+Given system zmiennych jest zaimplementowany
+When użytkownik otwiera listę zmiennych
+Then widzi pogrupowane zmienne:
+ - Zamówienie: numer, źródło, kwota, waluta, data
+ - Kupujący: imię i nazwisko, email, telefon, login
+ - Adres dostawy: ulica, miasto, kod pocztowy, kraj
+ - Firma: nazwa, NIP (jeśli faktura)
+And każda zmienna ma opis i placeholder (np. {{zamowienie.numer}})
+```
+
+## AC-6: Toggle statusu i usuwanie
+```gherkin
+Given szablon istnieje na liście
+When użytkownik klika Włącz/Wyłącz
+Then status is_active się zmienia (toggle AJAX)
+When użytkownik klika Usuń i potwierdzi (OrderProAlerts.confirm)
+Then szablon jest usunięty z bazy
+```
+
+## AC-7: Podgląd szablonu z przykładowymi danymi
+```gherkin
+Given użytkownik edytuje szablon z zmiennymi
+When klika przycisk "Podgląd"
+Then widzi modal z treścią szablonu gdzie zmienne są zastąpione przykładowymi danymi
+And temat wiadomości jest również rozwiązany z przykładowymi danymi
+```
+
+
+
+
+
+
+ Task 1: EmailTemplateRepository + EmailTemplateController + routes
+
+ src/Modules/Settings/EmailTemplateRepository.php,
+ src/Modules/Settings/EmailTemplateController.php,
+ routes/web.php
+
+
+ **EmailTemplateRepository** (wzorowany na EmailMailboxRepository):
+ - listAll(): array — pobiera wszystkie szablony JOIN email_mailboxes (nazwa skrzynki), ORDER BY name
+ - findById(int $id): ?array — jeden szablon po ID
+ - save(array $data): void — INSERT lub UPDATE (id > 0 = update)
+ - delete(int $id): void — DELETE po ID
+ - toggleStatus(int $id): void — toggle is_active (UPDATE SET is_active = NOT is_active)
+ - listActive(): array — szablony z is_active=1 (do użycia w fazie 15)
+ - Medoo + prepared statements, bez surowego SQL
+
+ **EmailTemplateController** (wzorowany na EmailMailboxController):
+ - __construct(TemplateEngine, Translator, Auth, EmailTemplateRepository, EmailMailboxRepository)
+ - index(Request): Response — lista szablonów + formularz (edit mode jeśli ?edit=ID)
+ - save(Request): Response — walidacja (name, subject, body_html required) + CSRF + zapis + redirect z Flash
+ - delete(Request): Response — CSRF + usunięcie + redirect z Flash
+ - toggleStatus(Request): Response — AJAX POST, JSON response {success: true}
+ - preview(Request): Response — AJAX POST, przyjmuje subject + body_html, zwraca JSON z resolved variables (przykładowe dane)
+ - getVariables(Request): Response — AJAX GET, zwraca JSON z definicją dostępnych zmiennych pogrupowanych
+
+ **Definicja zmiennych** (statyczna metoda lub stała w kontrolerze):
+ ```
+ Zamówienie:
+ {{zamowienie.numer}} — Numer wewnętrzny (OP...)
+ {{zamowienie.numer_zewnetrzny}} — Numer z platformy
+ {{zamowienie.zrodlo}} — Źródło (Allegro/shopPRO/...)
+ {{zamowienie.kwota}} — Kwota brutto
+ {{zamowienie.waluta}} — Waluta (PLN/EUR/...)
+ {{zamowienie.data}} — Data zamówienia
+ Kupujący:
+ {{kupujacy.imie_nazwisko}} — Imię i nazwisko
+ {{kupujacy.email}} — Adres e-mail
+ {{kupujacy.telefon}} — Telefon
+ {{kupujacy.login}} — Login platformy
+ Adres dostawy:
+ {{adres.ulica}} — Ulica z numerem
+ {{adres.miasto}} — Miasto
+ {{adres.kod_pocztowy}} — Kod pocztowy
+ {{adres.kraj}} — Kraj
+ Firma:
+ {{firma.nazwa}} — Nazwa firmy
+ {{firma.nip}} — NIP
+ ```
+
+ **Metoda resolveVariables(string $text, array $sampleData): string**
+ - Zamienia {{klucz.pole}} na wartości z $sampleData
+ - Dla podglądu: używa przykładowych (hardcoded) danych
+ - Dla wysyłki (faza 15): otrzyma prawdziwe dane zamówienia
+
+ **Routes** (dodać w web.php obok email-mailboxes):
+ - GET /settings/email-templates → index
+ - POST /settings/email-templates/save → save
+ - POST /settings/email-templates/delete → delete
+ - POST /settings/email-templates/toggle → toggleStatus
+ - POST /settings/email-templates/preview → preview (AJAX)
+ - GET /settings/email-templates/variables → getVariables (AJAX)
+
+
+ - Klasy się ładują bez Fatal Error (PHP syntax check)
+ - Routes zarejestrowane poprawnie
+ - Strona /settings/email-templates renderuje się bez błędów
+
+ AC-1, AC-2, AC-5, AC-6, AC-7 backend satisfied
+
+
+
+ Task 2: Widoki — lista szablonów + formularz z Quill.js + system zmiennych UI
+
+ resources/views/settings/email-templates.php,
+ resources/views/settings/email-template-form.php,
+ resources/views/layouts/app.php,
+ resources/scss/app.scss,
+ public/assets/css/app.css
+
+
+ **Widok listy** (resources/views/settings/email-templates.php):
+ - Tabela: Nazwa, Temat, Skrzynka (nazwa lub "—"), Status (badge), Akcje
+ - Przycisk "Edytuj" → ?edit=ID
+ - Toggle status: AJAX POST do /settings/email-templates/toggle (jak w mailboxes)
+ - Usuwanie: window.OrderProAlerts.confirm() → POST /settings/email-templates/delete
+ - Flash messages (success/error)
+ - Przycisk "Nowy szablon" → przejście do formularza
+
+ **Formularz edycji** (osobny plik lub sekcja w tym samym widoku):
+ - Pola: nazwa (input), temat (input — z możliwością wpisania zmiennych ręcznie), skrzynka (select z listActive), status (checkbox)
+ - Edytor Quill.js:
+ - Załadować z CDN: quill@2 (https://cdn.quilljs.com/2.0.3/quill.snow.css + quill.js)
+ - Toolbar: bold, italic, underline, strike, headers (h1-h3), lists (ordered/bullet), link, color, background, align
+ - Hidden input #body_html synchronizowany z Quill content on form submit
+ - Panel zmiennych (sidebar lub dropdown):
+ - Przycisk "Wstaw zmienną" otwiera listę pogrupowaną (pobrana AJAX z /variables)
+ - Klik na zmienną → wstawia {{zmienna.pole}} w miejsce kursora w Quill
+ - Przycisk "Podgląd":
+ - AJAX POST do /settings/email-templates/preview z subject + body_html
+ - Wynik w modalu (resolved subject + resolved body_html)
+ - Przycisk "Zapisz" → submit formularza
+
+ **Sidebar** (resources/views/layouts/app.php):
+ - Dodać link "Szablony e-mail" pod "Skrzynki pocztowe" w sekcji Settings
+ - activeSettings === 'email-templates'
+
+ **Style** (resources/scss/app.scss → public/assets/css/app.css):
+ - Styl dla kontenera Quill (.ql-editor min-height: 200px)
+ - Styl dla panelu zmiennych (.email-var-list, .email-var-group, .email-var-item)
+ - Styl dla modala podglądu (reuse istniejący .modal jeśli jest, lub prosty modal)
+ - Kompaktowy layout zgodnie z zasadami projektu
+
+ **Nie używać** natywnych alert()/confirm() — tylko OrderProAlerts.
+ **Quill CDN** — nie dodawać jako zależność npm/composer, wystarczy CDN w widoku.
+
+
+ - Quill.js ładuje się i renderuje edytor
+ - Formularz zapisuje poprawnie (body_html zawiera HTML z Quill)
+ - Zmienne wstawiane w edytor poprawnie
+ - Podgląd wyświetla resolved template
+ - SCSS skompilowane do CSS
+
+ AC-1, AC-2, AC-3, AC-4, AC-5, AC-6, AC-7 UI satisfied
+
+
+
+ CRUD szablonów e-mail z Quill.js i systemem zmiennych
+
+ 1. Otwórz: /settings/email-templates
+ 2. Sprawdź: link "Szablony e-mail" widoczny w sidebarze
+ 3. Kliknij "Nowy szablon":
+ a. Wypełnij nazwę, temat (np. "Potwierdzenie zamówienia {{zamowienie.numer}}")
+ b. Wybierz skrzynkę z listy
+ c. W Quill wpisz treść, użyj formatowania (bold, listy)
+ d. Kliknij "Wstaw zmienną" → wybierz np. {{kupujacy.imie_nazwisko}}
+ e. Kliknij "Podgląd" → sprawdź czy zmienne zamienione na przykładowe dane
+ f. Zapisz szablon
+ 4. Na liście: sprawdź czy szablon się pojawił z poprawną nazwą/tematem/skrzynką
+ 5. Edytuj szablon — sprawdź czy Quill załadował treść HTML poprawnie
+ 6. Toggle status (włącz/wyłącz) — badge powinien się zmienić
+ 7. Usuń szablon — potwierdzenie OrderProAlerts, usunięcie z listy
+
+ Type "approved" to continue, or describe issues to fix
+
+
+
+
+
+
+## DO NOT CHANGE
+- database/migrations/* (tabela email_templates już istnieje z fazy 13)
+- src/Modules/Settings/EmailMailboxController.php (tylko import/reuse)
+- src/Modules/Settings/EmailMailboxRepository.php (tylko wywołanie listActive)
+
+## SCOPE LIMITS
+- Nie implementować wysyłki e-mail (faza 15)
+- Nie dodawać PHPMailer/SwiftMailer (faza 15)
+- Nie modyfikować tabeli email_templates (schemat zamrożony)
+- Quill.js z CDN — bez npm/bundlera
+- Zmienne rozwiązywane tylko z przykładowymi danymi (prawdziwe dane zamówienia w fazie 15)
+
+
+
+
+Before declaring plan complete:
+- [ ] /settings/email-templates renderuje się bez błędów PHP
+- [ ] CRUD: create, read, update, delete szablonów działa
+- [ ] Quill.js edytor ładuje się i zapisuje HTML
+- [ ] System zmiennych: lista, wstawianie, podgląd z przykładowymi danymi
+- [ ] Toggle statusu via AJAX działa
+- [ ] Usuwanie z potwierdzeniem OrderProAlerts działa
+- [ ] Link w sidebarze Settings aktywny
+- [ ] SCSS skompilowane, brak inline styles w widokach
+- [ ] Brak natywnych alert()/confirm()
+- [ ] CSRF walidowany we wszystkich POST
+
+
+
+- Wszystkie AC-1 do AC-7 spełnione
+- Wszystkie taski zakończone
+- Checkpoint human-verify approved
+- Brak błędów PHP, brak broken UI
+
+
+
diff --git a/public/assets/css/app.css b/public/assets/css/app.css
index 3624162..5d187f8 100644
--- a/public/assets/css/app.css
+++ b/public/assets/css/app.css
@@ -1 +1 @@
-:root{--c-primary: #6690f4;--c-primary-dark: #3164db;--c-bg: #f4f6f9;--c-surface: #ffffff;--c-text: #4e5e6a;--c-text-strong: #2d3748;--c-muted: #718096;--c-border: #b0bec5;--c-danger: #cc0000;--focus-ring: 0 0 0 3px rgba(102, 144, 244, 0.15);--shadow-card: 0 1px 4px rgba(0, 0, 0, 0.06)}.btn{display:inline-flex;align-items:center;justify-content:center;min-height:34px;padding:6px 12px;border:1px solid rgba(0,0,0,0);border-radius:8px;font:inherit;font-weight:600;text-decoration:none;cursor:pointer;transition:background-color .2s ease,border-color .2s ease,color .2s ease,transform .1s ease}.btn--primary{color:#fff;background:var(--c-primary)}.btn--primary:hover{background:var(--c-primary-dark)}.btn--secondary{color:var(--c-text-strong);border-color:var(--c-border);background:var(--c-surface)}.btn--secondary:hover{border-color:#cbd5e0;background:#f8fafc}.btn--danger{color:#fff;border-color:#b91c1c;background:#dc2626}.btn--danger:hover{border-color:#991b1b;background:#b91c1c}.btn--sm{min-height:28px;padding:3px 10px;font-size:12px}.btn--block{width:100%}.btn--disabled{opacity:.3;cursor:not-allowed;pointer-events:none}.btn:active{transform:translateY(1px)}.btn:focus-visible{outline:none;box-shadow:var(--focus-ring);border-color:var(--c-primary)}.form-control{width:100%;min-height:30px;border:1px solid var(--c-border);border-radius:6px;padding:4px 8px;font:inherit;color:var(--c-text-strong);background:#fff;transition:border-color .2s ease,box-shadow .2s ease}.form-control:focus{outline:none;border-color:var(--c-primary);box-shadow:var(--focus-ring)}.input{min-height:34px;border:1px solid var(--c-border);border-radius:8px;padding:5px 10px;font:inherit;color:var(--c-text-strong);background:#fff}.input--sm{min-height:28px;padding:3px 8px;font-size:12px}.flash{padding:8px 12px;border-radius:6px;font-size:13px}.flash--success{border:1px solid #b7ebcf;background:#f0fff6;color:#0f6b39}.flash--error{border:1px solid #fed7d7;background:#fff5f5;color:var(--c-danger)}.alert{padding:12px 14px;border-radius:8px;border:1px solid rgba(0,0,0,0);font-size:13px;min-height:44px}.alert--danger{border-color:#fed7d7;background:#fff5f5;color:var(--c-danger)}.alert--success{border-color:#b7ebcf;background:#f0fff6;color:#0f6b39}.alert--warning{border-color:#f7dd8b;background:#fff8e8;color:#815500}.form-field{display:grid;gap:5px}.field-label{color:var(--c-text-strong);font-size:13px;font-weight:600}.table-wrap{width:100%;overflow-x:auto}.table-wrap--visible{overflow:visible !important;overflow-x:visible !important}.table{width:100%;border-collapse:collapse;background:var(--c-surface)}.table th,.table td{padding:10px 12px;border-bottom:1px solid var(--c-border);text-align:left}.table th{color:var(--c-text-strong);font-weight:700;background:#f8fafc}.table--details th{white-space:nowrap}.table--details th:first-child,.table--details td:first-child{width:36px;text-align:center}.pagination{display:flex;align-items:center;flex-wrap:wrap;gap:8px}.pagination__item{display:inline-flex;align-items:center;justify-content:center;min-width:36px;height:36px;padding:0 10px;border-radius:8px;border:1px solid var(--c-border);color:var(--c-text-strong);background:var(--c-surface);text-decoration:none;font-weight:600}.pagination__item:hover{border-color:#cbd5e0;background:#f8fafc}.pagination__item.is-active{border-color:var(--c-primary);color:var(--c-primary);background:#edf2ff}.receipt-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:16px;padding-bottom:12px;border-bottom:2px solid var(--c-text-strong)}.receipt-header__seller{flex:1}.receipt-header__seller strong{font-size:14px;display:block;margin-bottom:4px}.receipt-header__title{text-align:right}.receipt-header__title h1{font-size:18px;font-weight:700;margin-bottom:4px}.receipt-print{max-width:700px;margin:0 auto}@media print{.receipt-print{max-width:100%}}*{box-sizing:border-box}html,body{min-height:100%}body{margin:0;font-family:"Roboto","Segoe UI",sans-serif;font-size:13px;color:var(--c-text);background:var(--c-bg)}a{color:var(--c-primary)}.app-shell{min-height:100vh;display:flex}.sidebar{width:260px;min-width:260px;flex-shrink:0;overflow:hidden;transition:width .22s ease,min-width .22s ease;border-right:1px solid #243041;background:#111a28;padding:18px 10px;display:flex;flex-direction:column}.sidebar.is-collapsed{width:52px;min-width:52px}.sidebar__brand{display:flex;align-items:center;justify-content:space-between;margin:4px 4px 16px;gap:6px;min-width:0}.sidebar__brand-text{color:#e9f0ff;font-size:24px;font-weight:300;letter-spacing:-0.02em;white-space:nowrap;overflow:hidden;flex:1;min-width:0}.sidebar__brand-text strong{font-weight:700}.sidebar__collapse-btn{flex-shrink:0;width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0);border:1px solid #2a3a54;border-radius:6px;color:#64748b;cursor:pointer;padding:0;transition:background .15s,color .15s}.sidebar__collapse-btn:hover{background:#1b2a3f;color:#cbd5e1}.sidebar__collapse-icon{display:block;transition:transform .22s ease;flex-shrink:0}.sidebar.is-collapsed .sidebar__collapse-icon{transform:rotate(180deg)}.sidebar__nav{display:grid;gap:4px}.sidebar__link{border-radius:8px;padding:10px 12px;text-decoration:none;color:#cbd5e1;font-weight:600}.sidebar__link:hover{color:#f8fafc;background:#1b2a3f}.sidebar__link.is-active{color:#fff;background:#2e4f93}.sidebar__group{display:grid;gap:2px}.sidebar__group-toggle{list-style:none;border-radius:8px;padding:9px 10px;color:#cbd5e1;font-weight:600;cursor:pointer;display:flex;align-items:center;gap:9px;white-space:nowrap;user-select:none}.sidebar__group-toggle::-webkit-details-marker{display:none}.sidebar__group:hover .sidebar__group-toggle,.sidebar__group-toggle:hover{color:#f8fafc;background:#1b2a3f}.sidebar__group.is-active .sidebar__group-toggle{color:#fff;background:#2e4f93}.sidebar__icon{flex-shrink:0;width:18px;height:18px;display:flex;align-items:center;justify-content:center;opacity:.85}.sidebar__label{flex:1;min-width:0;overflow:hidden}.sidebar__toggle-arrow{flex-shrink:0;margin-left:auto;opacity:.5;transition:transform .18s ease}details[open]>.sidebar__group-toggle .sidebar__toggle-arrow{transform:rotate(180deg)}.sidebar__group-links{display:grid;gap:2px;padding-left:12px;overflow:hidden}.sidebar__sublink{border-radius:6px;padding:7px 10px 7px 8px;text-decoration:none;color:#94a3b8;font-size:12.5px;font-weight:500;display:flex;align-items:center;gap:8px;white-space:nowrap}.sidebar__sublink::before{content:"";flex-shrink:0;width:5px;height:5px;border-radius:50%;background:rgba(148,163,184,.3);transition:background .15s}.sidebar__sublink:hover{color:#e2e8f0;background:#1b2a3f}.sidebar__sublink:hover::before{background:rgba(148,163,184,.65)}.sidebar__sublink.is-active{color:#fff;background:rgba(46,79,147,.55)}.sidebar__sublink.is-active::before{background:#93c5fd}.app-main{flex:1;min-width:0}.topbar{height:50px;border-bottom:1px solid var(--c-border);background:var(--c-surface);display:flex;align-items:center;justify-content:space-between;padding:0 20px;position:sticky;top:0;z-index:100}.brand{font-size:22px;font-weight:300;letter-spacing:-0.02em;color:var(--c-text-strong)}.brand strong{font-weight:700}.container{max-width:none;width:calc(100% - 20px);margin:12px 10px;padding:0 4px 14px}.card{background:var(--c-surface);border-radius:10px;box-shadow:var(--shadow-card);padding:14px}.card h1{margin:0 0 10px;color:var(--c-text-strong);font-size:24px;font-weight:700}.muted{color:var(--c-muted)}.accent{color:var(--c-primary);font-weight:600}.users-form{display:grid;gap:14px;max-width:460px}.form-field{margin-bottom:12px}.section-title{margin:0;color:var(--c-text-strong);font-size:18px;font-weight:700}h2.section-title,h3.section-title,h4.section-title{display:flex;align-items:center;gap:6px;font-weight:600;padding:6px 0;border-bottom:1px solid #e2e8f0;color:var(--c-primary, #2563eb)}h2.section-title::before,h3.section-title::before,h4.section-title::before{content:"■";font-size:.55em;opacity:.5}h3.section-title,h4.section-title{font-size:15px}h3.section-title::before,h4.section-title::before{content:"◆";font-size:.5em}.mt-0{margin-top:0}.mt-4{margin-top:4px}.mt-12{margin-top:8px}.mt-16{margin-top:12px}.settings-grid{display:grid;grid-template-columns:repeat(3, minmax(0, 1fr));gap:12px}.settings-nav{display:flex;gap:8px;flex-wrap:wrap}.settings-nav__link{text-decoration:none;border:1px solid var(--c-border);border-radius:8px;padding:8px 12px;color:var(--c-text-strong);font-weight:600}.settings-nav__link:hover{background:#f8fafc}.settings-nav__link.is-active{border-color:var(--c-primary);color:var(--c-primary);background:#edf2ff}.settings-stat{border:1px solid var(--c-border);border-radius:8px;padding:12px;background:#f8fafc}.settings-stat__label{display:block;color:var(--c-muted);font-size:12px;margin-bottom:4px}.settings-stat__value{color:var(--c-text-strong);font-size:20px}.settings-logs{margin:0;padding:12px;border-radius:8px;border:1px solid var(--c-border);background:#0b1220;color:#d1d5db;font-size:12px;line-height:1.5;overflow:auto}.settings-allegro-callback{display:block;width:100%;padding:8px 10px;border:1px solid var(--c-border);border-radius:8px;background:#f8fafc;color:var(--c-text-strong);font-size:12px;line-height:1.45;word-break:break-all}.page-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.filters-grid{display:grid;grid-template-columns:repeat(3, minmax(0, 1fr));gap:12px}.filters-actions{display:flex;align-items:center;gap:8px}.product-form .form-control{width:100%}.form-grid{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:12px}.form-grid-2{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:12px;align-items:start}.form-grid-3{display:grid;grid-template-columns:repeat(3, minmax(0, 1fr));gap:12px;align-items:start}.form-grid-4{display:grid;grid-template-columns:repeat(4, minmax(0, 1fr));gap:12px;align-items:start}.form-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:flex-start}.form-actions .btn{align-self:flex-start}.statuses-form{display:grid;gap:8px;grid-template-columns:repeat(2, minmax(0, 1fr))}.statuses-form .form-actions{grid-column:1/-1}.statuses-color-input{min-height:32px;padding:2px}.statuses-hint{grid-column:1/-1;margin:0}.statuses-group-block{border:1px solid var(--c-border);border-radius:10px;padding:8px;background:#fbfdff}.statuses-group-block__head{display:flex;align-items:center;justify-content:space-between;gap:6px;flex-wrap:wrap}.statuses-group-block__title{margin:0;display:inline-flex;align-items:center;gap:6px;color:var(--c-text-strong);font-size:14px}.statuses-color-dot{width:12px;height:12px;border-radius:999px;border:1px solid rgba(15,23,42,.15)}.statuses-dnd-list{margin:6px 0 0;padding:0;list-style:none;display:grid;gap:6px}.statuses-dnd-item{display:grid;grid-template-columns:24px 1fr;gap:6px;border:1px solid #dce4f0;border-radius:8px;background:#fff;padding:6px}.statuses-dnd-item__content{display:flex;align-items:center;gap:6px;min-width:0}.statuses-dnd-item.is-dragging{opacity:.6}.statuses-dnd-item__drag{display:inline-flex;align-items:center;justify-content:center;border:1px dashed #cbd5e1;border-radius:6px;color:#64748b;cursor:grab;user-select:none;font-weight:700;font-size:12px}.statuses-dnd-item__drag:active{cursor:grabbing}.statuses-inline-form{display:grid;gap:6px}.statuses-inline-form--row{grid-template-columns:minmax(180px, 1.4fr) minmax(150px, 1fr) auto auto auto;align-items:center;flex:1 1 auto;min-width:0}.statuses-inline-form--row-group{grid-template-columns:minmax(180px, 1.5fr) 56px auto auto auto;align-items:center;flex:1 1 auto;min-width:0}.statuses-inline-form--row .form-control,.statuses-inline-form--row-group .form-control{min-height:30px;padding:4px 8px}.statuses-inline-form--row .btn,.statuses-inline-form--row-group .btn,.statuses-inline-delete .btn{min-height:30px;padding:4px 10px;font-size:12px}.statuses-inline-check{margin-top:0;white-space:nowrap;font-size:12px}.statuses-inline-delete{margin:0;flex:0 0 auto}.statuses-code-label{font-size:12px;color:var(--c-muted)}.statuses-code-readonly{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;font-size:12px}.statuses-code-readonly code{background:#eef2f7;border-radius:6px;padding:1px 6px;color:#1f2937;font-size:12px}.field-inline{display:flex;align-items:center;gap:8px;margin-top:2px}.modal-backdrop{position:fixed;inset:0;background:rgba(15,23,42,.5);display:flex;align-items:center;justify-content:center;padding:16px;z-index:200}.modal-backdrop[hidden]{display:none}.modal{width:min(560px,100%);background:#fff;border-radius:10px;box-shadow:0 20px 40px rgba(15,23,42,.35);overflow:hidden}.modal__header{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:16px 18px;border-bottom:1px solid var(--c-border)}.modal__header h3{margin:0;font-size:18px;color:var(--c-text-strong)}.modal__body{padding:16px 18px 18px}.status-pill{display:inline-flex;align-items:center;justify-content:center;border:1px solid #fed7d7;background:#fff5f5;color:#9b2c2c;padding:2px 8px;border-radius:999px;font-size:12px;font-weight:600}.status-pill.is-active{border-color:#b7ebcf;background:#f0fff6;color:#0f6b39}.table-row-actions{display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap}.table-row-actions form{margin:0}.table-list{display:grid;gap:14px}.table-list__header{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap}.table-list__left{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.table-list-header-actions{display:inline-flex;align-items:center;gap:10px;flex-wrap:wrap}.js-filter-toggle-btn.is-active{border-color:#cbd5e0;background:#edf2ff;color:var(--c-primary-dark)}.table-filter-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;font-size:11px;font-weight:700;color:#fff;background:var(--c-primary);border-radius:999px}.table-filters-wrapper{display:none}.table-filters-wrapper.is-open{display:block}.table-list-filters{display:grid;gap:12px;grid-template-columns:repeat(auto-fit, minmax(170px, 1fr));align-items:end}.table-col-toggle-wrapper{position:relative}.table-col-toggle-dropdown{display:none;position:absolute;right:0;top:calc(100% + 6px);z-index:30;width:260px;max-height:360px;overflow:auto;border:1px solid var(--c-border);border-radius:10px;background:#fff;box-shadow:0 10px 25px rgba(15,23,42,.12)}.table-col-toggle-dropdown.is-open{display:block}.table-col-toggle-header{padding:10px 12px;border-bottom:1px solid var(--c-border);font-size:12px;font-weight:700;color:var(--c-muted)}.table-col-toggle-item{display:flex;align-items:center;gap:10px;padding:8px 12px;font-size:13px;color:var(--c-text-strong)}.table-col-toggle-item:hover{background:#f8fafc}.table-col-toggle-footer{border-top:1px solid var(--c-border);padding:8px 12px}.table-col-hidden{display:none}.table-col-switch{position:relative;display:inline-block;width:34px;min-width:34px;height:18px}.table-col-switch input{opacity:0;width:0;height:0;position:absolute}.table-col-switch-slider{position:absolute;top:0;left:0;right:0;bottom:0;background:#cbd5e1;border-radius:999px;transition:background-color .2s ease}.table-col-switch-slider::before{content:"";position:absolute;height:14px;width:14px;left:2px;bottom:2px;background:#fff;border-radius:50%;transition:transform .2s ease}.table-col-switch input:checked+.table-col-switch-slider{background:#16a34a}.table-col-switch input:checked+.table-col-switch-slider::before{transform:translateX(16px)}.table-sort-link{display:inline-flex;align-items:center;gap:6px;color:var(--c-text-strong);text-decoration:none}.table-sort-link:hover{color:var(--c-primary-dark)}.table-sort-icon.is-muted{color:#a0aec0}.table-list__footer{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}.table-list-per-page-form{display:inline-flex;align-items:center;gap:8px}.table-list-per-page-form .form-control{min-width:90px}.table-select-col{width:44px;text-align:center}.table-select-toggle{display:inline-flex;align-items:center;justify-content:center}.table-select-toggle input[type=checkbox]{width:16px;height:16px}.orders-page .orders-head{background:linear-gradient(120deg, #f8fbff 0%, #eef5ff 100%);border:1px solid #dbe7fb}.orders-page .table-list{border:1px solid #dde5f2;border-radius:12px;box-shadow:0 6px 16px rgba(20,44,86,.08)}.orders-page .table-list__header{padding:10px 6px 2px}.orders-page .table-list-filters{padding:6px 6px 2px;border-top:1px solid #ebf0f7;border-bottom:1px solid #ebf0f7;background:#f9fbff}.orders-page .table-wrap{border-radius:10px;overflow:hidden;border:1px solid #e7edf6}.orders-page .table thead th{background:#f3f7fd;color:#30435f;font-size:12px;text-transform:uppercase;letter-spacing:.03em}.orders-page .table tbody td{vertical-align:middle;padding-top:10px;padding-bottom:10px;border-bottom-color:#edf2f8}.orders-page .table tbody tr:hover td{background:#f9fcff}.orders-list-page{padding:10px;margin-bottom:10px}.orders-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap}.orders-stats{display:inline-grid;grid-template-columns:repeat(3, minmax(86px, auto));gap:8px}.orders-stat{border:1px solid #d8e2f0;background:#f8fbff;border-radius:8px;padding:6px 8px;line-height:1.15}.orders-stat__label{display:block;color:#5f6f83;font-size:11px;margin-bottom:2px}.orders-stat__value{color:#12233a;font-size:16px;font-weight:700}.orders-ref{display:grid;gap:2px;min-width:170px}.orders-ref__main{font-weight:700;color:#0f1f35;font-size:14px}.orders-ref__meta{display:inline-flex;flex-wrap:wrap;gap:4px 10px;color:#64748b;font-size:12px}.orders-buyer{display:grid;gap:2px}.orders-buyer__name{color:#0f172a;font-weight:600;font-size:14px}.orders-buyer__meta{display:inline-flex;flex-wrap:wrap;gap:4px 10px;color:#64748b;font-size:12px}.orders-status-wrap{display:inline-flex;align-items:center;gap:5px;flex-wrap:wrap}.order-tag{display:inline-flex;align-items:center;justify-content:center;border:1px solid #d8e1ef;background:#f8fafc;color:#334155;border-radius:999px;padding:2px 8px;font-size:12px;font-weight:700;line-height:1.1}.order-tag.is-info{border-color:#bfdbfe;background:#eff6ff;color:#1d4ed8}.order-tag.is-success{border-color:#bbf7d0;background:#f0fdf4;color:#166534}.order-tag.is-danger{border-color:#fecaca;background:#fef2f2;color:#b91c1c}.order-tag.is-warn{border-color:#fde68a;background:#fffbeb;color:#92400e}.order-tag.is-cod{border-color:#f9a8d4;background:#fdf2f8;color:#9d174d}.order-tag.is-unpaid{border-color:#fca5a5;background:#fef2f2;color:#b91c1c}.orders-mini{font-size:14px;color:#223247;line-height:1.25}.orders-mini__delivery{font-size:12px;color:#64748b;margin-bottom:2px;max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.orders-products{display:grid;gap:4px;min-width:240px}.orders-products__meta,.orders-products__more{font-size:12px;color:#64748b}.orders-product{display:grid;grid-template-columns:48px 1fr;gap:6px;align-items:center}.orders-product__thumb{width:48px;height:48px;border-radius:4px;border:1px solid #dbe3ef;object-fit:cover;background:#fff}.orders-product__thumb--empty{display:inline-block;background:#eef2f7;border-style:dashed}.orders-product__txt{min-width:0;display:grid;gap:1px}.orders-product__name{font-size:14px;color:#0f172a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.orders-product__qty{font-size:12px;color:#64748b}.orders-image-hover-wrap{position:relative;display:inline-flex;align-items:center;justify-content:center;cursor:zoom-in}.orders-image-hover-popup{display:none;position:fixed;left:auto;top:auto;width:350px;max-height:350px;object-fit:contain;border-radius:8px;background:#fff;box-shadow:0 8px 24px rgba(0,0,0,.18);border:1px solid #dfe3ea;z-index:100;pointer-events:none}.orders-image-hover-wrap:hover .orders-image-hover-popup{display:block}.activity-type-badge{display:inline-block;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:500;white-space:nowrap;background:#e2e8f0;color:#334155}.activity-type-badge--status_change{background:#dbeafe;color:#1e40af}.activity-type-badge--payment{background:#dcfce7;color:#166534}.activity-type-badge--invoice{background:#fef3c7;color:#92400e}.activity-type-badge--shipment{background:#e0e7ff;color:#3730a3}.activity-type-badge--message{background:#f3e8ff;color:#6b21a8}.activity-type-badge--document{background:#fce7f3;color:#9d174d}.activity-type-badge--import{background:#f1f5f9;color:#475569}.activity-type-badge--note{background:#ecfdf5;color:#065f46}.text-nowrap{white-space:nowrap}.orders-money{display:grid;gap:2px}.orders-money__main{color:#0f172a;font-weight:700;font-size:14px}.orders-money__meta{color:#64748b;font-size:12px}.table-list[data-table-list-id=orders]{gap:8px}.table-list[data-table-list-id=orders] .table-list__header{padding:2px 0 0}.table-list[data-table-list-id=orders] .table-list-filters{gap:8px;grid-template-columns:repeat(auto-fit, minmax(150px, 1fr))}.table-list[data-table-list-id=orders] .table th,.table-list[data-table-list-id=orders] .table td{padding:6px 8px}.table-list[data-table-list-id=orders] .table thead th{font-size:12px;text-transform:uppercase;letter-spacing:.02em;white-space:nowrap}.table-list[data-table-list-id=orders] .table tbody td{vertical-align:top;font-size:14px;line-height:1.25}.order-show-layout{display:grid;grid-template-columns:220px minmax(0, 1fr);gap:12px;align-items:start}.order-statuses-side{position:sticky;top:60px;padding:10px}.order-statuses-side__title{font-size:13px;font-weight:700;color:#0f172a;margin-bottom:8px}.order-status-group{margin-bottom:10px}.order-status-group__name{font-size:12px;color:#475569;font-weight:700;margin-bottom:5px}.order-status-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 6px;border-radius:6px;color:#334155;font-size:12px;text-decoration:none}.order-status-row__count{min-width:24px;text-align:center;border-radius:999px;background:var(--status-color, #64748b);padding:1px 6px;font-weight:700;font-size:11px;color:#fff}.order-status-row:hover{background:#f1f5f9}.order-status-row.is-active{background:rgba(15,23,42,.06);color:#0f172a;font-weight:700}.order-show-main{min-width:0}.order-details-actions{display:inline-flex;flex-wrap:wrap;justify-content:flex-end;gap:6px}.order-details-page{padding:12px}.order-details-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap}.order-back-link{color:#475569;text-decoration:none;font-weight:600}.order-back-link:hover{color:#1d4ed8}.order-details-sub{display:inline-flex;gap:10px;flex-wrap:wrap;color:#64748b;font-size:12px}.order-details-pill{border-radius:999px;padding:5px 10px;background:#eef6ff;border:1px solid #cfe2ff;color:#1d4ed8;font-size:12px;font-weight:700}.order-status-change{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.order-status-change__form{display:flex;align-items:center;gap:6px}.order-status-change__select{min-width:180px}.order-details-tabs{display:flex;gap:6px;flex-wrap:wrap}.order-details-tab{border:1px solid #d6deea;border-radius:8px;padding:5px 10px;color:#475569;font-size:12px;background:#f8fafc;cursor:pointer}.order-details-tab.is-active{border-color:#bfdbfe;color:#1d4ed8;background:#eff6ff;font-weight:700}.order-item-cell{display:grid;grid-template-columns:44px 1fr;gap:8px;align-items:center;min-width:260px}.order-item-thumb{width:44px;height:44px;border-radius:6px;border:1px solid #dbe3ef;object-fit:cover}.order-item-thumb--empty{display:inline-block;background:#eef2f7;border-style:dashed}.order-item-name{font-weight:600;color:#0f172a}.order-grid-2{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:12px}.order-grid-3{display:grid;grid-template-columns:repeat(3, minmax(0, 1fr));gap:12px}.order-kv{margin:0;display:grid;grid-template-columns:150px 1fr;gap:6px 10px;font-size:12px}.payment-summary{display:grid;gap:6px;max-width:420px}.payment-summary__row{display:flex;align-items:center;gap:10px;font-size:12px}.payment-summary__label{width:150px;flex-shrink:0;color:#64748b}.payment-summary__value{font-weight:600;color:#0f172a}.order-kv dt{color:#64748b}.order-kv dd{margin:0;color:#0f172a;font-weight:600}.order-address{display:grid;gap:3px;font-size:12px;color:#0f172a}.order-events{display:grid;gap:8px}.order-event{border:1px solid #e2e8f0;border-radius:8px;padding:8px;background:#fbfdff}.order-event__head{color:#64748b;font-size:11px}.order-event__body{margin-top:4px;color:#0f172a;font-size:12px}.order-tab-panel{display:none}.order-tab-panel.is-active{display:block}.order-empty-placeholder{border:1px dashed #cbd5e1;border-radius:8px;min-height:180px;background:#f8fafc}.order-status-badge{display:inline-flex;align-items:center;justify-content:center;padding:4px 10px;border-radius:999px;font-size:12px;font-weight:700;border:1px solid #cbd5e1;color:#334155;background:#f8fafc}.order-status-badge.is-info{border-color:#bfdbfe;background:#eff6ff;color:#1d4ed8}.order-status-badge.is-success{border-color:#bbf7d0;background:#f0fdf4;color:#166534}.order-status-badge.is-danger{border-color:#fecaca;background:#fef2f2;color:#b91c1c}.order-status-badge.is-warn{border-color:#fde68a;background:#fffbeb;color:#92400e}.order-status-badge.is-empty{color:#94a3b8}.order-buyer{display:grid;gap:2px}.order-buyer__name{color:#0f172a;font-weight:600}.order-buyer__email{color:#64748b;font-size:12px}.table-inline-action{display:inline-block;margin-right:6px}.product-name-cell{display:inline-flex;align-items:center;gap:10px}.product-name-thumb{width:60px;height:60px;border-radius:6px;object-fit:cover;border:1px solid var(--c-border);background:#f8fafc}.product-name-thumb--empty{display:inline-block;width:60px;height:60px;border-radius:6px;border:1px dashed #cbd5e0;background:#f8fafc}.product-name-thumb-btn{border:0;padding:0;background:rgba(0,0,0,0);cursor:pointer;display:inline-flex;align-items:center;justify-content:center}.product-name-thumb-btn:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:8px}.modal--image-preview{width:min(760px,100%)}.product-image-preview__img{display:block;width:100%;max-height:70vh;object-fit:contain;border-radius:8px;background:#f8fafc}.product-images-grid{display:grid;grid-template-columns:repeat(auto-fill, minmax(220px, 1fr));gap:12px}.product-image-card{border:1px solid #dfe3ea;border-radius:10px;padding:10px;background:#fff}.product-image-card__thumb-wrap{position:relative;border-radius:8px;overflow:hidden;background:#f2f5f8}.product-image-card__thumb{width:100%;height:160px;object-fit:cover;display:block}.product-image-card__thumb.is-empty{height:160px;display:grid;place-items:center;color:#6b7785;font-size:12px}.product-image-card__badge{display:none;position:absolute;top:8px;left:8px;background:#1f7a43;color:#fff;padding:3px 8px;border-radius:999px;font-size:11px}.product-image-card.is-main .product-image-card__badge{display:inline-block}.product-image-card__meta{margin-top:8px;font-size:11px;line-height:1.25;color:#5f6b79;overflow-wrap:anywhere}.product-image-card__actions{margin-top:10px;display:grid;grid-template-columns:1fr;gap:8px}.product-image-card__actions .btn{min-height:34px;font-size:12px;line-height:1.2;padding:6px 10px}.product-links-search-form{display:grid;gap:12px;grid-template-columns:minmax(220px, 320px) minmax(220px, 1fr) auto;align-items:end}.product-links-head{display:grid;gap:8px;grid-template-columns:repeat(3, minmax(0, 1fr))}.product-tabs-nav{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.product-links-inline-form{display:grid;gap:8px;grid-template-columns:minmax(140px, 1fr) minmax(140px, 1fr) auto;align-items:center}.product-links-actions-row{display:flex;align-items:center;gap:8px;flex-wrap:nowrap}.product-links-actions-row .product-links-relink-form{flex:1 1 auto}.product-links-unlink-form{margin:0;flex:0 0 auto}.product-link-status-cell{display:inline-flex;align-items:center;gap:6px}.product-link-alert-indicator{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:999px;border:1px solid #f59e0b;background:#fffbeb;color:#b45309;font-size:12px;font-weight:700;cursor:help}.product-link-events-list{margin:0;padding:0;list-style:none;display:grid;gap:4px}.product-link-events-list li{display:grid;gap:2px}.product-link-events-type{font-weight:600;color:var(--c-text-strong)}.product-link-events-date{color:var(--c-muted);font-size:12px}.product-show-images-grid{display:grid;grid-template-columns:repeat(auto-fill, minmax(220px, 1fr));gap:12px}.product-show-image-card{border:1px solid var(--c-border);border-radius:10px;background:#fff;padding:10px;overflow:hidden}.product-show-image-card__meta{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;min-width:0}.product-show-image-path{font-size:12px;min-width:0;overflow:hidden}.product-show-image-path summary{cursor:pointer;color:var(--c-muted, #888);list-style:none;user-select:none;white-space:nowrap}.product-show-image-path summary::-webkit-details-marker{display:none}.product-show-image-path summary::after{content:" ▾"}.product-show-image-path[open] summary::after{content:" ▴"}.product-show-image-path__url{margin-top:4px;word-break:break-all;overflow-wrap:break-word;font-size:11px}.product-show-image{width:100%;max-height:260px;object-fit:cover;border-radius:8px;border:1px solid #d9e0ea}.shipment-grid{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:12px}.searchable-select{position:relative}.searchable-select__trigger{display:flex;align-items:center;justify-content:space-between;cursor:pointer;user-select:none;min-height:34px}.searchable-select__trigger::after{content:"";width:0;height:0;border-left:4px solid rgba(0,0,0,0);border-right:4px solid rgba(0,0,0,0);border-top:5px solid var(--c-text-muted, #6b7280);margin-left:8px;flex-shrink:0}.searchable-select__trigger--placeholder{color:var(--c-text-muted, #6b7280)}.searchable-select__dropdown{display:none;position:absolute;left:0;right:0;top:100%;z-index:50;max-height:280px;overflow:auto;background:#fff;border:1px solid var(--c-border);border-top:0;border-radius:0 0 8px 8px;box-shadow:0 8px 20px rgba(15,23,42,.12)}.searchable-select__dropdown.is-open{display:block}.searchable-select__search{position:sticky;top:0;border:none !important;border-bottom:1px solid var(--c-border) !important;border-radius:0 !important;box-shadow:none !important;font-size:13px;background:#fff;z-index:1}.searchable-select__option{padding:7px 10px;font-size:13px;cursor:pointer;color:var(--c-text-strong)}.searchable-select__option:hover{background:#f1f5f9}.searchable-select__option.is-selected{background:#edf2ff;font-weight:600}.flash{padding:10px 14px;border-radius:8px;font-size:13px;font-weight:500}.flash--success{background:#f0fdf4;border:1px solid #bbf7d0;color:#166534}.flash--error{background:#fef2f2;border:1px solid #fecaca;color:#b91c1c}.content-tabs-card{margin-top:0}.content-tabs-nav{display:flex;gap:4px;border-bottom:2px solid var(--c-border);margin-bottom:16px;flex-wrap:wrap}.content-tab-btn{padding:8px 16px;border:none;background:none;cursor:pointer;font-size:14px;font-weight:500;color:var(--c-text-muted, #6b7280);border-bottom:2px solid rgba(0,0,0,0);margin-bottom:-2px;border-radius:4px 4px 0 0;transition:color .15s,border-color .15s}.content-tab-btn:hover{color:var(--c-text-strong, #111827)}.content-tab-btn.is-active{color:var(--c-primary, #2563eb);border-bottom-color:var(--c-primary, #2563eb)}.content-tab-panel{display:none}.content-tab-panel.is-active{display:block}.shoppro-tabs-toolbar{display:flex;align-items:flex-end;justify-content:space-between;gap:10px;margin-bottom:10px;flex-wrap:wrap}.shoppro-tabs-toolbar__field{margin:0;min-width:260px;max-width:420px;flex:1 1 320px}.shoppro-tabs-toolbar__field .form-control{width:100%}.shoppro-tabs-toolbar__actions{display:inline-flex;align-items:center;gap:8px}.dm-carrier-select{min-width:140px}.dm-service-wrap{min-width:200px}.dm-service-wrap .dm-inpost-panel .form-control,.dm-service-wrap .dm-apaczka-panel .form-control{width:100%}.integration-settings-group{grid-column:1/-1;border:1px solid var(--c-border);border-radius:10px;background:#f8fbff;padding:10px}.integration-settings-group__head{margin-bottom:8px;padding:4px 0;border-bottom:1px solid #e2e8f0}.integration-settings-group__title{margin:0;font-size:14px;font-weight:600;letter-spacing:.01em;color:var(--c-text-strong, #1e293b)}.integration-settings-group__desc{margin:4px 0 0;color:#4b5563}.integration-settings-group__grid{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:10px 12px;align-items:start}.integration-settings-group__full{grid-column:1/-1}.integration-settings-group__grid .form-field{margin:0;align-self:start}.integration-settings-group__grid .form-control{min-height:34px;height:34px}.integration-settings-group__grid input[type=date].form-control{line-height:1.2}.integration-settings-checkboxes{border:0;padding:0;margin:0}.integration-settings-checkboxes .field-label{display:block;margin-bottom:2px}.integration-settings-checkboxes__list{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:6px 12px}.integration-settings-checkboxes__item{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:#334155}@media(max-width: 768px){.app-shell{flex-direction:column}.sidebar{width:100% !important;min-width:0 !important;border-right:0;border-bottom:1px solid #243041;padding:14px;overflow-x:auto}.sidebar__brand{margin:0 0 10px;font-size:22px}.sidebar__collapse-btn{display:none}.sidebar__nav{display:flex;gap:8px;overflow-x:auto}.sidebar__link{white-space:nowrap}.topbar{padding:0 14px}.container{margin-top:16px;width:calc(100% - 16px);margin-left:8px;margin-right:8px;padding:0 3px 12px}.settings-grid{grid-template-columns:1fr}.page-head{flex-direction:column;align-items:flex-start}.orders-stats{grid-template-columns:1fr;width:100%}.order-show-layout{grid-template-columns:1fr}.order-statuses-side{position:static;top:auto}.order-details-actions{justify-content:flex-start}.order-grid-2,.order-grid-3{grid-template-columns:1fr}.order-kv{grid-template-columns:1fr;gap:2px}.filters-grid,.form-grid,.form-grid-2,.form-grid-3,.form-grid-4,.shipment-grid,.statuses-form,.statuses-inline-form,.table-list-filters,.product-links-search-form,.product-links-inline-form{grid-template-columns:1fr}.statuses-dnd-item__content{display:block}.statuses-inline-delete{margin-top:6px}.filters-actions{align-items:center}.table-list__header,.table-list__footer{align-items:flex-start}.product-links-head{grid-template-columns:1fr}.integration-settings-group__grid{grid-template-columns:1fr}.integration-settings-checkboxes__list{grid-template-columns:1fr}.card{padding:12px}.modal--image-preview{width:min(92vw,100%)}}
+:root{--c-primary: #6690f4;--c-primary-dark: #3164db;--c-bg: #f4f6f9;--c-surface: #ffffff;--c-text: #4e5e6a;--c-text-strong: #2d3748;--c-muted: #718096;--c-border: #b0bec5;--c-danger: #cc0000;--focus-ring: 0 0 0 3px rgba(102, 144, 244, 0.15);--shadow-card: 0 1px 4px rgba(0, 0, 0, 0.06)}.btn{display:inline-flex;align-items:center;justify-content:center;min-height:34px;padding:6px 12px;border:1px solid rgba(0,0,0,0);border-radius:8px;font:inherit;font-weight:600;text-decoration:none;cursor:pointer;transition:background-color .2s ease,border-color .2s ease,color .2s ease,transform .1s ease}.btn--primary{color:#fff;background:var(--c-primary)}.btn--primary:hover{background:var(--c-primary-dark)}.btn--secondary{color:var(--c-text-strong);border-color:var(--c-border);background:var(--c-surface)}.btn--secondary:hover{border-color:#cbd5e0;background:#f8fafc}.btn--danger{color:#fff;border-color:#b91c1c;background:#dc2626}.btn--danger:hover{border-color:#991b1b;background:#b91c1c}.btn--sm{min-height:28px;padding:3px 10px;font-size:12px}.btn--block{width:100%}.btn--disabled{opacity:.3;cursor:not-allowed;pointer-events:none}.btn:active{transform:translateY(1px)}.btn:focus-visible{outline:none;box-shadow:var(--focus-ring);border-color:var(--c-primary)}.form-control{width:100%;min-height:30px;border:1px solid var(--c-border);border-radius:6px;padding:4px 8px;font:inherit;color:var(--c-text-strong);background:#fff;transition:border-color .2s ease,box-shadow .2s ease}.form-control:focus{outline:none;border-color:var(--c-primary);box-shadow:var(--focus-ring)}.input{min-height:34px;border:1px solid var(--c-border);border-radius:8px;padding:5px 10px;font:inherit;color:var(--c-text-strong);background:#fff}.input--sm{min-height:28px;padding:3px 8px;font-size:12px}.flash{padding:8px 12px;border-radius:6px;font-size:13px}.flash--success{border:1px solid #b7ebcf;background:#f0fff6;color:#0f6b39}.flash--error{border:1px solid #fed7d7;background:#fff5f5;color:var(--c-danger)}.alert{padding:12px 14px;border-radius:8px;border:1px solid rgba(0,0,0,0);font-size:13px;min-height:44px}.alert--danger{border-color:#fed7d7;background:#fff5f5;color:var(--c-danger)}.alert--success{border-color:#b7ebcf;background:#f0fff6;color:#0f6b39}.alert--warning{border-color:#f7dd8b;background:#fff8e8;color:#815500}.form-field{display:grid;gap:5px}.field-label{color:var(--c-text-strong);font-size:13px;font-weight:600}.table-wrap{width:100%;overflow-x:auto}.table-wrap--visible{overflow:visible !important;overflow-x:visible !important}.table{width:100%;border-collapse:collapse;background:var(--c-surface)}.table th,.table td{padding:10px 12px;border-bottom:1px solid var(--c-border);text-align:left}.table th{color:var(--c-text-strong);font-weight:700;background:#f8fafc}.table--details th{white-space:nowrap}.table--details th:first-child,.table--details td:first-child{width:36px;text-align:center}.pagination{display:flex;align-items:center;flex-wrap:wrap;gap:8px}.pagination__item{display:inline-flex;align-items:center;justify-content:center;min-width:36px;height:36px;padding:0 10px;border-radius:8px;border:1px solid var(--c-border);color:var(--c-text-strong);background:var(--c-surface);text-decoration:none;font-weight:600}.pagination__item:hover{border-color:#cbd5e0;background:#f8fafc}.pagination__item.is-active{border-color:var(--c-primary);color:var(--c-primary);background:#edf2ff}.receipt-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:16px;padding-bottom:12px;border-bottom:2px solid var(--c-text-strong)}.receipt-header__seller{flex:1}.receipt-header__seller strong{font-size:14px;display:block;margin-bottom:4px}.receipt-header__title{text-align:right}.receipt-header__title h1{font-size:18px;font-weight:700;margin-bottom:4px}.receipt-print{max-width:700px;margin:0 auto}@media print{.receipt-print{max-width:100%}}*{box-sizing:border-box}html,body{min-height:100%}body{margin:0;font-family:"Roboto","Segoe UI",sans-serif;font-size:13px;color:var(--c-text);background:var(--c-bg)}a{color:var(--c-primary)}.app-shell{min-height:100vh;display:flex}.sidebar{width:260px;min-width:260px;flex-shrink:0;overflow:hidden;transition:width .22s ease,min-width .22s ease;border-right:1px solid #243041;background:#111a28;padding:18px 10px;display:flex;flex-direction:column}.sidebar.is-collapsed{width:52px;min-width:52px}.sidebar__brand{display:flex;align-items:center;justify-content:space-between;margin:4px 4px 16px;gap:6px;min-width:0}.sidebar__brand-text{color:#e9f0ff;font-size:24px;font-weight:300;letter-spacing:-0.02em;white-space:nowrap;overflow:hidden;flex:1;min-width:0}.sidebar__brand-text strong{font-weight:700}.sidebar__collapse-btn{flex-shrink:0;width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0);border:1px solid #2a3a54;border-radius:6px;color:#64748b;cursor:pointer;padding:0;transition:background .15s,color .15s}.sidebar__collapse-btn:hover{background:#1b2a3f;color:#cbd5e1}.sidebar__collapse-icon{display:block;transition:transform .22s ease;flex-shrink:0}.sidebar.is-collapsed .sidebar__collapse-icon{transform:rotate(180deg)}.sidebar__nav{display:grid;gap:4px}.sidebar__link{display:flex;align-items:center;gap:9px;white-space:nowrap;border-radius:8px;padding:9px 10px;text-decoration:none;color:#cbd5e1;font-weight:600}.sidebar__link:hover{color:#f8fafc;background:#1b2a3f}.sidebar__link.is-active{color:#fff;background:#2e4f93}.sidebar__group{display:grid;gap:2px}.sidebar__group-toggle{list-style:none;border-radius:8px;padding:9px 10px;color:#cbd5e1;font-weight:600;cursor:pointer;display:flex;align-items:center;gap:9px;white-space:nowrap;user-select:none}.sidebar__group-toggle::-webkit-details-marker{display:none}.sidebar__group:hover .sidebar__group-toggle,.sidebar__group-toggle:hover{color:#f8fafc;background:#1b2a3f}.sidebar__group.is-active .sidebar__group-toggle{color:#fff;background:#2e4f93}.sidebar__icon{flex-shrink:0;width:18px;height:18px;display:flex;align-items:center;justify-content:center;opacity:.85}.sidebar__label{flex:1;min-width:0;overflow:hidden}.sidebar__toggle-arrow{flex-shrink:0;margin-left:auto;opacity:.5;transition:transform .18s ease}details[open]>.sidebar__group-toggle .sidebar__toggle-arrow{transform:rotate(180deg)}.sidebar__group-links{display:grid;gap:2px;padding-left:12px;overflow:hidden}.sidebar__sublink{border-radius:6px;padding:7px 10px 7px 8px;text-decoration:none;color:#94a3b8;font-size:12.5px;font-weight:500;display:flex;align-items:center;gap:8px;white-space:nowrap}.sidebar__sublink::before{content:"";flex-shrink:0;width:5px;height:5px;border-radius:50%;background:rgba(148,163,184,.3);transition:background .15s}.sidebar__sublink:hover{color:#e2e8f0;background:#1b2a3f}.sidebar__sublink:hover::before{background:rgba(148,163,184,.65)}.sidebar__sublink.is-active{color:#fff;background:rgba(46,79,147,.55)}.sidebar__sublink.is-active::before{background:#93c5fd}.app-main{flex:1;min-width:0}.topbar{height:50px;border-bottom:1px solid var(--c-border);background:var(--c-surface);display:flex;align-items:center;justify-content:space-between;padding:0 20px;position:sticky;top:0;z-index:100}.brand{font-size:22px;font-weight:300;letter-spacing:-0.02em;color:var(--c-text-strong)}.brand strong{font-weight:700}.container{max-width:none;width:calc(100% - 20px);margin:12px 10px;padding:0 4px 14px}.card{background:var(--c-surface);border-radius:10px;box-shadow:var(--shadow-card);padding:14px}.card h1{margin:0 0 10px;color:var(--c-text-strong);font-size:24px;font-weight:700}.muted{color:var(--c-muted)}.accent{color:var(--c-primary);font-weight:600}.users-form{display:grid;gap:14px;max-width:460px}.form-field{margin-bottom:12px}.section-title{margin:0;color:var(--c-text-strong);font-size:18px;font-weight:700}h2.section-title,h3.section-title,h4.section-title{display:flex;align-items:center;gap:6px;font-weight:600;padding:6px 0;border-bottom:1px solid #e2e8f0;color:var(--c-primary, #2563eb)}h2.section-title::before,h3.section-title::before,h4.section-title::before{content:"■";font-size:.55em;opacity:.5}h3.section-title,h4.section-title{font-size:15px}h3.section-title::before,h4.section-title::before{content:"◆";font-size:.5em}.mt-0{margin-top:0}.mt-4{margin-top:4px}.mt-12{margin-top:8px}.mt-16{margin-top:12px}.settings-grid{display:grid;grid-template-columns:repeat(3, minmax(0, 1fr));gap:12px}.settings-nav{display:flex;gap:8px;flex-wrap:wrap}.settings-nav__link{text-decoration:none;border:1px solid var(--c-border);border-radius:8px;padding:8px 12px;color:var(--c-text-strong);font-weight:600}.settings-nav__link:hover{background:#f8fafc}.settings-nav__link.is-active{border-color:var(--c-primary);color:var(--c-primary);background:#edf2ff}.settings-stat{border:1px solid var(--c-border);border-radius:8px;padding:12px;background:#f8fafc}.settings-stat__label{display:block;color:var(--c-muted);font-size:12px;margin-bottom:4px}.settings-stat__value{color:var(--c-text-strong);font-size:20px}.settings-logs{margin:0;padding:12px;border-radius:8px;border:1px solid var(--c-border);background:#0b1220;color:#d1d5db;font-size:12px;line-height:1.5;overflow:auto}.settings-allegro-callback{display:block;width:100%;padding:8px 10px;border:1px solid var(--c-border);border-radius:8px;background:#f8fafc;color:var(--c-text-strong);font-size:12px;line-height:1.45;word-break:break-all}.page-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.filters-grid{display:grid;grid-template-columns:repeat(3, minmax(0, 1fr));gap:12px}.filters-actions{display:flex;align-items:center;gap:8px}.product-form .form-control{width:100%}.form-grid{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:12px}.form-grid-2{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:12px;align-items:start}.form-grid-3{display:grid;grid-template-columns:repeat(3, minmax(0, 1fr));gap:12px;align-items:start}.form-grid-4{display:grid;grid-template-columns:repeat(4, minmax(0, 1fr));gap:12px;align-items:start}.form-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:flex-start}.form-actions .btn{align-self:flex-start}.statuses-form{display:grid;gap:8px;grid-template-columns:repeat(2, minmax(0, 1fr))}.statuses-form .form-actions{grid-column:1/-1}.statuses-color-input{min-height:32px;padding:2px}.statuses-hint{grid-column:1/-1;margin:0}.statuses-group-block{border:1px solid var(--c-border);border-radius:10px;padding:8px;background:#fbfdff}.statuses-group-block__head{display:flex;align-items:center;justify-content:space-between;gap:6px;flex-wrap:wrap}.statuses-group-block__title{margin:0;display:inline-flex;align-items:center;gap:6px;color:var(--c-text-strong);font-size:14px}.statuses-color-dot{width:12px;height:12px;border-radius:999px;border:1px solid rgba(15,23,42,.15)}.statuses-dnd-list{margin:6px 0 0;padding:0;list-style:none;display:grid;gap:6px}.statuses-dnd-item{display:grid;grid-template-columns:24px 1fr;gap:6px;border:1px solid #dce4f0;border-radius:8px;background:#fff;padding:6px}.statuses-dnd-item__content{display:flex;align-items:center;gap:6px;min-width:0}.statuses-dnd-item.is-dragging{opacity:.6}.statuses-dnd-item__drag{display:inline-flex;align-items:center;justify-content:center;border:1px dashed #cbd5e1;border-radius:6px;color:#64748b;cursor:grab;user-select:none;font-weight:700;font-size:12px}.statuses-dnd-item__drag:active{cursor:grabbing}.statuses-inline-form{display:grid;gap:6px}.statuses-inline-form--row{grid-template-columns:minmax(180px, 1.4fr) minmax(150px, 1fr) auto auto auto;align-items:center;flex:1 1 auto;min-width:0}.statuses-inline-form--row-group{grid-template-columns:minmax(180px, 1.5fr) 56px auto auto auto;align-items:center;flex:1 1 auto;min-width:0}.statuses-inline-form--row .form-control,.statuses-inline-form--row-group .form-control{min-height:30px;padding:4px 8px}.statuses-inline-form--row .btn,.statuses-inline-form--row-group .btn,.statuses-inline-delete .btn{min-height:30px;padding:4px 10px;font-size:12px}.statuses-inline-check{margin-top:0;white-space:nowrap;font-size:12px}.statuses-inline-delete{margin:0;flex:0 0 auto}.statuses-code-label{font-size:12px;color:var(--c-muted)}.statuses-code-readonly{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;font-size:12px}.statuses-code-readonly code{background:#eef2f7;border-radius:6px;padding:1px 6px;color:#1f2937;font-size:12px}.field-inline{display:flex;align-items:center;gap:8px;margin-top:2px}.modal-backdrop{position:fixed;inset:0;background:rgba(15,23,42,.5);display:flex;align-items:center;justify-content:center;padding:16px;z-index:200}.modal-backdrop[hidden]{display:none}.modal{width:min(560px,100%);background:#fff;border-radius:10px;box-shadow:0 20px 40px rgba(15,23,42,.35);overflow:hidden}.modal__header{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:16px 18px;border-bottom:1px solid var(--c-border)}.modal__header h3{margin:0;font-size:18px;color:var(--c-text-strong)}.modal__body{padding:16px 18px 18px}.status-pill{display:inline-flex;align-items:center;justify-content:center;border:1px solid #fed7d7;background:#fff5f5;color:#9b2c2c;padding:2px 8px;border-radius:999px;font-size:12px;font-weight:600}.status-pill.is-active{border-color:#b7ebcf;background:#f0fff6;color:#0f6b39}.table-row-actions{display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap}.table-row-actions form{margin:0}.table-list{display:grid;gap:14px}.table-list__header{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap}.table-list__left{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.table-list-header-actions{display:inline-flex;align-items:center;gap:10px;flex-wrap:wrap}.js-filter-toggle-btn.is-active{border-color:#cbd5e0;background:#edf2ff;color:var(--c-primary-dark)}.table-filter-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;font-size:11px;font-weight:700;color:#fff;background:var(--c-primary);border-radius:999px}.table-filters-wrapper{display:none}.table-filters-wrapper.is-open{display:block}.table-list-filters{display:grid;gap:12px;grid-template-columns:repeat(auto-fit, minmax(170px, 1fr));align-items:end}.table-col-toggle-wrapper{position:relative}.table-col-toggle-dropdown{display:none;position:absolute;right:0;top:calc(100% + 6px);z-index:30;width:260px;max-height:360px;overflow:auto;border:1px solid var(--c-border);border-radius:10px;background:#fff;box-shadow:0 10px 25px rgba(15,23,42,.12)}.table-col-toggle-dropdown.is-open{display:block}.table-col-toggle-header{padding:10px 12px;border-bottom:1px solid var(--c-border);font-size:12px;font-weight:700;color:var(--c-muted)}.table-col-toggle-item{display:flex;align-items:center;gap:10px;padding:8px 12px;font-size:13px;color:var(--c-text-strong)}.table-col-toggle-item:hover{background:#f8fafc}.table-col-toggle-footer{border-top:1px solid var(--c-border);padding:8px 12px}.table-col-hidden{display:none}.table-col-switch{position:relative;display:inline-block;width:34px;min-width:34px;height:18px}.table-col-switch input{opacity:0;width:0;height:0;position:absolute}.table-col-switch-slider{position:absolute;top:0;left:0;right:0;bottom:0;background:#cbd5e1;border-radius:999px;transition:background-color .2s ease}.table-col-switch-slider::before{content:"";position:absolute;height:14px;width:14px;left:2px;bottom:2px;background:#fff;border-radius:50%;transition:transform .2s ease}.table-col-switch input:checked+.table-col-switch-slider{background:#16a34a}.table-col-switch input:checked+.table-col-switch-slider::before{transform:translateX(16px)}.table-sort-link{display:inline-flex;align-items:center;gap:6px;color:var(--c-text-strong);text-decoration:none}.table-sort-link:hover{color:var(--c-primary-dark)}.table-sort-icon.is-muted{color:#a0aec0}.table-list__footer{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}.table-list-per-page-form{display:inline-flex;align-items:center;gap:8px}.table-list-per-page-form .form-control{min-width:90px}.table-select-col{width:44px;text-align:center}.table-select-toggle{display:inline-flex;align-items:center;justify-content:center}.table-select-toggle input[type=checkbox]{width:16px;height:16px}.orders-page .orders-head{background:linear-gradient(120deg, #f8fbff 0%, #eef5ff 100%);border:1px solid #dbe7fb}.orders-page .table-list{border:1px solid #dde5f2;border-radius:12px;box-shadow:0 6px 16px rgba(20,44,86,.08)}.orders-page .table-list__header{padding:10px 6px 2px}.orders-page .table-list-filters{padding:6px 6px 2px;border-top:1px solid #ebf0f7;border-bottom:1px solid #ebf0f7;background:#f9fbff}.orders-page .table-wrap{border-radius:10px;overflow:hidden;border:1px solid #e7edf6}.orders-page .table thead th{background:#f3f7fd;color:#30435f;font-size:12px;text-transform:uppercase;letter-spacing:.03em}.orders-page .table tbody td{vertical-align:middle;padding-top:10px;padding-bottom:10px;border-bottom-color:#edf2f8}.orders-page .table tbody tr:hover td{background:#f9fcff}.orders-list-page{padding:10px;margin-bottom:10px}.orders-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap}.orders-stats{display:inline-grid;grid-template-columns:repeat(3, minmax(86px, auto));gap:8px}.orders-stat{border:1px solid #d8e2f0;background:#f8fbff;border-radius:8px;padding:6px 8px;line-height:1.15}.orders-stat__label{display:block;color:#5f6f83;font-size:11px;margin-bottom:2px}.orders-stat__value{color:#12233a;font-size:16px;font-weight:700}.orders-ref{display:grid;gap:2px;min-width:170px}.orders-ref__main{font-weight:700;color:#0f1f35;font-size:14px}.orders-ref__meta{display:inline-flex;flex-wrap:wrap;gap:4px 10px;color:#64748b;font-size:12px}.orders-buyer{display:grid;gap:2px}.orders-buyer__name{color:#0f172a;font-weight:600;font-size:14px}.orders-buyer__meta{display:inline-flex;flex-wrap:wrap;gap:4px 10px;color:#64748b;font-size:12px}.orders-status-wrap{display:inline-flex;align-items:center;gap:5px;flex-wrap:wrap}.order-tag{display:inline-flex;align-items:center;justify-content:center;border:1px solid #d8e1ef;background:#f8fafc;color:#334155;border-radius:999px;padding:2px 8px;font-size:12px;font-weight:700;line-height:1.1}.order-tag.is-info{border-color:#bfdbfe;background:#eff6ff;color:#1d4ed8}.order-tag.is-success{border-color:#bbf7d0;background:#f0fdf4;color:#166534}.order-tag.is-danger{border-color:#fecaca;background:#fef2f2;color:#b91c1c}.order-tag.is-warn{border-color:#fde68a;background:#fffbeb;color:#92400e}.order-tag.is-cod{border-color:#f9a8d4;background:#fdf2f8;color:#9d174d}.order-tag.is-unpaid{border-color:#fca5a5;background:#fef2f2;color:#b91c1c}.orders-mini{font-size:14px;color:#223247;line-height:1.25}.orders-mini__delivery{font-size:12px;color:#64748b;margin-bottom:2px;max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.orders-products{display:grid;gap:4px;min-width:240px}.orders-products__meta,.orders-products__more{font-size:12px;color:#64748b}.orders-product{display:grid;grid-template-columns:48px 1fr;gap:6px;align-items:center}.orders-product__thumb{width:48px;height:48px;border-radius:4px;border:1px solid #dbe3ef;object-fit:cover;background:#fff}.orders-product__thumb--empty{display:inline-block;background:#eef2f7;border-style:dashed}.orders-product__txt{min-width:0;display:grid;gap:1px}.orders-product__name{font-size:14px;color:#0f172a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.orders-product__qty{font-size:12px;color:#64748b}.orders-image-hover-wrap{position:relative;display:inline-flex;align-items:center;justify-content:center;cursor:zoom-in}.orders-image-hover-popup{display:none;position:fixed;left:auto;top:auto;width:350px;max-height:350px;object-fit:contain;border-radius:8px;background:#fff;box-shadow:0 8px 24px rgba(0,0,0,.18);border:1px solid #dfe3ea;z-index:100;pointer-events:none}.orders-image-hover-wrap:hover .orders-image-hover-popup{display:block}.activity-type-badge{display:inline-block;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:500;white-space:nowrap;background:#e2e8f0;color:#334155}.activity-type-badge--status_change{background:#dbeafe;color:#1e40af}.activity-type-badge--payment{background:#dcfce7;color:#166534}.activity-type-badge--invoice{background:#fef3c7;color:#92400e}.activity-type-badge--shipment{background:#e0e7ff;color:#3730a3}.activity-type-badge--message{background:#f3e8ff;color:#6b21a8}.activity-type-badge--document{background:#fce7f3;color:#9d174d}.activity-type-badge--import{background:#f1f5f9;color:#475569}.activity-type-badge--note{background:#ecfdf5;color:#065f46}.text-nowrap{white-space:nowrap}.orders-money{display:grid;gap:2px}.orders-money__main{color:#0f172a;font-weight:700;font-size:14px}.orders-money__meta{color:#64748b;font-size:12px}.table-list[data-table-list-id=orders]{gap:8px}.table-list[data-table-list-id=orders] .table-list__header{padding:2px 0 0}.table-list[data-table-list-id=orders] .table-list-filters{gap:8px;grid-template-columns:repeat(auto-fit, minmax(150px, 1fr))}.table-list[data-table-list-id=orders] .table th,.table-list[data-table-list-id=orders] .table td{padding:6px 8px}.table-list[data-table-list-id=orders] .table thead th{font-size:12px;text-transform:uppercase;letter-spacing:.02em;white-space:nowrap}.table-list[data-table-list-id=orders] .table tbody td{vertical-align:top;font-size:14px;line-height:1.25}.order-show-layout{display:grid;grid-template-columns:220px minmax(0, 1fr);gap:12px;align-items:start}.order-statuses-side{position:sticky;top:60px;padding:10px}.order-statuses-side__title{font-size:13px;font-weight:700;color:#0f172a;margin-bottom:8px}.order-status-group{margin-bottom:10px}.order-status-group__name{font-size:12px;color:#475569;font-weight:700;margin-bottom:5px}.order-status-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 6px;border-radius:6px;color:#334155;font-size:12px;text-decoration:none}.order-status-row__count{min-width:24px;text-align:center;border-radius:999px;background:var(--status-color, #64748b);padding:1px 6px;font-weight:700;font-size:11px;color:#fff}.order-status-row:hover{background:#f1f5f9}.order-status-row.is-active{background:rgba(15,23,42,.06);color:#0f172a;font-weight:700}.order-show-main{min-width:0}.order-details-actions{display:inline-flex;flex-wrap:wrap;justify-content:flex-end;gap:6px}.order-details-page{padding:12px}.order-details-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap}.order-back-link{color:#475569;text-decoration:none;font-weight:600}.order-back-link:hover{color:#1d4ed8}.order-details-sub{display:inline-flex;gap:10px;flex-wrap:wrap;color:#64748b;font-size:12px}.order-details-pill{border-radius:999px;padding:5px 10px;background:#eef6ff;border:1px solid #cfe2ff;color:#1d4ed8;font-size:12px;font-weight:700}.order-status-change{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.order-status-change__form{display:flex;align-items:center;gap:6px}.order-status-change__select{min-width:180px}.order-details-tabs{display:flex;gap:6px;flex-wrap:wrap}.order-details-tab{border:1px solid #d6deea;border-radius:8px;padding:5px 10px;color:#475569;font-size:12px;background:#f8fafc;cursor:pointer}.order-details-tab.is-active{border-color:#bfdbfe;color:#1d4ed8;background:#eff6ff;font-weight:700}.order-item-cell{display:grid;grid-template-columns:44px 1fr;gap:8px;align-items:center;min-width:260px}.order-item-thumb{width:44px;height:44px;border-radius:6px;border:1px solid #dbe3ef;object-fit:cover}.order-item-thumb--empty{display:inline-block;background:#eef2f7;border-style:dashed}.order-item-name{font-weight:600;color:#0f172a}.order-grid-2{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:12px}.order-grid-3{display:grid;grid-template-columns:repeat(3, minmax(0, 1fr));gap:12px}.order-kv{margin:0;display:grid;grid-template-columns:150px 1fr;gap:6px 10px;font-size:12px}.payment-summary{display:grid;gap:6px;max-width:420px}.payment-summary__row{display:flex;align-items:center;gap:10px;font-size:12px}.payment-summary__label{width:150px;flex-shrink:0;color:#64748b}.payment-summary__value{font-weight:600;color:#0f172a}.order-kv dt{color:#64748b}.order-kv dd{margin:0;color:#0f172a;font-weight:600}.order-address{display:grid;gap:3px;font-size:12px;color:#0f172a}.order-events{display:grid;gap:8px}.order-event{border:1px solid #e2e8f0;border-radius:8px;padding:8px;background:#fbfdff}.order-event__head{color:#64748b;font-size:11px}.order-event__body{margin-top:4px;color:#0f172a;font-size:12px}.order-tab-panel{display:none}.order-tab-panel.is-active{display:block}.order-empty-placeholder{border:1px dashed #cbd5e1;border-radius:8px;min-height:180px;background:#f8fafc}.order-status-badge{display:inline-flex;align-items:center;justify-content:center;padding:4px 10px;border-radius:999px;font-size:12px;font-weight:700;border:1px solid #cbd5e1;color:#334155;background:#f8fafc}.order-status-badge.is-info{border-color:#bfdbfe;background:#eff6ff;color:#1d4ed8}.order-status-badge.is-success{border-color:#bbf7d0;background:#f0fdf4;color:#166534}.order-status-badge.is-danger{border-color:#fecaca;background:#fef2f2;color:#b91c1c}.order-status-badge.is-warn{border-color:#fde68a;background:#fffbeb;color:#92400e}.order-status-badge.is-empty{color:#94a3b8}.order-buyer{display:grid;gap:2px}.order-buyer__name{color:#0f172a;font-weight:600}.order-buyer__email{color:#64748b;font-size:12px}.table-inline-action{display:inline-block;margin-right:6px}.product-name-cell{display:inline-flex;align-items:center;gap:10px}.product-name-thumb{width:60px;height:60px;border-radius:6px;object-fit:cover;border:1px solid var(--c-border);background:#f8fafc}.product-name-thumb--empty{display:inline-block;width:60px;height:60px;border-radius:6px;border:1px dashed #cbd5e0;background:#f8fafc}.product-name-thumb-btn{border:0;padding:0;background:rgba(0,0,0,0);cursor:pointer;display:inline-flex;align-items:center;justify-content:center}.product-name-thumb-btn:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:8px}.modal--image-preview{width:min(760px,100%)}.product-image-preview__img{display:block;width:100%;max-height:70vh;object-fit:contain;border-radius:8px;background:#f8fafc}.product-images-grid{display:grid;grid-template-columns:repeat(auto-fill, minmax(220px, 1fr));gap:12px}.product-image-card{border:1px solid #dfe3ea;border-radius:10px;padding:10px;background:#fff}.product-image-card__thumb-wrap{position:relative;border-radius:8px;overflow:hidden;background:#f2f5f8}.product-image-card__thumb{width:100%;height:160px;object-fit:cover;display:block}.product-image-card__thumb.is-empty{height:160px;display:grid;place-items:center;color:#6b7785;font-size:12px}.product-image-card__badge{display:none;position:absolute;top:8px;left:8px;background:#1f7a43;color:#fff;padding:3px 8px;border-radius:999px;font-size:11px}.product-image-card.is-main .product-image-card__badge{display:inline-block}.product-image-card__meta{margin-top:8px;font-size:11px;line-height:1.25;color:#5f6b79;overflow-wrap:anywhere}.product-image-card__actions{margin-top:10px;display:grid;grid-template-columns:1fr;gap:8px}.product-image-card__actions .btn{min-height:34px;font-size:12px;line-height:1.2;padding:6px 10px}.product-links-search-form{display:grid;gap:12px;grid-template-columns:minmax(220px, 320px) minmax(220px, 1fr) auto;align-items:end}.product-links-head{display:grid;gap:8px;grid-template-columns:repeat(3, minmax(0, 1fr))}.product-tabs-nav{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.product-links-inline-form{display:grid;gap:8px;grid-template-columns:minmax(140px, 1fr) minmax(140px, 1fr) auto;align-items:center}.product-links-actions-row{display:flex;align-items:center;gap:8px;flex-wrap:nowrap}.product-links-actions-row .product-links-relink-form{flex:1 1 auto}.product-links-unlink-form{margin:0;flex:0 0 auto}.product-link-status-cell{display:inline-flex;align-items:center;gap:6px}.product-link-alert-indicator{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:999px;border:1px solid #f59e0b;background:#fffbeb;color:#b45309;font-size:12px;font-weight:700;cursor:help}.product-link-events-list{margin:0;padding:0;list-style:none;display:grid;gap:4px}.product-link-events-list li{display:grid;gap:2px}.product-link-events-type{font-weight:600;color:var(--c-text-strong)}.product-link-events-date{color:var(--c-muted);font-size:12px}.product-show-images-grid{display:grid;grid-template-columns:repeat(auto-fill, minmax(220px, 1fr));gap:12px}.product-show-image-card{border:1px solid var(--c-border);border-radius:10px;background:#fff;padding:10px;overflow:hidden}.product-show-image-card__meta{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;min-width:0}.product-show-image-path{font-size:12px;min-width:0;overflow:hidden}.product-show-image-path summary{cursor:pointer;color:var(--c-muted, #888);list-style:none;user-select:none;white-space:nowrap}.product-show-image-path summary::-webkit-details-marker{display:none}.product-show-image-path summary::after{content:" ▾"}.product-show-image-path[open] summary::after{content:" ▴"}.product-show-image-path__url{margin-top:4px;word-break:break-all;overflow-wrap:break-word;font-size:11px}.product-show-image{width:100%;max-height:260px;object-fit:cover;border-radius:8px;border:1px solid #d9e0ea}.shipment-grid{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:12px}.searchable-select{position:relative}.searchable-select__trigger{display:flex;align-items:center;justify-content:space-between;cursor:pointer;user-select:none;min-height:34px}.searchable-select__trigger::after{content:"";width:0;height:0;border-left:4px solid rgba(0,0,0,0);border-right:4px solid rgba(0,0,0,0);border-top:5px solid var(--c-text-muted, #6b7280);margin-left:8px;flex-shrink:0}.searchable-select__trigger--placeholder{color:var(--c-text-muted, #6b7280)}.searchable-select__dropdown{display:none;position:absolute;left:0;right:0;top:100%;z-index:50;max-height:280px;overflow:auto;background:#fff;border:1px solid var(--c-border);border-top:0;border-radius:0 0 8px 8px;box-shadow:0 8px 20px rgba(15,23,42,.12)}.searchable-select__dropdown.is-open{display:block}.searchable-select__search{position:sticky;top:0;border:none !important;border-bottom:1px solid var(--c-border) !important;border-radius:0 !important;box-shadow:none !important;font-size:13px;background:#fff;z-index:1}.searchable-select__option{padding:7px 10px;font-size:13px;cursor:pointer;color:var(--c-text-strong)}.searchable-select__option:hover{background:#f1f5f9}.searchable-select__option.is-selected{background:#edf2ff;font-weight:600}.flash{padding:10px 14px;border-radius:8px;font-size:13px;font-weight:500}.flash--success{background:#f0fdf4;border:1px solid #bbf7d0;color:#166534}.flash--error{background:#fef2f2;border:1px solid #fecaca;color:#b91c1c}.content-tabs-card{margin-top:0}.content-tabs-nav{display:flex;gap:4px;border-bottom:2px solid var(--c-border);margin-bottom:16px;flex-wrap:wrap}.content-tab-btn{padding:8px 16px;border:none;background:none;cursor:pointer;font-size:14px;font-weight:500;color:var(--c-text-muted, #6b7280);border-bottom:2px solid rgba(0,0,0,0);margin-bottom:-2px;border-radius:4px 4px 0 0;transition:color .15s,border-color .15s}.content-tab-btn:hover{color:var(--c-text-strong, #111827)}.content-tab-btn.is-active{color:var(--c-primary, #2563eb);border-bottom-color:var(--c-primary, #2563eb)}.content-tab-panel{display:none}.content-tab-panel.is-active{display:block}.shoppro-tabs-toolbar{display:flex;align-items:flex-end;justify-content:space-between;gap:10px;margin-bottom:10px;flex-wrap:wrap}.shoppro-tabs-toolbar__field{margin:0;min-width:260px;max-width:420px;flex:1 1 320px}.shoppro-tabs-toolbar__field .form-control{width:100%}.shoppro-tabs-toolbar__actions{display:inline-flex;align-items:center;gap:8px}.dm-carrier-select{min-width:140px}.dm-service-wrap{min-width:200px}.dm-service-wrap .dm-inpost-panel .form-control,.dm-service-wrap .dm-apaczka-panel .form-control{width:100%}.integration-settings-group{grid-column:1/-1;border:1px solid var(--c-border);border-radius:10px;background:#f8fbff;padding:10px}.integration-settings-group__head{margin-bottom:8px;padding:4px 0;border-bottom:1px solid #e2e8f0}.integration-settings-group__title{margin:0;font-size:14px;font-weight:600;letter-spacing:.01em;color:var(--c-text-strong, #1e293b)}.integration-settings-group__desc{margin:4px 0 0;color:#4b5563}.integration-settings-group__grid{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:10px 12px;align-items:start}.integration-settings-group__full{grid-column:1/-1}.integration-settings-group__grid .form-field{margin:0;align-self:start}.integration-settings-group__grid .form-control{min-height:34px;height:34px}.integration-settings-group__grid input[type=date].form-control{line-height:1.2}.integration-settings-checkboxes{border:0;padding:0;margin:0}.integration-settings-checkboxes .field-label{display:block;margin-bottom:2px}.integration-settings-checkboxes__list{display:grid;grid-template-columns:repeat(2, minmax(0, 1fr));gap:6px 12px}.integration-settings-checkboxes__item{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:#334155}@media(max-width: 768px){.app-shell{flex-direction:column}.sidebar{width:100% !important;min-width:0 !important;border-right:0;border-bottom:1px solid #243041;padding:14px;overflow-x:auto}.sidebar__brand{margin:0 0 10px;font-size:22px}.sidebar__collapse-btn{display:none}.sidebar__nav{display:flex;gap:8px;overflow-x:auto}.sidebar__link{white-space:nowrap}.topbar{padding:0 14px}.container{margin-top:16px;width:calc(100% - 16px);margin-left:8px;margin-right:8px;padding:0 3px 12px}.settings-grid{grid-template-columns:1fr}.page-head{flex-direction:column;align-items:flex-start}.orders-stats{grid-template-columns:1fr;width:100%}.order-show-layout{grid-template-columns:1fr}.order-statuses-side{position:static;top:auto}.order-details-actions{justify-content:flex-start}.order-grid-2,.order-grid-3{grid-template-columns:1fr}.order-kv{grid-template-columns:1fr;gap:2px}.filters-grid,.form-grid,.form-grid-2,.form-grid-3,.form-grid-4,.shipment-grid,.statuses-form,.statuses-inline-form,.table-list-filters,.product-links-search-form,.product-links-inline-form{grid-template-columns:1fr}.statuses-dnd-item__content{display:block}.statuses-inline-delete{margin-top:6px}.filters-actions{align-items:center}.table-list__header,.table-list__footer{align-items:flex-start}.product-links-head{grid-template-columns:1fr}.integration-settings-group__grid{grid-template-columns:1fr}.integration-settings-checkboxes__list{grid-template-columns:1fr}.card{padding:12px}.modal--image-preview{width:min(92vw,100%)}.email-tpl-editor-wrap{flex-direction:column}.email-tpl-var-panel{min-width:200px}.modal-box{width:95vw;max-height:90vh}}.email-tpl-editor-wrap{display:flex;flex-direction:column;border:1px solid var(--c-border);border-radius:6px;overflow:hidden}.email-tpl-toolbar{display:flex;align-items:center;gap:6px;padding:6px 8px;background:var(--c-bg-subtle, #f8f9fa);border-bottom:1px solid var(--c-border)}.email-tpl-var-dropdown{position:relative}.email-tpl-var-panel{position:absolute;top:100%;left:0;z-index:50;min-width:260px;max-height:320px;overflow-y:auto;background:var(--c-bg);border:1px solid var(--c-border);border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,.12);padding:6px;margin-top:4px}.email-var-group:not(:first-child){margin-top:6px;padding-top:6px;border-top:1px solid var(--c-border)}.email-var-group__label{font-size:11px;font-weight:600;text-transform:uppercase;color:var(--c-text-muted);padding:2px 4px;letter-spacing:.03em}.email-var-item{display:block;width:100%;text-align:left;padding:3px 6px;margin:1px 0;border:none;background:none;font-size:12px;font-family:"Roboto Mono",monospace;color:var(--c-text);border-radius:3px;cursor:pointer}.email-var-item:hover{background:var(--c-primary);color:#fff}#js-quill-editor{min-height:200px}#js-quill-editor .ql-editor{min-height:200px;font-size:13px}.modal-overlay{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.45)}.modal-box{width:min(680px,90vw);max-height:80vh;background:var(--c-bg);border-radius:8px;box-shadow:0 8px 30px rgba(0,0,0,.2);display:flex;flex-direction:column;overflow:hidden}.modal-box__header{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;border-bottom:1px solid var(--c-border)}.modal-box__title{margin:0;font-size:15px;font-weight:600}.modal-box__close{background:none;border:none;font-size:22px;line-height:1;cursor:pointer;color:var(--c-text-muted);padding:0 4px}.modal-box__close:hover{color:var(--c-text)}.modal-box__body{padding:12px 16px;overflow-y:auto;flex:1}
diff --git a/resources/scss/app.scss b/resources/scss/app.scss
index 9b2f7ff..53e9cd3 100644
--- a/resources/scss/app.scss
+++ b/resources/scss/app.scss
@@ -105,8 +105,12 @@ a {
}
.sidebar__link {
+ display: flex;
+ align-items: center;
+ gap: 9px;
+ white-space: nowrap;
border-radius: 8px;
- padding: 10px 12px;
+ padding: 9px 10px;
text-decoration: none;
color: #cbd5e1;
font-weight: 600;
@@ -2303,5 +2307,158 @@ h4.section-title {
.modal--image-preview {
width: min(92vw, 100%);
}
+
+ .email-tpl-editor-wrap {
+ flex-direction: column;
+ }
+
+ .email-tpl-var-panel {
+ min-width: 200px;
+ }
+
+ .modal-box {
+ width: 95vw;
+ max-height: 90vh;
+ }
+}
+
+// Email template editor
+.email-tpl-editor-wrap {
+ display: flex;
+ flex-direction: column;
+ border: 1px solid var(--c-border);
+ border-radius: 6px;
+ overflow: hidden;
+}
+
+.email-tpl-toolbar {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ padding: 6px 8px;
+ background: var(--c-bg-subtle, #f8f9fa);
+ border-bottom: 1px solid var(--c-border);
+}
+
+.email-tpl-var-dropdown {
+ position: relative;
+}
+
+.email-tpl-var-panel {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 50;
+ min-width: 260px;
+ max-height: 320px;
+ overflow-y: auto;
+ background: var(--c-bg);
+ border: 1px solid var(--c-border);
+ border-radius: 6px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
+ padding: 6px;
+ margin-top: 4px;
+}
+
+.email-var-group {
+ &:not(:first-child) {
+ margin-top: 6px;
+ padding-top: 6px;
+ border-top: 1px solid var(--c-border);
+ }
+
+ &__label {
+ font-size: 11px;
+ font-weight: 600;
+ text-transform: uppercase;
+ color: var(--c-text-muted);
+ padding: 2px 4px;
+ letter-spacing: 0.03em;
+ }
+}
+
+.email-var-item {
+ display: block;
+ width: 100%;
+ text-align: left;
+ padding: 3px 6px;
+ margin: 1px 0;
+ border: none;
+ background: none;
+ font-size: 12px;
+ font-family: "Roboto Mono", monospace;
+ color: var(--c-text);
+ border-radius: 3px;
+ cursor: pointer;
+
+ &:hover {
+ background: var(--c-primary);
+ color: #fff;
+ }
+}
+
+#js-quill-editor {
+ min-height: 200px;
+
+ .ql-editor {
+ min-height: 200px;
+ font-size: 13px;
+ }
+}
+
+// Modal overlay (reusable)
+.modal-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 1000;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: rgba(0, 0, 0, 0.45);
+}
+
+.modal-box {
+ width: min(680px, 90vw);
+ max-height: 80vh;
+ background: var(--c-bg);
+ border-radius: 8px;
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2);
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+
+ &__header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 10px 16px;
+ border-bottom: 1px solid var(--c-border);
+ }
+
+ &__title {
+ margin: 0;
+ font-size: 15px;
+ font-weight: 600;
+ }
+
+ &__close {
+ background: none;
+ border: none;
+ font-size: 22px;
+ line-height: 1;
+ cursor: pointer;
+ color: var(--c-text-muted);
+ padding: 0 4px;
+
+ &:hover {
+ color: var(--c-text);
+ }
+ }
+
+ &__body {
+ padding: 12px 16px;
+ overflow-y: auto;
+ flex: 1;
+ }
}
diff --git a/resources/views/layouts/app.php b/resources/views/layouts/app.php
index 1884572..ef0cfa7 100644
--- a/resources/views/layouts/app.php
+++ b/resources/views/layouts/app.php
@@ -98,6 +98,9 @@
+
diff --git a/resources/views/settings/email-templates.php b/resources/views/settings/email-templates.php
new file mode 100644
index 0000000..3460020
--- /dev/null
+++ b/resources/views/settings/email-templates.php
@@ -0,0 +1,311 @@
+
+
+
+ Szablony e-mail
+ Szablony wiadomosci e-mail z edytorem i systemem zmiennych.
+
+
+ = $e((string) $errorMessage) ?>
+
+
+ = $e((string) $successMessage) ?>
+
+
+
+
+ Lista szablonow
+
+
+ Brak szablonow. Dodaj pierwszy szablon ponizej.
+
+
+
+
+
+ | Nazwa |
+ Temat |
+ Skrzynka |
+ Status |
+ Akcje |
+
+
+
+
+
+ | = $e((string) ($tpl['name'] ?? '')) ?> |
+ = $e((string) ($tpl['subject'] ?? '')) ?> |
+ = $e((string) ($tpl['mailbox_name'] ?? '—')) ?> |
+
+
+ Aktywny
+
+ Nieaktywny
+
+ |
+
+ Edytuj
+
+
+ |
+
+
+
+
+
+
+
+
+
+ = $isEdit ? 'Edytuj szablon' : 'Dodaj szablon' ?>
+
+
+
+
+
+
+
+
+
diff --git a/routes/web.php b/routes/web.php
index dd38679..a97ed8c 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -38,6 +38,8 @@ use App\Modules\Settings\ReceiptConfigController;
use App\Modules\Settings\ReceiptConfigRepository;
use App\Modules\Settings\EmailMailboxController;
use App\Modules\Settings\EmailMailboxRepository;
+use App\Modules\Settings\EmailTemplateController;
+use App\Modules\Settings\EmailTemplateRepository;
use App\Modules\Settings\IntegrationSecretCipher;
use App\Modules\Accounting\AccountingController;
use App\Modules\Accounting\ReceiptController;
@@ -197,6 +199,14 @@ return static function (Application $app): void {
$auth,
$emailMailboxRepository
);
+ $emailTemplateRepository = new EmailTemplateRepository($app->db());
+ $emailTemplateController = new EmailTemplateController(
+ $template,
+ $translator,
+ $auth,
+ $emailTemplateRepository,
+ $emailMailboxRepository
+ );
$receiptController = new ReceiptController(
$template,
$translator,
@@ -325,6 +335,12 @@ return static function (Application $app): void {
$router->post('/settings/email-mailboxes/delete', [$emailMailboxController, 'delete'], [$authMiddleware]);
$router->post('/settings/email-mailboxes/toggle', [$emailMailboxController, 'toggleStatus'], [$authMiddleware]);
$router->post('/settings/email-mailboxes/test', [$emailMailboxController, 'testConnection'], [$authMiddleware]);
+ $router->get('/settings/email-templates', [$emailTemplateController, 'index'], [$authMiddleware]);
+ $router->post('/settings/email-templates/save', [$emailTemplateController, 'save'], [$authMiddleware]);
+ $router->post('/settings/email-templates/delete', [$emailTemplateController, 'delete'], [$authMiddleware]);
+ $router->post('/settings/email-templates/toggle', [$emailTemplateController, 'toggleStatus'], [$authMiddleware]);
+ $router->post('/settings/email-templates/preview', [$emailTemplateController, 'preview'], [$authMiddleware]);
+ $router->get('/settings/email-templates/variables', [$emailTemplateController, 'getVariables'], [$authMiddleware]);
$router->get('/accounting', [$accountingController, 'index'], [$authMiddleware]);
$router->post('/accounting/export', [$accountingController, 'export'], [$authMiddleware]);
$router->get('/orders/{id}/receipt/create', [$receiptController, 'create'], [$authMiddleware]);
diff --git a/src/Modules/Settings/EmailTemplateController.php b/src/Modules/Settings/EmailTemplateController.php
new file mode 100644
index 0000000..27601ff
--- /dev/null
+++ b/src/Modules/Settings/EmailTemplateController.php
@@ -0,0 +1,228 @@
+ [
+ 'label' => 'Zamowienie',
+ 'vars' => [
+ 'numer' => 'Numer wewnetrzny (OP...)',
+ 'numer_zewnetrzny' => 'Numer z platformy',
+ 'zrodlo' => 'Zrodlo (Allegro/shopPRO/...)',
+ 'kwota' => 'Kwota brutto',
+ 'waluta' => 'Waluta (PLN/EUR/...)',
+ 'data' => 'Data zamowienia',
+ ],
+ ],
+ 'kupujacy' => [
+ 'label' => 'Kupujacy',
+ 'vars' => [
+ 'imie_nazwisko' => 'Imie i nazwisko',
+ 'email' => 'Adres e-mail',
+ 'telefon' => 'Telefon',
+ 'login' => 'Login platformy',
+ ],
+ ],
+ 'adres' => [
+ 'label' => 'Adres dostawy',
+ 'vars' => [
+ 'ulica' => 'Ulica z numerem',
+ 'miasto' => 'Miasto',
+ 'kod_pocztowy' => 'Kod pocztowy',
+ 'kraj' => 'Kraj',
+ ],
+ ],
+ 'firma' => [
+ 'label' => 'Firma',
+ 'vars' => [
+ 'nazwa' => 'Nazwa firmy',
+ 'nip' => 'NIP',
+ ],
+ ],
+ ];
+
+ private const SAMPLE_DATA = [
+ 'zamowienie.numer' => 'OP000001234',
+ 'zamowienie.numer_zewnetrzny' => 'ALG-98765432',
+ 'zamowienie.zrodlo' => 'Allegro',
+ 'zamowienie.kwota' => '149,99',
+ 'zamowienie.waluta' => 'PLN',
+ 'zamowienie.data' => '2026-03-16',
+ 'kupujacy.imie_nazwisko' => 'Jan Kowalski',
+ 'kupujacy.email' => 'jan.kowalski@example.com',
+ 'kupujacy.telefon' => '+48 600 123 456',
+ 'kupujacy.login' => 'jankowalski82',
+ 'adres.ulica' => 'ul. Dluga 15/3',
+ 'adres.miasto' => 'Warszawa',
+ 'adres.kod_pocztowy' => '00-238',
+ 'adres.kraj' => 'PL',
+ 'firma.nazwa' => 'Przykladowa Firma Sp. z o.o.',
+ 'firma.nip' => '5271234567',
+ ];
+
+ public function __construct(
+ private readonly Template $template,
+ private readonly Translator $translator,
+ private readonly AuthService $auth,
+ private readonly EmailTemplateRepository $repository,
+ private readonly EmailMailboxRepository $mailboxRepository
+ ) {
+ }
+
+ public function index(Request $request): Response
+ {
+ $t = $this->translator;
+ $templates = $this->repository->listAll();
+ $mailboxes = $this->mailboxRepository->listActive();
+
+ $editTemplate = null;
+ $editId = (int) $request->input('edit', '0');
+ if ($editId > 0) {
+ $editTemplate = $this->repository->findById($editId);
+ }
+
+ $html = $this->template->render('settings/email-templates', [
+ 'title' => 'Szablony e-mail',
+ 'activeMenu' => 'settings',
+ 'activeSettings' => 'email-templates',
+ 'user' => $this->auth->user(),
+ 'csrfToken' => Csrf::token(),
+ 'templates' => $templates,
+ 'mailboxes' => $mailboxes,
+ 'editTemplate' => $editTemplate,
+ 'variableGroups' => self::VARIABLE_GROUPS,
+ 'successMessage' => Flash::get('settings.email_templates.success', ''),
+ 'errorMessage' => Flash::get('settings.email_templates.error', ''),
+ ], 'layouts/app');
+
+ return Response::html($html);
+ }
+
+ public function save(Request $request): Response
+ {
+ if (!Csrf::validate((string) $request->input('_token', ''))) {
+ Flash::set('settings.email_templates.error', 'Nieprawidlowy token CSRF');
+ return Response::redirect('/settings/email-templates');
+ }
+
+ $name = trim((string) $request->input('name', ''));
+ $subject = trim((string) $request->input('subject', ''));
+ $bodyHtml = (string) $request->input('body_html', '');
+
+ if ($name === '' || $subject === '' || $bodyHtml === '') {
+ Flash::set('settings.email_templates.error', 'Nazwa, temat i tresc sa wymagane');
+ return Response::redirect('/settings/email-templates');
+ }
+
+ try {
+ $this->repository->save([
+ 'id' => $request->input('id', ''),
+ 'name' => $name,
+ 'subject' => $subject,
+ 'body_html' => $bodyHtml,
+ 'mailbox_id' => $request->input('mailbox_id', ''),
+ 'is_active' => $request->input('is_active', null),
+ ]);
+
+ Flash::set('settings.email_templates.success', 'Szablon zostal zapisany');
+ } catch (Throwable) {
+ Flash::set('settings.email_templates.error', 'Blad zapisu szablonu');
+ }
+
+ return Response::redirect('/settings/email-templates');
+ }
+
+ public function delete(Request $request): Response
+ {
+ if (!Csrf::validate((string) $request->input('_token', ''))) {
+ Flash::set('settings.email_templates.error', 'Nieprawidlowy token CSRF');
+ return Response::redirect('/settings/email-templates');
+ }
+
+ $id = (int) $request->input('id', '0');
+ if ($id <= 0) {
+ Flash::set('settings.email_templates.error', 'Nieprawidlowy identyfikator szablonu');
+ return Response::redirect('/settings/email-templates');
+ }
+
+ try {
+ $this->repository->delete($id);
+ Flash::set('settings.email_templates.success', 'Szablon zostal usuniety');
+ } catch (Throwable) {
+ Flash::set('settings.email_templates.error', 'Blad usuwania szablonu');
+ }
+
+ return Response::redirect('/settings/email-templates');
+ }
+
+ public function toggleStatus(Request $request): Response
+ {
+ if (!Csrf::validate((string) $request->input('_token', ''))) {
+ return Response::json(['success' => false, 'message' => 'Nieprawidlowy token CSRF'], 403);
+ }
+
+ $id = (int) $request->input('id', '0');
+ if ($id <= 0) {
+ return Response::json(['success' => false, 'message' => 'Nieprawidlowy identyfikator'], 400);
+ }
+
+ try {
+ $this->repository->toggleStatus($id);
+ return Response::json(['success' => true]);
+ } catch (Throwable) {
+ return Response::json(['success' => false, 'message' => 'Blad zmiany statusu'], 500);
+ }
+ }
+
+ public function preview(Request $request): Response
+ {
+ if (!Csrf::validate((string) $request->input('_token', ''))) {
+ return Response::json(['success' => false, 'message' => 'Nieprawidlowy token CSRF'], 403);
+ }
+
+ $subject = (string) $request->input('subject', '');
+ $bodyHtml = (string) $request->input('body_html', '');
+
+ return Response::json([
+ 'success' => true,
+ 'subject' => self::resolveVariables($subject, self::SAMPLE_DATA),
+ 'body_html' => self::resolveVariables($bodyHtml, self::SAMPLE_DATA),
+ ]);
+ }
+
+ public function getVariables(Request $request): Response
+ {
+ return Response::json([
+ 'success' => true,
+ 'groups' => self::VARIABLE_GROUPS,
+ ]);
+ }
+
+ /**
+ * @param array $data
+ */
+ public static function resolveVariables(string $text, array $data): string
+ {
+ return (string) preg_replace_callback(
+ '/\{\{([a-z_]+)\.([a-z_]+)\}\}/',
+ static function (array $matches) use ($data): string {
+ $key = $matches[1] . '.' . $matches[2];
+ return $data[$key] ?? $matches[0];
+ },
+ $text
+ );
+ }
+}
diff --git a/src/Modules/Settings/EmailTemplateRepository.php b/src/Modules/Settings/EmailTemplateRepository.php
new file mode 100644
index 0000000..f2d02f8
--- /dev/null
+++ b/src/Modules/Settings/EmailTemplateRepository.php
@@ -0,0 +1,117 @@
+>
+ */
+ public function listAll(): array
+ {
+ $statement = $this->pdo->prepare(
+ 'SELECT t.id, t.name, t.subject, t.mailbox_id, t.is_active, t.created_at, t.updated_at,
+ m.name AS mailbox_name
+ FROM email_templates t
+ LEFT JOIN email_mailboxes m ON m.id = t.mailbox_id
+ ORDER BY t.name ASC'
+ );
+ $statement->execute();
+ $rows = $statement->fetchAll(PDO::FETCH_ASSOC);
+
+ return is_array($rows) ? $rows : [];
+ }
+
+ /**
+ * @return array|null
+ */
+ public function findById(int $id): ?array
+ {
+ $statement = $this->pdo->prepare(
+ 'SELECT id, name, subject, body_html, mailbox_id, is_active, created_at, updated_at
+ FROM email_templates
+ WHERE id = :id'
+ );
+ $statement->execute(['id' => $id]);
+ $row = $statement->fetch(PDO::FETCH_ASSOC);
+
+ return is_array($row) ? $row : null;
+ }
+
+ /**
+ * @return list>
+ */
+ public function listActive(): array
+ {
+ $statement = $this->pdo->prepare(
+ 'SELECT id, name, subject, mailbox_id
+ FROM email_templates
+ WHERE is_active = 1
+ ORDER BY name ASC'
+ );
+ $statement->execute();
+ $rows = $statement->fetchAll(PDO::FETCH_ASSOC);
+
+ return is_array($rows) ? $rows : [];
+ }
+
+ /**
+ * @param array $data
+ */
+ public function save(array $data): void
+ {
+ $id = isset($data['id']) && $data['id'] !== '' ? (int) $data['id'] : null;
+
+ $mailboxId = isset($data['mailbox_id']) && $data['mailbox_id'] !== '' && $data['mailbox_id'] !== '0'
+ ? (int) $data['mailbox_id']
+ : null;
+
+ $params = [
+ 'name' => trim((string) ($data['name'] ?? '')),
+ 'subject' => trim((string) ($data['subject'] ?? '')),
+ 'body_html' => (string) ($data['body_html'] ?? ''),
+ 'mailbox_id' => $mailboxId,
+ 'is_active' => isset($data['is_active']) ? 1 : 0,
+ ];
+
+ if ($id !== null) {
+ $params['id'] = $id;
+ $statement = $this->pdo->prepare(
+ 'UPDATE email_templates
+ SET name = :name, subject = :subject, body_html = :body_html,
+ mailbox_id = :mailbox_id, is_active = :is_active
+ WHERE id = :id'
+ );
+ } else {
+ $statement = $this->pdo->prepare(
+ 'INSERT INTO email_templates (name, subject, body_html, mailbox_id, is_active)
+ VALUES (:name, :subject, :body_html, :mailbox_id, :is_active)'
+ );
+ }
+
+ $statement->execute($params);
+ }
+
+ public function delete(int $id): void
+ {
+ $statement = $this->pdo->prepare('DELETE FROM email_templates WHERE id = :id');
+ $statement->execute(['id' => $id]);
+ }
+
+ public function toggleStatus(int $id): void
+ {
+ $statement = $this->pdo->prepare(
+ 'UPDATE email_templates SET is_active = NOT is_active WHERE id = :id'
+ );
+ $statement->execute(['id' => $id]);
+ }
+}