bilingual-jekyll-resume-theme 1.0.0 → 1.0.2

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 bilingual-jekyll-resume-theme might be problematic. Click here for more details.

Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/README.md +8 -8
  4. data/{docs/_data/_config.sample.yml → _config.sample.yml} +5 -0
  5. data/_includes/language-switcher.html +56 -45
  6. data/_sass/_dark-mode.scss +0 -8
  7. data/_sass/_layout.scss +53 -14
  8. data/_sass/_resume-rtl.scss +0 -14
  9. data/bin/check-data-keys +5 -4
  10. data/bin/validate-resume +5 -4
  11. data/docs/ACCESSIBILITY_GUIDE.md +2 -2
  12. data/docs/COMPLETED_AUDIT.md +52 -45
  13. data/docs/CONFIG_GUIDE.md +2 -2
  14. data/docs/INCLUDES_GUIDE.md +2 -2
  15. data/docs/MULTILINGUAL_GUIDE.md +2 -2
  16. data/docs/PROJECT_OVERVIEW.md +7 -12
  17. data/docs/VALIDATION_GUIDE.md +10 -10
  18. data/lib/bilingual-jekyll-resume-theme/template_key_checker.rb +1 -1
  19. metadata +2 -88
  20. data/docs/_data/_config.demo.yml +0 -62
  21. data/docs/_data/ar/associations.yml +0 -36
  22. data/docs/_data/ar/certifications.yml +0 -51
  23. data/docs/_data/ar/courses.yml +0 -46
  24. data/docs/_data/ar/education.yml +0 -48
  25. data/docs/_data/ar/experience.yml +0 -55
  26. data/docs/_data/ar/header.yml +0 -7
  27. data/docs/_data/ar/interests.yml +0 -15
  28. data/docs/_data/ar/languages.yml +0 -29
  29. data/docs/_data/ar/links.yml +0 -24
  30. data/docs/_data/ar/projects.yml +0 -44
  31. data/docs/_data/ar/recognitions.yml +0 -42
  32. data/docs/_data/ar/skills.yml +0 -33
  33. data/docs/_data/ar/volunteering.yml +0 -44
  34. data/docs/_data/de/associations.yml +0 -36
  35. data/docs/_data/de/certifications.yml +0 -51
  36. data/docs/_data/de/courses.yml +0 -46
  37. data/docs/_data/de/education.yml +0 -48
  38. data/docs/_data/de/experience.yml +0 -55
  39. data/docs/_data/de/header.yml +0 -7
  40. data/docs/_data/de/interests.yml +0 -15
  41. data/docs/_data/de/languages.yml +0 -29
  42. data/docs/_data/de/links.yml +0 -24
  43. data/docs/_data/de/projects.yml +0 -44
  44. data/docs/_data/de/recognitions.yml +0 -42
  45. data/docs/_data/de/skills.yml +0 -33
  46. data/docs/_data/de/volunteering.yml +0 -44
  47. data/docs/_data/en/associations.yml +0 -36
  48. data/docs/_data/en/certifications.yml +0 -51
  49. data/docs/_data/en/courses.yml +0 -46
  50. data/docs/_data/en/education.yml +0 -48
  51. data/docs/_data/en/experience.yml +0 -55
  52. data/docs/_data/en/header.yml +0 -7
  53. data/docs/_data/en/interests.yml +0 -15
  54. data/docs/_data/en/languages.yml +0 -29
  55. data/docs/_data/en/links.yml +0 -24
  56. data/docs/_data/en/projects.yml +0 -44
  57. data/docs/_data/en/recognitions.yml +0 -42
  58. data/docs/_data/en/skills.yml +0 -33
  59. data/docs/_data/en/volunteering.yml +0 -44
  60. data/docs/_data/es/associations.yml +0 -36
  61. data/docs/_data/es/certifications.yml +0 -51
  62. data/docs/_data/es/courses.yml +0 -46
  63. data/docs/_data/es/education.yml +0 -48
  64. data/docs/_data/es/experience.yml +0 -55
  65. data/docs/_data/es/header.yml +0 -7
  66. data/docs/_data/es/interests.yml +0 -15
  67. data/docs/_data/es/languages.yml +0 -29
  68. data/docs/_data/es/links.yml +0 -24
  69. data/docs/_data/es/projects.yml +0 -44
  70. data/docs/_data/es/recognitions.yml +0 -42
  71. data/docs/_data/es/skills.yml +0 -33
  72. data/docs/_data/es/volunteering.yml +0 -44
  73. data/docs/_data/fr/associations.yml +0 -36
  74. data/docs/_data/fr/certifications.yml +0 -51
  75. data/docs/_data/fr/courses.yml +0 -46
  76. data/docs/_data/fr/education.yml +0 -48
  77. data/docs/_data/fr/experience.yml +0 -55
  78. data/docs/_data/fr/header.yml +0 -7
  79. data/docs/_data/fr/interests.yml +0 -15
  80. data/docs/_data/fr/languages.yml +0 -29
  81. data/docs/_data/fr/links.yml +0 -24
  82. data/docs/_data/fr/projects.yml +0 -44
  83. data/docs/_data/fr/recognitions.yml +0 -42
  84. data/docs/_data/fr/skills.yml +0 -33
  85. data/docs/_data/fr/volunteering.yml +0 -44
  86. data/docs/_data/ur/associations.yml +0 -36
  87. data/docs/_data/ur/certifications.yml +0 -51
  88. data/docs/_data/ur/courses.yml +0 -46
  89. data/docs/_data/ur/education.yml +0 -48
  90. data/docs/_data/ur/experience.yml +0 -55
  91. data/docs/_data/ur/header.yml +0 -7
  92. data/docs/_data/ur/interests.yml +0 -15
  93. data/docs/_data/ur/languages.yml +0 -29
  94. data/docs/_data/ur/links.yml +0 -24
  95. data/docs/_data/ur/projects.yml +0 -44
  96. data/docs/_data/ur/recognitions.yml +0 -42
  97. data/docs/_data/ur/skills.yml +0 -33
  98. data/docs/_data/ur/volunteering.yml +0 -44
  99. data/docs/assets/images/sherlock-holmes.jpg +0 -0
  100. data/docs/demo/ar.md +0 -5
  101. data/docs/demo/de.md +0 -5
  102. data/docs/demo/en.md +0 -5
  103. data/docs/demo/es.md +0 -5
  104. data/docs/demo/fr.md +0 -5
  105. data/docs/demo/ur.md +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00d980490bbad955afa894d864e4379a65a6f39f371d97a6db9d1808785ccaed
