@appaflytech/zeyrek-ai-mcp 0.0.48 → 0.0.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/.env.example +5 -0
  2. package/dist/config.js +2 -0
  3. package/dist/knowledge/access.js +4 -3
  4. package/dist/knowledge/assistantRun.js +165 -0
  5. package/dist/knowledge/componentCatalog.js +31 -0
  6. package/dist/knowledge/componentEvents.js +4 -1
  7. package/dist/knowledge/mobileComponentCatalog.js +21 -3
  8. package/dist/knowledge/mobileComponentEvents.js +9 -0
  9. package/dist/knowledge/mobileStore.js +14 -0
  10. package/dist/knowledge/motionResolve.js +1 -1
  11. package/dist/knowledge/platform/lint.js +36 -3
  12. package/dist/knowledge/platform/mobileRules.js +6 -0
  13. package/dist/knowledge/styleResolve.js +7 -0
  14. package/dist/platform/capture/actions.js +67 -0
  15. package/dist/platform/capture/capture.js +26 -21
  16. package/dist/platform/errors.js +9 -0
  17. package/dist/platform/http.js +7 -2
  18. package/dist/platform/storeArt/compose.js +114 -0
  19. package/dist/platform/storeArt/deck.js +133 -0
  20. package/dist/platform/storeArt/gallery.js +331 -0
  21. package/dist/platform/storeArt/layouts.js +121 -0
  22. package/dist/platform/storeArt/styles.js +54 -0
  23. package/dist/platform/tokenVault.js +15 -0
  24. package/dist/resources/examples/mobile-reorder-persist.json +491 -0
  25. package/dist/resources/guides/assistant.md +194 -0
  26. package/dist/resources/guides/deployment.md +19 -1
  27. package/dist/resources/guides/microservice.md +7 -0
  28. package/dist/resources/guides/mobile-publish.md +13 -0
  29. package/dist/resources/guides/mobile.md +4 -0
  30. package/dist/resources/guides/page.md +62 -0
  31. package/dist/resources/prompts/mobile-publish-prepare.md +3 -1
  32. package/dist/resources/schema-fingerprint.json +4 -4
  33. package/dist/resources/schemas/AccessMatrixDto.json +2 -1
  34. package/dist/resources/schemas/AccessPermissionDto.json +2 -1
  35. package/dist/resources/schemas/AccessResourceDto.json +2 -1
  36. package/dist/resources/schemas/AssistantCapabilitiesDto.json +256 -0
  37. package/dist/resources/schemas/AssistantPublishStateDto.json +57 -0
  38. package/dist/resources/schemas/AssistantScenarioDto.json +91 -0
  39. package/dist/resources/schemas/AssistantScenarioRunDto.json +62 -0
  40. package/dist/resources/schemas/AssistantSettingsDto.json +52 -0
  41. package/dist/resources/schemas/AssistantSkillDto.json +78 -0
  42. package/dist/resources/schemas/AssistantSummaryDto.json +100 -0
  43. package/dist/resources/schemas/CreateAssistantScenarioCommand.json +81 -0
  44. package/dist/resources/schemas/CreateAssistantSkillCommand.json +83 -0
  45. package/dist/resources/schemas/CreateMicroserviceCommand.json +16 -0
  46. package/dist/resources/schemas/DescribeAssistantCapabilityCommand.json +145 -0
  47. package/dist/resources/schemas/GlobalFunctionUpdateResultDto.json +5 -1
  48. package/dist/resources/schemas/MicroserviceDto.json +16 -0
  49. package/dist/resources/schemas/PublishAssistantCommand.json +15 -0
  50. package/dist/resources/schemas/RunAssistantScenariosCommand.json +39 -0
  51. package/dist/resources/schemas/SimulateAssistantCommand.json +106 -0
  52. package/dist/resources/schemas/UpdateAssistantScenarioCommand.json +79 -0
  53. package/dist/resources/schemas/UpdateAssistantSettingsCommand.json +52 -0
  54. package/dist/resources/schemas/UpdateAssistantSkillCommand.json +81 -0
  55. package/dist/resources/schemas/UpdateMicroserviceCommand.json +16 -0
  56. package/dist/resources/store-art/editor.css +389 -0
  57. package/dist/resources/store-art/editor.html +123 -0
  58. package/dist/resources/store-art/editor.js +990 -0
  59. package/dist/server.js +2 -0
  60. package/dist/tools/applications.js +4 -4
  61. package/dist/tools/assistant.js +382 -0
  62. package/dist/tools/deployments.js +9 -3
  63. package/dist/tools/microservices.js +1 -1
  64. package/dist/tools/mobile.js +2 -2
  65. package/dist/tools/mobileStore.js +56 -19
  66. package/dist/tools/pages.js +21 -5
  67. package/dist/tools/projects.js +2 -2
  68. package/dist/tools/templates.js +1 -1
  69. package/dist/tools/themes.js +2 -2
  70. package/package.json +2 -2
