madness 1.2.5 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +23 -1
  3. data/app/public/css/main.css +652 -401
  4. data/app/public/css/main.css.map +17 -19
  5. data/app/public/js/theme.js +81 -0
  6. data/app/public/js/vendor/mermaid.min.js +1509 -915
  7. data/app/styles/_anchor.scss +11 -3
  8. data/app/styles/_breadcrumbs.scss +8 -1
  9. data/app/styles/_code.scss +26 -8
  10. data/app/styles/_footnotes.scss +29 -0
  11. data/app/styles/_general.scss +6 -3
  12. data/app/styles/_image.scss +18 -0
  13. data/app/styles/_keyboard.scss +6 -4
  14. data/app/styles/_manifest.scss +1 -2
  15. data/app/styles/_nav.scss +200 -16
  16. data/app/styles/_pandoc_code.scss +55 -51
  17. data/app/styles/_rouge.scss +57 -211
  18. data/app/styles/_scrollbar.scss +17 -3
  19. data/app/styles/_search.scss +20 -8
  20. data/app/styles/_table.scss +6 -5
  21. data/app/styles/_typography.scss +44 -16
  22. data/app/styles/_variables.scss +216 -35
  23. data/app/views/_icon.slim +23 -0
  24. data/app/views/_mobile_search.slim +1 -1
  25. data/app/views/_nav.slim +18 -8
  26. data/app/views/_nav_tree.slim +13 -0
  27. data/app/views/layout.slim +26 -1
  28. data/lib/madness/directory.rb +7 -0
  29. data/lib/madness/item.rb +1 -0
  30. data/lib/madness/navigation.rb +24 -0
  31. data/lib/madness/rendering/pandoc.rb +2 -1
  32. data/lib/madness/rendering/redcarpet_custom.rb +6 -1
  33. data/lib/madness/settings.rb +1 -0
  34. data/lib/madness/templates/madness.yml +5 -0
  35. data/lib/madness/version.rb +1 -1
  36. metadata +5 -8
  37. data/app/public/font/fontello.eot +0 -0
  38. data/app/public/font/fontello.svg +0 -16
  39. data/app/public/font/fontello.ttf +0 -0
  40. data/app/public/font/fontello.woff +0 -0
  41. data/app/public/font/fontello.woff2 +0 -0
  42. data/app/styles/_fontello.scss +0 -59
