stat2025 commited on
Commit
dba6001
·
verified ·
1 Parent(s): ab3bd11

Upload 6 files

Browse files
Files changed (6) hide show
  1. README.md +3 -3
  2. app.js +67 -24
  3. data.js +0 -0
  4. generate-data.mjs +1 -1
  5. index.html +12 -12
  6. style.css +114 -2
README.md CHANGED
@@ -9,7 +9,7 @@ license: mit
9
  short_description: نظام استعلام المنشآت الصناعية
10
  ---
11
 
12
- # نظام استعلام المنشآت الصناعية
13
 
14
  واجهة عربية ثابتة للاستعلام عن المنشآت حسب المنطقة والمدينة الصناعية، مع بحث مباشر باسم المنشأة أو السجل التجاري.
15
 
@@ -24,11 +24,11 @@ short_description: نظام استعلام المنشآت الصناعية
24
 
25
  - إذا كانت الخانة تحتوي على إحداثيات رقمية، يظهر رابط مباشر إلى خرائط Google.
26
  - إذا كانت الخانة فارغة، لا يظهر حقل الإحداثيات.
27
- - إذا كانت الخانة تحتوي على نص تواصل ورقم جوال، تظهر أزرار اتصال وواتساب ونسخ رسالة جاهزة.
28
 
29
  ## تحديث البيانات
30
 
31
- رمز الدخول الافتراضي في النسخة الحالية هو `1234`.
32
 
33
  لتحديث ملف البيانات المشفر:
34
 
 
9
  short_description: نظام استعلام المنشآت الصناعية
10
  ---
11
 
12
+ # شاشة استعلام
13
 
14
  واجهة عربية ثابتة للاستعلام عن المنشآت حسب المنطقة والمدينة الصناعية، مع بحث مباشر باسم المنشأة أو السجل التجاري.
15
 
 
24
 
25
  - إذا كانت الخانة تحتوي على إحداثيات رقمية، يظهر رابط مباشر إلى خرائط Google.
26
  - إذا كانت الخانة فارغة، لا يظهر حقل الإحداثيات.
27
+ - إذا كانت الخانة تحتوي على نص تواصل ورقم جوال، تظهر باسم "إفادة مدن" مع أزرار نسخ الرقم وواتساب ونسخ رسالة مقترحة.
28
 
29
  ## تحديث البيانات
30
 
31
+ رمز الدخول الافتراضي في النسخة الحالية هو `20302030`.
32
 
33
  لتحديث ملف البيانات المشفر:
34
 
app.js CHANGED
@@ -9,6 +9,7 @@ const loginError = document.getElementById("loginError");
9
  const togglePassword = document.getElementById("togglePassword");
10
  const logoutButton = document.getElementById("logoutButton");
11
  const regionSelect = document.getElementById("regionSelect");
 
12
  const citySelect = document.getElementById("citySelect");
13
  const searchInput = document.getElementById("searchInput");
14
  const clearFiltersButton = document.getElementById("clearFiltersButton");
@@ -27,7 +28,7 @@ const toast = document.getElementById("toast");
27
 
28
  const PAGE_SIZE = 24;
29
  const CONTACT_MESSAGE = (name) =>
30
- `مرحبا استاذ\nاتواصل معاك لمعرف موقع (${name || "العينة"})\nهل ممكن تزودني بموقع العينة كرما`;
31
 
32
  let rows = [];
33
  let visibleRows = [];
