hdoc-tools 0.62.4 → 0.63.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.
Files changed (73) hide show
  1. package/editor/dist/assets/{index-BtxvGZHW.js → index-Dknn5g5A.js} +5 -4
  2. package/editor/dist/index.html +13 -13
  3. package/hdoc-build.js +5 -3
  4. package/hdoc-content-routes.js +136 -4
  5. package/hdoc-serve.js +26 -3
  6. package/hdoc-validate-interbook.js +8 -0
  7. package/hdoc-validate.js +92 -35
  8. package/package.json +1 -1
  9. package/ui/css/theme-default/styles/base.css +86 -21
  10. package/ui/css/theme-default/styles/components/api-doc.css +6 -3
  11. package/ui/css/theme-default/styles/components/content.css +140 -39
  12. package/ui/css/theme-default/styles/components/custom-block.css +1 -1
  13. package/ui/css/theme-default/styles/components/htl-doc.css +243 -64
  14. package/ui/css/theme-default/styles/components/htl-library.css +152 -0
  15. package/ui/css/theme-default/styles/components/htl-search.css +267 -0
  16. package/ui/css/theme-default/styles/components/sidebar.css +59 -16
  17. package/ui/css/theme-default/styles/fonts.css +17 -3
  18. package/ui/css/theme-default/styles/htldoc.layouts.css +756 -87
  19. package/ui/css/theme-default/styles/vars.css +40 -35
  20. package/ui/favicon.svg +64 -0
  21. package/ui/images/hornbill-logo-full-reversed.svg +92 -0
  22. package/ui/images/hornbill-logo-full.svg +92 -0
  23. package/ui/images/hug_library.jpg +0 -0
  24. package/ui/images/mcp-catalog.svg +9 -0
  25. package/ui/images/products/hornbill-square.svg +1 -0
  26. package/ui/index.html +1106 -342
  27. package/ui/js/bootstrap.js +89 -0
  28. package/ui/js/doc.hornbill.js +3156 -751
  29. package/ui/js/hb.vue.js +121 -0
  30. package/ui/js/highlightjs/highlight.pack.js +1513 -2
  31. package/ui/js/highlightjs/styles/vs2015-accessible.css +141 -0
  32. package/ui/js/highlightjs-badge.js +41 -58
  33. package/ui/js/mermaid.min.js +1447 -1295
  34. package/ui/js/webcomponents/hdocApprove.js +115 -0
  35. package/ui/js/highlightjs/styles/brown-paper.css +0 -64
  36. package/ui/js/highlightjs/styles/brown-papersq.png +0 -0
  37. package/ui/js/highlightjs/styles/codepen-embed.css +0 -60
  38. package/ui/js/highlightjs/styles/color-brewer.css +0 -71
  39. package/ui/js/highlightjs/styles/darcula.css +0 -77
  40. package/ui/js/highlightjs/styles/dark.css +0 -63
  41. package/ui/js/highlightjs/styles/darkula.css +0 -6
  42. package/ui/js/highlightjs/styles/default.css +0 -99
  43. package/ui/js/highlightjs/styles/dracula.css +0 -76
  44. package/ui/js/highlightjs/styles/far.css +0 -71
  45. package/ui/js/highlightjs/styles/foundation.css +0 -88
  46. package/ui/js/highlightjs/styles/github-gist.css +0 -71
  47. package/ui/js/highlightjs/styles/github-mm.css +0 -71
  48. package/ui/js/highlightjs/styles/github.css +0 -99
  49. package/ui/js/highlightjs/styles/googlecode.css +0 -89
  50. package/ui/js/highlightjs/styles/grayscale.css +0 -101
  51. package/ui/js/highlightjs/styles/idea.css +0 -97
  52. package/ui/js/highlightjs/styles/ir-black.css +0 -73
  53. package/ui/js/highlightjs/styles/kavadocs.css +0 -71
  54. package/ui/js/highlightjs/styles/kavadocsdark.css +0 -120
  55. package/ui/js/highlightjs/styles/kimbie.dark.css +0 -74
  56. package/ui/js/highlightjs/styles/kimbie.light.css +0 -74
  57. package/ui/js/highlightjs/styles/magula.css +0 -70
  58. package/ui/js/highlightjs/styles/mono-blue.css +0 -59
  59. package/ui/js/highlightjs/styles/monokai-sublime.css +0 -83
  60. package/ui/js/highlightjs/styles/monokai.css +0 -70
  61. package/ui/js/highlightjs/styles/obsidian.css +0 -88
  62. package/ui/js/highlightjs/styles/paraiso-dark.css +0 -72
  63. package/ui/js/highlightjs/styles/paraiso-light.css +0 -72
  64. package/ui/js/highlightjs/styles/railscasts.css +0 -106
  65. package/ui/js/highlightjs/styles/rainbow.css +0 -85
  66. package/ui/js/highlightjs/styles/solarized-dark.css +0 -84
  67. package/ui/js/highlightjs/styles/solarized-light.css +0 -84
  68. package/ui/js/highlightjs/styles/sunburst.css +0 -102
  69. package/ui/js/highlightjs/styles/twilight.css +0 -97
  70. package/ui/js/highlightjs/styles/vs.css +0 -68
  71. package/ui/js/highlightjs/styles/vs2015.css +0 -117
  72. package/ui/js/highlightjs/styles/xcode.css +0 -104
  73. package/ui/js/highlightjs/styles/zenburn.css +0 -80
@@ -1,55 +1,115 @@
1
1
  /* put htl styles here */
2
2
 