@@ -2,9 +2,17 @@ a {
2
2
  color: var(--link-color);
3
3
  text-decoration: none;
4
4
 
5
- &:active, &:hover, &:focus {
6
- outline-width: 0;
5
+ &:hover {
6
+ color: var(--link-hover-color);
7
7
  text-decoration: underline;
8
+ text-decoration-thickness: 1px;
9
+ text-underline-offset: 2px;
10
+ }
11
+
12
+ &:focus-visible {
13
+ outline: 2px solid var(--focus-ring-color);
14
+ outline-offset: 2px;
15
+ border-radius: 3px;
8
16
  }
9
17
 
10
18
  &:not([href]) {
@@ -15,4 +23,4 @@ a {
15
23
  &.icon {
16
24
  color: inherit;
17
25
  }
18
- }
26
+ }
@@ -1,9 +1,16 @@
1
1
  .breadcrumbs {
2
2
  margin-top: 6px;
3
3
  border-bottom: 1px solid var(--breadcrumbs-border-color);
4
+ font-size: 0.9em;
5
+ color: var(--quiet-color);
4
6
 
5
7
  a {
6
8
  display: inline-block;
7
- padding: 7px 0;
9
+ padding: 8px 0;
10
+ color: var(--quiet-color);
11
+
12
+ &:hover {
13
+ color: var(--link-color);
14
+ }
8
15
  }
9
16
  }
@@ -1,24 +1,42 @@
1
+ code, pre, kbd {
2
+ font-family: var(--font-family-monospace);
3
+ }
4
+
1
5
  code {
2
6
  background-color: var(--inline-code-bg-color);
3
- padding: 0px 8px;
7
+ color: var(--inline-code-color);
8
+ padding: 0.15em 0.4em;
4
9
  margin: 0;
5
- font-size: 90%;
6
- border-radius: 3px;
7
- display: inline-block;
10
+ font-size: 87%;
11
+ border-radius: 6px;
12
+ font-feature-settings: "calt" 0;
13
+ white-space: break-spaces;
8
14
  }
9
15
 
10
16
  pre {
11
17
  position: relative;
12
-
18
+ background-color: var(--code-bg-color);
13
19
  border: 1px solid var(--code-border-color);
14
- border-radius: 5px;
20
+ border-radius: 8px;
15
21
  overflow-x: auto;
16
- padding: 10px;
22
+ padding: 14px 16px;
23
+ font-size: 13.5px;
24
+ line-height: 1.55;
17
25
 
18
26
  code {
19
27
  background-color: transparent;
28
+ color: inherit;
29
+ padding: 0;
20
30
  display: block;
21
- line-height: 1.2;
31
+ line-height: inherit;
32
+ font-size: inherit;
22
33
  position: relative;
34
+ border-radius: 0;
23
35
  }
24
36
  }
37
+
38
+ // Soften inline-code inside links or headings.
39
+ a code, h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
40
+ font-size: 0.85em;
41
+ color: inherit;
42
+ }
@@ -1,5 +1,34 @@
1
1
  .footnotes {
2
2
  color: var(--footnotes-color);
3
3
  font-size: 85%;
4
+ border-top: 1px solid var(--hr-color);
5
+ margin-top: 2em;
6
+ padding-top: 1em;
7
+
8
+ ol {
9
+ padding-left: 1.5em;
10
+ }
11
+
12
+ li {
13
+ margin-bottom: 0.5em;
14
+ }
4
15
  }
5
16
 
17
+ // Mermaid diagram container. Mermaid emits an inline SVG; centering and
18
+ // breathing room here. The diagram itself themes via mermaid's own dark theme,
19
+ // initialized in the layout view based on data-theme.
20
+ .mermaid {
21
+ display: flex;
22
+ justify-content: center;
23
+ margin: 16px 0;
24
+ padding: 12px;
25
+ border: 1px solid var(--code-border-color);
26
+ border-radius: 8px;
27
+ background-color: transparent;
28
+ overflow-x: auto;
29
+
30
+ svg {
31
+ max-width: 100%;
32
+ height: auto;
33
+ }
34
+ }
@@ -4,14 +4,14 @@
4
4
 
5
5
  p {
6
6
  margin-top: 0;
7
- margin-bottom: 10px;
7
+ margin-bottom: 12px;
8
8
  }
9
9
 
10
10
  blockquote {
11
11
  color: var(--blockquote-color);
12
12
  border-left: 4px solid var(--blockquote-border-color);
13
13
  margin: 0;
14
- padding: 0 15px;
14
+ padding: 4px 16px;
15
15
 
16
16
  &>:first-child {
17
17
  margin-top: 0;
@@ -29,6 +29,9 @@ p, blockquote, ul, ol, dl, table, pre {
29
29
 
30
30
  mark {
31
31
  background-color: var(--highlight-color);
32
+ color: var(--highlight-text-color);
33
+ padding: 0 0.2em;
34
+ border-radius: 3px;
32
35
  }
33
36
 
34
37
  .quiet {
@@ -37,4 +40,4 @@ mark {
37
40
 
38
41
  .float-right {
39
42
  float: right;
40
- }
43
+ }
@@ -1,5 +1,23 @@
1
1
  img {
2
2
  border-style: none;
3
3
  max-width: 100%;
4
+ height: auto;
4
5
  box-sizing: content-box;
6
+ border-radius: 6px;
7
+ }
8
+
9
+ p > img:only-child {
10
+ display: block;
11
+ margin: 8px 0;
12
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.04);
13
+ }
14
+
15
+ :root[data-theme="dark"] p > img:only-child {
16
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.4);
17
+ }
18
+
19
+ @media (prefers-color-scheme: dark) {
20
+ :root:not([data-theme="light"]) p > img:only-child {
21
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.4);
22
+ }
5
23
  }
@@ -6,10 +6,12 @@ kbd {
6
6
  box-shadow: inset 0 -1px 0 var(--kbd-shadow-color);
7
7
 
8
8
  display: inline-block;
9
- padding: 6px 8px;
10
- font-size: 85%;
11
- line-height: 10px;
9
+ padding: 3px 6px;
10
+ font-size: 80%;
11
+ line-height: 1;
12
12
  vertical-align: middle;
13
- border-radius: 3px;
13
+ border-radius: 5px;
14
+ font-weight: 500;
15
+ font-family: var(--font-family-monospace);
14
16
  }
15
17
 
@@ -5,7 +5,6 @@
5
5
  @import "anchor";
6
6
  @import "breadcrumbs";
7
7
  @import "code";
8
- @import "fontello";
9
8
  @import "footnotes";
10
9
  @import "image";
11
10
  @import "keyboard";
@@ -21,4 +20,4 @@
21
20
  @import "typography";
22
21
 
23
22
  // Last
24
- @import "general";
23
+ @import "general";
data/app/styles/_nav.scss CHANGED
@@ -9,47 +9,231 @@ nav {
9
9
 
10
10
  background: var(--sidebar-bg-color);
11
11
  border-right: 1px solid var(--sidebar-border-right-color);
12
+ color: var(--font-color);
12
13
 
13
14
  height: 100vh;
14
15
  width: 300px;
15
16
  overflow-y: auto;
16
17
  position: fixed;
17
-
18
+ font-size: 14px;
18
19
  .icon-bar {
19
20
  background: var(--sidebar-bg-color);
20
- border-bottom: 1px dotted var(--sidebar-border-color);
21
+ border-bottom: 1px solid var(--sidebar-border-color);
21
22
  position: sticky;
22
23
  top: 0;
23
24
  z-index: 1;
25
+ display: flex;
26
+ align-items: center;
27
+ padding: 4px 8px;
24
28
  }
25
29
 
26
30
  a.document, span.document, .caption {
27
- border-bottom: 1px dotted var(--sidebar-border-color);
28
- // &:hover {
29
- // background: #e4e4e4;
30
- // }
31
-
31
+ border-bottom: 1px solid var(--sidebar-border-color);
32
32
  display: block;
33
- padding: 5px 20px 5px 30px;
33
+ padding: 8px 20px 8px 26px;
34
+ color: var(--font-color);
35
+ border-left: 3px solid transparent;
36
+ }
37
+
38
+ a.document:hover {
39
+ background: var(--sidebar-hover-bg-color);
40
+ color: var(--link-color);
41
+ border-left-color: var(--link-color);
42
+ }
43
+
44
+ a.document.strong {
45
+ font-weight: 600;
46
+ }
47
+
48
+ .caption {
49
+ color: var(--quiet-color);
50
+ font-size: 12px;
51
+ font-weight: 500;
52
+ padding-top: 14px;
53
+ padding-bottom: 6px;
54
+ border-bottom: none;
34
55
  }
35
56
 
36
57
  a.icon {
37
- display: inline-block;
38
- font-size: 1.5em;
39
- width: 50%;
40
- padding: 3px 20px 3px 30px;
58
+ display: inline-flex;
59
+ align-items: center;
60
+ justify-content: center;
61
+ font-size: 1.25em;
62
+ width: 44px;
63
+ height: 40px;
64
+ border-radius: 6px;
65
+ color: var(--font-color);
41
66
  &.wide {
42
- width: 100%
67
+ flex: 1;
68
+ }
69
+
70
+ &:hover {
71
+ background: var(--sidebar-hover-bg-color);
72
+ color: var(--link-color);
43
73
  }
44
- // &:hover {
45
- // background: #e4e4e4;
46
- // }
74
+
75
+ .icon-svg {
76
+ width: 18px;
77
+ height: 18px;
78
+ stroke: currentColor;
79
+ stroke-width: 2;
80
+ fill: none;
81
+ stroke-linecap: round;
82
+ stroke-linejoin: round;
83
+ }
84
+
47
85
  }
48
86
 
87
+ .icon-spacer {
88
+ flex: 1;
89
+ }
49
90
 
50
91
  &:after {
51
92
  content: "";
52
93
  height: 90px;
53
94
  display: block;
54
95
  }
96
+
97
+ // Nested folder tree (details/summary based).
98
+ details.tree-folder {
99
+ > summary.tree-summary {
100
+ list-style: none;
101
+ cursor: pointer;
102
+ display: flex;
103
+ align-items: center;
104
+ padding: 0;
105
+ border-bottom: 1px solid var(--sidebar-border-color);
106
+ &::-webkit-details-marker { display: none; }
107
+
108
+ &:hover {
109
+ background: var(--sidebar-hover-bg-color);
110
+ }
111
+
112
+ .tree-chevron {
113
+ flex: 0 0 18px;
114
+ width: 18px;
115
+ height: 18px;
116
+ margin-left: 8px;
117
+ position: relative;
118
+ color: var(--quiet-color);
119
+ transition: transform 150ms ease;
120
+
121
+ &::before {
122
+ content: "";
123
+ position: absolute;
124
+ top: 50%;
125
+ left: 50%;
126
+ width: 6px;
127
+ height: 6px;
128
+ border-right: 1.5px solid currentColor;
129
+ border-bottom: 1.5px solid currentColor;
130
+ transform: translate(-65%, -50%) rotate(-45deg);
131
+ }
132
+ }
133
+
134
+ // The .document anchor inside the summary should fill the row but not
135
+ // re-draw its own bottom border (the summary already has one).
136
+ > a.document {
137
+ flex: 1;
138
+ border-bottom: none;
139
+ border-left: none;
140
+ padding-left: 6px;
141
+ }
142
+
143
+ &:hover .tree-chevron {
144
+ color: var(--link-color);
145
+ }
146
+ }
147
+
148
+ &[open] > summary.tree-summary .tree-chevron::before {
149
+ transform: translate(-50%, -65%) rotate(45deg);
150
+ }
151
+
152
+ // Children container — subtle indent + left guide line.
153
+ .tree-children {
154
+ margin-left: 18px;
155
+ border-left: 1px solid var(--sidebar-border-color);
156
+
157
+ // Inside children, document rows lose the chunky left-padding so the
158
+ // hierarchy reads as indented but not crowded.
159
+ > a.document,
160
+ > details.tree-folder > summary.tree-summary > a.document {
161
+ padding-left: 10px;
162
+ }
163
+
164
+ > a.document {
165
+ padding-left: 16px;
166
+ }
167
+ }
168
+ }
169
+ }
170
+
171
+ // Theme toggle icon visibility — JS sets data-theme on <html>; CSS uses it to
172
+ // flip which glyph is shown. Falls back to system preference when no choice
173
+ // has been made.
174
+ .theme-toggle, .floating-theme-toggle {
175
+ .icon-sun { display: none; }
176
+ .icon-moon { display: inline-block; }
177
+ }
178
+
179
+ :root[data-theme="dark"] {
180
+ .theme-toggle, .floating-theme-toggle {
181
+ .icon-sun { display: inline-block; }
182
+ .icon-moon { display: none; }
183
+ }
184
+ }
185
+
186
+ @media (prefers-color-scheme: dark) {
187
+ :root:not([data-theme="light"]) {
188
+ .theme-toggle, .floating-theme-toggle {
189
+ .icon-sun { display: inline-block; }
190
+ .icon-moon { display: none; }
191
+ }
192
+ }
193
+ }
194
+
195
+ // Floating fallback toggle — visible when the sidebar isn't, so the toggle is
196
+ // always reachable. On desktop it hides because the sidebar version covers it.
197
+ .floating-theme-toggle {
198
+ position: fixed;
199
+ bottom: 18px;
200
+ right: 18px;
201
+ z-index: 100;
202
+ display: inline-flex;
203
+ align-items: center;
204
+ justify-content: center;
205
+ width: 42px;
206
+ height: 42px;
207
+ border-radius: 50%;
208
+ background: var(--sidebar-bg-color);
209
+ border: 1px solid var(--sidebar-border-color);
210
+ color: var(--font-color);
211
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
212
+ transition: transform 120ms ease;
213
+
214
+ &:hover {
215
+ background: var(--sidebar-hover-bg-color);
216
+ transform: translateY(-1px);
217
+ }
218
+
219
+ .icon-svg {
220
+ width: 18px;
221
+ height: 18px;
222
+ stroke: currentColor;
223
+ stroke-width: 2;
224
+ fill: none;
225
+ stroke-linecap: round;
226
+ stroke-linejoin: round;
227
+ }
228
+
229
+ @media print {
230
+ display: none;
231
+ }
232
+
233
+ @include desktop {
234
+ // On desktop, when a sidebar is present, the sidebar toggle is used.
235
+ body:has(nav) & {
236
+ display: none;
237
+ }
238
+ }
55
239
  }
@@ -1,63 +1,67 @@
1
+ // Pandoc syntax highlighting.
2
+ //
3
+ // Use `bundle exec run css pandoc` to generate update reference CSS.
4
+
1
5
  pre > code.sourceCode { white-space: pre; position: relative; }
2
6
  pre > code.sourceCode > span { line-height: 1.25; }
3
7
  pre > code.sourceCode > span:empty { height: 1.2em; }
4
- // .sourceCode { overflow: visible; }
5
8
  code.sourceCode > span { color: inherit; text-decoration: inherit; }
6
9
  div.sourceCode { margin: 1em 0; }
7
10
  pre.sourceCode { margin: 0; }
8
11
  @media screen {
9
- div.sourceCode { overflow: auto; }
12
+ div.sourceCode { overflow: auto; }
10
13
  }
11
14
  @media print {
12
- pre > code.sourceCode { white-space: pre-wrap; }
13
- pre > code.sourceCode > span { display: inline-block; text-indent: -5em; padding-left: 5em; }
15
+ pre > code.sourceCode { white-space: pre-wrap; }
16
+ pre > code.sourceCode > span { display: inline-block; text-indent: -5em; padding-left: 5em; }
17
+ }
18
+ pre.numberSource code { counter-reset: source-line 0; }
19
+ pre.numberSource code > span { position: relative; left: -4em; counter-increment: source-line; }
20
+ pre.numberSource code > span > a:first-child::before {
21
+ content: counter(source-line);
22
+ position: relative; left: -1em; text-align: right; vertical-align: baseline;
23
+ border: none; display: inline-block;
24
+ -webkit-touch-callout: none; -webkit-user-select: none;
25
+ -khtml-user-select: none; -moz-user-select: none;
26
+ -ms-user-select: none; user-select: none;
27
+ padding: 0 4px; width: 4em;
28
+ color: var(--rouge-line-number);
29
+ }
30
+ pre.numberSource {
31
+ margin-left: 3em;
32
+ border-left: 1px solid var(--rouge-line-number);
33
+ padding-left: 4px;
14
34
  }
15
- pre.numberSource code
16
- { counter-reset: source-line 0; }
17
- pre.numberSource code > span
18
- { position: relative; left: -4em; counter-increment: source-line; }
19
- pre.numberSource code > span > a:first-child::before
20
- { content: counter(source-line);
21
- position: relative; left: -1em; text-align: right; vertical-align: baseline;
22
- border: none; display: inline-block;
23
- -webkit-touch-callout: none; -webkit-user-select: none;
24
- -khtml-user-select: none; -moz-user-select: none;
25
- -ms-user-select: none; user-select: none;
26
- padding: 0 4px; width: 4em;
27
- color: #aaaaaa;
28
- }
29
- pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
30
- div.sourceCode
31
- { }
32
35
  @media screen {
33
- pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
36
+ pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
34
37
  }
35
- code span.al { color: #ff0000; font-weight: bold; } /* Alert */
36
- code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
37
- code span.at { color: #7d9029; } /* Attribute */
38
- code span.bn { color: #40a070; } /* BaseN */
39
- code span.bu { color: #008000; } /* BuiltIn */
40
- code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
41
- code span.ch { color: #4070a0; } /* Char */
42
- code span.cn { color: #880000; } /* Constant */
43
- code span.co { color: #60a0b0; font-style: italic; } /* Comment */
44
- code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
45
- code span.do { color: #ba2121; font-style: italic; } /* Documentation */
46
- code span.dt { color: #902000; } /* DataType */
47
- code span.dv { color: #40a070; } /* DecVal */
48
- code span.er { color: #ff0000; font-weight: bold; } /* Error */
49
- code span.ex { } /* Extension */
50
- code span.fl { color: #40a070; } /* Float */
51
- code span.fu { color: #06287e; } /* Function */
52
- code span.im { color: #008000; font-weight: bold; } /* Import */
53
- code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
54
- code span.kw { color: #007020; font-weight: bold; } /* Keyword */
55
- code span.op { color: #666666; } /* Operator */
56
- code span.ot { color: #007020; } /* Other */
57
- code span.pp { color: #bc7a00; } /* Preprocessor */
58
- code span.sc { color: #4070a0; } /* SpecialChar */
59
- code span.ss { color: #bb6688; } /* SpecialString */
60
- code span.st { color: #4070a0; } /* String */
61
- code span.va { color: #19177c; } /* Variable */
62
- code span.vs { color: #4070a0; } /* VerbatimString */
63
- code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
38
+
39
+ code span.al { color: var(--rouge-error-fg); font-weight: bold; } /* Alert */
40
+ code span.an { color: var(--rouge-comment); font-weight: bold; font-style: italic; } /* Annotation */
41
+ code span.at { color: var(--rouge-name-attribute); } /* Attribute */
42
+ code span.bn { color: var(--rouge-literal-number); } /* BaseN */
43
+ code span.bu { color: var(--rouge-name-builtin); } /* BuiltIn */
44
+ code span.cf { color: var(--rouge-keyword); font-weight: bold; } /* ControlFlow */
45
+ code span.ch { color: var(--rouge-literal-string); } /* Char */
46
+ code span.cn { color: var(--rouge-name-constant); } /* Constant */
47
+ code span.co { color: var(--rouge-comment); font-style: italic; } /* Comment */
48
+ code span.cv { color: var(--rouge-comment); font-weight: bold; font-style: italic; } /* CommentVar */
49
+ code span.do { color: var(--rouge-comment); font-style: italic; } /* Documentation */
50
+ code span.dt { color: var(--rouge-name-class); } /* DataType */
51
+ code span.dv { color: var(--rouge-literal-number); } /* DecVal */
52
+ code span.er { color: var(--rouge-error-fg); font-weight: bold; } /* Error */
53
+ code span.ex { } /* Extension */
54
+ code span.fl { color: var(--rouge-literal-number); } /* Float */
55
+ code span.fu { color: var(--rouge-name-function); } /* Function */
56
+ code span.im { color: var(--rouge-name-builtin); font-weight: bold; } /* Import */
57
+ code span.in { color: var(--rouge-comment); font-weight: bold; font-style: italic; } /* Information */
58
+ code span.kw { color: var(--rouge-keyword); font-weight: bold; } /* Keyword */
59
+ code span.op { color: var(--rouge-operator); } /* Operator */
60
+ code span.ot { color: var(--rouge-keyword); } /* Other */
61
+ code span.pp { color: var(--rouge-name-builtin); } /* Preprocessor */
62
+ code span.sc { color: var(--rouge-literal-string); } /* SpecialChar */
63
+ code span.ss { color: var(--rouge-literal-string); } /* SpecialString */
64
+ code span.st { color: var(--rouge-literal-string); } /* String */
65
+ code span.va { color: var(--rouge-name-variable); } /* Variable */
66
+ code span.vs { color: var(--rouge-literal-string); } /* VerbatimString */
67
+ code span.wa { color: var(--rouge-comment); font-weight: bold; font-style: italic; } /* Warning */