drf-to-mkdoc 0.1.5__py3-none-any.whl → 0.1.8__py3-none-any.whl

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.

Potentially problematic release.


This version of drf-to-mkdoc might be problematic. Click here for more details.

Files changed (42) hide show
  1. drf_to_mkdoc/__init__.py +1 -1
  2. drf_to_mkdoc/apps.py +6 -2
  3. drf_to_mkdoc/conf/defaults.py +0 -1
  4. drf_to_mkdoc/conf/settings.py +11 -5
  5. drf_to_mkdoc/management/commands/build_docs.py +61 -19
  6. drf_to_mkdoc/management/commands/generate_docs.py +5 -5
  7. drf_to_mkdoc/management/commands/generate_model_docs.py +37 -7
  8. drf_to_mkdoc/static/drf-to-mkdoc/javascripts/endpoints-filter.js +189 -0
  9. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/accessibility.css +21 -0
  10. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/animations.css +11 -0
  11. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/badges.css +54 -0
  12. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/base.css +84 -0
  13. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/endpoint-content.css +165 -0
  14. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/endpoints-grid.css +194 -0
  15. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/filter-section.css +209 -0
  16. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/fixes.css +44 -0
  17. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/layout.css +31 -0
  18. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/loading.css +35 -0
  19. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/responsive.css +96 -0
  20. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/sections.css +35 -0
  21. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/stats.css +34 -0
  22. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/tags.css +92 -0
  23. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/theme-toggle.css +42 -0
  24. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/endpoints/variables.css +73 -0
  25. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/models/animations.css +25 -0
  26. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/models/base.css +83 -0
  27. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/models/model-cards.css +126 -0
  28. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/models/model-tables.css +57 -0
  29. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/models/responsive.css +51 -0
  30. drf_to_mkdoc/static/drf-to-mkdoc/stylesheets/models/variables.css +46 -0
  31. drf_to_mkdoc/utils/common.py +31 -29
  32. drf_to_mkdoc/utils/{endpoint_generator.py → endpoint_detail_generator.py} +214 -384
  33. drf_to_mkdoc/utils/endpoint_list_generator.py +234 -0
  34. drf_to_mkdoc/utils/extractors/query_parameter_extractors.py +15 -16
  35. drf_to_mkdoc/utils/{model_generator.py → model_detail_generator.py} +20 -51
  36. drf_to_mkdoc/utils/model_list_generator.py +67 -0
  37. {drf_to_mkdoc-0.1.5.dist-info → drf_to_mkdoc-0.1.8.dist-info}/METADATA +3 -25
  38. drf_to_mkdoc-0.1.8.dist-info/RECORD +50 -0
  39. drf_to_mkdoc-0.1.5.dist-info/RECORD +0 -25
  40. {drf_to_mkdoc-0.1.5.dist-info → drf_to_mkdoc-0.1.8.dist-info}/WHEEL +0 -0
  41. {drf_to_mkdoc-0.1.5.dist-info → drf_to_mkdoc-0.1.8.dist-info}/licenses/LICENSE +0 -0
  42. {drf_to_mkdoc-0.1.5.dist-info → drf_to_mkdoc-0.1.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,165 @@
1
+ /* ===== ENDPOINT CONTENT ===== */
2
+ .endpoint-path {
3
+ font-family: 'Monaco', 'Menlo', 'SF Mono', monospace;
4
+ font-weight: 600;
5
+ color: var(--text-primary);
6
+ font-size: 15px;
7
+ margin-bottom: 8px;
8
+ word-break: break-all;
9
+ background: var(--bg-primary);
10
+ padding: 12px;
11
+ border-radius: 8px;
12
+ border: 1px solid var(--border-color);
13
+ flex: 1;
14
+ min-width: 0;
15
+ }
16
+
17
+ .endpoint-description {
18
+ color: var(--text-secondary);
19
+ font-size: 14px;
20
+ margin-bottom: 12px;
21
+ line-height: 1.5;
22
+ }
23
+
24
+ .related-models {
25
+ margin-bottom: 12px;
26
+ }
27
+
28
+ .related-models-label {
29
+ font-size: 12px;
30
+ color: var(--text-secondary);
31
+ margin-bottom: 4px;
32
+ }
33
+
34
+ .models-list {
35
+ display: flex;
36
+ flex-wrap: wrap;
37
+ gap: 4px;
38
+ }
39
+
40
+ .model-badge {
41
+ background: var(--bg-primary);
42
+ color: var(--text-primary);
43
+ padding: 2px 6px;
44
+ border-radius: 4px;
45
+ font-size: 11px;
46
+ font-family: monospace;
47
+ border: 1px solid var(--border-color);
48
+ }
49
+
50
+ /* Enhanced code blocks */
51
+ .highlight pre {
52
+ border-left: 4px solid var(--md-primary-fg-color);
53
+ background-color: var(--md-code-bg-color);
54
+ padding: 1rem;
55
+ border-radius: 0.2rem;
56
+ }
57
+
58
+ /* Model field tables */
59
+ table {
60
+ border-collapse: collapse;
61
+ width: 100%;
62
+ margin: 1rem 0;
63
+ }
64
+
65
+ table th {
66
+ background-color: var(--md-primary-fg-color--light);
67
+ color: var(--md-primary-bg-color);
68
+ padding: 0.75rem;
69
+ text-align: left;
70
+ font-weight: 600;
71
+ }
72
+
73
+ table td {
74
+ padding: 0.75rem;
75
+ border-bottom: 1px solid var(--md-default-fg-color--lightest);
76
+ }
77
+
78
+ table tr:hover {
79
+ background-color: var(--md-accent-fg-color--transparent);
80
+ }
81
+
82
+ /* Field and method grids */
83
+ .field-grid, .method-grid {
84
+ display: grid;
85
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
86
+ gap: 1rem;
87
+ margin: 1rem 0;
88
+ }
89
+
90
+ .field-item, .method-item {
91
+ background-color: var(--md-default-bg-color);
92
+ border: 1px solid var(--md-default-fg-color--lightest);
93
+ border-radius: 0.2rem;
94
+ padding: 1rem;
95
+ }
96
+
97
+ .field-item h4, .method-item h4 {
98
+ margin-top: 0;
99
+ color: var(--md-primary-fg-color);
100
+ }
101
+
102
+ /* API endpoint sections */
103
+ .endpoint-section {
104
+ border-left: 4px solid var(--md-accent-fg-color);
105
+ padding-left: 1rem;
106
+ margin: 2rem 0;
107
+ }
108
+
109
+ .endpoint-header {
110
+ display: flex;
111
+ align-items: center;
112
+ margin-bottom: 1rem;
113
+ }
114
+
115
+ /* Enhanced code blocks */
116
+ .highlight pre {
117
+ border-left: 4px solid var(--md-primary-fg-color);
118
+ background-color: var(--md-code-bg-color);
119
+ padding: 1rem;
120
+ border-radius: 0.2rem;
121
+ }
122
+
123
+ /* Model field tables */
124
+ table {
125
+ border-collapse: collapse;
126
+ width: 100%;
127
+ margin: 1rem 0;
128
+ }
129
+
130
+ table th {
131
+ background-color: var(--md-primary-fg-color--light);
132
+ color: var(--md-primary-bg-color);
133
+ padding: 0.75rem;
134
+ text-align: left;
135
+ font-weight: 600;
136
+ }
137
+
138
+ table td {
139
+ padding: 0.75rem;
140
+ border-bottom: 1px solid var(--md-default-fg-color--lightest);
141
+ }
142
+
143
+ table tr:hover {
144
+ background-color: var(--md-accent-fg-color--transparent);
145
+ }
146
+
147
+ /* Field and method grids */
148
+ .field-grid, .method-grid {
149
+ display: grid;
150
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
151
+ gap: 1rem;
152
+ margin: 1rem 0;
153
+ }
154
+
155
+ .field-item, .method-item {
156
+ background-color: var(--md-default-bg-color);
157
+ border: 1px solid var(--md-default-fg-color--lightest);
158
+ border-radius: 0.2rem;
159
+ padding: 1rem;
160
+ }
161
+
162
+ .field-item h4, .method-item h4 {
163
+ margin-top: 0;
164
+ color: var(--md-primary-fg-color);
165
+ }
@@ -0,0 +1,194 @@
1
+ /* ===== ENDPOINTS GRID ===== */
2
+ .endpoints-grid {
3
+ display: grid;
4
+ grid-template-columns: 1fr;
5
+ gap: 16px;
6
+ margin: 24px 0;
7
+ transition: all 0.3s ease;
8
+ width: 100%;
9
+ }
10
+
11
+ .endpoints-grid.filtering {
12
+ opacity: 0.7;
13
+ }
14
+
15
+ /* ===== ENDPOINT CARDS ===== */
16
+ .endpoint-card {
17
+ position: relative;
18
+ display: flex;
19
+ align-items: center;
20
+ gap: 16px;
21
+ padding: 20px;
22
+ background: var(--bg-secondary);
23
+ border: 1px solid var(--border-color);
24
+ border-radius: 12px;
25
+ transition: all 0.3s ease;
26
+ text-decoration: none;
27
+ color: var(--text-primary);
28
+ box-shadow: var(--shadow);
29
+ overflow: hidden;
30
+ width: 100%;
31
+ box-sizing: border-box;
32
+ }
33
+
34
+ .endpoint-card::before {
35
+ content: '';
36
+ position: absolute;
37
+ top: 0;
38
+ left: 0;
39
+ right: 0;
40
+ bottom: 0;
41
+ background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(147, 51, 234, 0.1));
42
+ opacity: 0;
43
+ transition: opacity 0.3s ease;
44
+ z-index: 1;
45
+ }
46
+
47
+ .endpoint-card:hover::before {
48
+ opacity: 1;
49
+ }
50
+
51
+ .endpoint-card:hover {
52
+ transform: translateY(-2px);
53
+ box-shadow: var(--shadow-hover);
54
+ }
55
+
56
+ .endpoint-card:focus {
57
+ outline: 2px solid var(--accent-primary);
58
+ outline-offset: 2px;
59
+ }
60
+
61
+ .endpoint-card.hidden {
62
+ opacity: 0;
63
+ transform: scale(0.95);
64
+ pointer-events: none;
65
+ position: absolute;
66
+ height: 0;
67
+ margin: 0;
68
+ padding: 0;
69
+ border: none;
70
+ }
71
+
72
+ .endpoint-card > * {
73
+ position: relative;
74
+ z-index: 2;
75
+ }
76
+
77
+ /* ===== DJANGO MODELS CARD LAYOUT ===== */
78
+ /* Models container */
79
+ .models-container {
80
+ max-width: 100%;
81
+ margin: 0 auto;
82
+ }
83
+
84
+ /* App description styling */
85
+ .app-description {
86
+ font-size: 1rem;
87
+ color: var(--md-default-fg-color--light);
88
+ margin-bottom: 1.5rem;
89
+ padding: 0.5rem 0;
90
+ border-bottom: 1px solid var(--md-default-fg-color--lightest);
91
+ }
92
+
93
+ /* Model cards grid */
94
+ .model-cards {
95
+ display: grid;
96
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
97
+ gap: 1.5rem;
98
+ margin-bottom: 3rem;
99
+ }
100
+
101
+ /* Individual model card */
102
+ .model-card {
103
+ background: var(--md-default-bg-color);
104
+ border: 1px solid var(--md-default-fg-color--lightest);
105
+ border-radius: 8px;
106
+ padding: 1.5rem;
107
+ transition: all 0.3s ease;
108
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
109
+ position: relative;
110
+ overflow: hidden;
111
+ }
112
+
113
+ .model-card:hover {
114
+ transform: translateY(-4px);
115
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
116
+ border-color: var(--md-primary-fg-color);
117
+ }
118
+
119
+ .model-card::before {
120
+ content: '';
121
+ position: absolute;
122
+ top: 0;
123
+ left: 0;
124
+ right: 0;
125
+ height: 4px;
126
+ background: linear-gradient(90deg, var(--md-primary-fg-color), var(--md-accent-fg-color));
127
+ opacity: 0;
128
+ transition: opacity 0.3s ease;
129
+ }
130
+
131
+ .model-card:hover::before {
132
+ opacity: 1;
133
+ }
134
+
135
+ /* Model header */
136
+ .model-header {
137
+ display: flex;
138
+ justify-content: space-between;
139
+ align-items: center;
140
+ margin-bottom: 0.5rem;
141
+ }
142
+
143
+ .model-header h3 {
144
+ margin: 0;
145
+ font-size: 1.25rem;
146
+ font-weight: 600;
147
+ }
148
+
149
+ .model-header h3 a {
150
+ color: var(--md-default-fg-color);
151
+ text-decoration: none;
152
+ transition: color 0.3s ease;
153
+ }
154
+
155
+ .model-header h3 a:hover {
156
+ color: var(--md-primary-fg-color);
157
+ }
158
+
159
+ /* Model badge */
160
+ .model-badge {
161
+ display: inline-block;
162
+ padding: 0.25rem 0.75rem;
163
+ background: var(--md-primary-fg-color);
164
+ color: var(--md-primary-bg-color);
165
+ border-radius: 20px;
166
+ font-size: 0.75rem;
167
+ font-weight: 600;
168
+ text-transform: uppercase;
169
+ letter-spacing: 0.5px;
170
+ }
171
+
172
+ /* Animation for cards appearing */
173
+ @keyframes fadeInUp {
174
+ from {
175
+ opacity: 0;
176
+ transform: translateY(20px);
177
+ }
178
+ to {
179
+ opacity: 1;
180
+ transform: translateY(0);
181
+ }
182
+ }
183
+
184
+ .model-card {
185
+ animation: fadeInUp 0.6s ease-out;
186
+ }
187
+
188
+ /* Stagger animation for multiple cards */
189
+ .model-card:nth-child(1) { animation-delay: 0.1s; }
190
+ .model-card:nth-child(2) { animation-delay: 0.2s; }
191
+ .model-card:nth-child(3) { animation-delay: 0.3s; }
192
+ .model-card:nth-child(4) { animation-delay: 0.4s; }
193
+ .model-card:nth-child(5) { animation-delay: 0.5s; }
194
+ .model-card:nth-child(6) { animation-delay: 0.6s; }
@@ -0,0 +1,209 @@
1
+ /* Filter Section - Fixed Layout */
2
+ .filter-section,
3
+ .filter-sidebar {
4
+ background: linear-gradient(135deg, #e0f2ff, #ffffff);
5
+ border: 1px solid var(--border-color);
6
+ border-radius: 16px;
7
+ padding: 24px;
8
+ margin-bottom: 32px;
9
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
10
+ transition: all 0.3s ease;
11
+ width: 100%;
12
+ max-width: 100%;
13
+ box-sizing: border-box; /* Prevents overflow */
14
+ position: relative; /* Ensures proper positioning */
15
+ z-index: 1; /* Prevents overlap with other elements */
16
+ }
17
+
18
+ .filter-sidebar.collapsed {
19
+ /* Add styles for collapsed state if needed */
20
+ overflow: hidden;
21
+ }
22
+
23
+ .filter-title {
24
+ font-size: 20px;
25
+ font-weight: 700;
26
+ color: var(--text-primary);
27
+ margin-bottom: 20px;
28
+ text-align: left;
29
+ display: flex;
30
+ align-items: center;
31
+ gap: 8px;
32
+ }
33
+
34
+ .filter-grid {
35
+ display: grid;
36
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
37
+ gap: 16px;
38
+ margin-bottom: 20px;
39
+ width: 100%;
40
+ }
41
+
42
+ .filter-group {
43
+ display: flex;
44
+ flex-direction: column;
45
+ gap: 6px;
46
+ min-width: 0; /* Prevents flex items from overflowing */
47
+ }
48
+
49
+ .filter-label {
50
+ font-size: 13px;
51
+ font-weight: 600;
52
+ color: var(--text-primary);
53
+ margin-bottom: 4px;
54
+ }
55
+
56
+ .filter-input,
57
+ .filter-select {
58
+ width: 100%;
59
+ max-width: 100%;
60
+ box-sizing: border-box;
61
+ padding: 10px 12px;
62
+ border: 1px solid var(--border-color);
63
+ border-radius: 8px;
64
+ font-size: 14px;
65
+ background: var(--bg-primary);
66
+ color: var(--text-primary);
67
+ transition: border 0.2s ease, box-shadow 0.2s ease;
68
+ appearance: none;
69
+ background-image: none;
70
+ min-height: 40px; /* Consistent height */
71
+ }
72
+
73
+ .filter-select {
74
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
75
+ background-position: right 10px center;
76
+ background-repeat: no-repeat;
77
+ background-size: 16px;
78
+ padding-right: 40px;
79
+ }
80
+
81
+ .filter-input:focus,
82
+ .filter-select:focus {
83
+ outline: none;
84
+ border-color: var(--accent-primary);
85
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
86
+ }
87
+
88
+ .filter-input:hover,
89
+ .filter-select:hover {
90
+ border-color: var(--accent-primary);
91
+ }
92
+
93
+ .filter-actions {
94
+ display: flex;
95
+ justify-content: center;
96
+ gap: 12px;
97
+ padding-top: 20px;
98
+ border-top: 1px solid var(--border-color);
99
+ margin-top: 20px;
100
+ }
101
+
102
+ .filter-apply,
103
+ .filter-clear {
104
+ padding: 10px 20px;
105
+ border-radius: 8px;
106
+ font-size: 14px;
107
+ font-weight: 600;
108
+ cursor: pointer;
109
+ transition: all 0.2s ease;
110
+ min-width: 100px;
111
+ border: none;
112
+ display: inline-flex;
113
+ align-items: center;
114
+ justify-content: center;
115
+ }
116
+
117
+ .filter-apply {
118
+ background: var(--accent-primary);
119
+ color: #fff;
120
+ }
121
+
122
+ .filter-clear {
123
+ background: transparent;
124
+ color: var(--text-secondary);
125
+ border: 1px solid var(--border-color);
126
+ }
127
+
128
+ .filter-apply:hover {
129
+ background: var(--accent-secondary);
130
+ transform: translateY(-1px);
131
+ }
132
+
133
+ .filter-clear:hover {
134
+ border-color: var(--accent-primary);
135
+ color: var(--text-primary);
136
+ background: rgba(59, 130, 246, 0.05);
137
+ }
138
+
139
+ .filter-apply:active,
140
+ .filter-clear:active {
141
+ transform: translateY(0);
142
+ }
143
+
144
+ .filter-results {
145
+ margin-top: 16px;
146
+ font-size: 13px;
147
+ text-align: center;
148
+ color: var(--text-secondary);
149
+ font-style: italic;
150
+ }
151
+
152
+ /* Main content layout to prevent overlap */
153
+ .main-content {
154
+ width: 100%;
155
+ max-width: 1200px;
156
+ margin: 0 auto;
157
+ padding: 0 16px;
158
+ }
159
+
160
+ /* Responsive adjustments */
161
+ @media (max-width: 768px) {
162
+ .filter-grid {
163
+ grid-template-columns: 1fr;
164
+ gap: 12px;
165
+ }
166
+
167
+ .filter-actions {
168
+ flex-direction: column;
169
+ gap: 8px;
170
+ }
171
+
172
+ .filter-apply,
173
+ .filter-clear {
174
+ width: 100%;
175
+ }
176
+
177
+ .filter-sidebar {
178
+ padding: 16px;
179
+ margin-bottom: 24px;
180
+ }
181
+ }
182
+
183
+ @media (max-width: 480px) {
184
+ .filter-title {
185
+ font-size: 18px;
186
+ }
187
+
188
+ .filter-input,
189
+ .filter-select {
190
+ font-size: 16px; /* Prevents zoom on iOS */
191
+ }
192
+ }
193
+
194
+ /* Ensure proper spacing with endpoint cards */
195
+ .endpoints-grid {
196
+ margin-top: 24px;
197
+ clear: both;
198
+ }
199
+
200
+ /* Fix any potential z-index issues */
201
+ .filter-sidebar {
202
+ position: relative;
203
+ z-index: 10;
204
+ }
205
+
206
+ .endpoint-card {
207
+ position: relative;
208
+ z-index: 1;
209
+ }
@@ -0,0 +1,44 @@
1
+ /* ===== CONTAINER FIXES ===== */
2
+ .container,
3
+ .content-wrapper {
4
+ width: 100%;
5
+ max-width: 100%;
6
+ overflow-x: hidden;
7
+ }
8
+
9
+ /* ===== FILTER VISIBILITY FIXES ===== */
10
+ .filter-section {
11
+ position: relative;
12
+ z-index: 10;
13
+ }
14
+
15
+ .filter-toggle {
16
+ white-space: nowrap;
17
+ overflow: hidden;
18
+ text-overflow: ellipsis;
19
+ }
20
+
21
+ /* Custom dropdown arrow for better cross-browser support */
22
+ .filter-select {
23
+ cursor: pointer;
24
+ }
25
+
26
+ .filter-select::-ms-expand {
27
+ display: none;
28
+ }
29
+
30
+ /* Ensure proper stacking context */
31
+ .main-content {
32
+ position: relative;
33
+ z-index: 1;
34
+ }
35
+
36
+ /* Fix for potential parent container issues */
37
+ html {
38
+ box-sizing: border-box;
39
+ }
40
+
41
+ html, body {
42
+ width: 100%;
43
+ overflow-x: hidden;
44
+ }
@@ -0,0 +1,31 @@
1
+ /* ===== LAYOUT ===== */
2
+ .main-content {
3
+ max-width: 1400px;
4
+ margin: 0 auto;
5
+ padding: 20px 20px 40px;
6
+ width: 100%;
7
+ box-sizing: border-box;
8
+ }
9
+
10
+ .page-header {
11
+ text-align: center;
12
+ margin-bottom: 48px;
13
+ }
14
+
15
+ .page-title {
16
+ font-size: 42px;
17
+ font-weight: 800;
18
+ color: var(--text-primary);
19
+ margin: 0 0 16px 0;
20
+ background: linear-gradient(135deg, var(--accent-primary), #9333ea);
21
+ -webkit-background-clip: text;
22
+ -webkit-text-fill-color: transparent;
23
+ background-clip: text;
24
+ }
25
+
26
+ .page-subtitle {
27
+ font-size: 18px;
28
+ color: var(--text-secondary);
29
+ margin: 0 auto;
30
+ max-width: 600px;
31
+ }
@@ -0,0 +1,35 @@
1
+ /* ===== LOADING STATES ===== */
2
+ .loading-overlay {
3
+ position: fixed;
4
+ top: 0;
5
+ left: 0;
6
+ right: 0;
7
+ bottom: 0;
8
+ background: rgba(0, 0, 0, 0.1);
9
+ display: flex;
10
+ align-items: center;
11
+ justify-content: center;
12
+ z-index: 9999;
13
+ opacity: 0;
14
+ pointer-events: none;
15
+ transition: opacity 0.3s ease;
16
+ }
17
+
18
+ .loading-overlay.show {
19
+ opacity: 1;
20
+ pointer-events: all;
21
+ }
22
+
23
+ .loading-spinner {
24
+ width: 40px;
25
+ height: 40px;
26
+ border: 3px solid var(--border-color);
27
+ border-top: 3px solid var(--accent-primary);
28
+ border-radius: 50%;
29
+ animation: spin 1s linear infinite;
30
+ }
31
+
32
+ @keyframes spin {
33
+ 0% { transform: rotate(0deg); }
34
+ 100% { transform: rotate(360deg); }
35
+ }