jekyll-theme-centos 2.52.0.beta.83 → 2.52.0.beta.85

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/_config.yml +1 -8
  3. data/_data/base/calendar_schema.yml +156 -0
  4. data/_data/base/card_schema.yml +10 -2
  5. data/_data/base/event_schema.yml +19 -58
  6. data/_data/base/project_schema.yml +6 -1
  7. data/_includes/base/bits.html.liquid +3 -3
  8. data/_includes/base/calendar-events.html.liquid +49 -0
  9. data/_includes/base/calendar-init.html.liquid +148 -0
  10. data/_includes/base/calendar.html.liquid +70 -0
  11. data/_includes/base/card.html.liquid +2 -2
  12. data/_includes/base/event.html.liquid +57 -2
  13. data/_includes/base/head.html.liquid +8 -1
  14. data/_includes/base/link.html.liquid +8 -0
  15. data/_sass/base/_calendar.scss +204 -0
  16. data/_sass/base/_customization.scss +13 -4
  17. data/assets/css/base/stylesheet.min.scss +4 -0
  18. data/assets/img/base/page-layout-default.svg +113 -134
  19. data/assets/img/base/page-with-alert.svg +348 -957
  20. data/assets/img/base/page-with-announcement.svg +363 -969
  21. data/assets/img/base/page-with-artwork.svg +327 -997
  22. data/assets/img/base/page-with-backtotop.svg +373 -918
  23. data/assets/img/base/page-with-bits.svg +278 -958
  24. data/assets/img/base/page-with-breadcrumb.svg +265 -958
  25. data/assets/img/base/page-with-breakingnews.svg +352 -969
  26. data/assets/img/base/page-with-calendar.svg +57 -0
  27. data/assets/img/base/page-with-copyright.svg +375 -916
  28. data/assets/img/base/page-with-event.svg +393 -463
  29. data/assets/img/base/page-with-footer.svg +375 -916
  30. data/assets/img/base/page-with-locales.svg +372 -917
  31. data/assets/img/base/page-with-project.svg +397 -599
  32. data/assets/img/base/page-with-shortcut.svg +373 -918
  33. data/assets/img/base/page-with-social.svg +373 -918
  34. data/assets/img/base/page-with-sponsors.svg +373 -918
  35. data/assets/img/base/page-with-title.svg +285 -545
  36. data/assets/img/base/page-with-toc.svg +268 -998
  37. data/assets/js/base/heading-anchor.js +1 -0
  38. metadata +7 -1
@@ -16,10 +16,12 @@ Design Logic:
16
16
 
17
17
  Required Inputs:
18
18
  - title: Event name/title
19
+ - start: Event start (YYYY-MM-DD for an all-day event, or YYYY-MM-DDTHH:MM
20
+ to give it a specific start time on that same day)
19
21
 
20
22
  Optional Inputs:
21
23
  - description: Event description text
22
- - date: Event date/time string
24
+ - end: Event inclusive end (same format as start), defaults to start
23
25
  - location: Event location name
24
26
  - color: Alert color scheme (default: "secondary")
25
27
  - icon: Icon class (default: "fa-solid fa-calendar")
@@ -57,8 +59,61 @@ Data Source Hierarchy (priority):
57
59
  {%- assign event_city = event.city | default: with_event_schema.city.default %}
58
60
  {%- assign event_color = event.color | default: with_event_schema.color.default %}
59
61
  {%- assign event_location = event.location | default: with_event_schema.location.default %}
60
- {%- assign event_date = event.date | default: with_event_schema.date.default %}
61
62
  {%- assign event_description = event.description | default: with_event_schema.description.default %}
