jekyll-theme-resume 1.3.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.
- checksums.yaml +7 -0
- data/403.html +6 -0
- data/404.html +6 -0
- data/500.html +6 -0
- data/CHANGELOG.md +498 -0
- data/CODE_OF_CONDUCT.md +92 -0
- data/LICENSE.txt +22 -0
- data/README.md +184 -0
- data/SECURITY.md +30 -0
- data/_config.sample.yml +329 -0
- data/_data/locales/ar.yml +85 -0
- data/_data/locales/de.yml +86 -0
- data/_data/locales/en.yml +84 -0
- data/_data/locales/es.yml +86 -0
- data/_data/locales/fr.yml +86 -0
- data/_data/locales/ur.yml +86 -0
- data/_data/social_networks.yml +83 -0
- data/_includes/analytics-body.html +12 -0
- data/_includes/analytics-head.html +36 -0
- data/_includes/avatar.html +84 -0
- data/_includes/dark-mode-toggle.html +202 -0
- data/_includes/data-loader.html +42 -0
- data/_includes/date-formatter.html +63 -0
- data/_includes/grouped-item-list.html +53 -0
- data/_includes/hreflang.html +58 -0
- data/_includes/language-switcher.html +72 -0
- data/_includes/print-social-links.html +23 -0
- data/_includes/resume-section.html +547 -0
- data/_includes/safe-url.html +21 -0
- data/_includes/shared-head.html +51 -0
- data/_includes/social-links.html +54 -0
- data/_includes/vendors/svg-icons/ATTRIBUTION.md +34 -0
- data/_includes/vendors/svg-icons/dev.svg +3 -0
- data/_includes/vendors/svg-icons/dribbble-symbol.svg +3 -0
- data/_includes/vendors/svg-icons/envelope.svg +4 -0
- data/_includes/vendors/svg-icons/facebook.svg +3 -0
- data/_includes/vendors/svg-icons/flickr.svg +4 -0
- data/_includes/vendors/svg-icons/github.svg +3 -0
- data/_includes/vendors/svg-icons/globe-1.svg +3 -0
- data/_includes/vendors/svg-icons/instagram.svg +4 -0
- data/_includes/vendors/svg-icons/linkedin.svg +3 -0
- data/_includes/vendors/svg-icons/medium.svg +3 -0
- data/_includes/vendors/svg-icons/phone.svg +13 -0
- data/_includes/vendors/svg-icons/pinterest.svg +3 -0
- data/_includes/vendors/svg-icons/postcard.svg +14 -0
- data/_includes/vendors/svg-icons/telegram.svg +3 -0
- data/_includes/vendors/svg-icons/whatsapp.svg +3 -0
- data/_includes/vendors/svg-icons/x.svg +3 -0
- data/_includes/vendors/svg-icons/youtube.svg +3 -0
- data/_layouts/default.html +65 -0
- data/_layouts/error.html +138 -0
- data/_layouts/profile.html +123 -0
- data/_layouts/resume.html +238 -0
- data/_plugins/error_pages_generator.rb +71 -0
- data/_plugins/json_resume_generator.rb +79 -0
- data/_plugins/resume_pages_generator.rb +71 -0
- data/_plugins/resume_validator.rb +40 -0
- data/_sass/_all-pages.scss +335 -0
- data/_sass/_base.scss +130 -0
- data/_sass/_dark-mode.scss +387 -0
- data/_sass/_layout.scss +116 -0
- data/_sass/_mixins.scss +136 -0
- data/_sass/_normalize.scss +379 -0
- data/_sass/_profile-page.scss +60 -0
- data/_sass/_resume-ltr.scss +436 -0
- data/_sass/_resume-rtl.scss +91 -0
- data/_sass/_variables.scss +45 -0
- data/assets/css/cv-ltr.scss +31 -0
- data/assets/css/cv-rtl.scss +36 -0
- data/assets/css/main.scss +8 -0
- data/assets/css/profile.scss +9 -0
- data/assets/favicon/resume/about.txt +6 -0
- data/assets/favicon/resume/android-chrome-192x192.png +0 -0
- data/assets/favicon/resume/android-chrome-512x512.png +0 -0
- data/assets/favicon/resume/apple-touch-icon.png +0 -0
- data/assets/favicon/resume/favicon-16x16.png +0 -0
- data/assets/favicon/resume/favicon-32x32.png +0 -0
- data/assets/favicon/resume/favicon.ico +0 -0
- data/assets/favicon/resume/site.webmanifest +1 -0
- data/bin/validate-resume +89 -0
- data/bin/verify +27 -0
- data/docs/README.md +89 -0
- data/docs/explanation/accessibility-decisions.md +27 -0
- data/docs/explanation/architecture.md +44 -0
- data/docs/explanation/dark-mode-approach.md +25 -0
- data/docs/explanation/data-driven-model.md +25 -0
- data/docs/explanation/multilingual-and-rtl-design.md +40 -0
- data/docs/how-to/add-a-language.md +57 -0
- data/docs/how-to/add-a-section.md +35 -0
- data/docs/how-to/add-a-social-platform.md +32 -0
- data/docs/how-to/add-a-test.md +34 -0
- data/docs/how-to/create-a-custom-layout.md +64 -0
- data/docs/how-to/enable-dark-mode.md +43 -0
- data/docs/how-to/link-translations-with-hreflang.md +25 -0
- data/docs/how-to/migrate-v0.9-to-v1.0.md +46 -0
- data/docs/how-to/override-locale-strings.md +51 -0
- data/docs/how-to/override-sass-partials.md +26 -0
- data/docs/how-to/proof-built-html.md +22 -0
- data/docs/how-to/publish-json-resume.md +38 -0
- data/docs/how-to/show-language-proficiency-in-header.md +13 -0
- data/docs/how-to/switch-resume-versions.md +42 -0
- data/docs/how-to/troubleshoot-builds.md +39 -0
- data/docs/how-to/validate-in-ci.md +38 -0
- data/docs/how-to/verify-accessibility.md +28 -0
- data/docs/reference/accessibility-coverage.md +39 -0
- data/docs/reference/config.md +378 -0
- data/docs/reference/data-schemas.md +529 -0
- data/docs/reference/glossary.md +39 -0
- data/docs/reference/includes.md +197 -0
- data/docs/reference/json-resume-fields.md +148 -0
- data/docs/reference/layouts.md +144 -0
- data/docs/reference/locale-keys.md +76 -0
- data/docs/reference/repository-map.md +83 -0
- data/docs/reference/sass-tokens.md +279 -0
- data/docs/reference/testing-suites.md +62 -0
- data/docs/reference/validator-cli.md +203 -0
- data/docs/tutorials/getting-started.md +173 -0
- data/lib/jekyll-theme-resume/json_resume_exporter.rb +334 -0
- data/lib/jekyll-theme-resume/resume_validator.rb +853 -0
- data/lib/jekyll-theme-resume/schemas/LICENSE.md +21 -0
- data/lib/jekyll-theme-resume/schemas/json_resume_v1.0.0.json +500 -0
- data/lib/jekyll-theme-resume.rb +21 -0
- metadata +371 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
// ==========================================================================
|
|
2
|
+
// Universal Shared Styles (_all-pages.scss)
|
|
3
|
+
// jekyll-theme-resume
|
|
4
|
+
//
|
|
5
|
+
// Shared styling across default, resume, profile, and error layouts.
|
|
6
|
+
// Covers SVG icon link mechanics, WCAG screen-reader utilities, markdown
|
|
7
|
+
// typography for .main-content (with CSS logical properties for bilingual parity),
|
|
8
|
+
// universal footer presentation, and the HTTP status error page suite (404, 403, 500).
|
|
9
|
+
// ==========================================================================
|
|
10
|
+
|
|
11
|
+
/* SVG Icons & Links */
|
|
12
|
+
// Anchor wrappers around inline SVG icons:
|
|
13
|
+
// 1. display: inline-flex + vertical-align: middle aligns icons with surrounding text.
|
|
14
|
+
// 2. line-height: 0 eliminates standard text descender space beneath the SVG.
|
|
15
|
+
// 3. text-decoration: none !important suppresses browser link underlines on vector images.
|
|
16
|
+
.icon-link,
|
|
17
|
+
.social-links a,
|
|
18
|
+
.social-links li a {
|
|
19
|
+
color: var(--icon-fill-muted, #555);
|
|
20
|
+
text-decoration: none !important;
|
|
21
|
+
line-height: 0;
|
|
22
|
+
display: inline-flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
justify-content: center;
|
|
25
|
+
vertical-align: middle;
|
|
26
|
+
|
|
27
|
+
&:hover,
|
|
28
|
+
&:focus {
|
|
29
|
+
color: var(--accent-hover, #307EA9);
|
|
30
|
+
text-decoration: none !important;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.icon-link:hover,
|
|
35
|
+
.icon-link:focus,
|
|
36
|
+
.social-links a:hover,
|
|
37
|
+
.social-links a:focus,
|
|
38
|
+
.social-links li a:hover,
|
|
39
|
+
.social-links li a:focus {
|
|
40
|
+
text-decoration: none !important;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Universal SVG sizing (30px width) with smooth 0.2s fill transition.
|
|
44
|
+
.svg-icon,
|
|
45
|
+
.icon-link svg,
|
|
46
|
+
.social-links svg,
|
|
47
|
+
.page-footer svg {
|
|
48
|
+
fill: var(--icon-fill-muted, #555);
|
|
49
|
+
width: 30px;
|
|
50
|
+
transition: fill 0.2s ease;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Path fill inheritance: ensures multi-path vector graphics inherit the parent SVG fill.
|
|
54
|
+
.social-links svg path,
|
|
55
|
+
.icon-link svg path,
|
|
56
|
+
.svg-icon path,
|
|
57
|
+
.page-footer svg path {
|
|
58
|
+
fill: inherit;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Interactive hover and focus states for SVG icons.
|
|
62
|
+
.svg-icon:hover,
|
|
63
|
+
.svg-icon:focus,
|
|
64
|
+
.icon-link:hover svg,
|
|
65
|
+
.icon-link:focus svg,
|
|
66
|
+
.social-links a:hover svg,
|
|
67
|
+
.social-links a:focus svg,
|
|
68
|
+
.page-footer a:hover svg,
|
|
69
|
+
.page-footer a:focus svg {
|
|
70
|
+
fill: var(--icon-fill-dark, #000);
|
|
71
|
+
|
|
72
|
+
path {
|
|
73
|
+
fill: inherit;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// .sr-only lives in _base.scss (loaded earlier in every entrypoint) - not redeclared here.
|
|
78
|
+
|
|
79
|
+
/* Following only apply to the resume header contact info icons */
|
|
80
|
+
// Scoped 20px sizing for inline contact details (email, phone, location) in resume headers.
|
|
81
|
+
.header-contact-info>p>svg {
|
|
82
|
+
width: 20px;
|
|
83
|
+
fill: var(--icon-fill-dark, #000);
|
|
84
|
+
vertical-align: middle;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
/* Footer */
|
|
89
|
+
// Universal page footer shared between default markdown pages and standalone layouts.
|
|
90
|
+
footer,
|
|
91
|
+
.page-footer {
|
|
92
|
+
padding-top: 1.5rem;
|
|
93
|
+
text-align: center;
|
|
94
|
+
margin-bottom: 3rem;
|
|
95
|
+
|
|
96
|
+
.footer-line,
|
|
97
|
+
.copyright {
|
|
98
|
+
margin: 0;
|
|
99
|
+
font-size: .875rem;
|
|
100
|
+
color: var(--text-muted, #999);
|
|
101
|
+
|
|
102
|
+
>a {
|
|
103
|
+
font-weight: 700;
|
|
104
|
+
color: var(--link-color, #333);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* Main Content Container for Default Layout */
|
|
110
|
+
// Markdown content container used in _layouts/default.html for generic pages and documentation.
|
|
111
|
+
.main-content {
|
|
112
|
+
width: 100%;
|
|
113
|
+
max-width: 800px;
|
|
114
|
+
margin: 0 auto;
|
|
115
|
+
padding: 2rem 1.5rem;
|
|
116
|
+
box-sizing: border-box;
|
|
117
|
+
|
|
118
|
+
// Headings: semantic colors and proportional top/bottom margins.
|
|
119
|
+
h1, h2, h3, h4, h5, h6 {
|
|
120
|
+
color: var(--text-color, #333);
|
|
121
|
+
font-weight: 700;
|
|
122
|
+
line-height: 1.3;
|
|
123
|
+
margin-top: 1.5em;
|
|
124
|
+
margin-bottom: 0.5em;
|
|
125
|
+
|
|
126
|
+
// Suppresses excess top margin on the document's opening heading.
|
|
127
|
+
&:first-child {
|
|
128
|
+
margin-top: 0;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
h1 { font-size: 2.25rem; }
|
|
133
|
+
h2 { font-size: 1.75rem; border-bottom: 1px solid var(--border-color, #c7c7c7); padding-bottom: 0.3em; }
|
|
134
|
+
h3 { font-size: 1.375rem; }
|
|
135
|
+
h4 { font-size: 1.125rem; }
|
|
136
|
+
|
|
137
|
+
p {
|
|
138
|
+
color: var(--text-color, #333);
|
|
139
|
+
line-height: 1.7; // Enhanced line-height for reading comfort
|
|
140
|
+
margin-top: 0;
|
|
141
|
+
margin-bottom: 1.25rem;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Hyperlinks: scoped with :not() so action buttons do not inherit underlines.
|
|
145
|
+
// Uses text-underline-offset for clean non-color link identification (WCAG 2.2).
|
|
146
|
+
a:not(.cv-button):not(.error-btn) {
|
|
147
|
+
color: var(--accent-color, #3064a9);
|
|
148
|
+
text-decoration: underline;
|
|
149
|
+
text-underline-offset: 2px;
|
|
150
|
+
transition: color 0.2s ease;
|
|
151
|
+
|
|
152
|
+
&:hover {
|
|
153
|
+
color: var(--accent-hover, #307EA9);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Blockquotes: uses CSS Logical Property border-inline-start to automatically mirror
|
|
158
|
+
// the 4px accent border to the left side in LTR and to the right side in RTL.
|
|
159
|
+
blockquote {
|
|
160
|
+
margin: 1.5rem 0;
|
|
161
|
+
padding: 0.75rem 1.25rem;
|
|
162
|
+
border-inline-start: 4px solid var(--accent-color, #3064a9);
|
|
163
|
+
background-color: var(--card-bg, #efefef);
|
|
164
|
+
color: var(--text-light, #646464);
|
|
165
|
+
border-radius: 0 4px 4px 0;
|
|
166
|
+
|
|
167
|
+
p:last-child {
|
|
168
|
+
margin-bottom: 0;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Unordered and ordered lists: uses padding-inline-start for bidirectional alignment parity.
|
|
173
|
+
ul, ol {
|
|
174
|
+
color: var(--text-color, #333);
|
|
175
|
+
padding-inline-start: 1.75rem;
|
|
176
|
+
margin-bottom: 1.25rem;
|
|
177
|
+
line-height: 1.6;
|
|
178
|
+
|
|
179
|
+
li {
|
|
180
|
+
margin-bottom: 0.35rem;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
hr {
|
|
185
|
+
border: 0;
|
|
186
|
+
height: 1px;
|
|
187
|
+
background-color: var(--border-color, #c7c7c7);
|
|
188
|
+
margin: 2rem 0;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Inline code snippets: dark-mode-aware background token.
|
|
192
|
+
code, kbd, samp {
|
|
193
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
194
|
+
font-size: 0.875em;
|
|
195
|
+
background-color: var(--card-bg, #efefef);
|
|
196
|
+
color: var(--text-color, #333);
|
|
197
|
+
padding: 0.2em 0.4em;
|
|
198
|
+
border-radius: 4px;
|
|
199
|
+
border: 1px solid var(--border-color, #c7c7c7);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Preformatted code blocks: horizontal scroll containment and theme borders.
|
|
203
|
+
pre {
|
|
204
|
+
background-color: var(--card-bg, #efefef);
|
|
205
|
+
border: 1px solid var(--border-color, #c7c7c7);
|
|
206
|
+
border-radius: 6px;
|
|
207
|
+
padding: 1rem 1.25rem;
|
|
208
|
+
overflow-x: auto;
|
|
209
|
+
margin: 1.5rem 0;
|
|
210
|
+
|
|
211
|
+
code {
|
|
212
|
+
background-color: transparent;
|
|
213
|
+
border: 0;
|
|
214
|
+
padding: 0;
|
|
215
|
+
font-size: 0.9em;
|
|
216
|
+
color: var(--text-color, #333);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Markdown data tables: full width, zebra-striped alternating rows.
|
|
221
|
+
table {
|
|
222
|
+
width: 100%;
|
|
223
|
+
border-collapse: collapse;
|
|
224
|
+
margin: 1.5rem 0;
|
|
225
|
+
color: var(--text-color, #333);
|
|
226
|
+
|
|
227
|
+
th, td {
|
|
228
|
+
border: 1px solid var(--border-color, #c7c7c7);
|
|
229
|
+
padding: 0.75rem 1rem;
|
|
230
|
+
text-align: start;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
th {
|
|
234
|
+
background-color: var(--card-bg, #efefef);
|
|
235
|
+
font-weight: 700;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
tr:nth-child(even) {
|
|
239
|
+
background-color: rgba(127, 127, 127, 0.05);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/* Error / 404 Page Styles */
|
|
245
|
+
// Presentation layer for _layouts/error.html (consumed by 404.html, 403.html, 500.html).
|
|
246
|
+
.error-page {
|
|
247
|
+
text-align: center;
|
|
248
|
+
padding: 3rem 1rem;
|
|
249
|
+
max-width: 650px;
|
|
250
|
+
margin: 0 auto;
|
|
251
|
+
|
|
252
|
+
// Prominent status code headline (e.g. "404"): fluid clamp scaling up to 7rem.
|
|
253
|
+
.error-code {
|
|
254
|
+
font-size: clamp(4rem, 12vw, 7rem);
|
|
255
|
+
font-weight: 900;
|
|
256
|
+
letter-spacing: -0.05em;
|
|
257
|
+
line-height: 1;
|
|
258
|
+
color: var(--accent-color, #3064a9);
|
|
259
|
+
margin: 0 0 1rem;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.error-bilingual-group {
|
|
263
|
+
margin: 2rem 0;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.error-lang-block {
|
|
267
|
+
margin: 1.5rem 0;
|
|
268
|
+
|
|
269
|
+
// RTL block in error suite: locale-driven font (Cairo for Arabic, Noto Nastaliq Urdu
|
|
270
|
+
// for Urdu, etc.) via --font-locale, matching every other component. Gated on the
|
|
271
|
+
// real dir="rtl" attribute error.html renders, not a class that's never applied.
|
|
272
|
+
&[dir="rtl"] {
|
|
273
|
+
.error-title,
|
|
274
|
+
.error-description {
|
|
275
|
+
font-family: var(--font-locale, 'Cairo', 'Noto Naskh Arabic', Tahoma, Arial, sans-serif);
|
|
276
|
+
line-height: 1.6;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.error-title {
|
|
282
|
+
font-size: 1.5rem;
|
|
283
|
+
font-weight: 700;
|
|
284
|
+
color: var(--text-color, #333);
|
|
285
|
+
margin: 0 0 0.5rem;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.error-description {
|
|
289
|
+
color: var(--text-light, #646464);
|
|
290
|
+
font-size: 1rem;
|
|
291
|
+
line-height: 1.6;
|
|
292
|
+
margin: 0;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Recovery action buttons (e.g. Return Home, View English CV, View Arabic CV).
|
|
296
|
+
.error-actions {
|
|
297
|
+
display: flex;
|
|
298
|
+
flex-wrap: wrap;
|
|
299
|
+
justify-content: center;
|
|
300
|
+
gap: 0.75rem;
|
|
301
|
+
margin-top: 2.5rem;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.error-btn {
|
|
305
|
+
display: inline-flex;
|
|
306
|
+
align-items: center;
|
|
307
|
+
justify-content: center;
|
|
308
|
+
padding: 0.75rem 1.5rem;
|
|
309
|
+
border-radius: 4px;
|
|
310
|
+
font-size: 1rem;
|
|
311
|
+
font-weight: 500;
|
|
312
|
+
text-decoration: none !important;
|
|
313
|
+
background-color: var(--button-bg, #efefef);
|
|
314
|
+
color: var(--button-text, #333);
|
|
315
|
+
border: 1px solid var(--border-color, #c7c7c7);
|
|
316
|
+
transition: background-color 0.2s ease, color 0.2s ease, transform 0.15s ease;
|
|
317
|
+
|
|
318
|
+
&:hover {
|
|
319
|
+
background-color: var(--button-hover-bg, #333);
|
|
320
|
+
color: var(--button-hover-text, #fff);
|
|
321
|
+
transform: translateY(-1px);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
&.primary {
|
|
325
|
+
background-color: var(--accent-color, #3064a9);
|
|
326
|
+
color: var(--accent-contrast-text, #fff);
|
|
327
|
+
border-color: var(--accent-color, #3064a9);
|
|
328
|
+
|
|
329
|
+
&:hover {
|
|
330
|
+
background-color: var(--accent-hover, #307EA9);
|
|
331
|
+
color: var(--accent-contrast-text, #fff);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
data/_sass/_base.scss
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// Base styles
|
|
2
|
+
// ---------------------------------------/
|
|
3
|
+
// jekyll-theme-resume
|
|
4
|
+
// Baseline CSS resets, universal border-box box model, root theme background binding,
|
|
5
|
+
// default serif typography, micro-clearfix container classes, custom text selection,
|
|
6
|
+
// and accessible screen-reader (.sr-only) utilities.
|
|
7
|
+
// ---------------------------------------/
|
|
8
|
+
|
|
9
|
+
@use "mixins";
|
|
10
|
+
@use "variables";
|
|
11
|
+
|
|
12
|
+
// Universal box model reset: ensures padding and borders are included in element total width/height.
|
|
13
|
+
* {
|
|
14
|
+
-webkit-box-sizing: border-box;
|
|
15
|
+
-moz-box-sizing: border-box;
|
|
16
|
+
box-sizing: border-box;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Dynamic background color bound to theme CSS variable token with SCSS fallback.
|
|
20
|
+
html {
|
|
21
|
+
background: var(--bg-color, variables.$white);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Baseline body typography: Lora serif, 16px font size, 1.5 line height.
|
|
25
|
+
body {
|
|
26
|
+
@include mixins.serif;
|
|
27
|
+
color: var(--text-color, variables.$text_color);
|
|
28
|
+
font-size: 16px;
|
|
29
|
+
line-height: 1.5;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Centered content wrapper with 800px max width and clearfix.
|
|
33
|
+
.wrapper:before,
|
|
34
|
+
.wrapper:after {
|
|
35
|
+
content: "";
|
|
36
|
+
display: table;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.wrapper:after {
|
|
40
|
+
clear: both;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.wrapper {
|
|
44
|
+
max-width: 800px;
|
|
45
|
+
padding: 0 24px;
|
|
46
|
+
margin: 0 auto;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Micro-clearfix helper
|
|
50
|
+
.group:before,
|
|
51
|
+
.group:after {
|
|
52
|
+
content: "";
|
|
53
|
+
display: table;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.group:after {
|
|
57
|
+
clear: both;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Custom text selection styling using theme tokens.
|
|
61
|
+
::-moz-selection {
|
|
62
|
+
background: var(--selection-bg, rgba(51, 51, 51, .8));
|
|
63
|
+
color: var(--selection-color, #fff);
|
|
64
|
+
text-shadow: none;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
::selection {
|
|
68
|
+
background: var(--selection-bg, rgba(51, 51, 51, .8));
|
|
69
|
+
color: var(--selection-color, #fff);
|
|
70
|
+
text-shadow: none;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Visually hidden utility for screen readers (WCAG 2.1 AA) */
|
|
74
|
+
// Clips element into a 1x1 pixel space out of flow to keep text accessible to assistive technology.
|
|
75
|
+
.sr-only {
|
|
76
|
+
position: absolute;
|
|
77
|
+
width: 1px;
|
|
78
|
+
height: 1px;
|
|
79
|
+
padding: 0;
|
|
80
|
+
margin: -1px;
|
|
81
|
+
overflow: hidden;
|
|
82
|
+
clip: rect(0, 0, 0, 0);
|
|
83
|
+
white-space: nowrap;
|
|
84
|
+
border-width: 0;
|
|
85
|
+
text-decoration: none !important;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* Accessible Skip-to-Content Link (WCAG 2.4.1 Bypass Blocks) */
|
|
89
|
+
.skip-link {
|
|
90
|
+
position: absolute;
|
|
91
|
+
top: -100px;
|
|
92
|
+
left: 1rem;
|
|
93
|
+
z-index: 9999;
|
|
94
|
+
padding: 0.5rem 1rem;
|
|
95
|
+
background: var(--accent-color, #3064a9);
|
|
96
|
+
color: var(--accent-contrast-text, #ffffff) !important;
|
|
97
|
+
font-family: var(--font-en, "Open Sans", -apple-system, BlinkMacSystemFont, sans-serif);
|
|
98
|
+
font-weight: 700;
|
|
99
|
+
font-size: 0.875rem;
|
|
100
|
+
border-radius: 4px;
|
|
101
|
+
text-decoration: none !important;
|
|
102
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
|
103
|
+
transition: top 0.2s ease;
|
|
104
|
+
|
|
105
|
+
&:focus,
|
|
106
|
+
&:focus-visible {
|
|
107
|
+
top: 1rem;
|
|
108
|
+
outline: 2px solid var(--accent-contrast-text, #ffffff);
|
|
109
|
+
outline-offset: 2px;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
html[dir="rtl"] .skip-link {
|
|
114
|
+
left: auto;
|
|
115
|
+
right: 1rem;
|
|
116
|
+
font-family: var(--font-locale, 'Cairo', 'Noto Naskh Arabic', Tahoma, sans-serif);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* Universal Accessible Focus Indicators (WCAG 2.4.7 Focus Visible) */
|
|
120
|
+
:focus-visible {
|
|
121
|
+
outline: 2px solid var(--accent-color, #3064a9);
|
|
122
|
+
outline-offset: 2px;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* Suppress focus outline on programmatic focus target */
|
|
126
|
+
main:focus,
|
|
127
|
+
.resume-main-content:focus {
|
|
128
|
+
outline: none;
|
|
129
|
+
}
|
|
130
|
+
|