@ozdao/martyrs 0.2.565 → 0.2.566

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 (99) hide show
  1. package/dist/martyrs/dist/main-B9o1iBAZ.js +943 -0
  2. package/dist/martyrs/dist/main-B9o1iBAZ.js.map +1 -0
  3. package/dist/martyrs/dist/web-BF3ijvEr.js +55 -0
  4. package/dist/martyrs/dist/web-BF3ijvEr.js.map +1 -0
  5. package/dist/martyrs/src/components/BottomSheet/BottomSheet.vue.js +96 -0
  6. package/dist/martyrs/src/components/BottomSheet/BottomSheet.vue.js.map +1 -0
  7. package/dist/martyrs/src/modules/core/views/components/layouts/App.vue.js +1 -1
  8. package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js +1 -0
  9. package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js.map +1 -1
  10. package/dist/martyrs/src/modules/core/views/components/sections/Walkthrough.vue.js +1 -1
  11. package/dist/martyrs/src/modules/events/components/elements/ButtonCheck.vue.js +1 -1
  12. package/dist/martyrs/src/modules/events/events.client.js +15 -12
  13. package/dist/martyrs/src/modules/events/events.client.js.map +1 -1
  14. package/dist/martyrs/src/modules/music/components/blocks/ActionButtons.vue.js +95 -0
  15. package/dist/martyrs/src/modules/music/components/blocks/ActionButtons.vue.js.map +1 -0
  16. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js +5 -2
  17. package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js.map +1 -1
  18. package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js +24 -24
  19. package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js.map +1 -1
  20. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js +31 -6
  21. package/dist/martyrs/src/modules/music/components/layouts/MusicBottomPlayer.vue.js.map +1 -1
  22. package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +120 -205
  23. package/dist/martyrs/src/modules/music/components/pages/Album.vue.js.map +1 -1
  24. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js +9 -13
  25. package/dist/martyrs/src/modules/music/components/pages/MusicHome.vue.js.map +1 -1
  26. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +166 -245
  27. package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js.map +1 -1
  28. package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +135 -220
  29. package/dist/martyrs/src/modules/music/components/pages/Track.vue.js.map +1 -1
  30. package/dist/martyrs/src/modules/music/components/player/FullscreenPlayer.vue.js +171 -0
  31. package/dist/martyrs/src/modules/music/components/player/FullscreenPlayer.vue.js.map +1 -0
  32. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js +31 -153
  33. package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js.map +1 -1
  34. package/dist/martyrs/src/modules/music/components/player/PlayerControls.vue.js +96 -0
  35. package/dist/martyrs/src/modules/music/components/player/PlayerControls.vue.js.map +1 -0
  36. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js +55 -27
  37. package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js.map +1 -1
  38. package/dist/martyrs/src/modules/music/components/player/tonar.png.js +5 -0
  39. package/dist/martyrs/src/modules/music/components/player/tonar.png.js.map +1 -0
  40. package/dist/martyrs/src/modules/music/store/albums.js +8 -2
  41. package/dist/martyrs/src/modules/music/store/albums.js.map +1 -1
  42. package/dist/martyrs/src/modules/music/store/player.js +83 -65
  43. package/dist/martyrs/src/modules/music/store/player.js.map +1 -1
  44. package/dist/martyrs/src/modules/music/store/tracks.js +4 -13
  45. package/dist/martyrs/src/modules/music/store/tracks.js.map +1 -1
  46. package/dist/martyrs/src/modules/notifications/notifications.client.js +2 -2
  47. package/dist/martyrs.css +1 -1
  48. package/dist/music.server.js +33 -6
  49. package/dist/node_modules/.pnpm/{@capacitor-mlkit_barcode-scanning@7.1.0_@capacitor_core@7.0.1 → @capacitor-mlkit_barcode-scanning@7.3.0_@capacitor_core@7.4.4}/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/definitions.js +1 -0
  50. package/dist/node_modules/.pnpm/@capacitor-mlkit_barcode-scanning@7.3.0_@capacitor_core@7.4.4/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/definitions.js.map +1 -0
  51. package/dist/node_modules/.pnpm/{@capacitor-mlkit_barcode-scanning@7.1.0_@capacitor_core@7.0.1 → @capacitor-mlkit_barcode-scanning@7.3.0_@capacitor_core@7.4.4}/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/index.js +1 -1
  52. package/dist/node_modules/.pnpm/{@capacitor-mlkit_barcode-scanning@7.1.0_@capacitor_core@7.0.1 → @capacitor-mlkit_barcode-scanning@7.3.0_@capacitor_core@7.4.4}/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/index.js.map +1 -1
  53. package/dist/node_modules/.pnpm/{@capacitor-mlkit_barcode-scanning@7.1.0_@capacitor_core@7.0.1 → @capacitor-mlkit_barcode-scanning@7.3.0_@capacitor_core@7.4.4}/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/web.js +16 -1
  54. package/dist/node_modules/.pnpm/@capacitor-mlkit_barcode-scanning@7.3.0_@capacitor_core@7.4.4/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/web.js.map +1 -0
  55. package/dist/node_modules/.pnpm/{@capacitor_core@7.0.1 → @capacitor_core@7.4.4}/node_modules/@capacitor/core/dist/index.js +2 -1
  56. package/dist/node_modules/.pnpm/@capacitor_core@7.4.4/node_modules/@capacitor/core/dist/index.js.map +1 -0
  57. package/dist/node_modules/.pnpm/{@capacitor_device@7.0.0_@capacitor_core@7.0.1 → @capacitor_device@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/device/dist/esm/index.js +1 -1
  58. package/dist/node_modules/.pnpm/{@capacitor_device@7.0.0_@capacitor_core@7.0.1 → @capacitor_device@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/device/dist/esm/index.js.map +1 -1
  59. package/dist/node_modules/.pnpm/{@capacitor_device@7.0.0_@capacitor_core@7.0.1 → @capacitor_device@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/device/dist/esm/web.js +1 -1
  60. package/dist/node_modules/.pnpm/{@capacitor_device@7.0.0_@capacitor_core@7.0.1 → @capacitor_device@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/device/dist/esm/web.js.map +1 -1
  61. package/dist/node_modules/.pnpm/{@capacitor_keyboard@7.0.0_@capacitor_core@7.0.1 → @capacitor_keyboard@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/keyboard/dist/esm/definitions.js.map +1 -1
  62. package/dist/node_modules/.pnpm/{@capacitor_keyboard@7.0.0_@capacitor_core@7.0.1 → @capacitor_keyboard@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/keyboard/dist/esm/index.js +1 -1
  63. package/dist/node_modules/.pnpm/{@capacitor_keyboard@7.0.0_@capacitor_core@7.0.1 → @capacitor_keyboard@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/keyboard/dist/esm/index.js.map +1 -1
  64. package/dist/node_modules/.pnpm/{@capacitor_push-notifications@7.0.0_@capacitor_core@7.0.1 → @capacitor_push-notifications@7.0.3_@capacitor_core@7.4.4}/node_modules/@capacitor/push-notifications/dist/esm/index.js +1 -1
  65. package/dist/node_modules/.pnpm/{@capacitor_push-notifications@7.0.0_@capacitor_core@7.0.1 → @capacitor_push-notifications@7.0.3_@capacitor_core@7.4.4}/node_modules/@capacitor/push-notifications/dist/esm/index.js.map +1 -1
  66. package/dist/node_modules/.pnpm/{capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.0.1 → capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.4.4}/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/index.js +1 -1
  67. package/dist/node_modules/.pnpm/{capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.0.1 → capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.4.4}/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/index.js.map +1 -1
  68. package/dist/node_modules/.pnpm/{capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.0.1 → capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.4.4}/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/web.js +1 -1
  69. package/dist/node_modules/.pnpm/{capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.0.1 → capacitor-plugin-app-tracking-transparency@2.0.5_@capacitor_core@7.4.4}/node_modules/capacitor-plugin-app-tracking-transparency/dist/esm/web.js.map +1 -1
  70. package/dist/style.css +214 -138
  71. package/package.json +1 -1
  72. package/src/components/BottomSheet/BottomSheet.vue +4 -4
  73. package/src/modules/LAYOUT.MD +767 -0
  74. package/src/modules/core/views/components/layouts/Client.vue +1 -1
  75. package/src/modules/events/events.client.js +3 -0
  76. package/src/modules/music/components/blocks/ActionButtons.vue +74 -0
  77. package/src/modules/music/components/cards/AlbumCard.vue +1 -1
  78. package/src/modules/music/components/cards/ArtistCardSmall.vue +8 -6
  79. package/src/modules/music/components/layouts/MusicBottomPlayer.vue +94 -4
  80. package/src/modules/music/components/pages/Album.vue +55 -67
  81. package/src/modules/music/components/pages/MusicHome.vue +4 -6
  82. package/src/modules/music/components/pages/Playlist.vue +61 -70
  83. package/src/modules/music/components/pages/Track.vue +54 -71
  84. package/src/modules/music/components/player/FullscreenPlayer.vue +248 -0
  85. package/src/modules/music/components/player/MusicPlayer.vue +21 -216
  86. package/src/modules/music/components/player/PlayerControls.vue +112 -0
  87. package/src/modules/music/components/player/Visualizer.vue +151 -0
  88. package/src/modules/music/components/player/VolumeControl.vue +75 -23
  89. package/src/modules/music/components/player/tonar.png +0 -0
  90. package/src/modules/music/routes/albums.routes.js +13 -12
  91. package/src/modules/music/routes/tracks.routes.js +39 -0
  92. package/src/modules/music/store/albums.js +10 -2
  93. package/src/modules/music/store/player.js +101 -89
  94. package/src/modules/music/store/tracks.js +5 -21
  95. package/src/styles/config.scss +6 -6
  96. package/dist/node_modules/.pnpm/@capacitor-mlkit_barcode-scanning@7.1.0_@capacitor_core@7.0.1/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/definitions.js.map +0 -1
  97. package/dist/node_modules/.pnpm/@capacitor-mlkit_barcode-scanning@7.1.0_@capacitor_core@7.0.1/node_modules/@capacitor-mlkit/barcode-scanning/dist/esm/web.js.map +0 -1
  98. package/dist/node_modules/.pnpm/@capacitor_core@7.0.1/node_modules/@capacitor/core/dist/index.js.map +0 -1
  99. /package/dist/node_modules/.pnpm/{@capacitor_keyboard@7.0.0_@capacitor_core@7.0.1 → @capacitor_keyboard@7.0.1_@capacitor_core@7.4.4}/node_modules/@capacitor/keyboard/dist/esm/definitions.js +0 -0
@@ -0,0 +1,767 @@
1
+ # МЕХАНИЗМ РАБОТЫ ЛЕЙАУТОВ OZDAO.DEV
2
+
3
+ **На основе реальных computed styles с localhost:8041**
4
+
5
+ ---
6
+
7
+ ## ИЕРАРХИЯ И COMPUTED VALUES
8
+
9
+ ### Структура от корня к элементам
10
+
11
+ ```
12
+ #app-wrapper (Root Container)
13
+
14
+ #screen (Screen Section)
15
+
16
+ Parent wrapper (grid container для scrollview)
17
+
18
+ #scrollview (скроллируемая область)
19
+
20
+ Page container
21
+
22
+ Sections/Blocks
23
+
24
+ Components
25
+ ```
26
+
27
+ ---
28
+
29
+ ## LEVEL 1: #app-wrapper
30
+
31
+ **Классы:**
32
+ ```
33
+ flex flex-column h-100 w-100 pos-relative o-hidden
34
+ ```
35
+
36
+ **Computed styles:**
37
+ ```css
38
+ display: flex
39
+ flex-direction: column
40
+ position: relative
41
+ width: 1200px /* viewport width */
42
+ height: 692px /* viewport height */
43
+ overflow: hidden
44
+ overflow-x: hidden
45
+ overflow-y: hidden
46
+ z-index: auto
47
+ box-sizing: border-box
48
+ ```
49
+
50
+ ### Как это работает:
51
+
52
+ **width: 1200px** - не 100% в процентах, а вычисленное значение viewport width в пикселях. Класс `.w-100` в CSS определен как `width: 100%`, но браузер вычисляет это как фактическую ширину viewport.
53
+
54
+ **height: 692px** - аналогично, вычисленная высота viewport.
55
+
56
+ **overflow: hidden** - это свойство применяется к контейнеру, чтобы предотвратить появление скроллбара на корневом элементе. Скролл будет только внутри `#scrollview`.
57
+
58
+ **flex-direction: column** - дочерние элементы укладываются вертикально (header → screen → footer).
59
+
60
+ ---
61
+
62
+ ## LEVEL 2: #screen
63
+
64
+ **Классы:**
65
+ ```
66
+ flex flex-nowrap h-100 pos-relative o-hidden transition-ease-in-out
67
+ ```
68
+
69
+ **Computed styles:**
70
+ ```css
71
+ display: flex
72
+ flex-direction: row /* горизонтальный flex */
73
+ flex-wrap: nowrap
74
+ position: relative
75
+ width: 1200px
76
+ height: 632.148px /* меньше родителя! */
77
+ overflow: hidden
78
+ overflow-x: hidden
79
+ overflow-y: hidden
80
+ transition: 0.33s cubic-bezier(0.42, 0, 0.58, 1)
81
+ z-index: auto
82
+ ```
83
+
84
+ ### Как это работает:
85
+
86
+ **height: 632.148px** - меньше чем родитель (692px). Разница ~60px ушла на header/navigationbar.
87
+
88
+ Вычисление: родитель flex-column → дочерние элементы делят высоту → если header занимает ~60px, screen получает остаток.
89
+
90
+ **flex-direction: row** - sidebar и content располагаются горизонтально.
91
+
92
+ **overflow: hidden** - скрывает всё что выходит за границы. Скролла здесь нет.
93
+
94
+ ---
95
+
96
+ ## LEVEL 3: #scrollview и его parent
97
+
98
+ **Parent классы:**
99
+ ```
100
+ rows-1-min0_max1 z-index-1 pos-relative w-100 h-100
101
+ ```
102
+
103
+ **Parent computed:**
104
+ ```css
105
+ display: grid
106
+ grid-template-rows: 632.148px /* одна строка фиксированной высоты */
107
+ position: relative
108
+ width: 1152px
109
+ height: 632.148px
110
+ z-index: 10
111
+ ```
112
+
113
+ **#scrollview классы:**
114
+ ```
115
+ o-y-scroll o-x-hidden h-100
116
+ ```
117
+
118
+ **#scrollview computed:**
119
+ ```css
120
+ display: block
121
+ position: static
122
+ width: 1152px
123
+ height: 632.148px
124
+ overflow: hidden scroll /* x: hidden, y: scroll */
125
+ overflow-x: hidden
126
+ overflow-y: scroll
127
+ box-sizing: border-box
128
+ z-index: auto
129
+ ```
130
+
131
+ ### Как это работает:
132
+
133
+ **Parent использует grid** с `grid-template-rows: 632.148px`. Класс `rows-1-min0_max1` создаёт одну строку grid с `minmax(0, 1fr)`.
134
+
135
+ Почему так: grid с одной строкой позволяет дочернему элементу (`#scrollview`) получить точную высоту родителя, при этом контент внутри `#scrollview` может быть любой высоты и скроллиться.
136
+
137
+ **#scrollview имеет overflow-y: scroll** - это единственное место в приложении где работает вертикальный скролл. Весь контент страниц находится внутри этого элемента.
138
+
139
+ **width: 1152px** - меньше чем `#screen` (1200px). Разница ~48px ушла на sidebar.
140
+
141
+ ---
142
+
143
+ ## LEVEL 4: Page Container
144
+
145
+ **Классы:**
146
+ ```
147
+ h-min-100 pos-relative w-100
148
+ ```
149
+
150
+ **Computed:**
151
+ ```css
152
+ display: block
153
+ position: relative
154
+ padding: 0px
155
+ width: 1152px /* = родитель (#scrollview) */
156
+ height: 2013.8px /* больше viewport - auto height */
157
+ box-sizing: border-box
158
+ ```
159
+
160
+ ### Как это работает:
161
+
162
+ **height: 2013.8px** - высота контента, не ограничена. Браузер вычисляет автоматически на основе дочерних элементов.
163
+
164
+ **width: 1152px** - наследуется от родителя (#scrollview). Класс `.w-100` даёт `width: 100%`, что вычисляется как 1152px.
165
+
166
+ **position: relative** - создаёт positioning context для дочерних элементов с `position: absolute`.
167
+
168
+ ---
169
+
170
+ ## FLEX CONTAINERS
171
+
172
+ ### Пример: кнопки в header
173
+
174
+ **Классы:**
175
+ ```
176
+ flex flex-center flex-nowrap gap-thin
177
+ ```
178
+
179
+ **Computed:**
180
+ ```css
181
+ display: flex
182
+ flex-direction: row
183
+ gap: 8px /* gap-thin = 0.5rem = 8px */
184
+ justify-content: center
185
+ align-items: center
186
+ flex-wrap: nowrap
187
+ width: 1048.97px
188
+ ```
189
+
190
+ ### Как это работает:
191
+
192
+ **gap: 8px** - браузер вычисляет из `0.5rem`. Base font-size = 16px → 0.5 * 16 = 8px.
193
+
194
+ **justify-content: center** - дочерние элементы центрируются по главной оси (горизонтально).
195
+
196
+ **align-items: center** - дочерние элементы центрируются по поперечной оси (вертикально).
197
+
198
+ **width: 1048.97px** - вычисленная ширина на основе родителя и других стилей. Не круглое число из-за вычислений браузера с sub-pixel precision.
199
+
200
+ ### Button внутри flex
201
+
202
+ **Классы:**
203
+ ```
204
+ hover-bg-light transition-quint-out w-100 flex radius-small flex-nowrap flex-v-center pd-thin
205
+ ```
206
+
207
+ **Computed:**
208
+ ```css
209
+ display: flex
210
+ padding: 8px /* pd-thin = 0.5rem = 8px */
211
+ border-radius: 12px /* radius-small */
212
+ background-color: rgba(0, 0, 0, 0)
213
+ transition: 0.33s cubic-bezier(0.22, 1, 0.36, 1)
214
+ ```
215
+
216
+ ### Как это работает:
217
+
218
+ Кнопка сама является flex контейнером для своего контента (иконка + текст).
219
+
220
+ **padding: 8px** - одинаковый со всех сторон. Вычислено из `pd-thin`.
221
+
222
+ **border-radius: 12px** - вычислено из `radius-small`. В CSS может быть определено в rem, браузер конвертирует в px.
223
+
224
+ ---
225
+
226
+ ## GRID LAYOUTS
227
+
228
+ ### Пример: .cols-2 на странице альбома
229
+
230
+ **Классы:**
231
+ ```
232
+ cols-2 mobile:cols-1 gap-big
233
+ ```
234
+
235
+ **Computed (desktop):**
236
+ ```css
237
+ display: grid
238
+ grid-template-columns: 538px 538px
239
+ gap: 52px /* gap-big = 3.25rem = 52px */
240
+ position: static
241
+ width: 1128px /* (538 * 2) + 52 = 1128 */
242
+ ```
243
+
244
+ ### Как это работает:
245
+
246
+ **grid-template-columns: 538px 538px** - две колонки равной ширины.
247
+
248
+ Вычисление: родитель имеет ширину (возможно с padding), браузер вычисляет: `(parent_width - gap) / 2`.
249
+
250
+ Пример: если parent = 1128px, gap = 52px → `(1128 - 52) / 2 = 538px`.
251
+
252
+ **gap: 52px** - промежуток между колонками. Вычислено: 3.25rem * 16px = 52px.
253
+
254
+ **width: 1128px** - вычисленная ширина grid контейнера из родителя (возможно с учётом padding родителя).
255
+
256
+ ### Left column (sticky)
257
+
258
+ **Классы:**
259
+ ```
260
+ pos-sticky pos-t-0 mobile:pos-relative album-cover-section
261
+ ```
262
+
263
+ **Computed:**
264
+ ```css
265
+ display: block
266
+ position: sticky
267
+ top: 0px
268
+ width: 538px /* = grid column width */
269
+ max-width: none
270
+ grid-column: auto
271
+ ```
272
+
273
+ ### Как это работает:
274
+
275
+ **position: sticky** - элемент ведёт себя как `relative` пока не достигнет порога скролла, затем как `fixed` относительно scrolling container.
276
+
277
+ **top: 0px** - порог: когда элемент достигает 0px от верха scrolling container (в данном случае `#scrollview`), он "прилипает".
278
+
279
+ Sticky работает только если:
280
+ 1. Есть scrolling parent (у нас `#scrollview` с `overflow-y: scroll`)
281
+ 2. Есть достаточно контента для скролла
282
+ 3. Position не `static`
283
+
284
+ **width: 538px** - наследуется от grid column. Grid child автоматически получает ширину своей колонки.
285
+
286
+ ### Right column
287
+
288
+ **Классы:**
289
+ ```
290
+ album-details-section
291
+ ```
292
+
293
+ **Computed:**
294
+ ```css
295
+ display: block
296
+ position: static
297
+ width: 538px /* = grid column width */
298
+ grid-column: auto
299
+ ```
300
+
301
+ Вторая колонка. При скролле контента правой колонки, левая (sticky) остаётся видимой в viewport.
302
+
303
+ ---
304
+
305
+ ## UTILITY КЛАССЫ И ИХ COMPUTED VALUES
306
+
307
+ ### Размеры
308
+
309
+ | Класс | CSS определение | Computed (16px base) | Пример элемента |
310
+ |-------|----------------|---------------------|------------------|
311
+ | `.gap-thin` | `gap: 0.5rem` | `gap: 8px` | flex containers |
312
+ | `.gap-small` | `gap: 0.75rem` | `gap: 12px` | - |
313
+ | `.gap-medium` | `gap: 1.5rem` | `gap: 24px` | - |
314
+ | `.gap-big` | `gap: 3.25rem` | `gap: 52px` | .cols-2 |
315
+ | `.pd-thin` | `padding: 0.5rem` | `padding: 8px` | buttons |
316
+ | `.pd-small` | `padding: 0.75rem` | `padding: 12px` | cards |
317
+ | `.pd-medium` | `padding: 1.5rem` | `padding: 24px` | sections |
318
+ | `.w-100` | `width: 100%` | `width: 1200px` | #app-wrapper |
319
+ | `.h-100` | `height: 100%` | `height: 692px` | #app-wrapper |
320
+
321
+ ### Как работает конверсия rem → px:
322
+
323
+ 1. Браузер имеет base font-size (обычно 16px)
324
+ 2. CSS: `gap: 3.25rem`
325
+ 3. Браузер вычисляет: `3.25 * 16 = 52px`
326
+ 4. Computed value: `52px`
327
+
328
+ На разных viewport base font-size может меняться (responsive typography), поэтому computed values будут разными:
329
+ - Desktop 16px base: `gap: 52px`
330
+ - Tablet 24px base: `gap: 78px`
331
+
332
+ ### Процентные значения
333
+
334
+ **Класс `.w-100`:**
335
+ - CSS: `width: 100%`
336
+ - Родитель (#app-wrapper): viewport width
337
+ - Вычисление: `100% от viewport width`
338
+ - Computed: `width: 1200px` (если viewport = 1200px)
339
+
340
+ Процент всегда вычисляется относительно родителя.
341
+
342
+ ---
343
+
344
+ ## POSITION И STACKING CONTEXT
345
+
346
+ ### Stacking Context
347
+
348
+ **Что создаёт stacking context:**
349
+ - `position: relative/absolute/fixed/sticky` + `z-index: <не auto>`
350
+ - `opacity: < 1`
351
+ - `transform: <не none>`
352
+ - И другие свойства
353
+
354
+ **Пример:**
355
+
356
+ ```html
357
+ <div style="position: relative; z-index: 1">
358
+ <!-- Stacking context A -->
359
+ <div style="position: absolute; z-index: 100">Child A</div>
360
+ </div>
361
+
362
+ <div style="position: relative; z-index: 2">
363
+ <!-- Stacking context B -->
364
+ <div style="position: absolute; z-index: 1">Child B</div>
365
+ </div>
366
+ ```
367
+
368
+ **Результат:** Child B будет поверх Child A, несмотря на то что у Child A z-index больше (100 vs 1).
369
+
370
+ **Почему:** Child A находится внутри stacking context A (z-index: 1), Child B внутри context B (z-index: 2). Context B выше context A, поэтому всё содержимое B будет выше A.
371
+
372
+ ### Position: sticky механизм
373
+
374
+ **Computed на левой колонке альбома:**
375
+ ```css
376
+ position: sticky
377
+ top: 0px
378
+ ```
379
+
380
+ **Как работает:**
381
+
382
+ 1. Элемент в normal flow (как `position: relative`)
383
+ 2. Скролл начинается
384
+ 3. Когда элемент достигает `top: 0px` от края scrolling container
385
+ 4. Элемент "прилипает" и ведёт себя как `position: fixed` относительно scrolling container
386
+ 5. Когда скролл доходит до конца parent element, sticky "отлипает" и уходит вместе с родителем
387
+
388
+ **Scrolling container** для sticky в проекте: `#scrollview` с `overflow-y: scroll`.
389
+
390
+ ---
391
+
392
+ ## OVERFLOW И SCROLLING
393
+
394
+ ### Цепочка overflow
395
+
396
+ ```
397
+ #app-wrapper: overflow: hidden
398
+
399
+ #screen: overflow: hidden
400
+
401
+ parent wrapper: display: grid (нет overflow)
402
+
403
+ #scrollview: overflow-y: scroll ← СКРОЛЛ ЗДЕСЬ
404
+
405
+ page content: height > viewport
406
+ ```
407
+
408
+ ### Как это работает:
409
+
410
+ **Overflow: hidden на #app-wrapper и #screen** - предотвращает появление скроллбара на этих уровнях. Даже если контент внутри больше, он будет обрезан, но скроллбар не появится.
411
+
412
+ **Overflow-y: scroll на #scrollview** - создаёт scrolling context. Контент внутри может быть любой высоты, появится вертикальный скроллбар.
413
+
414
+ **Grid parent** - не имеет overflow, но имеет фиксированную высоту через `grid-template-rows: 632.148px`. Это ограничивает высоту `#scrollview`, а внутри scrollview контент скроллится.
415
+
416
+ ---
417
+
418
+ ## АДАПТИВНОСТЬ (mobile: prefix)
419
+
420
+ ### Пример: .cols-2.mobile:cols-1
421
+
422
+ **Desktop computed:**
423
+ ```css
424
+ grid-template-columns: 538px 538px
425
+ ```
426
+
427
+ **Mobile computed:**
428
+ ```css
429
+ grid-template-columns: 1fr
430
+ ```
431
+
432
+ ### Как это работает:
433
+
434
+ В CSS определены media queries:
435
+
436
+ ```css
437
+ @media (max-width: 640px) {
438
+ .mobile\:cols-1 {
439
+ grid-template-columns: 1fr;
440
+ }
441
+ }
442
+ ```
443
+
444
+ На узком viewport (≤640px) применяется `.mobile:cols-1`, который перезаписывает `grid-template-columns`.
445
+
446
+ **Computed на mobile:** браузер видит одну колонку `1fr`, которая занимает всю доступную ширину.
447
+
448
+ ### Пример: .pos-sticky.mobile:pos-relative
449
+
450
+ **Desktop computed:**
451
+ ```css
452
+ position: sticky
453
+ top: 0px
454
+ ```
455
+
456
+ **Mobile computed:**
457
+ ```css
458
+ position: relative
459
+ top: 0px /* игнорируется для relative */
460
+ ```
461
+
462
+ **Почему так:** На mobile нет смысла в sticky sidebar, т.к. layout превращается в одну колонку (стэк). Sticky превращается в обычный relative элемент.
463
+
464
+ ---
465
+
466
+ ## FLEX VS GRID: КАК БРАУЗЕР ВЫБИРАЕТ РАЗМЕРЫ
467
+
468
+ ### Flex sizing
469
+
470
+ **Flex container:**
471
+ ```css
472
+ display: flex
473
+ gap: 8px
474
+ ```
475
+
476
+ **Flex child (без классов flex-*):**
477
+ ```css
478
+ flex: 0 1 auto /* flex-grow: 0, flex-shrink: 1, flex-basis: auto */
479
+ ```
480
+
481
+ **Вычисление:**
482
+ 1. `flex-basis: auto` → берётся content width
483
+ 2. `flex-grow: 0` → элемент не растёт
484
+ 3. `flex-shrink: 1` → элемент сжимается если нужно
485
+
486
+ **Flex child с .flex-child-1:**
487
+ ```css
488
+ flex: 1 /* flex-grow: 1, flex-shrink: 1, flex-basis: 0% */
489
+ ```
490
+
491
+ **Вычисление:**
492
+ 1. `flex-basis: 0%` → элемент начинает с нулевой ширины
493
+ 2. `flex-grow: 1` → элемент растёт и занимает доступное пространство
494
+ 3. Если несколько детей с `flex: 1`, они делят пространство поровну
495
+
496
+ ### Grid sizing
497
+
498
+ **Grid container:**
499
+ ```css
500
+ display: grid
501
+ grid-template-columns: 538px 538px
502
+ gap: 52px
503
+ ```
504
+
505
+ **Вычисление ширины grid:**
506
+ ```
507
+ width = column1 + column2 + gap
508
+ width = 538 + 538 + 52 = 1128px
509
+ ```
510
+
511
+ **Grid child:**
512
+ - Автоматически получает ширину своей колонки (538px)
513
+ - Не нужно указывать width явно
514
+
515
+ **Если grid-template-columns: 1fr 1fr:**
516
+ ```
517
+ available_width = parent_width - gap
518
+ column_width = available_width / 2
519
+ ```
520
+
521
+ Пример: parent = 1128px, gap = 52px
522
+ ```
523
+ available = 1128 - 52 = 1076px
524
+ column = 1076 / 2 = 538px
525
+ ```
526
+
527
+ **Вычисление в обратную сторону:**
528
+
529
+ Браузер смотрит на parent width, вычитает gap, делит на количество `1fr`, получает ширину каждой колонки, затем конвертирует `1fr` в конкретные px значения.
530
+
531
+ Поэтому в computed styles всегда px, а не `1fr`.
532
+
533
+ ---
534
+
535
+ ## КАК ВЫЧИСЛЯЮТСЯ РАЗМЕРЫ (CASCADE)
536
+
537
+ ### Пример: кнопка
538
+
539
+ **HTML:**
540
+ ```html
541
+ <button class="pd-thin radius-small flex gap-thin">
542
+ <Icon />
543
+ <span>Text</span>
544
+ </button>
545
+ ```
546
+
547
+ **CSS (упрощённо):**
548
+ ```css
549
+ .pd-thin { padding: 0.5rem; }
550
+ .radius-small { border-radius: 0.75rem; }
551
+ .flex { display: flex; }
552
+ .gap-thin { gap: 0.5rem; }
553
+ ```
554
+
555
+ **Computed:**
556
+ ```css
557
+ display: flex
558
+ padding: 8px
559
+ border-radius: 12px
560
+ gap: 8px
561
+ ```
562
+
563
+ **Процесс:**
564
+ 1. Браузер читает классы: `pd-thin`, `radius-small`, `flex`, `gap-thin`
565
+ 2. Находит соответствующие CSS правила
566
+ 3. Применяет их (в порядке специфичности/каскада)
567
+ 4. Вычисляет rem → px (base = 16px)
568
+ - `0.5rem` → `8px`
569
+ - `0.75rem` → `12px`
570
+ 5. Сохраняет в computed styles
571
+
572
+ **Если есть конфликт:**
573
+ ```css
574
+ .pd-thin { padding: 0.5rem; }
575
+ .custom-button { padding: 1rem; }
576
+ ```
577
+
578
+ ```html
579
+ <button class="pd-thin custom-button">
580
+ ```
581
+
582
+ **Computed:** `padding: 16px` (выиграло `.custom-button` если оно определено позже в CSS или имеет большую специфичность)
583
+
584
+ ---
585
+
586
+ ## ПОЧЕМУ COMPUTED ЗНАЧЕНИЯ В PX, А НЕ REM
587
+
588
+ Браузер всегда конвертирует относительные единицы (rem, em, %) в абсолютные (px) для рендеринга.
589
+
590
+ **CSS:**
591
+ ```css
592
+ .gap-big { gap: 3.25rem; }
593
+ ```
594
+
595
+ **Computed:**
596
+ ```css
597
+ gap: 52px
598
+ ```
599
+
600
+ **Процесс:**
601
+ 1. Браузер видит `3.25rem`
602
+ 2. Смотрит на root element font-size (обычно 16px)
603
+ 3. Вычисляет: `3.25 * 16 = 52`
604
+ 4. Сохраняет в computed styles как `52px`
605
+ 5. Использует это значение для layout
606
+
607
+ DevTools показывает computed styles - финальные значения после всех вычислений.
608
+
609
+ ---
610
+
611
+ ## VIEWPORT WIDTH/HEIGHT И ПРОЦЕНТНЫЕ ЗНАЧЕНИЯ
612
+
613
+ ### .w-100 и .h-100
614
+
615
+ **CSS:**
616
+ ```css
617
+ .w-100 { width: 100%; }
618
+ .h-100 { height: 100%; }
619
+ ```
620
+
621
+ **На #app-wrapper:**
622
+ ```html
623
+ <div id="app-wrapper" class="w-100 h-100">
624
+ ```
625
+
626
+ **Computed:**
627
+ ```css
628
+ width: 1200px
629
+ height: 692px
630
+ ```
631
+
632
+ **Процесс:**
633
+ 1. Браузер видит `width: 100%`
634
+ 2. Ищет parent element для вычисления процента
635
+ 3. Parent = viewport (browser window)
636
+ 4. Viewport width = 1200px
637
+ 5. Вычисляет: `100% от 1200px = 1200px`
638
+ 6. Computed: `width: 1200px`
639
+
640
+ **На вложенном элементе:**
641
+ ```html
642
+ <div id="app-wrapper" style="width: 1200px">
643
+ <div class="w-100">Child</div>
644
+ </div>
645
+ ```
646
+
647
+ **Child computed:**
648
+ ```css
649
+ width: 1200px /* 100% от родителя */
650
+ ```
651
+
652
+ ---
653
+
654
+ ## ЧТО ПРОИСХОДИТ ПРИ RESIZE VIEWPORT
655
+
656
+ **Начальное состояние (viewport 1200px):**
657
+ ```
658
+ #app-wrapper: width: 1200px
659
+ .cols-2: grid-template-columns: 538px 538px
660
+ ```
661
+
662
+ **После resize (viewport 800px):**
663
+ ```
664
+ #app-wrapper: width: 800px
665
+ .cols-2: grid-template-columns: 374px 374px
666
+ ```
667
+
668
+ **Процесс:**
669
+ 1. Viewport изменился
670
+ 2. Браузер пересчитывает все `width: 100%` элементы
671
+ 3. #app-wrapper получает новую ширину (800px)
672
+ 4. Grid пересчитывает колонки: `(800 - gap) / 2 = 374px`
673
+ 5. Layout обновляется
674
+
675
+ **На mobile (viewport ≤640px):**
676
+
677
+ Media query активируется:
678
+ ```css
679
+ @media (max-width: 640px) {
680
+ .mobile\:cols-1 { grid-template-columns: 1fr; }
681
+ }
682
+ ```
683
+
684
+ Grid меняется с 2 колонок на 1:
685
+ ```
686
+ grid-template-columns: 1fr
687
+ ```
688
+
689
+ Вычисленная ширина одной колонки = вся доступная ширина.
690
+
691
+ ---
692
+
693
+ ## DEBUGGING: КАК ЧИТАТЬ COMPUTED STYLES
694
+
695
+ **DevTools → Elements → Computed tab**
696
+
697
+ ### Что смотреть:
698
+
699
+ **display:**
700
+ - `flex` → элемент flex container
701
+ - `grid` → элемент grid container
702
+ - `block` → обычный блочный элемент
703
+
704
+ **flex-direction:** (если flex)
705
+ - `row` → горизонтальное направление
706
+ - `column` → вертикальное направление
707
+
708
+ **grid-template-columns:** (если grid)
709
+ - `538px 538px` → две колонки по 538px
710
+ - `1fr` → одна колонка на всю ширину
711
+
712
+ **gap:**
713
+ - Промежуток между flex/grid items в px
714
+
715
+ **position:**
716
+ - `static` → обычный flow
717
+ - `relative` → смещение от обычной позиции
718
+ - `absolute` → позиционирование относительно positioned parent
719
+ - `sticky` → прилипающий элемент
720
+ - `fixed` → фиксированный относительно viewport
721
+
722
+ **width/height:**
723
+ - Финальные вычисленные размеры в px
724
+
725
+ **overflow-x/overflow-y:**
726
+ - `hidden` → контент обрезается
727
+ - `scroll` → скроллбар всегда
728
+ - `auto` → скроллбар при необходимости
729
+
730
+ ---
731
+
732
+ ## РЕЗЮМЕ: КЛЮЧЕВЫЕ МЕХАНИЗМЫ
733
+
734
+ ### 1. Иерархия контейнеров
735
+ - Root → Screen → Scrollview parent (grid) → Scrollview → Page → Sections → Components
736
+
737
+ ### 2. Overflow chain
738
+ - Root и Screen: `overflow: hidden` (нет скролла)
739
+ - Scrollview: `overflow-y: scroll` (единственный скролл)
740
+
741
+ ### 3. Flex/Grid sizing
742
+ - Flex: `flex-grow`, `flex-shrink`, `flex-basis` определяют размер
743
+ - Grid: browser вычисляет px значения колонок из `fr` или других единиц
744
+
745
+ ### 4. Position: sticky
746
+ - Работает внутри scrolling container (#scrollview)
747
+ - Элемент "прилипает" при достижении порога (top/bottom)
748
+
749
+ ### 5. Stacking context
750
+ - Создаётся position + z-index
751
+ - Дочерние z-index работают только внутри своего контекста
752
+
753
+ ### 6. Computed values всегда в px
754
+ - rem → px (через base font-size)
755
+ - % → px (через parent размер)
756
+ - fr → px (grid вычисляет)
757
+
758
+ ### 7. Responsive (mobile:)
759
+ - Media queries перезаписывают стили на узких viewport
760
+ - Grid меняется с 2 колонок на 1
761
+ - Sticky превращается в relative
762
+
763
+ ---
764
+
765
+ **Дата:** 2025-01-20
766
+ **Источник:** Computed styles с http://localhost:8041
767
+ **Viewport:** 1200x692px desktop