63
+
64
+ {%- comment %}
65
+ Derive the same style of display string the old free-text `date` field
66
+ used to hold (e.g. "September 19 - 20, 2025") from the structured,
67
+ inclusive `start`/`end` ISO dates — collapsing the month/year whenever
68
+ both sides share it, spelling both out in full otherwise. No date
69
+ arithmetic here, only formatting and string comparison of the formatted
70
+ output; the calendar component (reading this same with_event_data) is
71
+ the one place that does inclusive-to-exclusive end-date arithmetic, in
72
+ JS. See the calendar component's event data contract documentation.
73
+
74
+ A `start` carrying a time-of-day (`YYYY-MM-DDTHH:MM`) is a same-day timed
75
+ event rather than a date range — it gets its own branch below that
76
+ appends the clock time(s) instead of running the range-collapsing logic.
77
+ {% endcomment %}
78
+ {%- assign event_start = event.start %}
79
+ {%- if event_start != "" and event_start != nil %}
80
+ {%- assign event_end = event.end | default: event_start %}
81
+ {%- if event_end == "" %}
82
+ {%- assign event_end = event_start %}
83
+ {%- endif %}
84
+ {%- if event_start contains "T" %}
85
+ {%- assign event_date = event_start | date: "%B %-d, %Y" %}
86
+ {%- assign event_start_time = event_start | date: "%-l:%M %p" %}
87
+ {%- if event_end != event_start %}
88
+ {%- assign event_end_time = event_end | date: "%-l:%M %p" %}
89
+ {%- assign event_date = event_date | append: ", " | append: event_start_time | append: " - " | append: event_end_time %}
90
+ {%- else %}
91
+ {%- assign event_date = event_date | append: ", " | append: event_start_time %}
92
+ {%- endif %}
93
+ {%- else %}
94
+ {%- assign event_start_ym = event_start | date: "%Y-%m" %}
95
+ {%- assign event_end_ym = event_end | date: "%Y-%m" %}
96
+ {%- assign event_start_y = event_start | date: "%Y" %}
97
+ {%- assign event_end_y = event_end | date: "%Y" %}
98
+ {%- if event_start == event_end %}
99
+ {%- assign event_date = event_start | date: "%B %-d, %Y" %}
100
+ {%- elsif event_start_ym == event_end_ym %}
101
+ {%- assign event_date_start = event_start | date: "%B %-d" %}
102
+ {%- assign event_date_end = event_end | date: "%-d, %Y" %}
103
+ {%- assign event_date = event_date_start | append: " - " | append: event_date_end %}
104
+ {%- elsif event_start_y == event_end_y %}
105
+ {%- assign event_date_start = event_start | date: "%B %-d" %}
106
+ {%- assign event_date_end = event_end | date: "%B %-d, %Y" %}
107
+ {%- assign event_date = event_date_start | append: " - " | append: event_date_end %}
108
+ {%- else %}
109
+ {%- assign event_date_start = event_start | date: "%B %-d, %Y" %}
110
+ {%- assign event_date_end = event_end | date: "%B %-d, %Y" %}
111
+ {%- assign event_date = event_date_start | append: " - " | append: event_date_end %}
112
+ {%- endif %}
113
+ {%- endif %}
114
+ {%- else %}
115
+ {%- assign event_date = "" %}
116
+ {%- endif %}
62
117
  {%- assign event_icon = event.icon | default: with_event_schema.icon.default %}
63
118
  {%- assign event_image_url = event.image_url | default: with_event_schema.image_url.default %}
64
119
  {%- assign event_link = event.link | default: with_event_schema.link.default %}
@@ -11,7 +11,7 @@ Design Logic:
11
11
  - Favicon support: multiple formats (16x16, 32x32, SVG with type, Apple Touch)
12
12
  - Google Fonts: Montserrat (5 weights) and Source Code Pro (2 weights) via async stylesheet
13
13
  - Breakingnews scroll offset: dynamic CSS calculation
14
- - Conditional includes: OGP, Highlight.js, DataTables, FontAwesome (SVG+JS)
14
+ - Conditional includes: OGP, Highlight.js, DataTables, FontAwesome (SVG+JS), Event Calendar
15
15
  - CSS prioritization: custom stylesheet last for override
16
16
  - Script loading: Bootstrap base first (defer), then optional extensions, then UI behaviors
17
17
  - Bootstrap and FontAwesome preloaded (high-priority fetch); CDN origins preconnected + dns-prefetched per active component
@@ -25,6 +25,7 @@ Optional Inputs:
25
25
  - page.with_ogp, page.with_fontawesome: Include OGP/Font Awesome SVG+JS (boolean)
26
26
  - page.with_breakingnews, page.with_highlight: Include breaking news/highlight