3
+ /*
4
+ No `.main-layout .library-banner` rule here. Nothing carried that class - index.html uses
5
+ .library-banner-hug below - so it was dead along with its 72KB /images/library.png.
6
+ Removed r723.
7
+ */
8
+
9
+ .main-layout .library-banner-hug{
10
+ position:relative;
11
+ /* scrim gradient UNDER the text, over the photo: the image's bright light-streak ran
12
+ straight behind "How can we help?" and made it hard to read. The gradient darkens the
13
+ left/text side and fades out by ~78% so the right of the image stays visible.
14
+ background-position/size/repeat are comma lists - first value per layer is the gradient,
15
+ second the photo. */
16
+ background-image: linear-gradient(90deg, rgba(0,0,0,0.78) 0%, rgba(0,0,0,0.55) 45%, rgba(0,0,0,0) 78%),
17
+ url(/images/hug_library.jpg);
18
+ background-repeat:no-repeat,no-repeat;
19
+ background-position: 0 0, 100% 50%;
20
+ background-size: 100% 100%, 900px;
21
+ background-color:#000000;
22
+ color: #ffffff;
23
+ height:250px;
24
+ }
25
+
26
+ .main-layout .library-banner-hug h1{
27
+ /* soft drop shadow lifts the heading off any bright detail the scrim doesn't fully cover */
28
+ text-shadow: 0 2px 12px rgba(0,0,0,0.85);
29
+ }
30
+
3
31
  /* LAYOUT */
4
32
  .hb-container-vertical{
5
- height: 100%;
6
33
  display: flex;
7
34
  flex-direction: column;
35
+ height:100%;
8
36
  }
37
+
9
38
  .hb-container-horizontal{
10
- display: flex;
39
+ display: flex;
11
40
  flex-direction: row;
12
- width: 100%;
41
+ width:100%;
13
42
  }
14
43
  .hb-container-vertical > *,
15
44
  .hb-container-horizontal > *{
16
45
  flex-shrink: 1;
17
46
  }
18
- .hb-container-vertical > .hb-container-expand,
47
+
48
+ /* "Grow to fill the parent" - a LAYOUT utility, nothing more.
49
+ *
50
+ * This used to declare `overflow: auto` alongside flex-grow, which quietly made every
51
+ * container that merely needed to fill its parent into a scroll container too. On the search
52
+ * view six of them nested inside each other and only the innermost two ever scrolled. Because
53
+ * :hover propagates to ancestors and the outer ones span the full width, any scrollbar they
54
+ * painted landed on the same pixels as the content scrollbar - so the content bar appeared to
55
+ * light up on its own when the filter sidebar was hovered.
56
+ *
57
+ * min-height/min-width are now explicit. They are NOT decoration: a flex item's automatic
58
+ * minimum size is its content size, which is why a nested flex column refuses to shrink and
59
+ * overflows its parent. `overflow: auto` used to set that minimum to zero as a side effect
60
+ * (per spec, any overflow value other than visible does), so removing the overflow without
61
+ * these would have broken every nested layout in the app.
62
+ *
63
+ * Scrolling is now opted into with .hb-scroll, below. */
64
+ .hb-container-expand,
19
65
  .hb-container-horizontal > .hb-container-expand{
20
66
  flex-grow: 1;
21
- overflow: auto;
22
- }
23
- .hb-full-height{
24
- height: 100%;
25
- }
26
- .hb-min-height{
27
- height: auto;
67
+ min-height: 0;
68
+ min-width: 0;
69
+ overflow: hidden;
28
70
  }