4
- data.tar.gz: b5c302a20cb5d88382151575fdb376b870969a4067d401da907cb2608f76ed3b
3
+ metadata.gz: b8eb8d16040a681b4a06c1d6eba60b957aee132434d038ce56b53415e74774f9
4
+ data.tar.gz: e7cb05ea3e65d241cab36fb5734062a13af1931e8cabe736ee749a108bf8655b
5
5
  SHA512:
6
- metadata.gz: 35046ae1202cd6e65a03d90313cb6dbf2ebecff360f4d1f4183a413b02b7b0da17df223b8066133ea90f3e44d5596dfb9ea2f6834ab981afa73d2165c53f480d
7
- data.tar.gz: ab8eb568a6ca00d51c040c2282efdfddb2dc3a29634f706e6b7d9cf96e08f49b069ceddb9c83d11f2582a5fcea9ca2d978674521aa866c9ed14281630c196135
6
+ metadata.gz: c13e0bd5ff9f935997e3977abe7e7e8b257ace6499f0fdc098f8955dc1999ffd36103518e5143c9d3357763f511cb9e5448e8fbb8cc41bc9c7be9ee9493cd432
7
+ data.tar.gz: '0069c903af37bd0e31ffa14ac4e5901d4f5c19d4ae3ffca36d41dd647196f931bd5d87593b65a158fd25017f75704cf7750f4803a6887e6a41665e6ed3ddda3a'
data/CHANGELOG.md CHANGED
@@ -4,6 +4,28 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+ ## [1.0.2] - 2026-09-25
8
+
9
+ ### Changed
10
+ * Update submodule to latest commit ([`f1779be`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/f1779be39697ccea22e9185b0bf57278e8a29707))
11
+
12
+ * Extract Sherlock Holmes demo to submodule and relocate sample config ([`bfd9e83`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/bfd9e8374753885fece3098cfd00f40606e5d26b))
13
+
14
+ * Archive completed features 3.2 and 3.3 and streamline audit log ([`39ae7f3`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/39ae7f346dff45828e74fafbfb445420b0d699dd))
15
+
16
+
17
+ ### Fixed
18
+ * Render language switcher on error pages ([`8e942f9`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/8e942f9fccc23a2c6e097938992c3f23f446bf97))
19
+
20
+ * Register theme gem in jekyll_plugins group; bump demo submodule ([`392c192`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/392c19209a42f629aba5e1c1e9a2a964832bf0a9))
21
+
22
+ ## [1.0.1] - 2026-09-24
23
+
24
+ ### Changed
25
+ * Replace language-switcher button row with a dropdown ([`f37c6f6`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/f37c6f6b410f5de4841ed36115db60408c805293))
26
+
27
+ * Pin language-switcher/dark-mode-toggle to fixed corners ([`305408c`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/305408c8885c194ad71d88831179b287d4a10ec3))
28
+
7
29
  ## [1.0.0] - 2026-09-24
8
30
 
9
31
  ### Added
@@ -350,6 +372,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
350
372
 