@@ -0,0 +1,81 @@
1
+ {
2
+ "schema": {
3
+ "required": [
4
+ "capabilityIds",
5
+ "name",
6
+ "slug",
7
+ "trigger"
8
+ ],
9
+ "type": "object",
10
+ "properties": {
11
+ "id": {
12
+ "type": "string",
13
+ "format": "uuid"
14
+ },
15
+ "name": {
16
+ "maxLength": 256,
17
+ "minLength": 1,
18
+ "type": "string"
19
+ },
20
+ "slug": {
21
+ "maxLength": 128,
22
+ "minLength": 1,
23
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
24
+ "type": "string"
25
+ },
26
+ "trigger": {
27
+ "maxLength": 1024,
28
+ "minLength": 1,
29
+ "type": "string"
30
+ },
31
+ "instructions": {
32
+ "type": "string",
33
+ "nullable": true
34
+ },
35
+ "outputFormat": {
36
+ "$ref": "#/components/schemas/NgApps.Domain.Contexts.Assistant.Skills.AssistantSkillOutputFormat"
37
+ },
38
+ "autonomy": {
39
+ "$ref": "#/components/schemas/NgApps.Domain.Contexts.Assistant.Skills.AssistantSkillAutonomy"
40
+ },
41
+ "languages": {
42
+ "type": "array",
43
+ "items": {
44
+ "type": "string"
45
+ },
46
+ "nullable": true
47
+ },
48
+ "capabilityIds": {
49
+ "minItems": 1,
50
+ "type": "array",
51
+ "items": {
52
+ "type": "string",
53
+ "format": "uuid"
54
+ }
55
+ }
56
+ },
57
+ "additionalProperties": false
58
+ },
59
+ "components": {
60
+ "schemas": {
61
+ "NgApps.Domain.Contexts.Assistant.Skills.AssistantSkillOutputFormat": {
62
+ "enum": [
63
+ "suggestion-card",
64
+ "list",
65
+ "findings",
66
+ "text"
67
+ ],
68
+ "type": "string",
69
+ "format": ""
70
+ },
71
+ "NgApps.Domain.Contexts.Assistant.Skills.AssistantSkillAutonomy": {
72
+ "enum": [
73
+ "suggest",
74
+ "execute"
75
+ ],
76
+ "type": "string",
77
+ "format": ""
78
+ }
79
+ }
80
+ }
81
+ }
@@ -23,6 +23,22 @@
23
23
  "type": "string",
24
24
  "nullable": true
25
25
  },
