@inchurch/matcha-theme 20.0.8 → 20.276.0

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/abstracts/_colors.scss +404 -404
  2. package/abstracts/_elevation.scss +102 -102
  3. package/abstracts/_functions.scss +1212 -1212
  4. package/abstracts/_media-breakpoint.scss +23 -23
  5. package/abstracts/_typography.scss +127 -127
  6. package/base/_reset.scss +438 -438
  7. package/components/app-page-header.scss +260 -0
  8. package/components/matcha-accordion.scss +294 -157
  9. package/components/matcha-avatar.scss +171 -31
  10. package/components/matcha-badge.scss +4 -4
  11. package/components/matcha-breadcrumb.scss +232 -126
  12. package/components/matcha-button-toggle.scss +44 -0
  13. package/components/matcha-buttons.scss +908 -784
  14. package/components/matcha-calendar.scss +70 -2
  15. package/components/matcha-cards.scss +28 -2
  16. package/components/matcha-checkbox.scss +191 -490
  17. package/components/matcha-chip.scss +297 -212
  18. package/components/matcha-command-palette.scss +291 -63
  19. package/components/matcha-crop.scss +407 -172
  20. package/components/matcha-date.scss +81 -81
  21. package/components/matcha-divider.scss +86 -31
  22. package/components/matcha-drawer.scss +201 -50
  23. package/components/matcha-drop-image.scss +14 -0
  24. package/components/matcha-drop-list.scss +42 -1
  25. package/components/matcha-empty-state.scss +195 -83
  26. package/components/matcha-flag.scss +93 -52
  27. package/components/matcha-footer.scss +68 -164
  28. package/components/matcha-form-field.scss +52 -0
  29. package/components/matcha-form-section.scss +101 -101
  30. package/components/matcha-header.scss +135 -325
  31. package/components/matcha-highlight.scss +65 -197
  32. package/components/matcha-hint-text.scss +21 -0
  33. package/components/matcha-horizontal-tree.scss +317 -317
  34. package/components/matcha-icon.scss +17 -25
  35. package/components/matcha-list.scss +5 -5
  36. package/components/matcha-menu.scss +13 -0
  37. package/components/matcha-modal.scss +58 -84
  38. package/components/matcha-nav.scss +361 -230
  39. package/components/matcha-notification.scss +413 -197
  40. package/components/matcha-option.scss +79 -23
  41. package/components/matcha-paginator.scss +689 -235
  42. package/components/matcha-panel.scss +42 -26
  43. package/components/matcha-profile-card.scss +50 -50
  44. package/components/matcha-progress-bar.scss +257 -153
  45. package/components/matcha-radio.scss +244 -452
  46. package/components/matcha-scrollbox-shadow.scss +122 -122
  47. package/components/matcha-select.scss +3 -3
  48. package/components/matcha-skeleton.scss +18 -0
  49. package/components/matcha-slide-toggle.scss +47 -2
  50. package/components/matcha-slider.scss +172 -75
  51. package/components/matcha-snack-bar.scss +114 -121
  52. package/components/matcha-spinner.scss +76 -57
  53. package/components/matcha-status-pill.scss +82 -0
  54. package/components/matcha-stepper.scss +377 -177
  55. package/components/matcha-table.scss +569 -785
  56. package/components/matcha-tabs.scss +624 -469
  57. package/components/matcha-text-editor.scss +98 -144
  58. package/components/matcha-toolbar.scss +359 -206
  59. package/components/matcha-tooltip.scss +156 -62
  60. package/components/matcha-tree-view.scss +189 -0
  61. package/components/matcha-uploader.scss +240 -62
  62. package/fonts/manrope/manrope-latin-ext.woff2 +0 -0
  63. package/fonts/manrope/manrope-latin.woff2 +0 -0
  64. package/layout/matcha-page-layout.scss +776 -0
  65. package/main.scss +232 -261
  66. package/package.json +1 -1
  67. package/tokens/_animations-tokens.scss +37 -37
  68. package/tokens/_breakpoints-tokens.scss +35 -26
  69. package/tokens/_color-tokens.scss +1152 -1152
  70. package/tokens/_css-custom-properties.scss +650 -568
  71. package/tokens/_spacing-tokens.scss +94 -94
  72. package/vendors/angular-editor.scss +56 -56
  73. package/vendors/angular-material-fixes.scss +297 -297
  74. package/vendors/charts.scss +92 -92
  75. package/vendors/ng5-slider.scss +56 -56
  76. package/vendors/ngx-material-timepicker.scss +50 -50
  77. package/fonts/CircularStd-Black.eot +0 -0
  78. package/fonts/CircularStd-Black.svg +0 -3426
  79. package/fonts/CircularStd-Black.ttf +0 -0
  80. package/fonts/CircularStd-Black.woff +0 -0
  81. package/fonts/CircularStd-Black.woff2 +0 -0
  82. package/fonts/CircularStd-Bold.eot +0 -0
  83. package/fonts/CircularStd-Bold.otf +0 -0
  84. package/fonts/CircularStd-Bold.svg +0 -13532
  85. package/fonts/CircularStd-Bold.ttf +0 -0
  86. package/fonts/CircularStd-Bold.woff +0 -0
  87. package/fonts/CircularStd-Bold.woff2 +0 -0
  88. package/fonts/CircularStd-Medium.eot +0 -0
  89. package/fonts/CircularStd-Medium.otf +0 -0
  90. package/fonts/CircularStd-Medium.svg +0 -13511
  91. package/fonts/CircularStd-Medium.ttf +0 -0
  92. package/fonts/CircularStd-Medium.woff +0 -0
  93. package/fonts/CircularStd-Medium.woff2 +0 -0
  94. package/fonts/CircularStd-Regular.eot +0 -0
  95. package/fonts/CircularStd-Regular.otf +0 -0
  96. package/fonts/CircularStd-Regular.svg +0 -2378
  97. package/fonts/CircularStd-Regular.ttf +0 -0
  98. package/fonts/CircularStd-Regular.woff +0 -0
  99. package/fonts/CircularStd-Regular.woff2 +0 -0