351
373
  * Initial commit (New Theme Template) ([`00af662`](https://github.com/kmutahar/bilingual-jekyll-resume-theme/commit/00af6628dfec7aefe0ef7d7083bf98c9713a5ffd))
352
374
 
375
+ [1.0.2]: https://github.com/kmutahar/bilingual-jekyll-resume-theme/compare/v1.0.1...v1.0.2
376
+ [1.0.1]: https://github.com/kmutahar/bilingual-jekyll-resume-theme/compare/v1.0.0...v1.0.1
353
377
  [1.0.0]: https://github.com/kmutahar/bilingual-jekyll-resume-theme/compare/v0.9.0...v1.0.0
354
378
  [0.9.0]: https://github.com/kmutahar/bilingual-jekyll-resume-theme/compare/v0.8.0...v0.9.0
355
379
  [0.8.0]: https://github.com/kmutahar/bilingual-jekyll-resume-theme/compare/v0.7.0...v0.8.0
data/README.md CHANGED
@@ -42,9 +42,9 @@ bundle install
42
42
 
43
43
  ### Basic Setup
44
44
 
45
- 1. **Copy sample configuration**: Use `docs/_data/_config.sample.yml` as a starting point for your `_config.yml`. Keep a `languages.<lang>` entry for each language you publish and delete the rest.
45
+ 1. **Copy sample configuration**: Use `_config.sample.yml` at the repository root as a starting point for your `_config.yml`. Keep a `languages.<lang>` entry for each language you publish and delete the rest.
46
46
 
47
- 2. **Copy sample data files**: Copy each language folder you need from `docs/_data/` (`en`, `ar`, `es`, `fr`, `de`, `ur`) to your site's `_data/`. Each holds 13 files, including `header.yml` for the intro paragraph.
47
+ 2. **Copy sample data files**: Copy each language folder you need from `demo/_data/` (`en`, `ar`, `es`, `fr`, `de`, `ur`) to your site's `_data/`. Each holds 13 files, including `header.yml` for the intro paragraph.
48
48
 
49
49
  3. **Create resume pages**: One page per language, all using the `resume` layout:
50
50
  ```yaml
@@ -130,7 +130,7 @@ See the [Configuration Guide](docs/CONFIG_GUIDE.md#3-languages) for every per-la
130
130
 
131
131
  ### Sample Files
132
132
 
133
- `docs/_data/{en,ar,es,fr,de,ur}/` hold a complete Sherlock Holmes demo resume in six languages, covering all 12 section types. Copy the folders you need to your site.
133
+ `demo/_data/{en,ar,es,fr,de,ur}/` hold a complete Sherlock Holmes demo resume in six languages, covering all 12 section types. Copy the folders you need to your site.
134
134
 
135
135
  ### Locales
136
136
 
@@ -144,18 +144,18 @@ To develop this theme locally:
144
144
  # Install dependencies
145
145
  bundle install
146
146
 
147
- # Serve the six-language demo (sample config + demo overlay pointing data_dir at docs/_data)
148
- bundle exec jekyll serve --config docs/_data/_config.sample.yml,docs/_data/_config.demo.yml
147
+ # Serve the six-language demo from the demo submodule
148
+ bundle exec jekyll serve --source demo --destination _site
149
149
 
150
150
  # Build static output
151
- bundle exec jekyll build --config docs/_data/_config.sample.yml,docs/_data/_config.demo.yml
151
+ bundle exec jekyll build --source demo --destination _site
152
152
 
153
153
  # Validate resume data schemas and parity (CLI or Rake)
154
- ./bin/validate-resume docs/_data
154
+ ./bin/validate-resume demo/_data
155
155
  bundle exec rake validate
156
156
 
157
157
  # Check that the theme's own templates only reference real data keys (CLI or Rake)
158
- ./bin/check-data-keys docs/_data
158
+ ./bin/check-data-keys demo/_data
159
159
  bundle exec rake check_data_keys
160
160
 
161
161
  # Validators, RuboCop, and tests together
@@ -274,6 +274,11 @@ analytics:
274
274
  # ==============================================================================
275
275
  # Required plugins (bundled as theme runtime dependencies)
276
276
  plugins:
277
+ # Belt-and-suspenders: Jekyll auto-requires gems listed here (site.gems) regardless
278
+ # of Bundler group, guarding against a Gemfile that forgets to put the theme gem in
279
+ # the `:jekyll_plugins` group — without that, the build-time resume validator and
280
+ # HTTP error page generator silently never run.
281
+ - bilingual-jekyll-resume-theme
277
282
  - jekyll-feed
278
283
  - jekyll-seo-tag
279
284
  - jekyll-sitemap
@@ -1,61 +1,72 @@
1
1
  {%- comment -%}
2
- Include: Reusable Multilingual Language Switcher Component (Feature 1.2)
3
- - Purpose: Floating list of links to every other configured language's resume.
4
- - Positioning: Fixed top-left (LTR layouts) / top-right (RTL layouts); mirrors the dark-mode toggle.
2
+ Include: Reusable Multilingual Language Switcher Component (Feature 1.2; dropdown redesign Feature 2.12)
3
+ - Purpose: Floating dropdown listing links to every other configured language's resume.
4
+ - Positioning: Fixed top-left viewport corner (see _sass/_layout.scss).
5
+ - Markup: Native <details>/<summary> disclosure — zero JavaScript, full keyboard support
6
+ (Enter/Space toggles the panel open and closed; browsers do not natively close it on Esc
7
+ or outside click, matching plain <details> behavior everywhere else). Scales to any number
8
+ of configured languages without growing a row of buttons.
5
9
  - Link Resolution (two-tier), per target language:
6
10
  1. Discovers the counterpart page via page.t_id + lang match (site.pages).
7
11
  2. Falls back to languages.<lang>.url from _config.yml.
8
- - Accessibility: Each link is labelled with its own locale's ui.language_name; the group
9
- wrapper is labelled with the current page's own locale ui.language_switcher string.
12
+ - Accessibility: The trigger's visible text is the current locale's ui.language_switcher
13
+ string. The panel is a <nav> landmark labelled with the same string. Each link is labelled
14
+ with its own locale's ui.language_name.
10
15
  - Print Safety: Decorated with class="no-print" — hidden on printed resume sheets.
11
16
  - Toggle: Disabled via site.resume_language_switcher: false in _config.yml.
12
17
  {%- endcomment -%}
13
18
 
14
- {% if site.resume_language_switcher != false and page.language_switcher != false and page.layout != 'error' %}
19
+ {% if site.resume_language_switcher != false and page.language_switcher != false %}
15
20
  {%- assign current_lang = page.lang | default: site.default_lang | default: 'en' -%}
16
21
  {%- assign current_locale = site.data.locales[current_lang] | default: site.data.locales[site.default_lang] -%}
17
22
 
18
- <div class="language-switcher no-print" role="navigation" aria-label="{{ current_locale.ui.language_switcher }}">
19
- {%- comment -%}
20
- IMPORTANT: {% include %} shares Liquid variable scope with its caller (resume.html),
21
- so every variable assigned in this loop body must use a switch_-prefixed name that
22
- cannot collide with resume.html's own lang/locale/lang_cfg - otherwise the last loop
23
- iteration's values would silently leak out and corrupt the rest of the caller's render.
24
- {%- endcomment -%}
25
- {% for switch_entry in site.languages %}
26
- {%- assign switch_lang = switch_entry[0] -%}
27
- {%- assign switch_lang_cfg = switch_entry[1] -%}
28
- {%- if switch_lang != current_lang -%}
29
- {%- assign switch_locale = site.data.locales[switch_lang] -%}
23
+ <details class="language-switcher no-print">
24
+ <summary class="language-switcher-trigger">
25
+ <span class="lang-icon" aria-hidden="true">🌐</span>
26
+ <span class="language-switcher-label">{{ current_locale.ui.language_switcher }}</span>
27
+ </summary>
28
+ <nav class="language-switcher-panel" aria-label="{{ current_locale.ui.language_switcher }}">
29
+ {%- comment -%}
30
+ IMPORTANT: {% include %} shares Liquid variable scope with its caller (resume.html),
31
+ so every variable assigned in this loop body must use a switch_-prefixed name that
32
+ cannot collide with resume.html's own lang/locale/lang_cfg - otherwise the last loop
33
+ iteration's values would silently leak out and corrupt the rest of the caller's render.
34
+ {%- endcomment -%}
35
+ {% for switch_entry in site.languages %}
36
+ {%- assign switch_lang = switch_entry[0] -%}
37
+ {%- assign switch_lang_cfg = switch_entry[1] -%}
38
+ {%- if switch_lang != current_lang -%}
39
+ {%- assign switch_locale = site.data.locales[switch_lang] -%}
30
40
 
31
- {%- comment -%}
32
- TIER 1: Auto-discover counterpart page by matching page.t_id + target language.
33
- Both pages must have the same t_id value in their front matter (e.g., t_id: cv-main).
34
- {%- endcomment -%}
35
- {%- assign switch_url = nil -%}
36
- {%- if page.t_id -%}
37
- {%- assign switch_matched_page = site.pages | where: "t_id", page.t_id | where: "lang", switch_lang | first -%}
38
- {%- if switch_matched_page -%}
39
- {%- assign switch_url = switch_matched_page.url | relative_url -%}
41
+ {%- comment -%}
42
+ TIER 1: Auto-discover counterpart page by matching page.t_id + target language.
43
+ Both pages must have the same t_id value in their front matter (e.g., t_id: cv-main).
44
+ {%- endcomment -%}
45
+ {%- assign switch_url = nil -%}
46
+ {%- if page.t_id -%}
47
+ {%- assign switch_matched_page = site.pages | where: "t_id", page.t_id | where: "lang", switch_lang | first -%}
48
+ {%- if switch_matched_page -%}
49
+ {%- assign switch_url = switch_matched_page.url | relative_url -%}
50
+ {%- endif -%}
40
51
  {%- endif -%}
41
- {%- endif -%}
42
52
 
43
- {%- comment -%}
44
- TIER 2: Fall back to languages.<lang>.url from _config.yml.
45
- {%- endcomment -%}
46
- {%- unless switch_url -%}
47
- {%- assign switch_url = switch_lang_cfg.url | relative_url -%}
48
- {%- endunless -%}
53
+ {%- comment -%}
54
+ TIER 2: Fall back to languages.<lang>.url from _config.yml.
55
+ {%- endcomment -%}
56
+ {%- unless switch_url -%}
57
+ {%- assign switch_url = switch_lang_cfg.url | relative_url -%}
58
+ {%- endunless -%}
49
59
 
50
- <a href="{{ switch_url }}"
51
- class="lang-switch-btn"
52
- aria-label="{{ switch_locale.ui.language_name }}"
53
- title="{{ switch_locale.ui.language_name }}"
54
- dir="{{ switch_locale.direction }}">
55
- <span class="lang-icon" aria-hidden="true">🌐</span>
56
- <span class="lang-label-target">{{ switch_locale.ui.language_name }}</span>
57
- </a>
58
- {%- endif -%}
59
- {% endfor %}
60
- </div>
60
+ <a href="{{ switch_url }}"
61
+ class="lang-switch-btn"
62
+ aria-label="{{ switch_locale.ui.language_name }}"
63
+ title="{{ switch_locale.ui.language_name }}"
64
+ dir="{{ switch_locale.direction }}">
65
+ <span class="lang-icon" aria-hidden="true">🌐</span>
66
+ <span class="lang-label-target">{{ switch_locale.ui.language_name }}</span>
67
+ </a>
68
+ {%- endif -%}
69
+ {% endfor %}
70
+ </nav>
71
+ </details>
61
72
  {% endif %}
@@ -385,11 +385,3 @@ html.light {
385
385
  }
386
386
  }
387
387
 
388
- // RTL layout positioning
389
- // Repositions the toggle button to the top-left corner in Arabic layouts.
390
- html[dir="rtl"] {
391
- .dark-mode-toggle {
392
- right: auto;
393
- left: 1.25rem;
394
- }
395
- }
data/_sass/_layout.scss CHANGED
@@ -84,12 +84,12 @@
84
84
  }
85
85
 
86
86
  // --------------------------------------------------------------------------
87
- // Language Switcher Component (Feature 1.2)
87
+ // Language Switcher Component (Feature 1.2; dropdown redesign Feature 2.12)
88
88
  // --------------------------------------------------------------------------
89
- // Floating pill button fixed to the top-left viewport corner in LTR layouts.
90
- // RTL coordinate flip is handled in _resume-rtl.scss for resume pages and
91
- // the html[dir="rtl"] block below for other layouts.
92
- // Mirrors the visual language of .dark-mode-toggle (same shadow and transition).
89
+ // <details>/<summary> disclosure fixed to the top-left viewport corner.
90
+ // The trigger (.language-switcher-trigger) mirrors the visual language of
91
+ // .dark-mode-toggle (same pill shape, shadow, and transition); the opened
92
+ // panel (.language-switcher-panel) lists every other configured language.
93
93
  // --------------------------------------------------------------------------
94
94
 
95
95
  .language-switcher {
@@ -98,7 +98,9 @@
98
98
  left: 1.25rem;
99
99
  z-index: 1000;
100
100
 
101
- .lang-switch-btn {
101
+ // <summary> gets a default disclosure marker in most browsers; suppress it since the
102
+ // trigger already renders its own icon + label.
103
+ .language-switcher-trigger {
102
104
  display: inline-flex;
103
105
  align-items: center;
104
106
  justify-content: center;
@@ -109,12 +111,18 @@
109
111
  color: var(--text-color, #333333);
110
112
  border: 1px solid var(--toggle-btn-border, #e0e0e0);
111
113
  border-radius: 9999px;
114
+ cursor: pointer;
115
+ list-style: none;
112
116
  text-decoration: none;
113
117
  font-size: 0.85rem;
114
118
  font-weight: 700;
115
119
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
116
120
  transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
117
121
 
122
+ &::-webkit-details-marker {
123
+ display: none;
124
+ }
125
+
118
126
  &:hover {
119
127
  background-color: var(--toggle-btn-hover-bg, #f5f5f5);
120
128
  border-color: var(--accent-color, #007acc);
@@ -127,6 +135,45 @@
127
135
  }
128
136
  }
129
137
 
138
+ &[open] .language-switcher-trigger {
139
+ border-color: var(--accent-color, #007acc);
140
+ }
141
+
142
+ .language-switcher-panel {
143
+ display: flex;
144
+ flex-direction: column;
145
+ gap: 0.25rem;
146
+ min-width: 10rem;
147
+ margin-top: 0.5rem;
148
+ padding: 0.5rem;
149
+ background: var(--bg-color, #ffffff);
150
+ border: 1px solid var(--toggle-btn-border, #e0e0e0);
151
+ border-radius: 0.75rem;
152
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
153
+ }
154
+
155
+ .lang-switch-btn {
156
+ display: inline-flex;
157
+ align-items: center;
158
+ gap: 0.5rem;
159
+ padding: 0.5rem 0.75rem;
160
+ color: var(--text-color, #333333);
161
+ text-decoration: none;
162
+ font-size: 0.85rem;
163
+ font-weight: 600;
164
+ border-radius: 0.5rem;
165
+ transition: background-color 0.2s ease;
166
+
167
+ &:hover {
168
+ background-color: var(--toggle-btn-hover-bg, #f5f5f5);
169
+ }
170
+
171
+ &:focus-visible {
172
+ outline: 2px solid var(--accent-color, #007acc);
173
+ outline-offset: 2px;
174
+ }
175
+ }
176
+
130
177
  .lang-icon {
131
178
  font-size: 1rem;
132
179
  line-height: 1;
@@ -137,14 +184,6 @@
137
184
  }
138
185
  }
139
186
 
140
- // RTL: mirror switcher to top-right (dark-mode toggle auto-mirrors to top-left)
141
- html[dir="rtl"] {
142
- .language-switcher {
143
- left: auto;
144
- right: 1.25rem;
145
- }
146
- }
147
-
148
187
  // Print: explicit safety net — .no-print on the element already handles most cases
149
188
  @media print {
150
189
  .language-switcher {
@@ -91,18 +91,4 @@ html[dir="rtl"] {
91
91
  .page-footer {
92
92
  text-align: center; // keep centered
93
93
  }
94
-
95
- // Dark mode toggle positioning for RTL
96
- // Mirrors the floating theme switcher from top-right to top-left (left: 1.25rem; right: auto)
97
- // to avoid colliding with right-aligned Arabic header titles.
98
- .dark-mode-toggle {
99
- right: auto;
100
- left: 1.25rem;
101
- }
102
-
103
- // Language switcher positioning for RTL
104
- .language-switcher {
105
- left: auto;
106
- right: 1.25rem;
107
- }
108
94
  }
data/bin/check-data-keys CHANGED
@@ -20,7 +20,7 @@ parser = OptionParser.new do |opts|
20
20
  opts.separator ""
21
21
  opts.separator "Options:"
22
22
 
23
- opts.on("-d", "--dir DIR", "Path to data directory (default: _data or docs/_data)") do |d|
23
+ opts.on("-d", "--dir DIR", "Path to data directory (default: _data or demo/_data)") do |d|
24
24
  options[:data_dir] = d
25
25
  end
26
26
 
@@ -51,9 +51,10 @@ parser.parse!
51
51
  # Positional argument takes precedence over -d, or fall back to standard data dirs
52
52
  data_dir = ARGV[0] || options[:data_dir]
53
53
  if data_dir.nil?
54
- # Prefer a directory that holds at least one language folder (a site's _data, else the theme's docs sample).
55
- data_dir = %w[_data docs/_data].find { |dir| BilingualJekyllResumeTheme::TemplateKeyChecker.new(dir).discover_languages.any? } ||
56
- "docs/_data"
54
+ # Prefer a directory that holds at least one language folder (a site's _data, else the theme's demo).
55
+ data_dir = %w[_data demo/_data].find do |dir|
56
+ BilingualJekyllResumeTheme::TemplateKeyChecker.new(dir).discover_languages.any?
57
+ end || "demo/_data"
57
58
  end
58
59
 
59
60
  checker = BilingualJekyllResumeTheme::TemplateKeyChecker.new(data_dir, config_path: options[:config_path])
data/bin/validate-resume CHANGED
@@ -22,7 +22,7 @@ parser = OptionParser.new do |opts|
22
22
  opts.separator ""
23
23
  opts.separator "Options:"
24
24
 
25
- opts.on("-d", "--dir DIR", "Path to data directory (default: _data or docs/_data)") do |d|
25
+ opts.on("-d", "--dir DIR", "Path to data directory (default: _data or demo/_data)") do |d|
26
26
  options[:data_dir] = d
27
27
  end
28
28
 
@@ -66,9 +66,10 @@ parser.parse!
66
66
  # Positional argument takes precedence over -d, or fall back to standard data dirs
67
67
  data_dir = ARGV[0] || options[:data_dir]
68
68
  if data_dir.nil?
69
- # Prefer a directory that holds at least one language folder (a site's _data, else the theme's docs sample).
70
- data_dir = %w[_data docs/_data].find { |dir| BilingualJekyllResumeTheme::ResumeValidator.new(dir).discover_languages.any? } ||
71
- "_data"
69
+ # Prefer a directory that holds at least one language folder (a site's _data, else the theme's demo).
70
+ data_dir = %w[_data demo/_data].find do |dir|
71
+ BilingualJekyllResumeTheme::ResumeValidator.new(dir).discover_languages.any?
72
+ end || "_data"
72
73
  end
73
74
 
74
75
  validator = BilingualJekyllResumeTheme::ResumeValidator.new(
@@ -37,7 +37,7 @@ All theme layouts define explicit ARIA landmark roles alongside semantic HTML5 e
37
37
  | `<header class="page-header">` | `role="banner"` | Page Header | Houses candidate name, title, avatar, and contact bar |
38
38
  | `<main class="main-content">` | `role="main"` | `id="main-content"` `tabindex="-1"` | Primary content container target of skip-to-content links |
39
39
  | `<footer class="page-footer">` | `role="contentinfo"` | Page Footer | Generation timestamp, copyright, and permalink |
40
- | `<nav class="language-switcher">`| `role="navigation"` | Language Switcher | Floating bilingual language selector |
40
+ | `<details class="language-switcher">` → `<nav class="language-switcher-panel">` | native disclosure + `role="navigation"` (implicit on `<nav>`) | Language Switcher | Floating dropdown language selector, zero JavaScript |
41
41
  | `<form class="error-search">` | `role="search"` | Search Form | Search interface on error pages |
42
42
 
43
43
  ---
@@ -127,7 +127,7 @@ Run the automated build and verify accessibility attributes:
127
127
 
128
128
  ```bash
129
129
  # Build static site
130
- bundle exec jekyll build --config docs/_data/_config.sample.yml
130
+ bundle exec jekyll build --source demo --destination _site
131
131
 
132
132
  # Verify skip link presence
133
133
  grep -q 'class="skip-link' _site/index.html && echo "Skip link verified."
@@ -1,47 +1,20 @@
1
1
  # Completed Historical Remediation & Engineering Audit Log
2
2
 
3
3
  **Project:** `bilingual-jekyll-resume-theme`
4
- **Current Release:** `v1.0.0` (Audited Baseline: `v0.7.0`)
4
+ **Current Release:** `v1.0.1` (Audited Baseline: `v0.7.0`)
5
5
  **Milestone:** M1 Completed Audit Archival
6
6
  **Audit Date:** September 2026
7
7
  **Master Active Roadmap:** [`/FEATURE_ROADMAP.md`](../FEATURE_ROADMAP.md)
8
- **Status:** Permanent Historical Record. 18 foundation items (through `v0.7.0`), later completed features, and the four v1.0.0 deliveries (Section 5), all completed and verified
8
+ **Status:** Permanent Historical Record. All foundation items, completed features, and release deliverables are verified in git history and documented in this audit archive.
9
9
 
10
10
  ---
11
11
 
12
12
  ## 1. Executive Summary & Audit Overview
13
13
 
14
- This document provides the definitive, permanent engineering record of all **18 bug fixes, security hardenings, data resilience enhancements, accessibility upgrades, and architectural feature deliverables** completed across the `bilingual-jekyll-resume-theme` repository up through release `v0.7.0`. While the current project release has advanced to `v1.0.0`, this document is preserved as the immutable historical record of the 18 foundation remediations.
14
+ This document provides the definitive, permanent engineering record of all **bug fixes, security hardenings, data resilience enhancements, accessibility upgrades, and architectural feature deliverables** completed across the `bilingual-jekyll-resume-theme` repository. It serves as the immutable historical record of foundation remediations and completed features across releases.
15
15
 
16
16
  To maintain strict hygiene in the active roadmap and eliminate document drift across planning cycles, completed items have been permanently retired from the active roadmap phases and archived in this audit document. For the active, forward-looking engineering roadmap detailing upcoming uncompleted features across Priorities 1 through 4, refer to the authoritative master roadmap at [`/FEATURE_ROADMAP.md`](../FEATURE_ROADMAP.md).
17
17
 
18
- ### 1.1 Remediation Metrics & Completion Summary
19
-
20
- | Scope Phase | Total Audited | Completed & Verified | Completion Rate | Releases Delivered |
21
- |---|---|---|---|---|
22
- | **Priority 0 (Immediate Stability, Correctness & Security)** | 16 | 16 | **100%** | `v0.4.0`, `v0.7.0` |
23
- | **Priority 1 (Visual Enhancements & Quick Wins)** | 2 (P1.2, P1.4) | 2 | **100%** | `v0.7.0`, `v0.8.0` |
24
- | **Priority 2 (Core Functional & Architecture)** | 3 (P2.4, P2.7, #216) | 3 | **100%** | `v0.7.0`, `v0.8.0` |
25
- | **Total Completed Engineering Deliverables** | **21** | **21** | **100%** | `v0.4.0` – `v0.8.0` |
26
- | **v1.0.0 Roadmap Features (1.7, 2.8, 4.1, 4.6)** | 4 | 4 | **100%** | `v1.0.0` (on `feature/extended-multilingual-v1.0.0`, unreleased) |
27
-
28
- ### 1.2 Categorical Remediation Distribution
29
-
30
- ```
31
- +-------------------------------------------------------------+
32
- | Category Distribution of 21 Completed Items |
33
- +-------------------------------------------------------------+
34
- | Bug / Logic Fixes: 4 items (P0.1, P0.2, P0.3, P0.9)
35
- | Security & HTML Correctness: 2 items (P0.5, P0.7)
36
- | Data Resilience & Optionality: 3 items (P0.13, P0.14, P0.15)
37
- | Accessibility (WCAG 2.1/2.2): 3 items (P0.10, P1.4, P2.7)
38
- | RTL & Internationalization: 4 items (P0.8, P0.11, P1.4, P1.2)
39
- | Architecture & Navigation: 4 items (P0.4, P0.16, P2.4, #216)
40
- | Asset Management & 404s: 1 item (P0.6)
41
- | Governance & Versioning: 1 item (P0.12)
42
- +-------------------------------------------------------------+
43
- ```
44
-
45
18
  ---
46
19
 
47
20
  ## 2. Master Completed Remediation Matrix
@@ -73,6 +46,10 @@ To maintain strict hygiene in the active roadmap and eliminate document drift ac
73
46
  | **F2.8** | Header Contact Icon and Text Alignment in Arabic Layout | Issue [#217](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/217) | RTL / a11y | `v1.0.0` | `315356972b326d9fcd5ff58e0208da9a2140116f` | `_layouts/resume-ar.html` (carried into `_layouts/resume.html`) |
74
47
  | **F4.1** | Extended Multilingual Support (EN, AR, ES, FR, DE, UR) | Issue [#15](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/15) | i18n / Architecture | `v1.0.0` | `54b40a4`, `3e840a7`, `5058532`, `c37df29`, `da2cd74`, `3f467fe`, `5188e96` | `_data/locales/*.yml`, `_layouts/resume.html`, `_includes/resume-section.html`, `_includes/date-formatter.html`, `_sass/_resume-ltr.scss`, `assets/css/cv-{ltr,rtl}.scss`, every locale consumer, `docs/_data/`, `docs/demo/` |
75
48
  | **F4.6** | Deprecation Retirement & Legacy Fallbacks Cleanup | Issue [#214](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/214) | Cleanup / Config | `v1.0.0` | `2c88adf75c915cb682634ac0c98a2211caedb101` | `_includes/avatar.html`, `_includes/analytics-head.html`, `_includes/resume-section.html` |
49
+ | **F3.2** | Automated CI/CD Build & Verification Pipeline | Issue [#206](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/206) | CI/CD | `v1.0.0` | `3be935f` | `.github/workflows/ci.yml`, `.github/workflows/lint.yml`, `README.md` |
50
+ | **F3.3** | YAML Resume Data Validator & Schema Linter | Issue [#13](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/13) | Tooling / Quality | `v1.0.0` | `3be935f` | `bin/validate-resume`, `lib/bilingual-jekyll-resume-theme/resume_validator.rb`, `_plugins/resume_validator.rb`, `docs/VALIDATION_GUIDE.md`, `test/test_resume_validator.rb` |
51
+ | **F2.11** | Pin Language-Switcher/Dark-Mode-Toggle to Fixed Corners (Remove RTL Mirror) | Issue [#227](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/227) | Layout / RTL | `v1.0.1` | `305408c` | `_sass/_layout.scss`, `_sass/_dark-mode.scss`, `_sass/_resume-rtl.scss`, `test/test_language_switcher.rb`, `docs/INCLUDES_GUIDE.md` |
52
+ | **F2.12** | Dropdown Language Switcher (Replace Per-Language Button Row) | Issue [#228](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/228) | i18n / a11y | `v1.0.1` | `f37c6f6` | `_includes/language-switcher.html`, `_sass/_layout.scss`, `test/test_language_switcher.rb`, `docs/INCLUDES_GUIDE.md`, `docs/ACCESSIBILITY_GUIDE.md`, `docs/PROJECT_OVERVIEW.md` |
76
53
 
77
54
  ---
78
55
 
@@ -603,9 +580,9 @@ To maintain strict hygiene in the active roadmap and eliminate document drift ac
603
580
 
604
581
  ---
605
582
 
606
- ## 5. v1.0.0 Delivered Features (1.7, 2.8, 4.1, 4.6)
583
+ ## 5. v1.0.0 Delivered Features (1.7, 2.8, 3.2, 3.3, 4.1, 4.6)
607
584
 
608
- The v1.0.0 multilingual release was executed on branch `feature/extended-multilingual-v1.0.0` from an implementation plan that has since been retired; this section, [`../CHANGELOG.md`](../CHANGELOG.md), and [`MULTILINGUAL_GUIDE.md`](MULTILINGUAL_GUIDE.md) are its permanent record. v1.0.0 is a hard break with no compatibility aliases; the full removed-to-replacement table is in [`MULTILINGUAL_GUIDE.md`](MULTILINGUAL_GUIDE.md#breaking-changes--migration-v090-to-v100). Features 3.2 (CI pipeline, #206) and 3.3 (validator, #13) were implemented on the same branch but stay in the active roadmap until their closure checks pass.
585
+ The v1.0.0 multilingual release was executed on branch `feature/extended-multilingual-v1.0.0` from an implementation plan that has since been retired; this section, [`../CHANGELOG.md`](../CHANGELOG.md), and [`MULTILINGUAL_GUIDE.md`](MULTILINGUAL_GUIDE.md) are its permanent record. v1.0.0 is a hard break with no compatibility aliases; the full removed-to-replacement table is in [`MULTILINGUAL_GUIDE.md`](MULTILINGUAL_GUIDE.md#breaking-changes--migration-v090-to-v100). All deliverables, including the CI/CD pipeline (#206) and the validator (#13), are verified live and permanently archived here.
609
586
 
610
587
  ### 5.1 Feature 1.7: Native Email Support in Social Links Include (#215)
611
588
 
@@ -638,35 +615,65 @@ The v1.0.0 multilingual release was executed on branch `feature/extended-multili
638
615
  - **Delivered:** Removed the `site.avatar` fallback from `_includes/avatar.html`, the `analytics.ga` Universal Analytics branch from `_includes/analytics-head.html`, and the singular `resume_section.recognition` fallback (dropped in `_includes/resume-section.html`). Confirmed `site.resume_dark_mode` and `site.resume_header_intro` have no remaining references.
639
616
  - **Commit:** `2c88adf75c915cb682634ac0c98a2211caedb101` (`chore(cleanup): purge deprecated site.avatar, analytics.ga, and resume_dark_mode fallbacks`).
640
617
 
618
+ ### 5.5 Feature 3.2: Automated CI/CD Build & Verification Pipeline (#206)
619
+
620
+ - **Problem:** Absence of automated continuous integration allowed invalid front-matter, broken YAML data, or gem specification packaging defects to reach consumers unnoticed.
621
+ - **Delivered:** Configured `.github/workflows/ci.yml` matrix testing across modern Ruby releases (3.3, 3.4, 4.0), strict Jekyll demo build, RuboCop, unit test execution, and gem packaging verification. Added `.github/workflows/lint.yml` and CI status badge to `README.md`.
622
+ - **Commit:** `3be935f` (carried in from `feature/resume-validator-ecosystem`, verified live on PR #220).
623
+
624
+ ### 5.6 Feature 3.3: YAML Resume Data Validator & Schema Linter (#13)
625
+
626
+ - **Problem:** Non-technical user errors in YAML syntax (missing fields, wrong data types, malformed dates, cross-locale file asymmetries) resulted in cryptic Liquid build failures.
627
+ - **Delivered:** Standalone CLI tool `bin/validate-resume` and core engine `lib/bilingual-jekyll-resume-theme/resume_validator.rb` validating all 13 standard resume files, date formats, active flags, and multi-locale parity. Includes build-time Jekyll plugin `_plugins/resume_validator.rb`, Rake task `rake validate`, comprehensive guide `docs/VALIDATION_GUIDE.md`, and full Minitest suite `test/test_resume_validator.rb`.
628
+ - **Commit:** `3be935f` (carried in from `feature/resume-validator-ecosystem`, verified live on PR #220).
629
+
630
+ ---
631
+
632
+ ## 6. v1.0.1 Delivered Features (2.11, 2.12)
633
+
634
+ The v1.0.1 maintenance release addressed two visual widget improvements scoped together before v1.0.0. Both were verified against live LTR and RTL builds and merged directly into `master`.
635
+
636
+ ### 6.1 Feature 2.11: Pin Language-Switcher/Dark-Mode-Toggle to Fixed Corners (#227)
637
+
638
+ - **Problem:** `.language-switcher` and `.dark-mode-toggle` previously swapped top-left/top-right corners based on `locale.direction`, with mirror rules duplicated across `_sass/_layout.scss`, `_sass/_dark-mode.scss`, and `_sass/_resume-rtl.scss`.
639
+ - **Delivered:** Pinned `.language-switcher` fixed to top-left and `.dark-mode-toggle` fixed to top-right across all locales (LTR and RTL), removing all three RTL override locations. Verified against live `ar/cv/` and `ur/cv/` builds at desktop and mobile widths confirming no collision with right-aligned Arabic header titles.
640
+ - **Commit:** `305408c8885c194ad71d88831179b287d4a10ec3` (`feat(layout): pin language-switcher/dark-mode-toggle to fixed corners (Closes #227)`).
641
+
642
+ ### 6.2 Feature 2.12: Dropdown Language Switcher (#228)
643
+
644
+ - **Problem:** `_includes/language-switcher.html` rendered one button per configured language in a flat row, taking excessive horizontal space and wrapping across multiple rows on mobile screens as locales increased.
645
+ - **Delivered:** Replaced the button row with a semantic `<details>/<summary>` disclosure element wrapping a `<nav>` landmark of per-language links with zero new JavaScript. Preserves full no-JS graceful degradation, keyboard navigation (Tab, Enter/Space, Esc), and accessible screen-reader states.
646
+ - **Commit:** `f37c6f6b410f5de4841ed36115db60408c805293` (`feat(i18n): replace language-switcher button row with a dropdown (Closes #228)`).
647
+
641
648
  ---
642
649
 
643
- ## 6. Verification Protocols & Independent Audit Attestation
650
+ ## 7. Verification Protocols & Independent Audit Attestation
644
651
 
645
652
  The following independent verification commands confirm the integrity of the codebase following the completion of all 18 remediation tasks:
646
653
 
647
- ### 6.1 RubyGem Packaging Verification
654
+ ### 7.1 RubyGem Packaging Verification
648
655
  ```bash
649
656
  gem build bilingual-jekyll-resume-theme.gemspec
650
657
  ```
651
658
  *Passing Result:* Successfully built RubyGem `bilingual-jekyll-resume-theme-0.7.0.gem` with zero packaging errors. All new files (`404.html`, `403.html`, `500.html`, `_layouts/error.html`, `_data/error_pages.yml`, `_includes/avatar.html`) are verified in the gem manifest.
652
659
 
653
- ### 6.2 Liquid Syntax & Template Tag Inspection
660
+ ### 7.2 Liquid Syntax & Template Tag Inspection
654
661
  All modified templates (`_layouts/resume-ar.html`, `_layouts/resume-en.html`, `_layouts/default.html`, `_layouts/error.html`, `_includes/analytics-body.html`, `_includes/analytics-head.html`, `_includes/avatar.html`, `_includes/resume-section-*.html`, `_includes/shared-head.html`, `_includes/social-links.html`, `_includes/print-social-links.html`) contain valid, balanced Liquid tags and conform to Jekyll 3.9+ / 4.x standards.
655
662
 
656
- ### 6.3 WCAG 2.1 AA Accessibility Attestation
663
+ ### 7.3 WCAG 2.1 AA Accessibility Attestation
657
664
  - All social links contain `aria-label`, `title`, and visually-hidden `<span class="sr-only">` text.
658
665
  - All SVG icons contain `aria-hidden="true" focusable="false"`.
659
666
  - Avatar image component includes bilingual fallback alt text, Schema.org `itemprop="image"`, and accessible link targets.
660
667
 
661
- ### 6.4 RTL & Bidirectional Text Isolation Attestation
668
+ ### 7.4 RTL & Bidirectional Text Isolation Attestation
662
669
  - Arabic templates enforce `dir="rtl"` root direction with `<span dir="ltr">` isolation for telephone links, URLs, and printed social links.
663
670
  - Arabic Google Font Cairo loads reliably across all themes and custom palettes with preconnect hints.
664
671
 
665
672
  ---
666
673
 
667
- ## 7. Closed Redundant Duplicate Issues Registry & Root Cause Analysis
674
+ ## 8. Closed Redundant Duplicate Issues Registry & Root Cause Analysis
668
675
 
669
- ### 7.1 Duplicate Creation Root Cause Analysis (RCA)
676
+ ### 8.1 Duplicate Creation Root Cause Analysis (RCA)
670
677
 
671
678
  Between `2026-09-12T11:37:00Z` and `2026-09-12T12:10:49Z`, an automated script executed 13 successive batch sweeps across the repository issue tracker. In each cycle, a batch of 14 items was generated:
672
679
  1. 11 remediation items corresponding to Phase 0 bug fixes (P0.1–P0.11): immediately closed upon creation.
@@ -681,9 +688,9 @@ Because 13 successive batch runs were triggered, 13 identical copies of the Soci
681
688
 
682
689
  The 13th batch produced `#204` and `#206`, which are designated as the **canonical active open issues** in [`/FEATURE_ROADMAP.md`](../FEATURE_ROADMAP.md). All preceding 24 issues were formally closed on GitHub using GitHub's native `state_reason: "duplicate"` linking to `#204` and `#206`, preceded by an explanatory cross-reference comment.
683
690
 
684
- ### 7.2 Social Media Platform Closed Duplicates (12 Issues)
691
+ ### 8.2 Social Media Platform Closed Duplicates
685
692
 
686
- All 12 duplicate issues share the title `"Expand Social Media Platforms (Mastodon, Discord, Bluesky, etc.)"`, labels `["enhancement", "phase-1"]`, and milestone `"Phase 1 (Quick Wins - 1-2 weeks)"`.
693
+ The duplicate issues share the title `"Expand Social Media Platforms (Mastodon, Discord, Bluesky, etc.)"`, labels `["enhancement", "phase-1"]`, and milestone `"Phase 1 (Quick Wins - 1-2 weeks)"`.
687
694
 
688
695
  | Issue # | Title | Created (UTC) | Closed (UTC) | Status | Canonical Reference | Resolution Details |
689
696
  |---|---|---|---|---|---|---|
@@ -700,9 +707,9 @@ All 12 duplicate issues share the title `"Expand Social Media Platforms (Mastodo
700
707
  | [#176](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/176) | Expand Social Media Platforms | 2026-09-12T12:05:43Z | 2026-09-12T14:06:23Z | `CLOSED (duplicate)` | [#204](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/204) | Closed via GitHub API with cross-reference comment to #204 |
701
708
  | [#190](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/190) | Expand Social Media Platforms | 2026-09-12T12:08:26Z | 2026-09-12T14:06:35Z | `CLOSED (duplicate)` | [#204](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/204) | Closed via GitHub API with cross-reference comment to #204 |
702
709
 
703
- ### 7.3 CI/CD Pipeline Closed Duplicates (12 Issues)
710
+ ### 8.3 CI/CD Pipeline Closed Duplicates
704
711
 
705
- All 12 duplicate issues share the title `"Automated CI/CD Build & Verification Pipeline"`, labels `["enhancement", "phase-3"]`, and milestone `"Phase 3 (Long-term - 2-3 months)"`.
712
+ The duplicate issues share the title `"Automated CI/CD Build & Verification Pipeline"`, labels `["enhancement", "phase-3"]`, and milestone `"Phase 3 (Long-term - 2-3 months)"`.
706
713
 
707
714
  | Issue # | Title | Created (UTC) | Closed (UTC) | Status | Canonical Reference | Resolution Details |
708
715
  |---|---|---|---|---|---|---|
@@ -719,7 +726,7 @@ All 12 duplicate issues share the title `"Automated CI/CD Build & Verification P
719
726
  | [#178](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/178) | Automated CI/CD Build & Pipeline | 2026-09-12T12:05:54Z | 2026-09-12T14:08:45Z | `CLOSED (duplicate)` | [#206](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/206) | Closed via GitHub API with cross-reference comment to #206 |
720
727
  | [#192](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/192) | Automated CI/CD Build & Pipeline | 2026-09-12T12:08:37Z | 2026-09-12T14:08:57Z | `CLOSED (duplicate)` | [#206](https://github.com/kmutahar/bilingual-jekyll-resume-theme/issues/206) | Closed via GitHub API with cross-reference comment to #206 |
721
728
 
722
- ### 7.4 Closing Comment Audit Trail
729
+ ### 8.4 Closing Comment Audit Trail
723
730
 
724
731
  Each duplicate issue received a courteous explanatory comment before closure on GitHub:
725
732
  - **Social Media Comment:**
@@ -733,7 +740,7 @@ Each duplicate issue received a courteous explanatory comment before closure on
733
740
 
734
741
  ---
735
742
 
736
- ## 8. Pull Requests & Ancillary GitHub Records
743
+ ## 9. Pull Requests & Ancillary GitHub Records
737
744
 
738
745
  | PR # | Status | Title | Description | Resolution |
739
746
  |---|---|---|---|---|