26
+ "assistantDescription": {
27
+ "type": "object",
28
+ "additionalProperties": {
29
+ "type": "string",
30
+ "nullable": true
31
+ },
32
+ "nullable": true
33
+ },
34
+ "assistantCaution": {
35
+ "type": "object",
36
+ "additionalProperties": {
37
+ "type": "string",
38
+ "nullable": true
39
+ },
40
+ "nullable": true
41
+ },
26
42
  "slug": {
27
43
  "minLength": 1,
28
44
  "type": "string"
@@ -0,0 +1,389 @@
1
+ :root {
2
+ --bg: #f3f3ef;
3
+ --panel: #ffffff;
4
+ --sunken: #ecebe6;
5
+ --line: #e1e0d9;
6
+ --text: #1b1b1a;
7
+ --muted: #6c6b66;
8
+ --accent: #2f6fec;
9
+ --accent-soft: rgba(47, 111, 236, 0.12);
10
+ --ok: #1a7f37;
11
+ --warn: #a35f00;
12
+ --err: #cf222e;
13
+ --shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 10px 30px rgba(0, 0, 0, 0.06);
14
+ --ratio: 0.46;
15
+ color-scheme: light;
16
+ }
17
+
18
+ @media (prefers-color-scheme: dark) {
19
+ :root {
20
+ --bg: #121212;
21
+ --panel: #1c1c1c;
22
+ --sunken: #242424;
23
+ --line: #2e2e2e;
24
+ --text: #ececea;
25
+ --muted: #9b9a95;
26
+ --accent: #5b93ff;
27
+ --accent-soft: rgba(91, 147, 255, 0.16);
28
+ --ok: #46c060;
29
+ --warn: #e0a440;
30
+ --err: #ff6b6b;
31
+ --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 10px 30px rgba(0, 0, 0, 0.35);
32
+ color-scheme: dark;
33
+ }
34
+ }
35
+
36
+ * { box-sizing: border-box; }
37
+ [hidden] { display: none !important; }
38
+
39
+ body {
40
+ margin: 0;
41
+ background: var(--bg);
42
+ color: var(--text);
43
+ font: 14px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
44
+ -webkit-font-smoothing: antialiased;
45
+ }
46
+
47
+ button, input, textarea { font: inherit; color: inherit; }
48
+ kbd {
49
+ display: inline-block;
50
+ min-width: 1.6em;
51
+ padding: 0 4px;
52
+ margin: 0 1px;
53
+ border: 1px solid var(--line);
54
+ border-bottom-width: 2px;
55
+ border-radius: 5px;
56
+ background: var(--panel);
57
+ font: 11px/1.5 ui-monospace, Menlo, monospace;
58
+ text-align: center;
59
+ }
60
+
61
+ /* Üst çubuk */
62
+ .bar {
63
+ position: sticky;
64
+ top: 0;
65
+ z-index: 10;
66
+ display: flex;
67
+ flex-wrap: wrap;
68
+ gap: 12px;
69
+ align-items: center;
70
+ justify-content: space-between;
71
+ padding: 12px 20px;
72
+ background: color-mix(in srgb, var(--bg) 86%, transparent);
73
+ backdrop-filter: blur(12px);
74
+ border-bottom: 1px solid var(--line);
75
+ }
76
+ .brand { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
77
+ .brand h1 { margin: 0; font-size: 17px; letter-spacing: -0.01em; }
78
+ .meta { color: var(--muted); font-size: 12px; font-family: ui-monospace, Menlo, monospace; }
79
+ .actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
80
+
81
+ button { cursor: pointer; }
82
+ button:disabled { cursor: default; opacity: 0.45; }
83
+ .primary, .ghost, .icon-button {
84
+ border-radius: 10px;
85
+ padding: 8px 14px;
86
+ font-weight: 600;
87
+ font-size: 13px;
88
+ transition: background 0.15s, border-color 0.15s, transform 0.1s;
89
+ }
90
+ .primary { background: var(--accent); color: #ffffff; border: 1px solid var(--accent); }
91
+ .primary:not(:disabled):hover { filter: brightness(1.07); }
92
+ .ghost, .icon-button { background: var(--panel); border: 1px solid var(--line); }
93
+ .ghost:not(:disabled):hover, .icon-button:not(:disabled):hover { border-color: var(--accent); }
94
+ .icon-button { padding: 6px 10px; font-size: 15px; line-height: 1; }
95
+ button:not(:disabled):active { transform: translateY(1px); }
96
+ .link { background: none; border: 0; padding: 0; color: var(--accent); font-size: 12px; }
97
+
98
+ /* Üç sütun */
99
+ .layout {
100
+ display: grid;
101
+ grid-template-columns: minmax(230px, 300px) minmax(0, 1fr) 330px;
102
+ gap: 20px;
103
+ padding: 20px;
104
+ align-items: start;
105
+ }
106
+ .strip, .stage, .panel { position: sticky; top: 74px; min-width: 0; }
107
+ .hint { margin: 10px 2px 0; color: var(--muted); font-size: 12px; text-align: center; }
108
+
109
+ /* Kartlar */
110
+ .cards {
111
+ display: grid;
112
+ grid-template-columns: repeat(2, minmax(0, 1fr));
113
+ gap: 12px;
114
+ max-height: calc(100vh - 130px);
115
+ overflow: auto;
116
+ padding: 4px;
117
+ }
118
+ .card {
119
+ position: relative;
120
+ display: flex;
121
+ flex-direction: column;
122
+ gap: 6px;
123
+ padding: 6px;
124
+ background: var(--panel);
125
+ border: 2px solid transparent;
126
+ border-radius: 14px;
127
+ box-shadow: var(--shadow);
128
+ cursor: pointer;
129
+ transition: border-color 0.15s, transform 0.15s, opacity 0.15s;
130
+ }
131
+ .card:hover { transform: translateY(-1px); }
132
+ .card.current { border-color: var(--accent); }
133
+ .card.dragging { opacity: 0.4; }
134
+ .card.drop-before::before, .card.drop-after::after {
135
+ content: "";
136
+ position: absolute;
137
+ top: 6px;
138
+ bottom: 6px;
139
+ width: 4px;
140
+ border-radius: 2px;
141
+ background: var(--accent);
142
+ }
143
+ .card.drop-before::before { left: -9px; }
144
+ .card.drop-after::after { right: -9px; }
145
+ .thumb {
146
+ position: relative;
147
+ aspect-ratio: var(--ratio);
148
+ border-radius: 9px;
149
+ overflow: hidden;
150
+ background: var(--sunken);
151
+ }
152
+ .thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
153
+ .thumb iframe {
154
+ position: absolute;
155
+ top: 0;
156
+ left: 0;
157
+ border: 0;
158
+ transform-origin: 0 0;
159
+ pointer-events: none;
160
+ }
161
+ .thumb .changed {
162
+ position: absolute;
163
+ top: 6px;
164
+ right: 6px;
165
+ padding: 1px 6px;
166
+ border-radius: 999px;
167
+ background: var(--warn);
168
+ color: #ffffff;
169
+ font-size: 10px;
170
+ font-weight: 700;
171
+ display: none;
172
+ }
173
+ .card.dirty .thumb .changed { display: block; }
174
+ .card-row { display: flex; align-items: center; gap: 6px; min-width: 0; }
175
+ .card-row input { margin: 0; accent-color: var(--accent); }
176
+ .card-name { font-size: 12px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
177
+ .badges { display: flex; flex-wrap: wrap; gap: 4px; min-height: 0; }
178
+ .badge {
179
+ display: inline-block;
180
+ padding: 1px 7px;
181
+ border-radius: 999px;
182
+ font-size: 10.5px;
183
+ font-weight: 700;
184
+ letter-spacing: 0.01em;
185
+ }
186
+ .badge.ok { background: color-mix(in srgb, var(--ok) 15%, transparent); color: var(--ok); }
187
+ .badge.warn { background: color-mix(in srgb, var(--warn) 16%, transparent); color: var(--warn); }
188
+ .badge.err { background: color-mix(in srgb, var(--err) 15%, transparent); color: var(--err); }
189
+ .badge.muted { background: var(--sunken); color: var(--muted); }
190
+
191
+ /* Önizleme */
192
+ .stage { display: flex; flex-direction: column; align-items: center; }
193
+ .preview-box {
194
+ position: relative;
195
+ overflow: hidden;
196
+ border-radius: 18px;
197
+ box-shadow: var(--shadow);
198
+ background: var(--sunken);
199
+ }
200
+ .preview-box iframe { position: absolute; top: 0; left: 0; border: 0; transform-origin: 0 0; }
201
+ .preview-box.rolled { animation: roll 0.5s cubic-bezier(0.2, 0.9, 0.3, 1.3); }
202
+ @keyframes roll {
203
+ 0% { transform: rotate(0) scale(1); }
204
+ 35% { transform: rotate(-3deg) scale(0.96); }
205
+ 70% { transform: rotate(2deg) scale(1.02); }
206
+ 100% { transform: rotate(0) scale(1); }
207
+ }
208
+ .problem {
209
+ margin: 12px 0 0;
210
+ padding: 8px 12px;
211
+ border-radius: 10px;
212
+ background: color-mix(in srgb, var(--err) 12%, transparent);
213
+ color: var(--err);
214
+ font-size: 13px;
215
+ font-weight: 600;
216
+ max-width: 420px;
217
+ text-align: center;
218
+ }
219
+
220
+ /* Panel */
221
+ .panel {
222
+ display: flex;
223
+ flex-direction: column;
224
+ gap: 14px;
225
+ padding: 16px;
226
+ background: var(--panel);
227
+ border-radius: 16px;
228
+ box-shadow: var(--shadow);
229
+ max-height: calc(100vh - 94px);
230
+ overflow: auto;
231
+ }
232
+ .panel-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
233
+ .panel-head strong { font-size: 14px; }
234
+ .field { display: flex; flex-direction: column; gap: 6px; margin: 0; }
235
+ .field.split { flex-direction: row; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
236
+ .label { display: flex; justify-content: space-between; color: var(--muted); font-size: 12px; font-weight: 600; }
237
+ .count { font-style: normal; font-weight: 500; font-variant-numeric: tabular-nums; }
238
+ .count.near { color: var(--warn); }
239
+ .count.full { color: var(--err); }
240
+ .field input:not([type]), .field textarea {
241
+ width: 100%;
242
+ padding: 8px 10px;
243
+ border: 1px solid var(--line);
244
+ border-radius: 9px;
245
+ background: var(--bg);
246
+ resize: vertical;
247
+ line-height: 1.35;
248
+ }
249
+ .field input:not([type]):focus, .field textarea:focus { outline: 2px solid var(--accent-soft); border-color: var(--accent); }
250
+
251
+ .chips { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
252
+ .chip {
253
+ display: flex;
254
+ flex-direction: column;
255
+ gap: 4px;
256
+ padding: 4px;
257
+ background: transparent;
258
+ border: 2px solid transparent;
259
+ border-radius: 10px;
260
+ font-size: 11px;
261
+ font-weight: 600;
262
+ color: var(--muted);
263
+ }
264
+ .chip .swatch { position: relative; height: 30px; border-radius: 7px; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08); }
265
+ .chip .swatch i { position: absolute; right: 5px; bottom: 5px; width: 9px; height: 9px; border-radius: 50%; }
266
+ .chip[aria-pressed="true"] { border-color: var(--accent); color: var(--text); }
267
+
268
+ .layouts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
269
+ .layout-button {
270
+ display: flex;
271
+ flex-direction: column;
272
+ align-items: center;
273
+ gap: 2px;
274
+ padding: 6px 4px;
275
+ border: 2px solid var(--line);
276
+ border-radius: 10px;
277
+ background: var(--bg);
278
+ font-size: 11px;
279
+ font-weight: 600;
280
+ color: var(--muted);
281
+ }
282
+ .layout-button svg { width: 28px; height: 38px; }
283
+ .layout-button[aria-pressed="true"] { border-color: var(--accent); color: var(--text); background: var(--accent-soft); }
284
+
285
+ .segmented { display: inline-flex; padding: 3px; gap: 2px; border-radius: 10px; background: var(--sunken); }
286
+ .segmented button { border: 0; background: transparent; padding: 5px 12px; border-radius: 8px; font-size: 12px; font-weight: 600; color: var(--muted); }
287
+ .segmented button[aria-pressed="true"] { background: var(--panel); color: var(--text); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12); }
288
+
289
+ .colors { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
290
+ .color { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
291
+ .color input { width: 30px; height: 26px; padding: 0; border: 1px solid var(--line); border-radius: 7px; background: none; }
292
+
293
+ .raws { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 2px; }
294
+ .raw {
295
+ flex: 0 0 auto;
296
+ width: 46px;
297
+ aspect-ratio: var(--ratio);
298
+ padding: 0;
299
+ border: 2px solid var(--line);
300
+ border-radius: 8px;
301
+ overflow: hidden;
302
+ background: var(--sunken);
303
+ }
304
+ .raw img { width: 100%; height: 100%; object-fit: cover; display: block; }
305
+ .raw.none { display: grid; place-items: center; font-size: 10px; font-weight: 700; color: var(--muted); }
306
+ .raw[aria-pressed="true"] { border-color: var(--accent); }
307
+
308
+ .toggle { flex-direction: row; align-items: center; gap: 8px; font-size: 13px; }
309
+ .toggle input { accent-color: var(--accent); }
310
+
311
+ .panel-actions { display: grid; grid-template-columns: 1fr 1fr 1.2fr; gap: 8px; }
312
+ .keys { margin: 0; color: var(--muted); font-size: 11px; line-height: 1.9; }
313
+
314
+ /* Bildirim */
315
+ .toast {
316
+ position: fixed;
317
+ left: 50%;
318
+ bottom: 24px;
319
+ z-index: 20;
320
+ max-width: min(560px, calc(100vw - 32px));
321
+ padding: 10px 16px;
322
+ border-radius: 12px;
323
+ background: #1b1b1a;
324
+ color: #ffffff;
325
+ font-size: 13px;
326
+ font-weight: 600;
327
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
328
+ opacity: 0;
329
+ transform: translate(-50%, 12px);
330
+ pointer-events: none;
331
+ transition: opacity 0.2s, transform 0.2s;
332
+ }
333
+ .toast.show { opacity: 1; transform: translate(-50%, 0); }
334
+ .toast.err { background: var(--err); }
335
+ .toast.ok { background: var(--ok); }
336
+
337
+ /* Vitrin */
338
+ .showcase {
339
+ width: min(460px, calc(100vw - 32px));
340
+ padding: 18px;
341
+ border: 0;
342
+ border-radius: 20px;
343
+ background: var(--panel);
344
+ color: var(--text);
345
+ box-shadow: 0 30px 80px rgba(0, 0, 0, 0.35);
346
+ }
347
+ .showcase::backdrop { background: rgba(0, 0, 0, 0.45); backdrop-filter: blur(3px); }
348
+ .showcase-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
349
+ .phone {
350
+ margin: 0 auto;
351
+ width: 320px;
352
+ max-width: 100%;
353
+ padding: 10px;
354
+ border-radius: 40px;
355
+ background: #0d0d0f;
356
+ box-shadow: inset 0 0 0 2px #3a3a3e;
357
+ }
358
+ .phone-screen {
359
+ display: flex;
360
+ flex-direction: column;
361
+ gap: 12px;
362
+ padding: 18px 14px 22px;
363
+ border-radius: 31px;
364
+ background: #ffffff;
365
+ color: #1b1b1a;
366
+ }
367
+ .search { padding: 7px 12px; border-radius: 10px; background: #eeeeef; color: #8a8a8e; font-size: 13px; }
368
+ .result { display: flex; align-items: center; gap: 10px; }
369
+ .app-icon { width: 46px; height: 46px; flex: 0 0 auto; border-radius: 11px; }
370
+ .lines { flex: 1; display: flex; flex-direction: column; gap: 6px; }
371
+ .lines span { display: block; height: 9px; border-radius: 5px; background: #d9d9dc; }
372
+ .lines span + span { width: 62%; background: #ececee; }
373
+ .pill { width: 54px; height: 24px; border-radius: 12px; background: #eeeeef; }
374
+ .shots { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
375
+ .shots img { width: 100%; aspect-ratio: var(--ratio); object-fit: cover; border-radius: 9px; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.06); display: block; }
376
+ .showcase-note { margin: 14px 2px 0; color: var(--muted); font-size: 12.5px; text-align: center; }
377
+
378
+ @media (max-width: 1100px) {
379
+ /* Yatay kart şeridi sütunu kendi içerik genişliğine (1871 px) açıyordu; önizleme ekranın dışına düşüyordu. */
380
+ .layout { grid-template-columns: minmax(0, 1fr); padding: 16px; }
381
+ .strip, .stage, .panel { position: static; }
382
+ .cards { display: flex; max-height: none; overflow-x: auto; overflow-y: hidden; padding-bottom: 8px; }
383
+ .card { flex: 0 0 132px; }
384
+ .panel { max-height: none; }
385
+ }
386
+
387
+ @media (prefers-reduced-motion: reduce) {
388
+ *, *::before, *::after { animation: none !important; transition: none !important; }
389
+ }
@@ -0,0 +1,123 @@
1
+ <!doctype html>
2
+ <html lang="tr">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <title>Mağaza görselleri</title>
7
+ <link rel="stylesheet" href="editor.css">
8
+ </head>
9
+ <body>
10
+ <header class="bar">
11
+ <div class="brand">
12
+ <h1>Mağaza görselleri</h1>
13
+ <span id="meta" class="meta">Yükleniyor…</span>
14
+ </div>
15
+ <div class="actions">
16
+ <button type="button" id="undo" class="icon-button" title="Geri al (⌘Z)" aria-label="Geri al">↶</button>
17
+ <button type="button" id="redo" class="icon-button" title="Yinele (⇧⌘Z)" aria-label="Yinele">↷</button>
18
+ <button type="button" id="shuffle" class="ghost" title="Bütün kartlara rastgele stil ve yerleşim; ardışık iki kart aynı yerleşimi almaz">🎲 Seriyi karıştır</button>
19
+ <button type="button" id="showcase" class="ghost">Vitrinde gör</button>
20
+ <button type="button" id="renderAll" class="ghost" disabled>Değişenleri çiz</button>
21
+ <button type="button" id="upload" class="primary" disabled>Seçilenleri yükle (0)</button>
22
+ </div>
23
+ </header>
24
+
25
+ <main class="layout">
26
+ <section class="strip" aria-label="Kartlar">
27
+ <div id="cards" class="cards"></div>
28
+ <p class="hint">Sürükleyerek sırala · sıra yükleme sırasıdır · <kbd>⌥←</kbd><kbd>⌥→</kbd> kartı taşır</p>
29
+ </section>
30
+
31
+ <section class="stage" aria-label="Önizleme">
32
+ <div id="previewBox" class="preview-box">
33
+ <iframe id="preview" title="Kartın birebir önizlemesi" sandbox="allow-same-origin"></iframe>
34
+ </div>
35
+ <p id="problem" class="problem" hidden></p>
36
+ <p class="hint">Başlığa, alt başlığa ya da üst etikete tıklayıp karenin üstünde yaz.</p>
37
+ </section>
38
+
39
+ <form id="panel" class="panel" autocomplete="off" aria-label="Kart ayarları">
40
+ <div class="panel-head">
41
+ <strong id="cardTitle">Kart</strong>
42
+ <span id="dirtyBadge" class="badge warn" hidden>çizilmedi</span>
43
+ </div>
44
+
45
+ <label class="field">
46
+ <span class="label">Üst etiket <em class="count" data-count="eyebrow"></em></span>
47
+ <input name="eyebrow" spellcheck="false">
48
+ </label>
49
+ <label class="field">
50
+ <span class="label">Başlık <em class="count" data-count="title"></em></span>
51
+ <textarea name="title" rows="2" spellcheck="false"></textarea>
52
+ </label>
53
+ <label class="field">
54
+ <span class="label">Alt başlık <em class="count" data-count="subtitle"></em></span>
55
+ <textarea name="subtitle" rows="2" spellcheck="false"></textarea>
56
+ </label>
57
+
58
+ <div class="field">
59
+ <span class="label">Stil</span>
60
+ <div id="styles" class="chips" role="group" aria-label="Stil"></div>
61
+ </div>
62
+
63
+ <div class="field">
64
+ <span class="label">Yerleşim</span>
65
+ <div id="layouts" class="layouts" role="group" aria-label="Yerleşim"></div>
66
+ </div>
67
+
68
+ <div class="field split">
69
+ <span class="label">Başlık yeri</span>
70
+ <div id="caption" class="segmented" role="group" aria-label="Başlık yeri">
71
+ <button type="button" data-value="top">Üstte</button>
72
+ <button type="button" data-value="bottom">Altta</button>
73
+ </div>
74
+ </div>
75
+
76
+ <div class="field split">
77
+ <span class="label">Renkler</span>
78
+ <div class="colors">
79
+ <label class="color">Vurgu <input type="color" name="accent"></label>
80
+ <label class="color">Yazı <input type="color" name="text"></label>
81
+ <button type="button" id="resetColors" class="link">Stilinkine dön</button>
82
+ </div>
83
+ </div>
84
+
85
+ <div class="field">
86
+ <span class="label">Ekran</span>
87
+ <div id="raws" class="raws" role="group" aria-label="Ham kare"></div>
88
+ </div>
89
+
90
+ <label class="field toggle"><input type="checkbox" name="frame"> Cihaz çerçevesi</label>
91
+
92
+ <div class="panel-actions">
93
+ <button type="button" id="dice" class="ghost" title="Rastgele stil, yerleşim ve renk (R)">🎲 Zar</button>
94
+ <button type="button" id="duplicate" class="ghost" title="Kartı kopyala (⌘D)">Kopyala</button>
95
+ <button type="button" id="render" class="primary" title="Kartı mağaza ölçüsünde çiz (⌘↵)">Çiz</button>
96
+ </div>
97
+ <p class="keys"><kbd>←</kbd><kbd>→</kbd> kart · <kbd>Space</kbd> seç · <kbd>R</kbd> zar · <kbd>⌘Z</kbd> geri al · <kbd>⌘↵</kbd> çiz · <kbd>⌘D</kbd> kopyala</p>
98
+ </form>
99
+ </main>
100
+
101
+ <dialog id="showcaseDialog" class="showcase" aria-labelledby="showcaseTitle">
102
+ <div class="showcase-head">
103
+ <strong id="showcaseTitle">Mağazada nasıl görünür</strong>
104
+ <button type="button" id="closeShowcase" class="icon-button" aria-label="Kapat">✕</button>
105
+ </div>
106
+ <div class="phone">
107
+ <div class="phone-screen">
108
+ <div class="search">Ara</div>
109
+ <div class="result">
110
+ <div id="showcaseIcon" class="app-icon"></div>
111
+ <div class="lines"><span></span><span></span></div>
112
+ <div class="pill"></div>
113
+ </div>
114
+ <div id="showcaseShots" class="shots"></div>
115
+ </div>
116
+ </div>
117
+ <p id="showcaseNote" class="showcase-note"></p>
118
+ </dialog>
119
+
120
+ <div id="toast" class="toast" role="status" aria-live="polite"></div>
121
+ <script src="editor.js"></script>
122
+ </body>
123
+ </html>