]> git.draconx.ca Git - homepage.git/blob - content/style.scss
M48T59Y battery replacement
[homepage.git] / content / style.scss
1 /*!
2  * Nick's web site: default stylesheet
3  *
4  * Copyright © 2018-2022 Nick Bowler
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18  */
19
20 @import "lib/colourmap.scss";
21
22 @include defcolours
23     ( $background:  #ffffff #000000
24     , $foreground:  #000000 #ffffff
25
26     , $linkdefault: #0000cd #a3aaff
27     , $linkactive:  #ff0000
28     , $linkvisited: #800080 #e493f7
29     , $focusring:   #628cb2
30
31     , $annotation:  #708090
32     , $tableshade:  #f5f5f5 #101010
33
34     , $ruledefault: #d3d3d3 #494949
35     , $rulestrong:  #696969 #939393
36     );
37
38 @mixin header_size($maxwidth, $fontsize) {
39     font-size: $fontsize;
40     max-width: 1em * ($maxwidth / $fontsize);
41 }
42
43 html { @include usecolours($background-color: background); }
44 body {
45     @include usecolours($color: foreground);
46     font-family: sans-serif;
47     margin: 1em;
48 }
49
50 a:link {
51     @include usecolours($color: linkdefault, $border-color: linkdefault);
52 }
53 a:visited {
54     @include usecolours($color: linkvisited, $border-color: linkvisited);
55 }
56 a:active {
57     @include usecolours($color: linkactive, $border-color: linkactive);
58 }
59
60 @supports (outline-style: auto) {
61     a:link { border-width: 0; }
62     a:focus { @include usecolour(outline, focusring, auto); }
63     li, td, dt { &>a:link { border: solid 1px transparent; } }
64 }
65
66 h1 { @include header_size(60em, 2em); }
67 h2 { @include header_size(60em, 1.5em); }
68 h5 { @include header_size(60em, 1em); }
69
70 @supports (display: grid) {
71     .gallery {
72         display: grid;
73         grid-column-gap: 1em;
74         grid-template-columns: repeat( auto-fill, minmax(18em, 1fr) );
75         align-items: center;
76
77         p.img { margin: 0.5em 0; }
78     }
79
80     @media (max-width: 45em) {
81         .inline.gallery {
82             display: block;
83             p.img {
84                 a { max-width: 24em; }
85                 margin: 1em 0;
86             }
87         }
88     }
89 }
90
91 p.img {
92     text-align: center;
93
94     img {
95         vertical-align: bottom;
96         max-width: 40em;
97         width: 100%;
98         height: auto;
99     }
100
101     a {
102         text-decoration: none;
103         display: inline-block;
104         border: solid 2px;
105     }
106
107     a.left { margin: 0 1em 0.5em 0; float: left; clear: left; }
108     a.right { margin: 0 0 0.5em 1em; float: right; clear: right; }
109     a.left, a.right {
110         @media (max-width: 45em) { float: none; margin: 0; }
111
112         max-width: 24em;
113     }
114
115     small {
116         @include usecolours($color: foreground);
117         @media (max-width: 24em) { text-align: left; }
118         padding: 0.5ex;
119         display: block;
120         display: -moz-inline-box;
121         display: inline-block;
122         text-align: justify;
123         font-size: 0.9em;
124     }
125 }
126
127 p, dt, dd, li {
128     text-align: justify;
129     @media (max-width: 28em) { text-align: left; }
130     padding: 0;
131     margin: 0;
132 }
133
134 p, table, div, ul, ol, dl, hr {
135     max-width: 50em;
136     padding: 0;
137     margin: 0;
138 }
139
140 p, table, body>div, h5 { margin: 1em 0; }
141 blockquote {
142     @media (max-width: 28em) { margin: 1em 0.5em; }
143     margin: 1em;
144 }
145
146 li { margin: 0 0 0 2em; }
147 dd { margin: 0 0 0 1em; }
148
149 hr {
150     clear: both;
151     margin: 0.5em 0;
152     border: 0;
153     @include usecolour(border-top, ruledefault, 1px solid);
154 }
155
156 kbd {
157     font-family: monospace;
158     font-size: 0.95em;
159     &:before { content: "% "; }
160     &.ok:before { content: "ok "; }
161     &>span { white-space: nowrap; }
162
163     blockquote & {
164         display: block;
165         & + br { display: none; }
166         text-align: left;
167         padding-left: 3em;
168         text-indent: -3em;
169     }
170 }
171
172 .permalink {
173     @include usecolours($color: annotation);
174     font-size: small;
175
176     a:link, a:visited { color: inherit; }
177     a:active { @include usecolours($color: linkactive); }
178     @media not screen { visibility: hidden; }
179 }
180
181 // General table styles.
182 table {
183     @include usecolour(border-top, ruledefault, 1px solid);
184     border-collapse: collapse;
185     clear: both;
186     width: 100%;
187 }
188
189 table>* { font-size: 0.9em; }
190 caption {
191     caption-side: top;
192     font-weight: bold;
193     font-size: 1em;
194     text-align: left;
195     margin: 0 0 0.5em 0;
196 }
197
198 td, th {
199     vertical-align: middle;
200     text-align: left;
201     padding: 1ex;
202     margin: 0;
203 }
204
205 thead>tr, tbody>tr { @include usecolour(border, ruledefault, solid); }
206 th, thead>tr { @include usecolour(border-bottom, rulestrong, 1px solid); }
207 tbody+tbody { @include usecolour(border-bottom, ruledefault, 1px solid); }
208 *>table, *>th { border: none; }
209 thead>tr { border-width: 1px; }
210 tbody>tr { border-width: 0 1px; }
211
212 td + td {
213     @include usecolour(box-shadow, background, -1px 0);
214 }
215
216 tbody>tr {
217     &:nth-of-type(even) { @include usecolours($background-color: tableshade); }
218     &:last-child { @include usecolour(border-bottom, ruledefault, solid 1px); }
219 }
220
221 // Specific table styles
222 table.cc {
223     &>tr>*:first-child, &>*>tr>*:first-child {
224         &+* { text-align: center; }
225         text-align: center;
226     }
227 }
228
229 // CSS rules for stortable clicky table headers: Update the display of
230 // the /table based on the current state.  Each column has its own set
231 // nearly-identical rules, only the class names differ.
232 //
233 // The clickytables.xsl stylesheet generates two inputs for each column.
234 // These inputs are siblings of the table and all precede it in document
235 // order.  Moreover, the inputs for a column are ordered with respect to
236 // each other, in this sequence:
237 //
238 //   input.clicky-NAME     -- checked iff NAME is selected for sorting.
239 //   input.clicky-NAME-rev -- checked to select reverse order.
240 //
241 // One of the column selection inputs will have a 'checked' attribute to
242 // indicate the default order.  This input is always first in document
243 // order.  No other inputs begin checked.
244 //
245 // The table itself consists of a thead (where the header labels are
246 // located) and two tbody elements.  The bulk of these rules relate
247 // to updating the headers to visually indicate the current state.
248 //
249 // A sortable column's th element has the .clicky-NAME class, matching
250 // its corresponding inputs, and has two label children.  The first label
251 // is visible only when the column is unselected, and is linked to the
252 // .clicky-NAME input to activate that column.  The second label is visible
253 // only on the selected column and is linked to the .clicky-NAME-rev input
254 // to toggle the reverse order.
255 //
256 // For the table body, the first tbody contains the default ordering
257 // and is not styled by these rules (except to hide it when alternate
258 // orderings are selected).  The second tbody contains rows for all
259 // alternate orderings, and is revealed by these rules.  When revealed,
260 // rows with the NAMEfwd or NAMErev class (for the forward and reverse
261 // orderings, respectively) are shown and other rows are hidden.
262
263 $clickynames: name, date, size;
264 @each $col in $clickynames {
265     input.clicky-#{$col} {
266         &:checked {
267             &~table {
268                 // Update table header state
269                 & th.clicky-#{$col} {
270                     label~label {
271                         display: -moz-inline-box !important;
272                         display: inline-block !important;
273                     }
274                     label { display: none; }
275                 }
276
277                 // Show only appropriate items from the sort body (forward)
278                 &>tbody+tbody>tr.#{$col}fwd { display: table-row; }
279                 &>tbody+tbody>tr { display: none; }
280
281                 // Unhide sort body
282                 &>tbody {
283                     &+tbody { display: table-row-group !important; }
284                     display: none;
285                 }
286             }
287
288             // reverse state for selected sort column
289             &~input.clicky-#{$col}-rev {
290                 &:checked ~ table {
291                     // Show only appropriate items from sort body (reversed)
292                     &>tbody+tbody>tr.#{$col}rev { display: table-row; }
293                     &>tbody+tbody>tr { display: none; }
294
295                     // Unhide sort body
296                     &>tbody {
297                         &+tbody { display: table-row-group !important; }
298                         display: none;
299                     }
300                 }
301
302                 // Unhide to allow keyboard navigation to this input
303                 display: block !important;
304             }
305         }
306
307         // If default input element is the only one selected, match it to
308         // return to default view (overriding the changes above).  It is
309         // always the first input element among all the sibling elements.
310         // This seems to interoperate better than using the [checked] or
311         // :first-of-type selectors.
312         @at-root &:first-child, :not(input)+& {
313             &:checked~table>tbody {
314                 &+tbody { display: none !important; }
315                 display: table-row-group;
316             }
317         }
318
319         // Unhide to allow keyboard navigation
320         display: block !important;
321         pointer-events: none;
322         position: absolute;
323         opacity: 0;
324         z-index: -1;
325     }
326
327     input.clicky-#{$col}-rev {
328         &:checked ~ table {
329             // Update table header state
330             & th.clicky-#{$col} {
331                 .svg+.svg {
332                     display: -moz-inline-box !important;
333                     display: inline-block !important;
334                 }
335                 .svg { display: none; }
336             }
337         }
338
339         pointer-events: none;
340         position: absolute;
341         opacity: 0;
342         z-index: -2;
343     }
344
345     $focuslabel: ":focus ~ table th.clicky-#{$col}>label~label";
346     #{"input.clicky-#{$col+$focuslabel}"}>span:first-child
347     , #{"input.clicky-#{$col}-rev#{$focuslabel}"} .svg
348     {
349         @include usecolours($border-color: foreground);
350         @at-root { @supports (outline-style: auto) { & {
351             @include usecolour(outline, focusring, auto);
352             border-color: transparent !important;
353         }}}
354     }
355 }
356
357 thead.clicky label {
358     white-space: nowrap;
359     line-height: 1.5em;
360     cursor: pointer;
361
362     &>* {
363         display: -moz-inline-box;
364         display: inline-block;
365         border: 1px dotted transparent;
366         vertical-align: middle;
367     }
368
369     // Expand the first label a bit so the table (hopefully)
370     // does not reshape as columns are selected.
371     &:first-child {
372         margin-right: 1.75em;
373         padding-right: 2px;
374     }
375
376     &:active { @include usecolours($color: linkactive); }
377     &:first-child:active>span, &~label:active>.svg {
378         @include usecolours($border-color: linkactive);
379         @at-root { @supports (outline-style: auto) { & {
380             @include usecolour(outline, focusring, auto);
381             border-color: transparent;
382         }}}
383     }
384
385     .svg {
386         margin-left: 0.25em;
387     }
388
389     .svg, svg, img.svgfallback {
390         height: 1.5em;
391         width: auto;
392     }
393     .svg svg { width: 1.5em; }
394 }
395
396 table.filelist {
397     &>*>tr>*:first-child {
398         &+* { width: 50%; }
399         // chrome doesn't like width: 0 for some reason
400         width: 0.1px;
401     }
402
403     tbody {
404         .svg, svg, img.svgfallback {
405             vertical-align: middle;
406             height: 1.5em;
407             width: auto;
408         }
409
410         .svg {
411             svg { width: 1.5em; }
412             display: inline-block;
413         }
414     }
415 }
416
417 // Site header rules
418 #breadcrumbs>*, #sitetitle>* { font-size: 0.8em; }
419 #breadcrumbs {
420     * {
421         display: inline;
422         list-style-type: none;
423         vertical-align: top;
424         padding: 0;
425         margin: 0;
426     }
427
428     li + li:before { content: "/ "; }
429 }
430 #sitetitle * {
431     display: inline-block;
432     float: right;
433 }
434
435 // Site footer rules
436 #footer, #article-info {
437     text-align: center;
438     max-width: 44em;
439     padding: 0 3em;
440     margin: 0;
441
442     p {
443         display: inline-block;
444         font-size: 0.8em;
445         max-width: 100%;
446         margin: 0.2em 0;
447     }
448 }
449
450 #footer p { @include usecolours($color: annotation); }
451 #article-info p { font-style: italic; }
452
453 .wbr:after { content: "\200b"; }
454
455 // "unordered" lists with explicit ordering in content
456 ul.ordered > {
457     li { list-style: none; }
458     li>span:first-child, li>*:first-child>span:first-child {
459         display: inline-block;
460         text-align: right;
461         margin-left: -1.8em;
462         min-width: 1.8em;
463     }
464 }
465
466 @media (max-width: 512px) {
467     body { margin: 0.6em; }
468     ul ul { margin-left: -1.2em; }
469     dd { margin: 0; }
470 }
471
472 @media (max-width: 35em) {
473     #sitetitle * { float: none; }
474     #footer { padding: 0 1em; }
475 }
476
477 // lighten icon shadows in dark mode
478 @media (prefers-color-scheme: dark) {
479     svg.icons { path.shadow, g.shadow>* { opacity: 0.7; } }
480     svg.icons .shadow>stop { stop-color: #aaa; }
481     svg.return path.shadow { opacity: 0.45; }
482 }
483
484 // page-specific dark mode styles
485 @media (prefers-color-scheme: dark) and (min-width: 35em) {
486     #page_weblog_responsive_tables {
487         @each $tN in t6 t7 t8 {
488             ##{$tN}>tbody>tr.#{$tN}-split {
489                 @include usecolour_dark_(border-bottom, ruledefault);
490
491                 &:nth-of-type(odd) ~ tr:nth-of-type(odd) {
492                     @include usecolour_dark_(background-color, tableshade);
493                 }
494             }
495         }
496     }
497 }