27
27
  - page.with_datatable: Include DataTables (boolean)
28
+ - page.with_calendar: Include Event Calendar (boolean)
28
29
  - page.with_breakingnews_data: Array of breaking news items
29
30
  - page.with_backtotop: Include back-to-top button (boolean)
30
31
  - page.with_copyvalue: Include copy-to-clipboard behavior (boolean)
@@ -67,6 +68,10 @@ Optional Inputs:
67
68
  <link rel="preconnect" href="https://cdn.datatables.net" crossorigin />
68
69
  <link rel="dns-prefetch" href="https://cdn.datatables.net" />
69
70
  {%- endif %}
71
+ {%- if page.with_calendar %}
72
+ <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
73
+ <link rel="dns-prefetch" href="https://cdn.jsdelivr.net" />
74
+ {%- endif %}
70
75
  <link rel="preload" href="{{ site.baseurl }}/assets/js/bootstrap.bundle.min.js" as="script" fetchpriority="high" />
71
76
  {%- include base/fontawesome.html.liquid type="preload" %}
72
77
  <link rel="preload" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&family=Source+Code+Pro:ital,wght@0,400;0,700&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'" />
@@ -121,6 +126,7 @@ Uses CSS custom properties for cleaner, more maintainable dynamic styling.
121
126
  {%- include base/fontawesome.html.liquid type="head" %}
122
127
  {%- include base/highlight.html.liquid type="head" %}
123
128
  {%- include base/datatable.html.liquid type="head" %}
129
+ {%- include base/calendar.html.liquid type="head" %}
124
130
 
125
131
  {%- comment %} JavaScript base — Bootstrap must execute before all component scripts {%- endcomment %}
126
132
  <script src="{{ site.baseurl }}/assets/js/bootstrap.bundle.min.js" defer></script>
@@ -130,6 +136,7 @@ Uses CSS custom properties for cleaner, more maintainable dynamic styling.
130
136
  {%- include base/fontawesome.html.liquid type="script" %}
131
137
  {%- include base/highlight.html.liquid type="script" %}
132
138
  {%- include base/datatable.html.liquid type="script" %}
139
+ {%- include base/calendar.html.liquid type="script" %}
133
140
 
134
141
  {%- comment %} JavaScript UI behavior components — depend on Bootstrap and FontAwesome SVG+JS {%- endcomment %}
135
142
  {%- include base/backtotop.html.liquid %}
@@ -64,6 +64,14 @@ Security & External Links:
64
64
  {%- assign anchor = nil %}
65
65
  {%- assign rel_attr = nil %}
66
66
 
67
+ {%- comment %} --- Security: neutralize dangerous URI schemes --- {% endcomment %}
68
+ {%- if link != nil -%}
69
+ {%- assign link_downcase = link | downcase -%}
70
+ {%- if link_downcase contains "javascript:" or link_downcase contains "data:" or link_downcase contains "vbscript:" -%}
71
+ {%- assign link = "#" -%}
72
+ {%- endif -%}
73
+ {%- endif -%}
74
+
67
75
  {%- comment %} === Data processing === {% endcomment %}
68
76
  {%- if link != nil -%}
69
77
  {%- assign link_char1 = link | slice: 0, 1 -%}
