|
5 | 5 | viewBox="0 0 {{ diagram_width }} {{ diagram_height }}" |
6 | 6 | > |
7 | 7 | <style> |
| 8 | + :root { |
| 9 | + color-scheme: light dark; |
| 10 | +
|
| 11 | + {# Copy vars from Furo theme if present #} |
| 12 | + {% for varname, default in { |
| 13 | + 'color-foreground-primary': 'light-dark(#333, #fff)', |
| 14 | + 'color-background-primary': 'light-dark(#fff, #333)', |
| 15 | + 'color-brand-primary': '#4B8BBE', |
| 16 | + 'color-background-item': '#e0e0e0', |
| 17 | + }.items() %} |
| 18 | + --svg-{{varname}}: var(--{{varname}}, {{default}}); |
| 19 | + {% endfor %} |
| 20 | + } |
8 | 21 | /* Embedded styles for standalone viewing */ |
9 | 22 | .release-cycle-chart { |
10 | | - font-family: Arial, sans-serif; |
| 23 | + font-family: var( |
| 24 | + --font-stack, |
| 25 | + -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, |
| 26 | + Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji); |
11 | 27 | width: 100%; |
| 28 | +
|
| 29 | + --blob-border-width: 1.6px; |
12 | 30 | } |
13 | 31 | .release-cycle-year-line { |
14 | | - stroke: #333; |
| 32 | + stroke: var(--svg-color-foreground-primary); |
15 | 33 | stroke-width: 0.8px; |
16 | 34 | opacity: 75%; |
17 | 35 | } |
18 | 36 | .release-cycle-year-text { |
19 | | - fill: #333; |
| 37 | + fill: var(--svg-color-foreground-primary); |
20 | 38 | } |
21 | 39 | .release-cycle-today-line { |
22 | | - stroke: #4B8BBE; |
23 | | - stroke-width: 1.6px; |
| 40 | + stroke: var(--svg-color-brand-primary); |
| 41 | + stroke-width: var(--blob-border-width); |
24 | 42 | } |
25 | 43 | .release-cycle-row-shade { |
26 | | - fill: #e0e0e0; |
| 44 | + fill: var(--svg-color-background-item); |
27 | 45 | opacity: 50%; |
28 | 46 | } |
29 | 47 | .release-cycle-version-label { |
30 | | - fill: #333; |
| 48 | + fill: var(--svg-color-foreground-primary); |
31 | 49 | } |
32 | 50 | .release-cycle-blob { |
33 | | - stroke-width: 1.6px; |
34 | | - } |
35 | | - .release-cycle-blob-label { |
36 | | - /* white looks good on both light and dark */ |
37 | | - fill: white; |
| 51 | + stroke-width: var(--blob-border-width); |
38 | 52 | } |
39 | | - .release-cycle-blob-label.release-cycle-status-security, |
40 | | - .release-cycle-blob-label.release-cycle-status-bugfix { |
41 | | - /* but use black to improve contrast for lighter backgrounds */ |
42 | | - fill: black; |
| 53 | + text { |
| 54 | + fill: var(--svg-color-foreground-primary); |
| 55 | +
|
| 56 | + /* an outline of the background color, in case it's not set |
| 57 | + correctly */ |
| 58 | + stroke: var(--svg-color-background-primary); |
| 59 | + stroke-width: var(--blob-border-width); |
| 60 | + /* draw stroke first (half of it will be visible as outline) */ |
| 61 | + paint-order: stroke; |
| 62 | +
|
| 63 | + /* use specific colours on known backgrounds */ |
| 64 | + &.release-cycle-status-security , |
| 65 | + &.release-cycle-status-bugfix { |
| 66 | + fill: black; |
| 67 | + stroke: var(--status-bg-color); |
| 68 | + } |
| 69 | + /* For year labels, keep outline below the row shading |
| 70 | + (it's a separate element) */ |
| 71 | + &.release-cycle-version-label-outline { |
| 72 | + fill: transparent; |
| 73 | + } |
| 74 | + &.release-cycle-version-label { |
| 75 | + stroke: none; |
| 76 | + } |
43 | 77 | } |
44 | | - .release-cycle-blob-label.release-cycle-status-end-of-life, |
45 | | - .release-cycle-blob-label.release-cycle-status-prerelease, |
46 | | - .release-cycle-blob-label.release-cycle-status-feature { |
47 | | - fill: #333; |
| 78 | + .release-cycle-status-end-of-life { |
| 79 | + --status-bg-color: #DD2200; |
| 80 | + --status-border-color: #FF8888; |
48 | 81 | } |
49 | | - .release-cycle-status-end-of-life .release-cycle-blob, |
50 | | - .release-cycle-blob.release-cycle-status-end-of-life { |
51 | | - fill: #DD2200; |
52 | | - stroke: #FF8888; |
| 82 | + .release-cycle-status-security { |
| 83 | + --status-bg-color: #FFDD44; |
| 84 | + --status-border-color: #FF8800; |
53 | 85 | } |
54 | | - .release-cycle-status-security .release-cycle-blob, |
55 | | - .release-cycle-blob.release-cycle-status-security { |
56 | | - fill: #FFDD44; |
57 | | - stroke: transparent; |
| 86 | + .release-cycle-status-bugfix { |
| 87 | + --status-bg-color: #00DD22; |
| 88 | + --status-border-color: #008844; |
58 | 89 | } |
59 | | - .release-cycle-status-bugfix .release-cycle-blob, |
60 | | - .release-cycle-blob.release-cycle-status-bugfix { |
61 | | - fill: #00DD22; |
62 | | - stroke: transparent; |
| 90 | + .release-cycle-status-prerelease { |
| 91 | + --status-bg-color: teal; |
| 92 | + --status-border-color: darkgreen; |
63 | 93 | } |
64 | | - .release-cycle-status-prerelease .release-cycle-blob, |
65 | | - .release-cycle-blob.release-cycle-status-prerelease { |
66 | | - fill: teal; |
67 | | - stroke: transparent; |
| 94 | + .release-cycle-status-feature { |
| 95 | + --status-bg-color: #2222EE; |
| 96 | + --status-border-color: #008888; |
68 | 97 | } |
69 | | - .release-cycle-status-feature .release-cycle-blob, |
70 | | - .release-cycle-blob.release-cycle-status-feature { |
71 | | - fill: #2222EE; |
| 98 | + .release-cycle-blob { |
| 99 | + fill: var(--status-bg-color); |
72 | 100 | stroke: transparent; |
73 | 101 | } |
74 | | - .release-cycle-blob-full.release-cycle-status-end-of-life { |
75 | | - fill: #DD2200; |
76 | | - stroke: #FF8888; |
77 | | - } |
78 | | - .release-cycle-border.release-cycle-status-security { |
79 | | - fill: transparent; |
80 | | - stroke: #FF8800; |
81 | | - stroke-width: 1.6px; |
82 | | - } |
83 | | - .release-cycle-border.release-cycle-status-bugfix { |
84 | | - fill: transparent; |
85 | | - stroke: #008844; |
86 | | - stroke-width: 1.6px; |
| 102 | + .release-cycle-blob-full { |
| 103 | + fill: var(--status-bg-color); |
| 104 | + stroke: var(--status-border-color); |
87 | 105 | } |
88 | | - .release-cycle-border.release-cycle-status-prerelease { |
| 106 | + .release-cycle-border { |
89 | 107 | fill: transparent; |
90 | | - stroke: darkgreen; |
91 | | - stroke-width: 1.6px; |
92 | | - } |
93 | | - .release-cycle-border.release-cycle-status-feature { |
94 | | - fill: transparent; |
95 | | - stroke: #008888; |
96 | | - stroke-width: 1.6px; |
| 108 | + stroke: var(--status-border-color); |
| 109 | + stroke-width: var(--blob-border-width); |
97 | 110 | } |
98 | 111 | </style> |
99 | 112 | <defs> |
|
105 | 118 |
|
106 | 119 | {% for version in versions %} |
107 | 120 | {% set y = version.y * line_height %} |
| 121 | + <!-- Outline for legend on the left --> |
| 122 | + <text |
| 123 | + class="release-cycle-version-label-outline" |
| 124 | + x="{{ 0.5 * SCALE }}" |
| 125 | + y="{{ version.y * line_height }}" |
| 126 | + font-size="{{ SCALE }}" |
| 127 | + > |
| 128 | + Python {{ version.key }} |
| 129 | + </text> |
108 | 130 |
|
109 | 131 | {% if version.y % 2 %} |
110 | 132 | <!-- Row shading --> |
|
166 | 188 | </mask> |
167 | 189 |
|
168 | 190 | {% for version in versions %} |
169 | | - <!-- Colourful blob with a label. --> |
| 191 | + <!-- Colourful blob. --> |
170 | 192 |
|
171 | 193 | {% set top_y = version.y * line_height - 1 * SCALE %} |
172 | 194 | {% set height = 1.25 * SCALE %} |
173 | 195 | {% set start_x = date_to_x(version.first_release_date) %} |
174 | 196 | {% set end_x = date_to_x(version.end_of_life_date) %} |
175 | 197 | {% set radius = 0.25 * SCALE %} |
176 | 198 |
|
177 | | - {% set small_text_y = version.y * line_height - 0.1 * SCALE %} |
178 | | - |
179 | 199 | <!-- bugfix/security blobs need to be split between the two phases. |
180 | 200 | Draw the rectangle with two path elements instead. |
181 | 201 | Thanks Claude.ai for the initial conversion. |
|
243 | 263 | mask="url(#release-cycle-mask-{{ id_key }})" |
244 | 264 | /> |
245 | 265 | {% endif %} |
| 266 | + {% endfor %} |
| 267 | + |
| 268 | + <!-- A line for today --> |
| 269 | + <line |
| 270 | + class="release-cycle-today-line" |
| 271 | + x1="{{ date_to_x(today) }}" |
| 272 | + x2="{{ date_to_x(today) }}" |
| 273 | + y1="0" |
| 274 | + y2="{{ diagram_height - line_height }}" |
| 275 | + font-size="{{ SCALE }}" |
| 276 | + /> |
| 277 | + |
| 278 | + {% for version in versions %} |
| 279 | + <!-- Label for colourful blob --> |
| 280 | + |
| 281 | + {% set start_x = date_to_x(version.first_release_date) %} |
| 282 | + {% set end_x = date_to_x(version.end_of_life_date) %} |
| 283 | + {% set middle_x = ([end_x, date_to_x(version.start_security_date)]|min) %} |
| 284 | + {% set small_text_y = version.y * line_height - 0.1 * SCALE %} |
246 | 285 |
|
247 | 286 | <!-- Add text before/after/inside the blob --> |
248 | 287 | <text |
|
276 | 315 | Python {{ version.key }} |
277 | 316 | </text> |
278 | 317 | {% endfor %} |
279 | | - |
280 | | - <!-- A line for today --> |
281 | | - <line |
282 | | - class="release-cycle-today-line" |
283 | | - x1="{{ date_to_x(today) }}" |
284 | | - x2="{{ date_to_x(today) }}" |
285 | | - y1="0" |
286 | | - y2="{{ diagram_height - line_height }}" |
287 | | - font-size="{{ SCALE }}" |
288 | | - /> |
289 | 318 | </svg> |
0 commit comments