@@ -1,172 +1,407 @@
1
- @use "sass:map";
2
-
3
- // =============================================================================
4
- // matcha-crop.scss — Image cropper modal
5
- // Aligned with Figma matcha/crop:
6
- // Ratio(2: 16:9, 1:1) — Crop area with overlay mask
7
- // Angular: matcha-crop (wraps cropper logic inside matcha-modal)
8
- // =============================================================================
9
-
10
- @mixin matcha-crop-theme($theme) {
11
- $is-dark: map.get($theme, is-dark);
12
-
13
- .matcha-crop {
14
- .matcha-crop__header {
15
- color: var(--matcha-color-fg, #{getForeground($theme)});
16
- }
17
-
18
- .matcha-crop__overlay {
19
- background: rgba(#212121, 0.6); // ok: structural
20
- }
21
-
22
- .matcha-crop__area {
23
- border: var(--matcha-border-thin, 2px) solid var(--matcha-color-accent, #{getAccent($theme)});
24
- }
25
-
26
- .matcha-crop__grid-line {
27
- background: rgba(#ffffff, 0.3); // ok: structural
28
- }
29
-
30
- .matcha-crop__canvas {
31
- background: var(--matcha-color-surface-inverse, #{if($is-dark, getSurface($theme), #121212)});
32
- }
33
-
34
- .matcha-crop__handle {
35
- background: var(--matcha-color-surface, #{getSurface($theme)});
36
- border-color: var(--matcha-color-accent, #{getAccent($theme)});
37
- }
38
- }
39
- }
40
-
41
- // ── Layout ──────────────────────────────────────────────────────────────────
42
-
43
- .matcha-crop {
44
- display: flex;
45
- flex-direction: column;
46
- width: 100%;
47
- height: 100%;
48
- }
49
-
50
- .matcha-crop__header {
51
- display: flex;
52
- align-items: center;
53
- gap: var(--matcha-space-100, 8px);
54
- padding: var(--matcha-space-200, 16px) var(--matcha-space-300, 24px);
55
- font-family: var(--matcha-font-family);
56
- font-size: var(--matcha-text-title-sm, 16px);
57
- font-weight: var(--matcha-weight-semibold, 600);
58
- line-height: var(--matcha-leading-title-sm, 22px);
59
- }
60
-
61
- .matcha-crop__canvas {
62
- position: relative;
63
- flex: 1;
64
- display: flex;
65
- align-items: center;
66
- justify-content: center;
67
- overflow: hidden;
68
- min-height: 300px;
69
- }
70
-
71
- .matcha-crop__image {
72
- max-width: 100%;
73
- max-height: 100%;
74
- object-fit: contain;
75
- user-select: none;
76
- -webkit-user-drag: none;
77
- }
78
-
79
- .matcha-crop__overlay {
80
- position: absolute;
81
- inset: 0;
82
- pointer-events: none;
83
- }
84
-
85
- .matcha-crop__area {
86
- position: absolute;
87
- box-sizing: border-box;
88
- cursor: move;
89
- touch-action: none;
90
- }
91
-
92
- // ── Aspect ratios ──
93
- .matcha-crop__area--16x9 {
94
- aspect-ratio: 16 / 9;
95
- }
96
-
97
- .matcha-crop__area--1x1 {
98
- aspect-ratio: 1 / 1;
99
- border-radius: 0;
100
- }
101
-
102
- .matcha-crop__area--1x1-circle {
103
- aspect-ratio: 1 / 1;
104
- border-radius: 50%;
105
- }
106
-
107
- // ── Rule of thirds grid ──
108
- .matcha-crop__grid {
109
- position: absolute;
110
- inset: 0;
111
- display: grid;
112
- grid-template-columns: 1fr 1fr 1fr;
113
- grid-template-rows: 1fr 1fr 1fr;
114
- pointer-events: none;
115
- }
116
-
117
- .matcha-crop__grid-line {
118
- &:nth-child(1) { grid-column: 2; grid-row: 1 / 4; width: var(--matcha-border-hairline, 1px); }
119
- &:nth-child(2) { grid-column: 3; grid-row: 1 / 4; width: var(--matcha-border-hairline, 1px); }
120
- &:nth-child(3) { grid-column: 1 / 4; grid-row: 2; height: var(--matcha-border-hairline, 1px); }
121
- &:nth-child(4) { grid-column: 1 / 4; grid-row: 3; height: var(--matcha-border-hairline, 1px); }
122
- }
123
-
124
- // ── Resize handles ──
125
- .matcha-crop__handle {
126
- position: absolute;
127
- width: var(--matcha-space-150, 12px);
128
- height: var(--matcha-space-150, 12px);
129
- border: var(--matcha-border-thin, 2px) solid transparent;
130
- border-radius: 50%;
131
- pointer-events: auto;
132
-
133
- // Offset negativo = -6px = -(handle/2) pra centralizar no canto
134
- &--nw { top: calc(-1 * var(--matcha-space-075, 6px)); left: calc(-1 * var(--matcha-space-075, 6px)); cursor: nw-resize; }
135
- &--ne { top: calc(-1 * var(--matcha-space-075, 6px)); right: calc(-1 * var(--matcha-space-075, 6px)); cursor: ne-resize; }
136
- &--sw { bottom: calc(-1 * var(--matcha-space-075, 6px)); left: calc(-1 * var(--matcha-space-075, 6px)); cursor: sw-resize; }
137
- &--se { bottom: calc(-1 * var(--matcha-space-075, 6px)); right: calc(-1 * var(--matcha-space-075, 6px)); cursor: se-resize; }
138
- }
139
-
140
- // ── Footer ──
141
- .matcha-crop__footer {
142
- display: flex;
143
- align-items: center;
144
- justify-content: flex-end;
145
- gap: var(--matcha-space-100, 8px);
146
- padding: var(--matcha-space-200, 16px) var(--matcha-space-300, 24px);
147
- }
148
-
149
- // ── Responsive ──────────────────────────────────────────────────────────────
150
-
151
- @include media-breakpoint('xs') {
152
- .matcha-crop__header {
153
- padding: var(--matcha-space-150, 12px) var(--matcha-space-200, 16px);
154
- }
155
-
156
- .matcha-crop__footer {
157
- padding: var(--matcha-space-150, 12px) var(--matcha-space-200, 16px);
158
- }
159
-
160
- .matcha-crop__canvas {
161
- min-height: 240px;
162
- }
163
- }
164
-
165
- // ── Reduced motion ──────────────────────────────────────────────────────────
166
-
167
- @media (prefers-reduced-motion: reduce) {
168
- .matcha-crop__area,
169
- .matcha-crop__image {
170
- transition: none;
171
- }
172
- }
1
+ @use "sass:map";
2
+
3
+ // =============================================================================
4
+ // matcha-crop.scss — Image cropper (Tier 1 + Tier 2 gold)
5
+ //
6
+ // Estrutura:
7
+ // .matcha-crop host flex column (data-state, data-shape, data-ratio)
8
+ // .matcha-crop__header — title + toolbar (reset, lock)
9
+ // .matcha-crop__canvas — image stage + interaction surface
10
+ // .matcha-crop__image — source img (transforma via translate/scale)
11
+ // .matcha-crop__overlay — punch-out mask via clip-path
12
+ // .matcha-crop__area — crop frame draggable + 8 handles
13
+ // .matcha-crop__handle--{nw|n|ne|...} — resize handles (44×44 touch target)
14
+ // .matcha-crop__zoom-bar — slider de zoom
15
+ // .matcha-crop__state — empty / loading / error visuals
16
+ // .matcha-crop__footer — ng-content de actions
17
+ // =============================================================================
18
+
19
+ @mixin matcha-crop-theme($theme) {
20
+ $is-dark: map.get($theme, is-dark);
21
+
22
+ .matcha-crop {
23
+ color: var(--matcha-color-text-primary);
24
+
25
+ .matcha-crop__header {
26
+ color: var(--matcha-color-text-primary);
27
+ border-bottom: var(--matcha-border-hairline, 1px) solid var(--matcha-color-surface-border);
28
+ }
29
+
30
+ .matcha-crop__canvas {
31
+ background: var(--matcha-color-surface-inverse, #121212);
32
+ }
33
+
34
+ .matcha-crop__overlay {
35
+ background: var(--matcha-color-scrim, rgba(0, 0, 0, 0.55));
36
+ }
37
+
38
+ .matcha-crop__area {
39
+ border: var(--matcha-border-thin, 2px) solid var(--matcha-color-accent);
40
+ box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1);
41
+
42
+ &:focus-visible {
43
+ outline: 3px solid var(--matcha-color-focus-ring);
44
+ outline-offset: 4px;
45
+ }
46
+ }
47
+
48
+ .matcha-crop__grid-line {
49
+ background: var(--matcha-color-on-overlay, rgba(255, 255, 255, 0.3));
50
+ }
51
+
52
+ .matcha-crop__handle {
53
+ background: var(--matcha-color-surface);
54
+ border-color: var(--matcha-color-accent);
55
+ }
56
+
57
+ .matcha-crop__zoom-bar {
58
+ background: var(--matcha-color-surface-card);
59
+ border: var(--matcha-border-hairline, 1px) solid var(--matcha-color-surface-border);
60
+ color: var(--matcha-color-text-secondary);
61
+ }
62
+
63
+ .matcha-crop__icon-btn {
64
+ color: var(--matcha-color-text-secondary);
65
+
66
+ &:hover { background: var(--matcha-color-surface-hover); color: var(--matcha-color-text-primary); }
67
+ &:focus-visible { outline: 2px solid var(--matcha-color-focus-ring); outline-offset: 2px; }
68
+ &.is-active { color: var(--matcha-color-accent); background: var(--matcha-color-accent-surface-hover); }
69
+ }
70
+
71
+ .matcha-crop__state-icon { color: var(--matcha-color-text-muted); }
72
+ .matcha-crop__state-title { color: var(--matcha-color-text-primary); }
73
+ .matcha-crop__state-desc { color: var(--matcha-color-text-secondary); }
74
+
75
+ .matcha-crop__state--error .matcha-crop__state-icon { color: var(--matcha-color-danger); }
76
+ }
77
+ }
78
+
79
+ // ── Layout ──────────────────────────────────────────────────────────────────
80
+
81
+ .matcha-crop {
82
+ display: flex;
83
+ flex-direction: column;
84
+ width: 100%;
85
+ height: 100%;
86
+ min-height: 320px;
87
+ }
88
+
89
+ // ── Header ──────────────────────────────────────────────────────────────────
90
+
91
+ .matcha-crop__header {
92
+ display: flex;
93
+ align-items: center;
94
+ gap: var(--matcha-space-100, 8px);
95
+ padding: var(--matcha-space-200, 16px) var(--matcha-space-300, 24px);
96
+ font-family: var(--matcha-font-family);
97
+ font-size: var(--matcha-text-title-sm, 16px);
98
+ font-weight: var(--matcha-weight-semibold, 600);
99
+ line-height: var(--matcha-leading-title-sm, 22px);
100
+ flex-shrink: 0;
101
+ }
102
+
103
+ .matcha-crop__title {
104
+ flex: 1;
105
+ min-width: 0;
106
+ overflow: hidden;
107
+ text-overflow: ellipsis;
108
+ white-space: nowrap;
109
+ }
110
+
111
+ .matcha-crop__toolbar {
112
+ display: flex;
113
+ align-items: center;
114
+ gap: var(--matcha-space-050, 4px);
115
+ }
116
+
117
+ .matcha-crop__icon-btn {
118
+ display: inline-flex;
119
+ align-items: center;
120
+ justify-content: center;
121
+ width: 32px;
122
+ height: 32px;
123
+ padding: 0;
124
+ background: transparent;
125
+ border: 0;
126
+ border-radius: var(--matcha-radius-md, 4px);
127
+ cursor: pointer;
128
+ transition: background 150ms ease, color 150ms ease;
129
+ }
130
+
131
+ // ── Canvas (interaction area) ──────────────────────────────────────────────
132
+
133
+ .matcha-crop__canvas {
134
+ position: relative;
135
+ flex: 1;
136
+ display: flex;
137
+ align-items: center;
138
+ justify-content: center;
139
+ overflow: hidden;
140
+ min-height: 320px;
141
+ cursor: grab;
142
+ user-select: none;
143
+
144
+ &.is-interacting { cursor: grabbing; }
145
+ }
146
+
147
+ // `width/height: 100%` + `object-fit: contain` é o pareamento correto: força o
148
+ // IMG box a ocupar o canvas inteiro (mesmo pra natural < container), com o
149
+ // conteúdo escalado preservando aspect ratio. `max-width/height` causava bug
150
+ // em fotos menores que o canvas (ex: thumbnail 80×80 num modal 432×320): o
151
+ // browser não upscala via max-*, mas o JS calculava displayRatio = container/
152
+ // natural > 1 assumindo upscale, fazendo o mapeamento display→source ficar
153
+ // deslocado e o crop sair errado.
154
+ .matcha-crop__image {
155
+ width: 100%;
156
+ height: 100%;
157
+ object-fit: contain;
158
+ user-select: none;
159
+ -webkit-user-drag: none;
160
+ pointer-events: none;
161
+ transform-origin: center center;
162
+ will-change: transform;
163
+ transition: transform 80ms ease-out;
164
+ }
165
+
166
+ // ── Overlay (punch-out via clip-path) ───────────────────────────────────────
167
+
168
+ .matcha-crop__overlay {
169
+ position: absolute;
170
+ inset: 0;
171
+ pointer-events: none;
172
+ transition: clip-path 80ms ease-out;
173
+ }
174
+
175
+ // ── Crop area ───────────────────────────────────────────────────────────────
176
+
177
+ .matcha-crop__area {
178
+ position: absolute;
179
+ box-sizing: border-box;
180
+ cursor: move;
181
+ touch-action: none;
182
+
183
+ &--circle {
184
+ border-radius: 50%;
185
+ }
186
+ }
187
+
188
+ // Posicionado ACIMA da área de crop em vez do centro. Quando shape=circle,
189
+ // o texto do centro era cruzado pelo border (visualmente parecia cortado).
190
+ // Acima fica em zona de overlay escurecido, sempre legível.
191
+ .matcha-crop__hint {
192
+ position: absolute;
193
+ bottom: calc(100% + var(--matcha-space-100, 8px));
194
+ left: 50%;
195
+ transform: translateX(-50%);
196
+ padding: var(--matcha-space-050, 4px) var(--matcha-space-100, 8px);
197
+ font-size: 11px;
198
+ color: rgba(255, 255, 255, 0.85);
199
+ background: rgba(0, 0, 0, 0.7);
200
+ border-radius: var(--matcha-radius-sm, 2px);
201
+ pointer-events: none;
202
+ white-space: nowrap;
203
+ }
204
+
205
+ // ── Rule of thirds grid (mostra só durante interação) ──────────────────────
206
+
207
+ .matcha-crop__grid {
208
+ position: absolute;
209
+ inset: 0;
210
+ display: grid;
211
+ grid-template-columns: 1fr 1fr 1fr;
212
+ grid-template-rows: 1fr 1fr 1fr;
213
+ pointer-events: none;
214
+ }
215
+
216
+ .matcha-crop__grid-line {
217
+ &:nth-child(1) { grid-column: 2; grid-row: 1 / 4; width: 1px; justify-self: start; }
218
+ &:nth-child(2) { grid-column: 3; grid-row: 1 / 4; width: 1px; justify-self: start; }
219
+ &:nth-child(3) { grid-column: 1 / 4; grid-row: 2; height: 1px; align-self: start; }
220
+ &:nth-child(4) { grid-column: 1 / 4; grid-row: 3; height: 1px; align-self: start; }
221
+ }
222
+
223
+ // ── Resize handles (8 directions, 44×44 touch target) ──────────────────────
224
+
225
+ .matcha-crop__handle {
226
+ position: absolute;
227
+ width: var(--matcha-crop-handle-size, 16px);
228
+ height: var(--matcha-crop-handle-size, 16px);
229
+ margin: calc(-1 * var(--matcha-crop-handle-size, 16px) / 2);
230
+ padding: 0;
231
+ background: transparent;
232
+ border: var(--matcha-border-thin, 2px) solid transparent;
233
+ border-radius: 50%;
234
+ pointer-events: auto;
235
+ z-index: 2;
236
+ touch-action: none;
237
+
238
+ // Expand touch target via ::after (visual = 16px, hit = 44px)
239
+ &::after {
240
+ content: '';
241
+ position: absolute;
242
+ inset: -14px;
243
+ }
244
+
245
+ &:focus-visible {
246
+ outline: 2px solid var(--matcha-color-focus-ring);
247
+ outline-offset: 2px;
248
+ }
249
+ }
250
+
251
+ // ── Zoom bar ────────────────────────────────────────────────────────────────
252
+
253
+ .matcha-crop__zoom-bar {
254
+ position: absolute;
255
+ bottom: var(--matcha-space-200, 16px);
256
+ left: 50%;
257
+ transform: translateX(-50%);
258
+ display: flex;
259
+ align-items: center;
260
+ gap: var(--matcha-space-100, 8px);
261
+ padding: var(--matcha-space-075, 6px) var(--matcha-space-150, 12px);
262
+ border-radius: var(--matcha-radius-pill, 9999px);
263
+ backdrop-filter: blur(8px);
264
+ font-size: var(--matcha-text-body-sm, 12px);
265
+ z-index: 3;
266
+ }
267
+
268
+ .matcha-crop__zoom-slider {
269
+ -webkit-appearance: none;
270
+ appearance: none;
271
+ width: 160px;
272
+ height: 4px;
273
+ background: var(--matcha-color-surface-border);
274
+ border-radius: 2px;
275
+ cursor: pointer;
276
+ outline: none;
277
+
278
+ &::-webkit-slider-thumb {
279
+ -webkit-appearance: none;
280
+ width: 16px;
281
+ height: 16px;
282
+ background: var(--matcha-color-accent);
283
+ border: 2px solid var(--matcha-color-surface);
284
+ border-radius: 50%;
285
+ cursor: grab;
286
+ }
287
+ &::-moz-range-thumb {
288
+ width: 16px;
289
+ height: 16px;
290
+ background: var(--matcha-color-accent);
291
+ border: 2px solid var(--matcha-color-surface);
292
+ border-radius: 50%;
293
+ cursor: grab;
294
+ }
295
+ &:focus-visible::-webkit-slider-thumb {
296
+ box-shadow: 0 0 0 3px var(--matcha-color-focus-ring);
297
+ }
298
+ }
299
+
300
+ .matcha-crop__zoom-value {
301
+ min-width: 40px;
302
+ font-family: 'Fira Code', Consolas, monospace;
303
+ font-variant-numeric: tabular-nums;
304
+ text-align: right;
305
+ }
306
+
307
+ // ── States (empty / loading / error) ────────────────────────────────────────
308
+
309
+ .matcha-crop__state {
310
+ display: flex;
311
+ flex-direction: column;
312
+ align-items: center;
313
+ justify-content: center;
314
+ gap: var(--matcha-space-100, 8px);
315
+ padding: var(--matcha-space-300, 24px);
316
+ text-align: center;
317
+ max-width: 360px;
318
+ }
319
+
320
+ .matcha-crop__state-icon {
321
+ font-size: 48px;
322
+ width: 48px;
323
+ height: 48px;
324
+ --matcha-icon-color: currentColor;
325
+
326
+ &--spin {
327
+ animation: matcha-crop-spin 1.2s linear infinite;
328
+ }
329
+ }
330
+
331
+ .matcha-crop__state-title {
332
+ margin: 0;
333
+ font-size: var(--matcha-text-title-sm, 16px);
334
+ font-weight: var(--matcha-weight-semibold, 600);
335
+ }
336
+
337
+ .matcha-crop__state-desc {
338
+ margin: 0;
339
+ font-size: var(--matcha-text-body-sm, 12px);
340
+ line-height: 1.4;
341
+
342
+ code {
343
+ padding: 2px 6px;
344
+ background: var(--matcha-color-surface-card);
345
+ border-radius: var(--matcha-radius-sm, 2px);
346
+ font-family: 'Fira Code', Consolas, monospace;
347
+ font-size: 11px;
348
+ }
349
+ }
350
+
351
+ @keyframes matcha-crop-spin {
352
+ to { transform: rotate(360deg); }
353
+ }
354
+
355
+ // ── SR-only live region ────────────────────────────────────────────────────
356
+
357
+ .matcha-crop__sr-live {
358
+ position: absolute;
359
+ width: 1px;
360
+ height: 1px;
361
+ padding: 0;
362
+ margin: -1px;
363
+ overflow: hidden;
364
+ clip: rect(0, 0, 0, 0);
365
+ white-space: nowrap;
366
+ border: 0;
367
+ }
368
+
369
+ // ── Footer ──────────────────────────────────────────────────────────────────
370
+ // Footer só ocupa espaço quando ng-content tem children projetados.
371
+ // Truque CSS: empty footer fica height 0 via :has() — quando vazio, esconde.
372
+
373
+ .matcha-crop__footer {
374
+ display: flex;
375
+ align-items: center;
376
+ justify-content: flex-end;
377
+ gap: var(--matcha-space-100, 8px);
378
+ padding: var(--matcha-space-200, 16px) var(--matcha-space-300, 24px);
379
+ flex-shrink: 0;
380
+
381
+ &:empty {
382
+ padding: 0;
383
+ }
384
+ }
385
+
386
+ // ── Responsive ──────────────────────────────────────────────────────────────
387
+
388
+ @media (max-width: 640px) {
389
+ .matcha-crop__header,
390
+ .matcha-crop__footer {
391
+ padding: var(--matcha-space-150, 12px) var(--matcha-space-200, 16px);
392
+ }
393
+ .matcha-crop__canvas { min-height: 280px; }
394
+ .matcha-crop__zoom-slider { width: 120px; }
395
+ }
396
+
397
+ // ── Reduced motion ──────────────────────────────────────────────────────────
398
+
399
+ @media (prefers-reduced-motion: reduce) {
400
+ .matcha-crop__image,
401
+ .matcha-crop__overlay {
402
+ transition: none;
403
+ }
404
+ .matcha-crop__state-icon--spin {
405
+ animation: none;
406
+ }
407
+ }