29
- .hb-overflow-hidden{
30
- overflow: hidden !important;
71
+
72
+ /* The scroll regions themselves. Selectors are specific enough to beat the
73
+ * `.hb-container-horizontal > .hb-container-expand` form above, which is (0,2,0) - a bare
74
+ * .hb-scroll would lose the tie and silently do nothing. */
75
+ .hb-scroll,
76
+ .hb-container-expand.hb-scroll,
77
+ .hb-container-horizontal > .hb-container-expand.hb-scroll{
78
+ overflow: auto;
31
79
  }
80
+
81
+ /* hb-full-height / hb-min-height / hb-overflow-hidden / hb-center-h / hb-text-overflow were
82
+ unused hb- layout utilities (the hb- system is app chrome, never authored content) and have
83
+ been removed. hb-text-overflow duplicated .overflow-ellipsis, which is the one in use. */
32
84
  .hb-center-v
33
85
  {
34
86
  margin-top: auto;
35
87
  margin-bottom: auto;
36
88
  }
37
- .hb-text-overflow
89
+
90
+ .hb-bg-mute
38
91
  {
39
- white-space: nowrap;
40
- overflow: hidden;
41
- text-overflow: ellipsis;
92
+ background-color: var(--htl-c-bg-mute);
42
93
  }
43
94
 
44
95
  /* toolbar */
45
96
  .toolbar-layout
46
97
  {
47
- min-height: 58px;
48
98
  height: 58px;
49
99
  line-height: 58px;
50
100
  border-bottom: 1px solid var(--htl-c-divider-light);
51
101
  }
52
102
 
103
+ .toolbar-layout .documentation-home
104
+ {
105
+ font-size:16px;
106
+ font-weight:500;
107
+ color: var(--htl-button-alt-text);
108
+ border-left: 2px solid #efefef;
109
+ padding-left: 20px;
110
+ margin: 0;
111
+ }
112
+
53
113
  .toolbar-logo
54
114
  {
55
115
  width: 200px;
@@ -60,18 +120,15 @@
60
120
 
61
121
  .toolbar-logo-image
62
122
  {
63
- background: url(/css/images/hornbill-logo-full.svg) no-repeat left center;
123
+ cursor: pointer;
124
+ background: url(/images/hornbill-logo-full.svg) no-repeat left center;
64
125
  height:100%;
126
+ display: block;
65
127
  }
66
128
 
67
- .toolbar-split {
68
- margin-top: auto;
69
- margin-bottom: auto;
70
- height: 50%;
71
- border-left: 2px solid var(--htl-c-divider-light);
72
- margin-left: 0.5rem;
73
- margin-right: 0.5rem;
74
- display: block;
129
+ .dark .toolbar-logo-image
130
+ {
131
+ background-image: url(/images/hornbill-logo-full-reversed.svg);
75
132
  }
76
133
 
77
134
  .toolbar-middle
@@ -82,53 +139,155 @@
82
139
  .toolbar-right
83
140
  {
84
141
  padding: 0px 20px;
142
+ /* never flex-shrink the icon/profile groups: when the toolbar row ran short of space the
143
+ default shrink squeezed the profile <img> (max-width:100%) to a 19px-wide oval. The
144
+ search-bar variant below is the one element that gives up width instead. */
145
+ flex-shrink: 0;
146
+ }
147
+
148
+ .toolbar-right.toolbar-search-bar
149
+ {
150
+ /* the flexible element of the toolbar: fixed 240px basis when there is room, shrinks down
151
+ to 130px before anything else in the row is squeezed (everything else is flex-shrink:0) */
152
+ flex: 0 1 240px;
153
+ min-width: 130px;
154
+ }
155
+
156
+ .toolbar-search-bar .position-relative
157
+ {
158
+ width: 100%; /* let the search input track the flexing container width */
159
+ }
160
+
161
+ /* Transient "needs two characters" hint under the toolbar search box. Positioned against
162
+ .toolbar-search-bar .position-relative (the input wrapper), right-aligned because the box
163
+ sits at the right edge of the toolbar and a left-aligned bubble would run off screen at
164
+ narrow widths. Not in flow, so it never nudges the toolbar. */
165
+ .search-tooshort-hint
166
+ {
167
+ position: absolute;
168
+ top: calc(100% + 6px);
169
+ right: 0;
170
+ z-index: 1200;
171
+ padding: 6px 10px;
172
+ border: 1px solid var(--htl-c-divider);
173
+ border-radius: 6px;
174
+ background-color: var(--htl-c-bg-soft);
175
+ color: var(--htl-c-text-2);
176
+ font-size: 0.8rem;
177
+ line-height: 1.2;
178
+ white-space: nowrap;
179
+ box-shadow: 0 2px 8px rgba(0,0,0,0.18);
85
180
  }
86
181
 
87
182
  .toolbar-action
88
183
  {
89
184
  cursor:pointer;
90
185
  text-decoration : none;
91
- padding: 4px;
186
+ padding: 6px;
92
187
  }
93
188
  .toolbar-action:hover
94
189
  {
95
190
  background-color: var(--htl-c-blue-dimm-2);
191
+ border-radius: 4px 4px;
192
+ }
193
+ .toolbar-action.documentation-menu-popper
194
+ {
195
+ display:none;
96
196
  }
97
197
 
198
+ /* circular toolbar icon buttons */
199
+ .toolbar-icon-btn
200
+ {
201
+ width: 32px;
202
+ height: 32px;
203
+ padding: 0;
204
+ display: inline-flex;
205
+ align-items: center;
206
+ justify-content: center;
207
+ }
98
208
 
209
+ /* Glyph size for the toolbar buttons. These are btn-sm, so without this the Bootstrap
210
+ Icons inherit a 12px font-size and read as specks in a 32px button. Sized here rather
211
+ than per-icon so every toolbar button matches - the MCP catalog icon is a CSS mask
212
+ (.hb-icon-mcp) and fills its box exactly, whereas an icon font glyph carries its own
213
+ internal padding, so the mask is set slightly smaller to land at the same weight. */
214
+ .toolbar-icon-btn .bi
215
+ {
216
+ font-size: 1.15rem;
217
+ line-height: 1;
218
+ }
99
219
 
220
+ /* WCAG 2.5.5: 44px minimum touch target - only on touch devices */
221
+ @media (pointer: coarse) {
222
+ .toolbar-icon-btn {
223
+ width: 44px;
224
+ height: 44px;
225
+ }
226
+ }
100
227
 
101
- /* toolbar title and desc */
228
+ /* toolbar title (the description span is .description2, styled in base.css) */
102
229
  .toolbar-layout .title
103
230
  {
104
231
  white-space: nowrap;
105
232
  overflow: hidden;
106
233
  text-overflow: ellipsis;
107
234
  }
108
- .toolbar-layout .description
109
- {
110
- white-space: nowrap;
111
- overflow: hidden;
112
- text-overflow: ellipsis;
113
- }
114
235
 
115
- .toolbar-layout .mobile-menu-btn
236
+ /* mobile burger (book navigation toggle). Lives in the book title band in the main app and in
237
+ the toolbar in the settings app - hence the unscoped selector. Hidden >=1020px (sidebar.css). */
238
+ .mobile-menu-btn
116
239
  {
117
240
  border-radius: 4px 4px;
118
241
  margin-left:10px;
119
- padding: 4 4;
242
+ /* no padding declaration: the old "padding: 4 4;" was unitless and therefore DROPPED by the
243
+ parser, so the button has always rendered with the UA default - keep that, don't "fix" it
244
+ into a visual change */
120
245
  font-size: var(--htl-massive-font-size);
121
246
  border-color: var(--htl-button-brand-border);
122
247
  color:var(--htl-c-brand-dark);
123
248
  }
124
249
 
125
- .toolbar-layout .mobile-menu-btn:hover
250
+ .mobile-menu-btn:hover
126
251
  {
127
252
  border: var(--htl-button-brand-lighter);
128
253
  color:var(--htl-c-text-dark-1);
129
254
  background:var(--htl-c-brand);
130
255
  }
131
256
 
257
+ /* book title band - burger sits left of the title/description block, vertically centered */
258
+ .title-band
259
+ {
260
+ display: flex;
261
+ align-items: center;
262
+ gap: 12px;
263
+ }
264
+ /* round brand button, matching the in-page TOC button (.toc-mobile-btn in content.css).
265
+ sidebar.css hides it >=1020px with an equal-specificity selector - it loads later, so
266
+ the display:flex here loses there by source order, as intended. */
267
+ .title-band .mobile-menu-btn
268
+ {
269
+ margin-left: 0;
270
+ flex: 0 0 auto;
271
+ width: 44px;
272
+ height: 44px;
273
+ border-radius: 50%;
274
+ border: none;
275
+ background: var(--htl-c-brand);
276
+ color: var(--htl-c-text-dark-1);
277
+ box-shadow: var(--htl-shadow-3);
278
+ font-size: 1.4rem;
279
+ display: flex;
280
+ align-items: center;
281
+ justify-content: center;
282
+ }
283
+ .title-band .mobile-menu-btn:hover
284
+ {
285
+ border: none;
286
+ background: var(--htl-c-brand);
287
+ color: var(--htl-c-text-dark-1);
288
+ filter: brightness(1.05);
289
+ }
290
+
132
291
  /* top nav bar */
133
292
  .nav-bar-nav-list {
134
293
  align-items: stretch;
@@ -171,8 +330,8 @@
171
330
  {
172
331
  background-color: var(--htl-c-white-soft);
173
332
  padding:10px;
174
- border: 1px solid var(--htl-c-divider-light);
175
- border-radius: 4px 4px 0 0;
333
+ border: 1px solid var(--htl-c-divider-light);
334
+ border-radius: var(--htl-box-radius) var(--htl-box-radius) 0 0;
176
335
  }
177
336
  .panel-header .icon
178
337
  {
@@ -198,12 +357,14 @@
198
357
  {
199
358
  background-color: var(--htl-c-black);
200
359
  }
360
+
201
361
  .panel-content
202
362
  {
203
363
  padding:10px;
204
- border: 1px solid var(--htl-c-divider-light);
364
+ border: 1px solid var(--htl-c-divider-light);
205
365
  border-color: var(--htl-c-divider-light)!important;
206
366
  border-top-width: 0px;
367
+ border-radius: 0 0 var(--htl-box-radius) var(--htl-box-radius);
207
368
  }
208
369
 
209
370
  .lh-normal
@@ -216,14 +377,30 @@
216
377
  }
217
378
  .fs-12
218
379
  {
219
- font-size:12px;
380
+ font-size:12px !important;
220
381
  }
221
- /* user profile stuff */
222
- .dark .userprofile
382
+ .fs-14
223
383
  {
224
- background-color: var(--htl-c-bg);
225
-
384
+ font-size:14px !important;
226
385
  }
386
+ .fs-16
387
+ {
388
+ font-size:16px !important;
389
+ }
390
+ .fs-18
391
+ {
392
+ font-size:18px !important;
393
+ }
394
+ .fs-20
395
+ {
396
+ font-size:20px !important;
397
+ }
398
+
399
+ /* user profile stuff */
400
+ /* No background on .userprofile itself: the wrapper spans the toolbar's full 58px height,
401
+ so an opaque dark fill painted OVER the toolbar's border-bottom - a toolbar-coloured
402
+ notch "hanging" into the band below, dark mode only. The open menu is coloured by the
403
+ .dropdown-menu rules below, which is all the removed .dark rule was ever needed for. */
227
404
 
228
405
  .dark .userprofile .dropdown-menu
229
406
  {
@@ -241,70 +418,562 @@
241
418
  {
242
419
  display:none;
243
420
  }
244
- .userprofile .svg-prof
421
+ /* unscoped: covers the toolbar dropdown avatars (.userprofile) AND the settings profile
422
+ details view, which renders .svg-prof outside .userprofile */
423
+ .svg-prof
245
424
  {
246
425
  border-radius: 50%;
426
+ /* the default avatar SVG is an octagon with TRANSPARENT corners, so border-radius alone
427
+ changed nothing visible - a solid fill behind it makes the clipped shape read as a
428
+ circle, and the border keeps that circle visible on same-coloured toolbars */
429
+ background-color: #ffffff;
430
+ border: 1px solid var(--htl-c-divider-light);
247
431
  }
432
+ /* eof user profile stuff */
248
433
 
249
- /* theme switcher */
250
- .theme-switch {
251
- position:relative;
434
+ /* The .theme-switch / .slider checkbox-toggle block lived here. The theme control has been the
435
+ two toolbar buttons for a long time - no markup anywhere emits theme-switch or slider, and
436
+ `input:checked + .slider` was an unscoped global rule. Removed along with the
437
+ .theme-switch-checkbox JS that used to drive it. */
438
+
439
+ .input-group-text.white
440
+ {
441
+ background-color: #ffffff;
442
+ }
443
+
444
+ /* Dark mode: Search input and filter button styles.
445
+ Borderless (transparent, not none, so the box height stays in step with the adjoining
446
+ .form-control) - the visible border made the magnifier segment stand out against the
447
+ search input beside it. */
448
+ .dark .input-group-text.white
449
+ {
450
+ background-color: var(--htl-c-bg-soft);
451
+ color: var(--htl-c-text-1);
452
+ border-color: transparent;
453
+ }
454
+
455
+ .dark .input-group .form-control
456
+ {
457
+ background-color: var(--htl-c-bg-soft);
458
+ color: var(--htl-c-text-1);
459
+ /* transparent, matching .input-group-text.white above - a divider-coloured border left
460
+ light notches at the segment join and a faint outline round the input half while the
461
+ magnifier half was borderless */
462
+ border-color: transparent;
463
+ /* bootstrap's .form-control clips its background to padding-box, so with a transparent
464
+ border the fill stops 1px short all round and the input renders smaller than the
465
+ magnifier segment - paint under the border like .input-group-text does */
466
+ background-clip: border-box;
467
+ }
468
+
469
+ /* Dark mode: Toolbar search input */
470
+ .dark .toolbar-search-bar .form-control
471
+ {
472
+ background-color: var(--htl-c-bg-soft);
473
+ color: var(--htl-c-text-1);
474
+ border-color: var(--htl-c-divider);
475
+ }
476
+
477
+ /* Bootstrap's default placeholder is a near-black grey (rgba(33,37,41,.75)) - unreadable on
478
+ the dark-soft input backgrounds above. Covers every dark-mode text input in one go. */
479
+ .dark .form-control::placeholder
480
+ {
481
+ /* text-4 rather than text-2: placeholder is a hint, not content - the brighter tone read
482
+ like typed text. Still ~5:1 on the dark-soft input background. */
483
+ color: var(--htl-c-text-4);
484
+ }
485
+
486
+ .dark .LibraryContent .btn-light,
487
+ .dark .library-banner-hug .btn-light
488
+ {
489
+ background-color: var(--htl-c-bg-soft);
490
+ color: var(--htl-c-text-1);
491
+ border-color: var(--htl-c-divider);
492
+ }
493
+
494
+ .dark .LibraryContent .btn-light:hover,
495
+ .dark .library-banner-hug .btn-light:hover
496
+ {
497
+ background-color: var(--htl-c-bg-mute);
498
+ color: var(--htl-c-text-1);
499
+ border-color: var(--htl-c-divider-light);
500
+ }
501
+
502
+ .dark .LibraryContent .dropdown-menu,
503
+ .dark .library-banner-hug .dropdown-menu
504
+ {
505
+ background-color: var(--htl-c-bg-soft);
506
+ border-color: var(--htl-c-divider);
507
+ }
508
+
509
+ .dark .LibraryContent .dropdown-menu .dropdown-item,
510
+ .dark .library-banner-hug .dropdown-menu .dropdown-item
511
+ {
512
+ color: var(--htl-c-text-1);
513
+ }
514
+
515
+ .dark .LibraryContent .dropdown-menu .dropdown-item:hover,
516
+ .dark .library-banner-hug .dropdown-menu .dropdown-item:hover
517
+ {
518
+ background-color: var(--htl-c-bg-mute);
519
+ color: var(--htl-c-text-1);
520
+ }
521
+
522
+ .form-control:focus {
523
+ border-color: #0066cc;
524
+ box-shadow: 0 0 0 2px rgba(0, 102, 204, 0.25);
525
+ }
526
+
527
+ .pad-20
528
+ {
529
+ padding:20px 20px;
530
+ }
531
+
532
+ .c-pointer
533
+ {
534
+ cursor: pointer;
535
+ }
536
+
537
+ .mw-800
538
+ {
539
+ max-width: 800px!important;
540
+ }
541
+
542
+ .fs-7
543
+ {
544
+ font-size: 0.75rem!important;
545
+ }
546
+
547
+ .mt-018
548
+ {
549
+ margin-top: 0.18rem!important;
550
+ }
551
+
552
+ .overflow-ellipsis
553
+ {
554
+ text-overflow: ellipsis;
555
+ overflow: hidden;
556
+ white-space: nowrap;
557
+ }
558
+
559
+
560
+ .text-light-1
561
+ {
562
+ color: var(--htl-c-text-2);
563
+ }
564
+ .text-light-2
565
+ {
566
+ color: var(--htl-c-text-3);
567
+ }
568
+
569
+
570
+ /* edit action icon - to make align with pdf download */
571
+ .toolbar-action .bi
572
+ {
573
+ font-size: 20px;
574
+ top: 4px;
575
+ position: relative;
576
+ }
577
+ /* pdf download button */
578
+ .toolbar-action.pdffile:hover{
579
+ background: rgba(0, 0, 255, 0);
580
+
581
+ }
582
+ .toolbar-action.pdffile a {
252
583
  display: inline-block;
253
- width: 30px;
254
- height: 20px;
255
-
584
+ margin: 5px;
585
+ position: relative;
586
+ text-align: center;
587
+ vertical-align: middle;
588
+ width: 50px;
589
+ }
590
+
591
+ .toolbar-action.pdffile a span {
592
+ background: #a82315; /* Darkened for WCAG AAA (7:1) with white text */
593
+ border-radius: 4px;
594
+ color: #ffffff;
595
+ display: inline-block;
596
+ font-size: 8px;
597
+ font-weight: normal;
598
+ line-height: normal;
599
+ padding: 5px 10px;
600
+ position: relative;
601
+ text-transform: uppercase;
602
+ z-index: 1;
256
603
  }
257
604
 
258
- .theme-switch input {
259
- opacity: 0;
260
- width: 0;
261
- height: 0;
605
+ .toolbar-action.pdffile a span:last-child {
606
+ margin-left: -20px;
262
607
  }
263
608
 
264
- .slider {
609
+ .toolbar-action.pdffile a:after {
610
+ background: #ffffff;
611
+ border: solid 2px #9fb4cc;
612
+ border-radius: 4px;
613
+ content: '';
614
+ display: block;
615
+ height: 28px;
616
+ left: 50%;
617
+ margin: -16px 0 0 -8px;
265
618
  position: absolute;
266
- cursor: pointer;
267
- top: 0;
268
- left: 0;
269
- right: 0;
270
- bottom: 0;
271
- background-color: #ccc;
272
- -webkit-transition: .4s;
273
- transition: .4s;
619
+ top: 60%;
620
+ width: 22px;
621
+ }
622
+
623
+ .toolbar-action.pdffile a span:first-child {
624
+ display: none;
625
+ margin-left: -7px;
626
+ }
627
+
628
+ .toolbar-action.pdffile a:hover span:first-child {
629
+ display: inline-block;
630
+ }
631
+
632
+ .toolbar-action.pdffile a:hover span:last-child {
633
+ display: none;
634
+ }
635
+ /* eof pdf download button */
636
+
637
+
638
+ /* modal dialog - support dark mode */
639
+ .modal-content
640
+ {
641
+ color: var(--htl-c-text-1);
642
+ background-color: var(--htl-c-bg);
643
+ border: 1px solid var(--htl-c-divider-light);
274
644
  }
275
645
 
276
- .slider:before {
646
+ .dark .border{
647
+
648
+ border: 1px solid var(--htl-c-divider-light) !important;
649
+ }
650
+ .dark .border-bottom{
651
+
652
+ border-bottom: 1px solid var(--htl-c-divider-light) !important;
653
+ }
654
+ .dark .border-top{
655
+
656
+ border-top: 1px solid var(--htl-c-divider-light) !important;
657
+ }
658
+
659
+
660
+ /* only the hide-on-* utilities are used; the show-on-* twins matched nothing (and their
661
+ display:inherit made them a poor "show" anyway) */
662
+ @media (max-width: 900px) {
663
+
664
+ .hide-on-tablet
665
+ {
666
+ display:none;
667
+ }
668
+
669
+ /* compact the toolbar: at the fixed 200px logo width plus the default 20px paddings the
670
+ fixed toolbar pieces (logo, wordmark, icon buttons, profile) exceeded the viewport well
671
+ above phone widths, so the flex row squeezed whatever it could - most visibly the
672
+ profile image. Applies from here down rather than only <=602px for the same reason. */
673
+ .toolbar-logo {
674
+ width: auto;
675
+ min-width: 0;
676
+ flex: 0 0 auto; /* without this the flex row shrank the container under its own 140px image */
677
+ padding: 0 10px;
678
+ }
679
+
680
+ .toolbar-logo-image {
681
+ width: 140px;
682
+ background-size: contain;
683
+ }
684
+
685
+ /* the logo already reads "Hornbill"; the wordmark doesn't fit alongside the search
686
+ bar/button and profile at these widths */
687
+ .toolbar-layout .documentation-home {
688
+ display: none;
689
+ }
690
+
691
+ .toolbar-middle {
692
+ padding: 0;
693
+ }
694
+
695
+ .toolbar-right {
696
+ padding: 0 10px;
697
+ }
698
+
699
+ }
700
+
701
+
702
+ /* narrow-viewport-only elements (e.g. the toolbar search button that replaces the inline
703
+ search box below 602px) - hidden by default, shown by the media query below */
704
+ .show-on-mobile-only {
705
+ display: none;
706
+ }
707
+
708
+ @media (max-width: 602px) {
709
+ /* the inline search box is replaced by the .show-on-mobile-only search button */
710
+ .toolbar-search-bar{
711
+ display:none;
712
+ }
713
+
714
+ .hide-on-mobile
715
+ {
716
+ display:none;
717
+ }
718
+
719
+ .show-on-mobile-only {
720
+ display: inline-block;
721
+ }
722
+
723
+ /* the rest of the narrow-toolbar compaction (logo, wordmark, paddings) lives in the
724
+ max-width:900px block above - the toolbar ran out of space well above phone widths */
725
+
726
+ }
727
+
728
+
729
+ /* H2 toc/hash highlighter.
730
+ Declared on :root, not `*`: these used to be stamped onto every element in the document
731
+ instead of inherited once - a real style-recalc cost on element-heavy article pages. */
732
+ :root {
733
+ --highlight-anim-time: 3s;
734
+ --highlight-bkgnd: rgba(255, 219, 206, 0.212);
735
+ /* Was rgb(53,53,53) - fully opaque, and therefore able to hide the very section it is
736
+ highlighting if it ever paints above the text. White at 7.8% over the dark page background
737
+ (rgb(36,36,36)) composites to exactly that same rgb(53,53,53), so this is the same colour
738
+ with none of the risk, and it matches how the light-mode fill was already written. */
739
+ --dark-highlight-bkgnd: rgba(255, 255, 255, 0.078);
740
+ }
741
+
742
+ @keyframes ref-animation {
743
+ 0% { background-color: transparent; border: dashed 2px transparent;}
744
+ 4% { background-color: var(--highlight-bkgnd); border: dashed 2px rgb(202, 40, 0); }
745
+ 8% { background-color: transparent; border: dashed 2px transparent; }
746
+ 12% { background-color: var(--highlight-bkgnd); border: dashed 2px rgb(202, 40, 0); }
747
+ 100% { background-color: transparent; border: dashed 2px transparent; }
748
+ }
749
+
750
+ /* Section highlight. This is an OVERLAY drawn over the section, not a wrapper around it -
751
+ the old .highlight-container re-parented the heading and its siblings into a new div and
752
+ never put them back, so containers accumulated and nested on every hash click. The overlay
753
+ is positioned against .injected-document-container (position:relative) and is inert. */
754
+ .hb-section-highlight {
277
755
  position: absolute;
278
- content: "";
279
- height: 13px;
280
- width: 13px;
281
- left: 2px;
282
- bottom: 4px;
756
+ left: 8px;
757
+ right: 8px;
758
+ /* behind the article text. Both fills are translucent, so being on top would only tint rather
759
+ than hide - this is the preferred rendering, not a correctness crutch. Keep both properties
760
+ that way round: if you ever make a fill opaque again, the overlay becomes a blindfold. */
761
+ z-index: -1;
762
+ pointer-events: none;
763
+ border-radius: 8px;
764
+ box-sizing: border-box;
765
+ animation-name: ref-animation;
766
+ animation-duration: var(--highlight-anim-time);
767
+ }
768
+
769
+ .dark .hb-section-highlight {
770
+ animation-name: dark-ref-animation;
771
+ }
772
+
773
+ @keyframes dark-ref-animation {
774
+ 0% { background-color: transparent; border: dashed 2px transparent; }
775
+ 4% { background-color: var(--dark-highlight-bkgnd); border: dashed 2px rgb(146, 146, 146); }
776
+ 8% { background-color: transparent; border: dashed 2px transparent; }
777
+ 12% { background-color: var(--dark-highlight-bkgnd); border: dashed 2px rgb(146, 146, 146); }
778
+ 100% { background-color: transparent; border: dashed 2px transparent; }
779
+ }
780
+
781
+ .HTL-doc table {
283
782
  background-color: white;
284
- -webkit-transition: .4s;
285
- transition: .4s;
286
783
  }
287
784
 
288
- input:checked + .slider {
289
- background-color: #2196F3;
785
+ .dark .HTL-doc table {
786
+ background-color: rgb(36, 36, 36);
290
787
  }
291
788
 
292
- input:focus + .slider {
293
- box-shadow: 0 0 1px #2196F3;
789
+ .HTL-fs-sm {
790
+ font-size: .875rem !important;
294
791
  }
295
792
 
296
- input:checked + .slider:before {
297
- -webkit-transform: translateX(13px);
298
- -ms-transform: translateX(13px);
299
- transform: translateX(13px);
793
+ .HTL-actionlink {
794
+ color: var(--htl-c-blue);
795
+ cursor: pointer;
300
796
  }
301
797
 
302
- /* Rounded sliders */
303
- .slider.round {
304
- border-radius: 34px;
798
+ /* --htl-c-blue is a dark blue tuned for light backgrounds; on the dark page background
799
+ it measures 1.86:1, well under the WCAG AA 4.5:1 floor and dimmer than the body text
800
+ beside it - backwards for a call to action. The lighter blue is the same one the
801
+ library and search result links switch to in dark mode. */
802
+ .dark .HTL-actionlink {
803
+ color: var(--htl-c-blue-light);
305
804
  }
306
805
 
307
- .slider.round:before {
308
- border-radius: 50%;
806
+ .HTL-skeleton{
807
+ background-color: var(--htl-c-gray-light-4);
808
+ position: relative;
809
+ border-radius: 0.25rem;
810
+ overflow: hidden;
309
811
  }
310
812
 
813
+ .HTL-skeleton::after {
814
+ content: "";
815
+ position: absolute;
816
+ top: 0;
817
+ left: 0;
818
+ right: 0;
819
+ bottom: 0;
820
+ background: linear-gradient(
821
+ 90deg,
822
+ transparent 0%,
823
+ rgba(255, 255, 255, 0.4) 20%,
824
+ rgba(255, 255, 255, 0.6) 50%,
825
+ rgba(255, 255, 255, 0.4) 80%,
826
+ transparent 100%
827
+ );
828
+ animation: HTL-wave-anim 1.5s ease-in-out infinite;
829
+ transform: translateX(-100%);
830
+ }
831
+
832
+ .dark .HTL-skeleton {
833
+ background-color: var(--htl-c-gray-dark-3);
834
+ }
835
+
836
+ .dark .HTL-skeleton::after {
837
+ background: linear-gradient(
838
+ 90deg,
839
+ transparent 0%,
840
+ rgba(255, 255, 255, 0.05) 20%,
841
+ rgba(255, 255, 255, 0.1) 50%,
842
+ rgba(255, 255, 255, 0.05) 80%,
843
+ transparent 100%
844
+ );
845
+ }
846
+
847
+ @keyframes HTL-wave-anim {
848
+ 0% {
849
+ transform: translateX(-100%);
850
+ }
851
+ 50% {
852
+ transform: translateX(100%);
853
+ }
854
+ 100% {
855
+ transform: translateX(100%);
856
+ }
857
+ }
858
+
859
+ /* skeletons are app chrome only (search + library loading states); the size variants that
860
+ nothing emits (-lg -sm -20 -40 -60 -80) have been removed - only -10 and -100 are used */
861
+ .HTL-skeleton.HTL-skeleton-text{
862
+ height: 1rem;
863
+ width: 40%;
864
+ border-radius: 0.25rem;
865
+ }
866
+ .HTL-skeleton.HTL-skeleton-text.HTL-skeleton-text-10{ width: 10%; }
867
+ .HTL-skeleton.HTL-skeleton-text.HTL-skeleton-text-100{ width: 100%; }
868
+
869
+ .btn-xs{
870
+ padding: .14rem .14rem !important;
871
+ font-size: .875rem!important;
872
+ border-radius: .1rem!important;
873
+ line-height: 0!important;
874
+ }
875
+
876
+
877
+ /* One scrollbar width for the whole site.
878
+
879
+ Deliberately separate from the fade below, and deliberately on `*`. Unlike
880
+ scrollbar-color, `scrollbar-width` does NOT inherit, so setting it only on the
881
+ regions named below leaves every other scroll container - modals, the mobile
882
+ TOC panel, the settings app, long <select> popups - at the browser default.
883
+ That default is roughly 15px against `thin`'s 11px, so two scrollbars sitting
884
+ side by side visibly differ in width. Applying it once, to everything, is what
885
+ makes the width uniform; which bars FADE is a separate question, answered by
886
+ the scoped selectors below. */
887
+ * { scrollbar-width: thin; }
888
+
889
+ /* ---------------------------------------------------------------------------
890
+ Overlay scrollbars for the app's scroll regions.
891
+
892
+ This is a fixed-viewport shell: the document itself never scrolls and each
893
+ view is its own scroll region, so those regions each paint a permanent
894
+ scrollbar. The bar is transparent at rest and fades in on hover of the region
895
+ it controls.
896
+
897
+ Driven by the standard `scrollbar-color`, NOT `::-webkit-scrollbar`. Two
898
+ reasons, both load-bearing:
899
+
900
+ 1. Chrome ignores the ::-webkit-scrollbar pseudo-elements entirely on any
901
+ element that also sets scrollbar-color or scrollbar-width. The two
902
+ cannot be combined - a Firefox fallback written the obvious way silently
903
+ disables the Chromium styling it was meant to complement.
904
+ 2. ::-webkit-scrollbar pseudo-elements cannot be transitioned, so a fade
905
+ through them needs a custom-property indirection. scrollbar-color is a
906
+ real animatable property (verified interpolating in Chrome 151), so the
907
+ transition is just a transition.
908
+
909
+ Keyed off .hb-scroll, which is the class a scroll region opts in with (see the
910
+ top of this file). This used to be a hand-maintained list naming each region
911
+ individually, because .hb-container-expand could not be used as the shorthand -
912
+ it set `overflow: auto` alongside `flex-grow: 1`, so every layout container was
913
+ a scroll container too, and since :hover propagates to ancestors, hovering the
914
+ filter sidebar lit all six of the nested ones. Now that grow-to-fill and
915
+ is-a-scroll-region are separate classes, the fade can simply follow the latter
916
+ and stays correct as views are added.
917
+
918
+ .DocSidebar is listed separately because the search filter panel takes its
919
+ overflow from Bootstrap's .overflow-auto utility rather than from .hb-scroll.
920
+
921
+ Each region also declares the transparent rest value ITSELF rather than leaning
922
+ on an ancestor: scrollbar-color is an inherited property, and a region that only
923
+ inherits it never matches its own :hover rule.
924
+
925
+ Applied per-region rather than globally: touch and keyboard users, and anyone
926
+ who never hovers, still need to know a region scrolls. Touch keeps the
927
+ platform's own overlay bar, and the thumb still appears while scrolling.
928
+
929
+ No prefers-reduced-motion guard, deliberately. That query is about motion that
930
+ can cause discomfort - parallax, transforms, things that travel. This is a
931
+ colour cross-fade on a 10px bar, which travels nowhere. Guarding it would mean
932
+ anyone with the OS "reduce animations" setting on (common on Windows, and on
933
+ this machine) silently loses the behaviour entirely.
934
+ --------------------------------------------------------------------------- */
935
+ .hb-scroll,
936
+ .DocSidebar,
937
+ .injected-document-content
938
+ {
939
+ scrollbar-color: transparent transparent;
940
+ transition: scrollbar-color 0.12s ease-out;
941
+ }
942
+
943
+ .hb-scroll:hover,
944
+ .DocSidebar:hover,
945
+ .injected-document-content:hover
946
+ {
947
+ scrollbar-color: var(--htl-c-gray-light-2) transparent;
948
+ }
949
+
950
+ .dark .hb-scroll:hover,
951
+ .dark .DocSidebar:hover,
952
+ .dark .injected-document-content:hover
953
+ {
954
+ scrollbar-color: var(--htl-c-gray-dark-1) transparent;
955
+ }
956
+
957
+ /* Safari predates scrollbar-color; it gets the pseudo-elements instead. Kept in
958
+ @supports so it can never apply alongside the block above. */
959
+ @supports not (scrollbar-color: transparent) {
960
+ .hb-scroll::-webkit-scrollbar,
961
+ .DocSidebar::-webkit-scrollbar,
962
+ .injected-document-content::-webkit-scrollbar { width: 10px; }
963
+
964
+ .hb-scroll::-webkit-scrollbar-track,
965
+ .DocSidebar::-webkit-scrollbar-track,
966
+ .injected-document-content::-webkit-scrollbar-track { background: transparent; }
967
+
968
+ .hb-scroll::-webkit-scrollbar-thumb,
969
+ .DocSidebar::-webkit-scrollbar-thumb,
970
+ .injected-document-content::-webkit-scrollbar-thumb { background: transparent; }
971
+
972
+ .hb-scroll:hover::-webkit-scrollbar-thumb,
973
+ .DocSidebar:hover::-webkit-scrollbar-thumb,
974
+ .injected-document-content:hover::-webkit-scrollbar-thumb
975
+ {
976
+ background-color: var(--htl-c-gray-light-2);
977
+ border-radius: 10px;
978
+ }
979
+ }