@@ -0,0 +1,204 @@
1
+ // ================================================================================
2
+ // Event Calendar (@event-calendar/build) theming
3
+ // ================================================================================
4
+ // Purpose: Map the CentOS color palette onto the Event Calendar library's own
5
+ // CSS custom properties (--ec-*), instead of hand-rolling calendar styles.
6
+ //
7
+ // Selector specificity note: the library ships its own `.ec { --ec-*: ...; }`
8
+ // block (see https://github.com/vkurko/calendar/blob/master/packages/core/src/styles/theme.css)
9
+ // inside event-calendar.min.css, which this theme loads via the "CSS
10
+ // dependencies" block in head.html.liquid — AFTER this theme's own
11
+ // stylesheet.min.css. A same-specificity `.ec { ... }` override placed here
12
+ // would therefore lose the cascade to the library's own later-loaded rule.
13
+ // Prefixing with `body` bumps our selector's specificity above the
14
+ // library's plain `.ec` rule so our values win regardless of load order
15
+ // (the same technique this file's DataTables corrections use in
16
+ // _customization.scss, e.g. `.content .dt-container`).
17
+ //
18
+ // The dark-mode toggle classes (`.ec-dark`/`.ec-auto-dark`) are applied by
19
+ // the page to whichever element wraps the calendar — commonly `<body>`
20
+ // itself, per this library's own docs. A `body .ec-dark .ec` selector would
21
+ // require `.ec-dark` on a *descendant* of body and never match when body
22
+ // carries the class directly, so the dark blocks anchor to `html` instead
23
+ // (always an ancestor of body, regardless of which element the toggle class
24
+ // lands on) to stay correct in both cases.
25
+ // ================================================================================
26
+
27
+ body .ec {
28
+ // The library defines --ec-bg-color but never applies it to .ec itself
29
+ // (only to specific inner elements like popups), so the calendar's outer
30
+ // container has no background of its own and shows whatever it's placed
31
+ // on through — inconsistent depending on the page's own layout. Declared
32
+ // once here (not repeated in the dark-mode blocks below): --ec-surface-bg-color
33
+ // cascades normally, so this always reads whichever value currently wins
34
+ // for this element, light or dark.
35
+ //
36
+ // Deliberately a separate variable from --ec-bg-color, not the same one:
37
+ // the library also derives --ec-day-bg-color (grid cells), .ec-sidebar,
38
+ // and .ec-col-head (weekday row) from --ec-bg-color. Every component's
39
+ // "Live example" across this theme's docs sits inside a `.text-bg-light`
40
+ // preview box (see e.g. components/calendar.md), painted with $light —
41
+ // so the outer container/toolbar use $light too, to sit flush with that
42
+ // surface. But feeding $light into --ec-bg-color directly also recolors
43
+ // the day cells and weekday header to $light, flattening the grid against
44
+ // its own container and losing the contrast that gives the calendar its
45
+ // shape. --ec-bg-color stays $white so those inner surfaces keep
46
+ // contrasting against the (now $light) outer one.
47
+ background-color: var(--ec-surface-bg-color);
48
+ --ec-surface-bg-color: #{$light};
49
+
50
+ --ec-bg-color: #{$white};
51
+ --ec-text-color: #{$body-color};
52
+ --ec-border-color: #{$border-color};
53
+
54
+ --ec-button-bg-color: #{$white};
55
+ --ec-button-border-color: #{$border-color};
56
+ --ec-button-text-color: #{$body-color};
57
+ --ec-button-active-bg-color: #{map-get($theme-colors, 'centos-purple-100')};
58
+ --ec-button-active-border-color: #{$primary};
59
+ --ec-button-active-text-color: #{$primary};
60
+
61
+ --ec-today-bg-color: #{map-get($theme-colors, 'centos-orange-50')};
62
+ --ec-highlight-color: #{map-get($theme-colors, 'centos-purple-50')};
63
+
64
+ --ec-event-bg-color: #{$primary};
65
+ --ec-event-text-color: #{$white};
66
+ --ec-bg-event-color: #{map-get($theme-colors, 'centos-purple-200')};
67
+
68
+ --ec-now-indicator-color: #{$danger};
69
+ --ec-popup-bg-color: #{$white};
70
+
71
+ // The library renders event titles as <h4 class="ec-event-title"> but only
72
+ // resets its font-size in list view (`.ec-list .ec-event-title`) — in every
73
+ // other view it falls through to this theme's Bootstrap h4 size. Match it
74
+ // to the calendar's own body text size (the same size the day-of-week
75
+ // header row uses) instead of an oversized heading.
76
+ //
77
+ // In month/all-day grid views the library also sets a `min-block-size:
78
+ // 1.5em` on this same element for tap-target sizing. Since it's
79
+ // `display: block`, that extra height just extends downward past the
80
+ // (now correctly-sized, single-line) text instead of centering it,
81
+ // leaving the name visibly top-biased in its pill. Making the title a
82
+ // flex container of its own single line of text centers it within
83
+ // whatever height the library gives it — a no-op in list/time-grid views,
84
+ // which don't set that min-height in the first place.
85
+ .ec-event-title {
86
+ font-size: #{$font-size-base};
87
+ display: flex;
88
+ align-items: center;
89
+ }
90
+
91
+ // List view's day-group heading (day name + date) is also an <h4>, hitting
92
+ // the same Bootstrap h4 collision as .ec-event-title above. Match it to the
93
+ // same body text size as the event name, kept bold (the library's own
94
+ // default weight for this heading) so the two rows stay visually distinct.
95
+ // (.ec-day-head doubles as the day-number cell in month view, so this
96
+ // covers both.)
97
+ .ec-day-head {
98
+ font-size: #{$font-size-base};
99
+ font-weight: 700;
100
+ }
101
+
102
+ // Headings inside the calendar (.ec-title — the "August 2026" navigation
103
+ // title; .ec-col-head, the Sun/Mon/… weekday row; .ec-day-head, the
104
+ // day-number/day-group heading above) all rely on inherited `color`, since
105
+ // the library never sets one itself: its own h1-h6 rule is `color:
106
+ // var(--bs-heading-color)`, and this theme leaves that Bootstrap variable
107
+ // empty (`$headings-color: null`), so the value is invalid and falls back
108
+ // to whatever color is inherited from the calendar's ancestors. That's
109
+ // normally this theme's own body color, but it silently breaks wherever
110
+ // the calendar is embedded inside anything that sets its own text color —
111
+ // e.g. this component's own doc example, wrapped in Bootstrap's
112
+ // `.text-bg-light` for a bordered preview box, which forces black. Set it
113
+ // explicitly instead of depending on inheritance, so the calendar's
114
+ // headings always match the page's own heading color regardless of what
115
+ // wraps it.
116
+ .ec-title,
117
+ .ec-col-head,
118
+ .ec-day-head {
119
+ color: var(--ec-text-color);
120
+ }
121
+
122
+ // List view's per-event color tag (a thin bar next to the event name) only
123
+ // gets an inline background color when the event data itself sets one; our
124
+ // example events don't, so give it the same event color used everywhere
125
+ // else instead of leaving it transparent/invisible.
126
+ .ec-event-tag {
127
+ background-color: var(--ec-event-bg-color);
128
+ }
129
+
130
+ // The toolbar (view title + nav/view-switcher buttons) sits inside
131
+ // .ec-header, which the library makes `position: sticky` so it stays
132
+ // pinned while the grid/list body scrolls underneath — but the library
133
+ // never gives the toolbar its own background. Left unset it stays
134
+ // transparent, so scrolled-under event content shows through it instead
135
+ // of the toolbar blending into the calendar around it. Match it to the
136
+ // same --ec-surface-bg-color used for .ec itself so it reads as one
137
+ // surface (see the --ec-surface-bg-color vs. --ec-bg-color note above).
138
+ //
139
+ // The library also spaces the toolbar from the grid/list body below with
140
+ // `margin-block-end: 1em`, not padding. A margin sits outside the
141
+ // toolbar's own border box, so that gap isn't painted by the
142
+ // background-color above — it shows whatever is behind the (transparent)
143
+ // .ec-header instead, leaving a visible seam of mismatched color between
144
+ // the toolbar and the calendar body. Zero out the margin and swap in the
145
+ // same amount of padding so the toolbar's own background extends through
146
+ // that space instead of leaving a gap for it to show through.
147
+ .ec-toolbar {
148
+ background-color: var(--ec-surface-bg-color);
149
+ margin-block-end: 0;
150
+ padding-block-end: 1em;
151
+ }
152
+ }
153
+
154
+ // Manual dark toggle (an ancestor — typically <body> itself — carries the
155
+ // .ec-dark class).
156
+ html .ec-dark .ec {
157
+ --ec-surface-bg-color: #{$dark};
158
+ --ec-bg-color: #{$dark};
159
+ --ec-text-color: #{$light};
160
+ --ec-border-color: #{map-get($theme-colors, 'centos-purple-800')};
161
+
162
+ --ec-button-bg-color: #{$dark};
163
+ --ec-button-border-color: #{map-get($theme-colors, 'centos-purple-800')};
164
+ --ec-button-text-color: #{$light};
165
+ --ec-button-active-bg-color: #{map-get($theme-colors, 'centos-purple-700')};
166
+ --ec-button-active-border-color: #{map-get($theme-colors, 'centos-purple-400')};
167
+ --ec-button-active-text-color: #{$light};
168
+
169
+ --ec-today-bg-color: #{map-get($theme-colors, 'centos-orange-900')};
170
+ --ec-highlight-color: #{map-get($theme-colors, 'centos-purple-900')};
171
+
172
+ --ec-event-bg-color: #{map-get($theme-colors, 'centos-purple-400')};
173
+ --ec-event-text-color: #{$dark};
174
+ --ec-bg-event-color: #{map-get($theme-colors, 'centos-purple-800')};
175
+
176
+ --ec-popup-bg-color: #{$dark};
177
+ }
178
+
179
+ // Automatic dark mode (an ancestor carries the .ec-auto-dark class and the
180
+ // OS/browser prefers a dark color scheme) — same values as the manual toggle.
181
+ @media (prefers-color-scheme: dark) {
182
+ html .ec-auto-dark .ec {
183
+ --ec-surface-bg-color: #{$dark};
184
+ --ec-bg-color: #{$dark};
185
+ --ec-text-color: #{$light};
186
+ --ec-border-color: #{map-get($theme-colors, 'centos-purple-800')};
187
+
188
+ --ec-button-bg-color: #{$dark};
189
+ --ec-button-border-color: #{map-get($theme-colors, 'centos-purple-800')};
190
+ --ec-button-text-color: #{$light};
191
+ --ec-button-active-bg-color: #{map-get($theme-colors, 'centos-purple-700')};
192
+ --ec-button-active-border-color: #{map-get($theme-colors, 'centos-purple-400')};
193
+ --ec-button-active-text-color: #{$light};
194
+
195
+ --ec-today-bg-color: #{map-get($theme-colors, 'centos-orange-900')};
196
+ --ec-highlight-color: #{map-get($theme-colors, 'centos-purple-900')};
197
+
198
+ --ec-event-bg-color: #{map-get($theme-colors, 'centos-purple-400')};
199
+ --ec-event-text-color: #{$dark};
200
+ --ec-bg-event-color: #{map-get($theme-colors, 'centos-purple-800')};
201
+
202
+ --ec-popup-bg-color: #{$dark};
203
+ }
204
+ }
@@ -242,7 +242,8 @@ main {
242
242
  height: 1lh;
243
243
  display: flex;
244
244
  align-items: center;
245
- transform: translateX(-100%);
245
+ transform: translateX(calc(-100% - #{$spacer * 0.5}));
246
+ transition: transform 200ms ease-out, opacity 200ms ease-out;
246
247
  font-size: 1em;
247
248
  margin-left: 0 !important;
248
249
  margin-right: 0 !important;
@@ -270,13 +271,21 @@ main {
270
271
  .content > h4:hover .heading-anchor,
271
272
  .content > h5:hover .heading-anchor,
272
273
  .content > h6:hover .heading-anchor,
273
- .heading-anchor:focus {
274
+ .content > h1 .heading-anchor:focus,
275
+ .content > h2 .heading-anchor:focus,
276
+ .content > h3 .heading-anchor:focus,
277
+ .content > h4 .heading-anchor:focus,
278
+ .content > h5 .heading-anchor:focus,
279
+ .content > h6 .heading-anchor:focus {
274
280
  opacity: 1;
281
+ transform: translateX(-100%);
275
282
  }
276
- .heading-anchor.is-active,
277
- .heading-anchor.is-active i {
283
+ .heading-anchor.is-active {
278
284
  opacity: 1 !important;
279
285
  visibility: visible !important;
286
+ transform: translateX(-100%) !important;
287
+ }
288
+ .heading-anchor.is-active i {
280
289
  color: var(--bs-primary);
281
290
  }
282
291
 
@@ -33,3 +33,7 @@
33
33
 
34
34
  // 6. Add additional custom code here
35
35
  @import "base/customization";
36
+
37
+ // 7. Third-party component theme overrides (must load after our own
38
+ // customizations so component-specific corrections win the cascade).
39
+ @import "base/calendar";