@@ -88,6 +89,27 @@ function setOptions(select, values, placeholder) {
88
  values.forEach((value) => select.add(new Option(value, value)));
89
  }
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  function showToast(message) {
92
  clearTimeout(toastTimer);
93
  toast.textContent = message;
@@ -120,6 +142,12 @@ function phoneDigits(value) {
120
  return `966${digits}`;
121
  }
122
 
 
 
 
 
 
 
123
  function isCoordinate(value) {
124
  return /^[-+]?\d{1,2}(?:\.\d+)?\s*,\s*[-+]?\d{1,3}(?:\.\d+)?$/.test(String(value ?? "").trim());
125
  }
@@ -165,7 +193,7 @@ function createCoordinatesBlock(row) {
165
  item.className = "detail-item coordinates-detail";
166
  const label = document.createElement("span");
167
  label.className = "detail-label";
168
- label.textContent = "الإحداثيات";
169
  item.append(label);
170
 
171
  if (isCoordinate(value)) {
@@ -189,15 +217,25 @@ function createCoordinatesBlock(row) {
189
  const message = CONTACT_MESSAGE(row.establishmentName);
190
  const actions = document.createElement("div");
191
  actions.className = "contact-actions";
 
 
 
 
 
 
 
 
 
 
192
  actions.append(
193
- createActionLink("اتصال", `tel:+${phone}`, "M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.1 4.2 2 2 0 0 1 4.1 2h3a2 2 0 0 1 2 1.7c.1.9.3 1.8.6 2.6a2 2 0 0 1-.4 2.1L8.1 9.6a16 16 0 0 0 6.3 6.3l1.2-1.2a2 2 0 0 1 2.1-.4c.8.3 1.7.5 2.6.6a2 2 0 0 1 1.7 2Z"),
194
  createActionLink("واتساب", `https://wa.me/${phone}?text=${encodeURIComponent(message)}`, "M20.5 11.5a8.5 8.5 0 0 1-12.6 7.4L3 20l1.2-4.7A8.5 8.5 0 1 1 20.5 11.5Z M8.6 8.7c.2 3.3 2.7 5.8 6 6.2"),
195
  );
196
  const copyButton = document.createElement("button");
197
  copyButton.type = "button";
198
  copyButton.className = "action-link";
199
- copyButton.append(createSvgIcon("M8 8h11v11H8z M5 16H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"), document.createTextNode("نسخ الرسالة"));
200
- copyButton.addEventListener("click", () => copyText(message, "تم نسخ الرسالة الجاهزة"));
201
  actions.append(copyButton);
202
  item.append(actions);
203
  }
@@ -288,20 +326,34 @@ function applyFilters() {
288
  function initializeDashboard(data) {
289
  rows = data.rows || [];
290
  totalCounter.textContent = `${rows.length} منشأة`;
291
- setOptions(regionSelect, data.regions || uniqueSorted(rows.map((row) => row.region)), "اختر المنطقة");
 
292
  const regionCounts = new Map();
293
  rows.forEach((row) => regionCounts.set(row.region, (regionCounts.get(row.region) || 0) + 1));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
  regionStats.replaceChildren(
295
- ...(data.regions || uniqueSorted(rows.map((row) => row.region))).map((region) => {
296
  const chip = document.createElement("button");
297
  chip.type = "button";
298
  chip.className = "region-stat";
299
  chip.innerHTML = `<span>${region}</span><strong>${regionCounts.get(region) || 0}</strong>`;
300
- chip.addEventListener("click", () => {
301
- regionSelect.value = region;
302
- regionSelect.dispatchEvent(new Event("change"));
303
- window.scrollTo({ top: document.querySelector(".controls-panel").offsetTop - 84, behavior: "smooth" });
304
- });
305
  return chip;
306
  }),
307
  );
@@ -314,7 +366,7 @@ function performLogout() {
314
  rows = [];
315
  visibleRows = [];
316
  searchInput.value = "";
317
- regionSelect.value = "";
318
  citySelect.value = "";
319
  dashboardView.hidden = true;
320
  loginView.hidden = false;
@@ -352,23 +404,14 @@ togglePassword.addEventListener("click", () => {
352
 
353
  logoutButton.addEventListener("click", performLogout);
354
 
355
- regionSelect.addEventListener("change", () => {
356
- const cities = uniqueSorted(rows.filter((row) => row.region === regionSelect.value).map((row) => row.city));
357
- setOptions(citySelect, cities, "اختر المدينة الصناعية");
358
- citySelect.disabled = !regionSelect.value;
359
- citySelect.value = "";
360
- applyFilters();
361
- });
362
 
363
  citySelect.addEventListener("change", applyFilters);
364
  searchInput.addEventListener("input", applyFilters);
365
  loadMoreButton.addEventListener("click", () => renderVisibleRows());
366
  clearFiltersButton.addEventListener("click", () => {
367
- regionSelect.value = "";
368
  searchInput.value = "";
369
- setOptions(citySelect, [], "اختر المدينة الصناعية");
370
- citySelect.disabled = true;
371
- applyFilters();
372
  showToast("تم مسح الاختيارات");
373
  });
374
 
 
9
  const togglePassword = document.getElementById("togglePassword");
10
  const logoutButton = document.getElementById("logoutButton");
11
  const regionSelect = document.getElementById("regionSelect");
12
+ const regionButtons = document.getElementById("regionButtons");
13
  const citySelect = document.getElementById("citySelect");
14
  const searchInput = document.getElementById("searchInput");
15
  const clearFiltersButton = document.getElementById("clearFiltersButton");
 
28
 
29
  const PAGE_SIZE = 24;
30
  const CONTACT_MESSAGE = (name) =>
31
+ `السلام عليكم ورحمة الله وبركاته\n\nأستاذي الكريم،\nنأمل تزويدنا بموقع منشأة (${name || "العينة"})، وذلك لاستكمال بيانات الزيارة الميدانية.\n\nشاكرين لكم تعاونكم.`;
32
 
33
  let rows = [];
34
  let visibleRows = [];
 
89
  values.forEach((value) => select.add(new Option(value, value)));
90
  }
91
 
92
+ function updateRegionButtonState() {
93
+ regionButtons.querySelectorAll(".region-choice").forEach((button) => {
94
+ const isActive = button.dataset.region === regionSelect.value;
95
+ button.classList.toggle("active", isActive);
96
+ button.setAttribute("aria-checked", String(isActive));
97
+ });
98
+ }
99
+
100
+ function setRegion(region, scrollToControls = false) {
101
+ regionSelect.value = region;
102
+ updateRegionButtonState();
103
+ const cities = uniqueSorted(rows.filter((row) => row.region === region).map((row) => row.city));
104
+ setOptions(citySelect, cities, "اختر المدينة الصناعية");
105
+ citySelect.disabled = !region;
106
+ citySelect.value = "";
107
+ applyFilters();
108
+ if (scrollToControls) {
109
+ window.scrollTo({ top: document.querySelector(".controls-panel").offsetTop - 16, behavior: "smooth" });
110
+ }
111
+ }
112
+
113
  function showToast(message) {
114
  clearTimeout(toastTimer);
115
  toast.textContent = message;
 
142
  return `966${digits}`;
143
  }
144
 
145
+ function localPhoneNumber(value) {
146
+ const digits = phoneDigits(value);
147
+ if (!digits) return "";
148
+ return digits.startsWith("966") ? `0${digits.slice(3)}` : digits;
149
+ }
150
+
151
  function isCoordinate(value) {
152
  return /^[-+]?\d{1,2}(?:\.\d+)?\s*,\s*[-+]?\d{1,3}(?:\.\d+)?$/.test(String(value ?? "").trim());
153
  }
 
193
  item.className = "detail-item coordinates-detail";
194
  const label = document.createElement("span");
195
  label.className = "detail-label";
196
+ label.textContent = isCoordinate(value) ? "الإحداثيات" : "إفادة مدن";
197
  item.append(label);
198
 
199
  if (isCoordinate(value)) {
 
217
  const message = CONTACT_MESSAGE(row.establishmentName);
218
  const actions = document.createElement("div");
219
  actions.className = "contact-actions";
220
+ const copyPhoneButton = document.createElement("button");
221
+ copyPhoneButton.type = "button";
222
+ copyPhoneButton.className = "action-link";
223
+ copyPhoneButton.append(
224
+ createSvgIcon("M8 8h11v11H8z M5 16H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"),
225
+ document.createTextNode("نسخ الرقم"),
226
+ );
227
+ copyPhoneButton.addEventListener("click", () =>
228
+ copyText(localPhoneNumber(value), "تم نسخ الرقم"),
229
+ );
230
  actions.append(
231
+ copyPhoneButton,
232
  createActionLink("واتساب", `https://wa.me/${phone}?text=${encodeURIComponent(message)}`, "M20.5 11.5a8.5 8.5 0 0 1-12.6 7.4L3 20l1.2-4.7A8.5 8.5 0 1 1 20.5 11.5Z M8.6 8.7c.2 3.3 2.7 5.8 6 6.2"),
233
  );
234
  const copyButton = document.createElement("button");
235
  copyButton.type = "button";
236
  copyButton.className = "action-link";
237
+ copyButton.append(createSvgIcon("M8 8h11v11H8z M5 16H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"), document.createTextNode("نسخ رسالة مقترحة"));
238
+ copyButton.addEventListener("click", () => copyText(message, "تم نسخ الرسالة المقترحة"));
239
  actions.append(copyButton);
240
  item.append(actions);
241
  }
 
326
  function initializeDashboard(data) {
327
  rows = data.rows || [];
328
  totalCounter.textContent = `${rows.length} منشأة`;
329
+ const regions = data.regions || uniqueSorted(rows.map((row) => row.region));
330
+ setOptions(regionSelect, regions, "اختر المنطقة");
331
  const regionCounts = new Map();
332
  rows.forEach((row) => regionCounts.set(row.region, (regionCounts.get(row.region) || 0) + 1));
333
+ regionButtons.replaceChildren(
334
+ ...regions.map((region) => {
335
+ const button = document.createElement("button");
336
+ button.type = "button";
337
+ button.className = "region-choice";
338
+ button.dataset.region = region;
339
+ button.setAttribute("role", "radio");
340
+ button.setAttribute("aria-checked", "false");
341
+ const name = document.createElement("span");
342
+ name.textContent = region;
343
+ const count = document.createElement("strong");
344
+ count.textContent = regionCounts.get(region) || 0;
345
+ button.append(name, count);
346
+ button.addEventListener("click", () => setRegion(region));
347
+ return button;
348
+ }),
349
+ );
350
  regionStats.replaceChildren(
351
+ ...regions.map((region) => {
352
  const chip = document.createElement("button");
353
  chip.type = "button";
354
  chip.className = "region-stat";
355
  chip.innerHTML = `<span>${region}</span><strong>${regionCounts.get(region) || 0}</strong>`;
356
+ chip.addEventListener("click", () => setRegion(region, true));
 
 
 
 
357
  return chip;
358
  }),
359
  );
 
366
  rows = [];
367
  visibleRows = [];
368
  searchInput.value = "";
369
+ setRegion("");
370
  citySelect.value = "";
371
  dashboardView.hidden = true;
372
  loginView.hidden = false;
 
404
 
405
  logoutButton.addEventListener("click", performLogout);
406
 
407
+ regionSelect.addEventListener("change", () => setRegion(regionSelect.value));
 
 
 
 
 
 
408
 
409
  citySelect.addEventListener("change", applyFilters);
410
  searchInput.addEventListener("input", applyFilters);
411
  loadMoreButton.addEventListener("click", () => renderVisibleRows());
412
  clearFiltersButton.addEventListener("click", () => {
 
413
  searchInput.value = "";
414
+ setRegion("");
 
 
415
  showToast("تم مسح الاختيارات");
416
  });
417
 
data.js CHANGED
The diff for this file is too large to render. See raw diff
 
generate-data.mjs CHANGED
@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
2
  import crypto from "node:crypto";
3
  import { FileBlob, SpreadsheetFile } from "@oai/artifact-tool";
4
 
5
- const [inputPath, outputPath, password = "1234"] = process.argv.slice(2);
6
 
7
  const CITY_INFO = new Map([
8
  ["المدينة الصناعية الأولى بالدمام", { region: "منطقة الدمام", city: "الصناعية الأولى بالدمام" }],
 
2
  import crypto from "node:crypto";
3
  import { FileBlob, SpreadsheetFile } from "@oai/artifact-tool";
4
 
5
+ const [inputPath, outputPath, password = "20302030"] = process.argv.slice(2);
6
 
7
  const CITY_INFO = new Map([
8
  ["المدينة الصناعية الأولى بالدمام", { region: "منطقة الدمام", city: "الصناعية الأولى بالدمام" }],
index.html CHANGED
@@ -5,7 +5,7 @@
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
  <meta name="theme-color" content="#0f4c5c" />
7
  <meta name="robots" content="noindex, nofollow" />
8
- <title>نظام استعلام المنشآت الصناعية</title>
9
  <link rel="preconnect" href="https://fonts.googleapis.com" />
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
11
  <link
@@ -21,9 +21,9 @@
21
  <div class="brand-mark" aria-hidden="true">
22
  <svg viewBox="0 0 24 24"><path d="M4 20V8l8-4 8 4v12H4Z" /><path d="M8 20v-7h8v7" /></svg>
23
  </div>
24
- <p class="eyebrow">بوابة الاستعلام</p>
25
- <h1>نظام استعلام المنشآت الصناعية</h1>
26
- <p class="login-description">أدخل رمز الدخول لعرض بيانات المنشآت والمواقع وبيانات التواصل.</p>
27
 
28
  <label for="password">رمز الدخول</label>
29
  <div class="password-field">
@@ -48,7 +48,7 @@
48
  </div>
49
  <div>
50
  <p>نظام الاستعلام</p>
51
- <h1>المنشآت الصناعية</h1>
52
  </div>
53
  </div>
54
  <button id="logoutButton" class="secondary-button compact" type="button">
@@ -71,12 +71,12 @@
71
 
72
  <section class="controls-panel">
73
  <div class="filters-grid">
74
- <div class="field-group">
75
- <label for="regionSelect">المنطقة</label>
76
- <div class="select-wrap">
77
- <select id="regionSelect"><option value="">اختر المنطقة</option></select>
78
- <svg viewBox="0 0 24 24"><path d="m7 10 5 5 5-5" /></svg>
79
- </div>
80
  </div>
81
 
82
  <div class="field-group">
@@ -130,7 +130,7 @@
130
  </section>
131
  </main>
132
 
133
- <footer>إعداد نظام الاستعلام</footer>
134
  <div id="toast" class="toast" role="status" aria-live="polite"></div>
135
 
136
  <script src="data.js"></script>
 
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
  <meta name="theme-color" content="#0f4c5c" />
7
  <meta name="robots" content="noindex, nofollow" />
8
+ <title>شاشة استعلام</title>
9
  <link rel="preconnect" href="https://fonts.googleapis.com" />
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
11
  <link
 
21
  <div class="brand-mark" aria-hidden="true">
22
  <svg viewBox="0 0 24 24"><path d="M4 20V8l8-4 8 4v12H4Z" /><path d="M8 20v-7h8v7" /></svg>
23
  </div>
24
+ <p class="eyebrow">نظام الاستعلام</p>
25
+ <h1>شاشة استعلام</h1>
26
+ <p class="login-description">أدخل رمز الدخول للمتابعة.</p>
27
 
28
  <label for="password">رمز الدخول</label>
29
  <div class="password-field">
 
48
  </div>
49
  <div>
50
  <p>نظام الاستعلام</p>
51
+ <h1>شاشة استعلام</h1>
52
  </div>
53
  </div>
54
  <button id="logoutButton" class="secondary-button compact" type="button">
 
71
 
72
  <section class="controls-panel">
73
  <div class="filters-grid">
74
+ <div class="field-group region-group">
75
+ <span class="field-label">المنطقة</span>
76
+ <div id="regionButtons" class="region-buttons" role="radiogroup" aria-label="اختيار المنطقة"></div>
77
+ <select id="regionSelect" class="region-select-hidden" aria-hidden="true" tabindex="-1">
78
+ <option value="">اختر المنطقة</option>
79
+ </select>
80
  </div>
81
 
82
  <div class="field-group">
 
130
  </section>
131
  </main>
132
 
133
+ <footer>إعداد نوف الناصر</footer>
134
  <div id="toast" class="toast" role="status" aria-live="polite"></div>
135
 
136
  <script src="data.js"></script>
style.css CHANGED
@@ -852,8 +852,8 @@ select:focus-visible {
852
  }
853
 
854
  .controls-panel {
855
- position: sticky;
856
- top: 86px;
857
  z-index: 15;
858
  border-color: rgba(217, 227, 232, 0.92);
859
  }
@@ -1094,3 +1094,115 @@ select:focus-visible {
1094
  transform: translateY(0);
1095
  }
1096
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
852
  }
853
 
854
  .controls-panel {
855
+ position: static;
856
+ top: auto;
857
  z-index: 15;
858
  border-color: rgba(217, 227, 232, 0.92);
859
  }
 
1094
  transform: translateY(0);
1095
  }
1096
  }
1097
+
1098
+ /* Region buttons replace the region dropdown */
1099
+ .login-card label,
1100
+ .field-group label,
1101
+ .field-label {
1102
+ display: block;
1103
+ margin-bottom: 8px;
1104
+ color: #34495a;
1105
+ font-weight: 700;
1106
+ }
1107
+
1108
+ .filters-grid {
1109
+ grid-template-columns: minmax(220px, 1fr) minmax(300px, 1.35fr);
1110
+ }
1111
+
1112
+ .region-group {
1113
+ grid-column: 1 / -1;
1114
+ }
1115
+
1116
+ .region-select-hidden {
1117
+ position: absolute;
1118
+ width: 1px;
1119
+ height: 1px;
1120
+ overflow: hidden;
1121
+ clip: rect(0 0 0 0);
1122
+ white-space: nowrap;
1123
+ border: 0;
1124
+ opacity: 0;
1125
+ pointer-events: none;
1126
+ }
1127
+
1128
+ .region-buttons {
1129
+ display: grid;
1130
+ grid-template-columns: repeat(4, minmax(0, 1fr));
1131
+ gap: 10px;
1132
+ }
1133
+
1134
+ .region-choice {
1135
+ display: flex;
1136
+ align-items: center;
1137
+ justify-content: space-between;
1138
+ gap: 10px;
1139
+ min-width: 0;
1140
+ min-height: 54px;
1141
+ padding: 10px 13px;
1142
+ color: #315161;
1143
+ text-align: right;
1144
+ background: #fbfdfe;
1145
+ border: 1px solid #d2dfe6;
1146
+ border-radius: 8px;
1147
+ font-weight: 800;
1148
+ transition: transform 0.18s, color 0.18s, background 0.18s, border-color 0.18s, box-shadow 0.18s;
1149
+ }
1150
+
1151
+ .region-choice:hover {
1152
+ background: #eef7f9;
1153
+ border-color: #bcd8df;
1154
+ transform: translateY(-1px);
1155
+ }
1156
+
1157
+ .region-choice.active {
1158
+ color: #fff;
1159
+ background: linear-gradient(145deg, var(--primary), #177b72);
1160
+ border-color: transparent;
1161
+ box-shadow: 0 12px 26px rgba(15, 76, 92, 0.16);
1162
+ }
1163
+
1164
+ .region-choice span {
1165
+ min-width: 0;
1166
+ overflow: hidden;
1167
+ text-overflow: ellipsis;
1168
+ white-space: nowrap;
1169
+ }
1170
+
1171
+ .region-choice strong {
1172
+ flex: 0 0 auto;
1173
+ min-width: 34px;
1174
+ padding: 3px 8px;
1175
+ color: var(--accent);
1176
+ text-align: center;
1177
+ background: var(--accent-soft);
1178
+ border-radius: 8px;
1179
+ }
1180
+
1181
+ .region-choice.active strong {
1182
+ color: var(--primary-dark);
1183
+ background: #d9fff4;
1184
+ }
1185
+
1186
+ @media (max-width: 900px) {
1187
+ .filters-grid {
1188
+ grid-template-columns: 1fr;
1189
+ }
1190
+
1191
+ .region-buttons {
1192
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1193
+ }
1194
+ }
1195
+
1196
+ @media (max-width: 560px) {
1197
+ .filters-grid {
1198
+ grid-template-columns: 1fr;
1199
+ }
1200
+
1201
+ .region-buttons {
1202
+ grid-template-columns: 1fr;
1203
+ }
1204
+
1205
+ .region-choice {
1206
+ min-height: 48px;
1207
+ }
1208
+ }