explico 0.7.0 → 0.11.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.
- package/CHANGELOG.md +1409 -1
- package/README.md +60 -15
- package/dist/compiler/astro.d.ts +6 -1
- package/dist/compiler/cli.d.ts +54 -3
- package/dist/compiler/cli.js +80 -6
- package/dist/compiler/collections.d.ts +35 -2
- package/dist/compiler/collections.js +84 -8
- package/dist/compiler/course-config.d.ts +3 -194
- package/dist/compiler/course-config.js +78 -5
- package/dist/compiler/exports/standalone-html.d.ts +6 -1
- package/dist/compiler/knowledge-version.js +1 -1
- package/dist/compiler/lesson-derivation.d.ts +27 -10
- package/dist/compiler/lesson-derivation.js +23 -8
- package/dist/compiler/logging.d.ts +14 -1
- package/dist/compiler/logging.js +6 -2
- package/dist/compiler/manifest.d.ts +204 -31
- package/dist/compiler/manifest.js +270 -55
- package/dist/compiler/resolution-report.d.ts +6 -1
- package/dist/course-config-Dsnri9Tk.d.ts +464 -0
- package/dist/reference/base-accents.d.mts +26 -0
- package/dist/reference/base-accents.mjs +31 -0
- package/dist/reference/base-roman-labels.d.mts +2 -2
- package/dist/reference/base-roman-labels.mjs +2 -2
- package/dist/reference/consistency.d.ts +14 -2
- package/dist/reference/consistency.js +108 -4
- package/dist/reference/delimiter-size.d.ts +21 -11
- package/dist/reference/delimiter-size.js +15 -39
- package/dist/reference/diagrams-validate.d.ts +7 -2
- package/dist/reference/diagrams-validate.js +9 -1
- package/dist/reference/equations-validate.d.ts +8 -5
- package/dist/reference/equations-validate.js +1 -0
- package/dist/reference/equations.d.mts +69 -34
- package/dist/reference/equations.mjs +90 -44
- package/dist/reference/examples-validate.d.ts +31 -0
- package/dist/reference/examples-validate.js +48 -0
- package/dist/reference/figures-validate.d.ts +1 -1
- package/dist/reference/figures-validate.js +4 -1
- package/dist/reference/folds-validate.d.ts +33 -0
- package/dist/reference/folds-validate.js +32 -0
- package/dist/reference/gate-abbreviations.d.ts +3 -1
- package/dist/reference/gate-abbreviations.js +3 -2
- package/dist/reference/gate-course-rules.d.ts +32 -0
- package/dist/reference/gate-course-rules.js +85 -0
- package/dist/reference/gate-heading-length.d.ts +5 -2
- package/dist/reference/gate-heading-length.js +47 -23
- package/dist/reference/gate-heading-structure.d.ts +41 -0
- package/dist/reference/gate-heading-structure.js +113 -0
- package/dist/reference/gate-math-punctuation.d.ts +71 -0
- package/dist/reference/gate-math-punctuation.js +251 -0
- package/dist/reference/gate-math.d.ts +44 -6
- package/dist/reference/gate-math.js +63 -10
- package/dist/reference/gate-part-pages.d.ts +50 -0
- package/dist/reference/gate-part-pages.js +118 -0
- package/dist/reference/gate-prose-notation.d.ts +32 -11
- package/dist/reference/gate-prose-notation.js +30 -8
- package/dist/reference/katex-delimiters.d.mts +15 -0
- package/dist/reference/katex-delimiters.mjs +138 -0
- package/dist/reference/katex-options.mjs +4 -0
- package/dist/reference/keyed-float-validate.d.ts +27 -10
- package/dist/reference/keyed-float-validate.js +15 -1
- package/dist/reference/keyed-jsx-floats.d.mts +11 -5
- package/dist/reference/keyed-jsx-floats.mjs +73 -20
- package/dist/reference/knowledge-checks-validate.d.ts +1 -1
- package/dist/reference/knowledge-checks.d.mts +3 -1
- package/dist/reference/knowledge-checks.mjs +9 -4
- package/dist/reference/lab-math-scope.d.ts +1 -0
- package/dist/reference/lab-math-slot.d.ts +34 -0
- package/dist/reference/lab-math-slot.js +6 -0
- package/dist/reference/math-glyphs.d.mts +80 -4
- package/dist/reference/math-glyphs.mjs +588 -39
- package/dist/reference/page-notation.d.ts +6 -1
- package/dist/reference/raw-floats-validate.js +1 -1
- package/dist/reference/raw-floats.mjs +1 -1
- package/dist/reference/rehype-heading-anchors.d.mts +14 -0
- package/dist/reference/rehype-heading-anchors.mjs +116 -17
- package/dist/reference/rehype-table-header-labels.d.mts +6 -1
- package/dist/reference/rehype-table-header-labels.mjs +21 -3
- package/dist/reference/remark-asides.d.mts +3 -0
- package/dist/reference/remark-asides.mjs +180 -0
- package/dist/reference/remark-memo.d.mts +3 -1
- package/dist/reference/remark-memo.mjs +42 -11
- package/dist/reference/remark-notation.d.mts +60 -10
- package/dist/reference/remark-notation.mjs +387 -36
- package/dist/reference/render-lab-math.d.ts +4 -26
- package/dist/reference/render-lab-math.js +5 -5
- package/dist/reference/sections-validate.d.ts +27 -0
- package/dist/reference/sections-validate.js +41 -0
- package/dist/reference/sections.d.mts +97 -0
- package/dist/reference/sections.mjs +306 -0
- package/dist/reference/tables-validate.d.ts +1 -1
- package/dist/reference/types.d.ts +24 -1
- package/dist/reference/unit-words.d.ts +37 -0
- package/dist/reference/unit-words.js +170 -0
- package/dist/rules/catalog.d.ts +176 -0
- package/dist/rules/catalog.js +983 -0
- package/dist/rules/course-rules.d.ts +115 -0
- package/dist/rules/course-rules.js +292 -0
- package/dist/rules/course-rules.schema.json +138 -0
- package/dist/rules/in-effect.d.ts +53 -0
- package/dist/rules/in-effect.js +142 -0
- package/dist/rules/rules.schema.json +1072 -0
- package/dist/rules/settings.d.ts +3 -0
- package/dist/rules/settings.js +290 -0
- package/dist/rules/waivers.d.ts +53 -0
- package/dist/rules/waivers.js +132 -0
- package/dist/session/PreferenceStore.d.ts +5 -0
- package/dist/session/PreferenceStore.js +9 -0
- package/docs/VERSIONING.md +2 -2
- package/docs/authoring/README.md +232 -40
- package/docs/authoring/agents.md +55 -9
- package/docs/authoring/components.md +178 -22
- package/docs/authoring/migrating.md +1324 -2
- package/docs/authoring/notation.md +616 -344
- package/docs/authoring/prose.md +551 -0
- package/docs/authoring/retired.md +35 -0
- package/docs/authoring/structure-rules.md +422 -40
- package/docs/authoring/structure.md +445 -62
- package/docs/authoring/versioning.md +20 -28
- package/docs/authoring/visualizations.md +142 -20
- package/docs/katex-bracket-scaling.md +191 -0
- package/package.json +3 -2
- package/src/compiler/cli.ts +139 -6
- package/src/compiler/collections.ts +144 -10
- package/src/compiler/course-config.ts +273 -34
- package/src/compiler/knowledge-version.ts +1 -1
- package/src/compiler/lesson-derivation.ts +54 -15
- package/src/compiler/logging.ts +21 -4
- package/src/compiler/manifest.ts +573 -104
- package/src/components/BlockHeading.astro +113 -0
- package/src/components/CourseContents.astro +221 -0
- package/src/components/CurriculumMap.astro +5 -6
- package/src/components/FloatIndex.astro +200 -0
- package/src/components/HoverPanel.astro +431 -79
- package/src/components/PartBridge.astro +27 -0
- package/src/components/PartOverview.astro +401 -0
- package/src/components/PartScope.astro +27 -0
- package/src/components/abbreviation/AbbreviationLayer.astro +49 -51
- package/src/components/assessments/AssessmentRunner.tsx +8 -5
- package/src/components/assessments/AssessmentSet.astro +23 -26
- package/src/components/block-heading.ts +146 -0
- package/src/components/card-arrow.ts +243 -0
- package/src/components/card-drag.ts +631 -0
- package/src/components/card-jump.ts +45 -0
- package/src/components/card-manager.ts +1589 -0
- package/src/components/card-memory.ts +177 -0
- package/src/components/card-placement.ts +504 -0
- package/src/components/card-side.ts +336 -0
- package/src/components/card-travel.ts +197 -0
- package/src/components/citation/CitationLayer.astro +77 -76
- package/src/components/diagram/Diagram.astro +161 -316
- package/src/components/disclosure/course-disclosure.ts +24 -0
- package/src/components/disclosure/hover-preview.ts +122 -42
- package/src/components/disclosure/persisted-disclosure.ts +3 -3
- package/src/components/disclosure/print-as-shown.ts +252 -0
- package/src/components/examples/CompactExample.astro +3 -1
- package/src/components/examples/CompactExamples.astro +101 -94
- package/src/components/figure/Figure.astro +174 -274
- package/src/components/figure/FloatCaption.astro +87 -0
- package/src/components/figure/figure-state.ts +58 -0
- package/src/components/figure/figure-tools.ts +87 -0
- package/src/components/float-name.ts +101 -0
- package/src/components/fold/Fold.astro +125 -0
- package/src/components/fold/fold-id.ts +40 -0
- package/src/components/memo/Memo.astro +162 -231
- package/src/components/memo/ShortNote.astro +6 -6
- package/src/components/notation/NotationFormula.astro +5 -1
- package/src/components/notation/NotationGlossary.astro +24 -14
- package/src/components/notation/NotationLayer.astro +169 -162
- package/src/components/notation/NotationMath.astro +10 -1
- package/src/components/notation/render-notation-math.ts +111 -10
- package/src/components/reference/FloatRefLayer.astro +485 -423
- package/src/components/starlight/AboutPanel.astro +22 -6
- package/src/components/starlight/CollapsibleSections.astro +207 -93
- package/src/components/starlight/DiagramEnhancer.astro +15 -138
- package/src/components/starlight/HeadingAnchorEnhancer.astro +193 -1
- package/src/components/starlight/KeyedFloatEnhancer.astro +100 -9
- package/src/components/starlight/LayoutHeader.astro +298 -19
- package/src/components/starlight/LayoutPageSidebar.astro +99 -12
- package/src/components/starlight/LayoutPageTitle.astro +120 -0
- package/src/components/starlight/LayoutSidebar.astro +229 -11
- package/src/components/starlight/LessonExportActions.astro +53 -72
- package/src/components/starlight/LessonFooter.astro +26 -4
- package/src/components/starlight/section-parts.ts +15 -2
- package/src/components/starlight/section-summary.ts +181 -0
- package/src/components/table/Table.astro +95 -76
- package/src/components/table/TableOverflowExpander.astro +65 -28
- package/src/content-config.ts +40 -4
- package/src/reference/base-accents.mjs +31 -0
- package/src/reference/base-roman-labels.mjs +2 -2
- package/src/reference/consistency.ts +176 -5
- package/src/reference/delimiter-size.ts +40 -61
- package/src/reference/diagrams-validate.ts +17 -1
- package/src/reference/equations-validate.ts +10 -5
- package/src/reference/equations.mjs +90 -44
- package/src/reference/examples-validate.ts +97 -0
- package/src/reference/figures-validate.ts +6 -1
- package/src/reference/folds-validate.ts +65 -0
- package/src/reference/gate-abbreviations.ts +3 -2
- package/src/reference/gate-course-rules.ts +134 -0
- package/src/reference/gate-heading-length.ts +68 -37
- package/src/reference/gate-heading-structure.ts +193 -0
- package/src/reference/gate-math-punctuation.ts +381 -0
- package/src/reference/gate-math.ts +119 -12
- package/src/reference/gate-part-pages.ts +217 -0
- package/src/reference/gate-prose-notation.ts +74 -13
- package/src/reference/katex-delimiters.mjs +138 -0
- package/src/reference/katex-options.mjs +4 -0
- package/src/reference/keyed-float-validate.ts +45 -11
- package/src/reference/keyed-jsx-floats.mjs +73 -20
- package/src/reference/knowledge-checks-validate.ts +1 -1
- package/src/reference/knowledge-checks.mjs +9 -4
- package/src/reference/lab-math-slot.ts +36 -0
- package/src/reference/math-glyphs.mjs +588 -39
- package/src/reference/raw-floats-validate.ts +1 -1
- package/src/reference/raw-floats.mjs +1 -1
- package/src/reference/rehype-heading-anchors.mjs +116 -17
- package/src/reference/rehype-table-header-labels.mjs +21 -3
- package/src/reference/remark-asides.mjs +180 -0
- package/src/reference/remark-memo.mjs +42 -11
- package/src/reference/remark-notation.mjs +387 -36
- package/src/reference/render-lab-math.ts +17 -32
- package/src/reference/sections-validate.ts +81 -0
- package/src/reference/sections.mjs +306 -0
- package/src/reference/tables-validate.ts +2 -1
- package/src/reference/types.ts +24 -0
- package/src/reference/unit-words.ts +233 -0
- package/src/rules/catalog.ts +1298 -0
- package/src/rules/course-rules.ts +456 -0
- package/src/rules/in-effect.ts +235 -0
- package/src/rules/settings.ts +448 -0
- package/src/rules/waivers.ts +249 -0
- package/src/session/PreferenceStore.ts +15 -0
- package/src/styles/global.css +1471 -163
- package/src/styles/surfaces.css +182 -0
- package/src/components/hover-panel.ts +0 -339
- package/src/components/popup-stack.ts +0 -345
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* The shell every explanation card is cloned from: notation, citation,
|
|
4
|
+
* abbreviation and reference cards alike (rule C6 of
|
|
5
|
+
* `docs/plans/hover-card-consistency.md`).
|
|
4
6
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* It renders a `<template>`, so nothing shows until a layer's script clones
|
|
8
|
+
* it with `cloneCardShell` (`./card-manager.ts`) — once per card, which is
|
|
9
|
+
* what lets a layer show several cards at once. A card is an `<aside>` with
|
|
10
|
+
* a header row — a grip, the layer's `heading` slot, then a Side toggle, a
|
|
11
|
+
* Pin toggle and a × — a note line under it, and the layer's own fields in
|
|
12
|
+
* the default slot. The card manager owns the buttons (`data-card-grip`,
|
|
13
|
+
* `data-card-side`, `data-card-pin`, `data-card-close`), the note
|
|
14
|
+
* (`data-card-note`), the mode (`data-card-mode`: hover, pinned, side or
|
|
15
|
+
* moved), the flash (`is-card-flashing`) and where the card goes
|
|
16
|
+
* (`./card-placement.ts`, `./card-side.ts`, `./card-drag.ts`).
|
|
10
17
|
*
|
|
11
|
-
* Extra attributes (
|
|
12
|
-
*
|
|
13
|
-
* controls already reference.
|
|
18
|
+
* Extra attributes (`data-citation-panel`, `data-float-ref-panel`, …) go on
|
|
19
|
+
* every card, so each layer keeps the hook its styles and tests use.
|
|
14
20
|
*
|
|
15
|
-
* `tabindex="-1"`: never in the tab order, but a
|
|
16
|
-
*
|
|
17
|
-
* own content (D15's in-panel navigation) needs somewhere stable to move
|
|
18
|
-
* focus to before it replaces whatever the reader just clicked — otherwise
|
|
19
|
-
* removing the focused node drops focus to nothing, and the shared
|
|
20
|
-
* `focusout` handler in `./hover-panel.ts` reads that as "the reader left"
|
|
21
|
-
* and closes the panel it was just asked to update.
|
|
21
|
+
* `tabindex="-1"`: never in the tab order, but focusable, so a click inside
|
|
22
|
+
* a card raises it and focus has somewhere stable to go.
|
|
22
23
|
*/
|
|
23
24
|
export interface Props {
|
|
24
|
-
/**
|
|
25
|
+
/** The template's id. Each card cloned from it gets `‹id›-‹n›`. */
|
|
25
26
|
id: string;
|
|
26
|
-
/** Accessible name for the
|
|
27
|
+
/** Accessible name for each card, until the layer gives it a specific one. */
|
|
27
28
|
label: string;
|
|
28
29
|
class?: string;
|
|
29
30
|
}
|
|
@@ -31,52 +32,100 @@ export interface Props {
|
|
|
31
32
|
const { id, label, class: className, ...rest } = Astro.props;
|
|
32
33
|
---
|
|
33
34
|
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
hidden
|
|
42
|
-
tabindex="-1"
|
|
43
|
-
{...rest}
|
|
44
|
-
>
|
|
45
|
-
<button
|
|
46
|
-
class="hover-panel-close"
|
|
47
|
-
type="button"
|
|
48
|
-
data-hover-panel-close
|
|
49
|
-
aria-label="Close"
|
|
35
|
+
<template id={id} data-card-template>
|
|
36
|
+
<aside
|
|
37
|
+
class:list={['hover-panel', className]}
|
|
38
|
+
role="region"
|
|
39
|
+
aria-label={label}
|
|
40
|
+
tabindex="-1"
|
|
41
|
+
{...rest}
|
|
50
42
|
>
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
43
|
+
<div class="hover-panel-header">
|
|
44
|
+
<button
|
|
45
|
+
class="hover-panel-grip"
|
|
46
|
+
type="button"
|
|
47
|
+
data-card-grip
|
|
48
|
+
aria-label="Move card"
|
|
49
|
+
title="Drag to move this card. Arrow keys move it; Home puts it back."
|
|
50
|
+
>
|
|
51
|
+
<svg viewBox="0 0 10 16" width="10" height="16" aria-hidden="true">
|
|
52
|
+
<circle cx="3" cy="4" r="1.15"></circle>
|
|
53
|
+
<circle cx="7" cy="4" r="1.15"></circle>
|
|
54
|
+
<circle cx="3" cy="8" r="1.15"></circle>
|
|
55
|
+
<circle cx="7" cy="8" r="1.15"></circle>
|
|
56
|
+
<circle cx="3" cy="12" r="1.15"></circle>
|
|
57
|
+
<circle cx="7" cy="12" r="1.15"></circle>
|
|
58
|
+
</svg>
|
|
59
|
+
</button>
|
|
60
|
+
<div class="hover-panel-heading"><slot name="heading" /></div>
|
|
61
|
+
<div class="hover-panel-tools">
|
|
62
|
+
<button
|
|
63
|
+
class="hover-panel-side"
|
|
64
|
+
type="button"
|
|
65
|
+
data-card-side
|
|
66
|
+
aria-pressed="false"
|
|
67
|
+
aria-label="Side"
|
|
68
|
+
title="Keep this card beside the article"
|
|
69
|
+
>
|
|
70
|
+
<svg viewBox="0 0 16 16" width="15" height="15" aria-hidden="true">
|
|
71
|
+
<rect x="1.75" y="2.75" width="12.5" height="10.5" rx="1.5"></rect>
|
|
72
|
+
<path class="hover-panel-side-column" d="M10.25 2.75v10.5"></path>
|
|
73
|
+
<path class="hover-panel-side-fill" d="M10.25 3.5h3.25v9h-3.25z"></path>
|
|
74
|
+
</svg>
|
|
75
|
+
</button>
|
|
76
|
+
<button
|
|
77
|
+
class="hover-panel-pin"
|
|
78
|
+
type="button"
|
|
79
|
+
data-card-pin
|
|
80
|
+
aria-pressed="false"
|
|
81
|
+
aria-label="Pin"
|
|
82
|
+
title="Keep this card open"
|
|
83
|
+
>
|
|
84
|
+
<svg viewBox="0 0 16 16" width="15" height="15" aria-hidden="true">
|
|
85
|
+
<path
|
|
86
|
+
class="hover-panel-pin-head"
|
|
87
|
+
d="M6 1.75h4v4.25l2.25 2.75h-8.5L6 6z"
|
|
88
|
+
></path>
|
|
89
|
+
<path d="M8 8.75V14.5"></path>
|
|
90
|
+
</svg>
|
|
91
|
+
</button>
|
|
92
|
+
<button
|
|
93
|
+
class="hover-panel-close"
|
|
94
|
+
type="button"
|
|
95
|
+
data-hover-panel-close
|
|
96
|
+
data-card-close
|
|
97
|
+
aria-label="Close"
|
|
98
|
+
>
|
|
99
|
+
<span aria-hidden="true">×</span>
|
|
100
|
+
</button>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
<p class="hover-panel-note" data-card-note role="status" hidden></p>
|
|
104
|
+
<div class="hover-panel-scroll">
|
|
105
|
+
<slot />
|
|
106
|
+
</div>
|
|
107
|
+
</aside>
|
|
108
|
+
</template>
|
|
57
109
|
|
|
58
110
|
<style>
|
|
59
111
|
@layer starlight.components {
|
|
60
112
|
.hover-panel {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
would offset a position:fixed box from its computed `top`, so the
|
|
65
|
-
JS placement (which clears display equations) must start from zero. */
|
|
113
|
+
/* In the card layer, whose origin is the document's: `left`/`top` are
|
|
114
|
+
page coordinates, so the card scrolls with the page (P1). */
|
|
115
|
+
position: absolute;
|
|
66
116
|
margin: 0;
|
|
67
|
-
width: min(23rem, calc(100vw - 1.5rem));
|
|
117
|
+
width: min(var(--explico-card-width, 23rem), calc(100vw - 1.5rem));
|
|
68
118
|
display: flex;
|
|
69
119
|
flex-direction: column;
|
|
70
|
-
/* The scrolling lives on `.hover-panel-scroll` below,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
with it (which is what happens to an absolutely-positioned child of
|
|
74
|
-
the scroll container itself). `hidden` also keeps the rounded
|
|
75
|
-
corners clean around the inner scroller. */
|
|
120
|
+
/* The scrolling lives on `.hover-panel-scroll` below, so the header
|
|
121
|
+
row stays put while a long card scrolls; `hidden` also keeps the
|
|
122
|
+
rounded corners clean around that scroller. */
|
|
76
123
|
overflow: hidden;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
124
|
+
/* No accent top rule: the system has none (`surfaces.css`). A floating
|
|
125
|
+
card keeps its overlay shadow — that is what lifts it off the page —
|
|
126
|
+
which is not the accent tier's in-flow `raised` depth. */
|
|
127
|
+
border: var(--ex-edge-border);
|
|
128
|
+
border-radius: var(--ex-radius-meta);
|
|
80
129
|
color: var(--sl-color-text);
|
|
81
130
|
background: var(--sl-color-bg);
|
|
82
131
|
box-shadow: var(--sl-shadow-lg);
|
|
@@ -85,41 +134,135 @@ const { id, label, class: className, ...rest } = Astro.props;
|
|
|
85
134
|
|
|
86
135
|
/* `.hover-panel { display: flex }` above has the same specificity as the
|
|
87
136
|
UA stylesheet's `[hidden] { display: none }` and comes later in the
|
|
88
|
-
cascade, so it would otherwise win and defeat the `hidden` attribute
|
|
89
|
-
that every layer's JS relies on to actually hide the panel. */
|
|
137
|
+
cascade, so it would otherwise win and defeat the `hidden` attribute. */
|
|
90
138
|
.hover-panel[hidden] {
|
|
91
139
|
display: none;
|
|
92
140
|
}
|
|
93
141
|
|
|
94
|
-
/*
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
142
|
+
/* C6: a kept card shows it, on its border as well as its Pin or Side
|
|
143
|
+
button. */
|
|
144
|
+
.hover-panel:is([data-card-mode='pinned'], [data-card-mode='side'], [data-card-mode='moved']) {
|
|
145
|
+
border-color: var(--sl-color-accent);
|
|
146
|
+
box-shadow:
|
|
147
|
+
var(--sl-shadow-lg),
|
|
148
|
+
0 0 0 1px var(--sl-color-accent);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* C8: pointing at another occurrence of a kept card's item. */
|
|
152
|
+
.hover-panel.is-card-flashing {
|
|
153
|
+
outline: 3px solid transparent;
|
|
154
|
+
outline-offset: 2px;
|
|
155
|
+
animation: explico-card-flash var(--explico-card-flash, 500ms) ease-out;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@keyframes explico-card-flash {
|
|
159
|
+
from {
|
|
160
|
+
outline-color: var(--sl-color-accent);
|
|
161
|
+
}
|
|
162
|
+
to {
|
|
163
|
+
outline-color: transparent;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@media (prefers-reduced-motion: reduce) {
|
|
168
|
+
.hover-panel.is-card-flashing {
|
|
169
|
+
animation: none;
|
|
170
|
+
outline-color: var(--sl-color-accent);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* P5: a reference card fits its content, a short reference or a wide
|
|
175
|
+
equation, up to the cap; wider content scrolls inside it. */
|
|
100
176
|
.hover-panel[data-float-ref-panel] {
|
|
101
177
|
width: fit-content;
|
|
102
|
-
min-width: min(
|
|
103
|
-
max-width:
|
|
178
|
+
min-width: min(var(--explico-card-width, 23rem), calc(100vw - 1.5rem));
|
|
179
|
+
max-width: min(
|
|
180
|
+
var(--explico-card-reference-max-width, 80ch),
|
|
181
|
+
calc(100vw - 1.5rem)
|
|
182
|
+
);
|
|
104
183
|
}
|
|
105
184
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
inside it (the same flexbox trap `.float-ref-panel-content` guards
|
|
112
|
-
against with its own `min-width: 0`). */
|
|
185
|
+
/* S1, S8: a docked card takes the side column's width, whatever its
|
|
186
|
+
layer: a wide reference wraps or scrolls inside rather than reaching
|
|
187
|
+
onto the rail. The manager caps its height. */
|
|
188
|
+
.hover-panel[data-card-mode='side'] {
|
|
189
|
+
width: var(--explico-card-side-width, var(--explico-card-width, 23rem));
|
|
113
190
|
min-width: 0;
|
|
114
|
-
|
|
115
|
-
padding: 1rem;
|
|
116
|
-
padding-inline-end: 2.4rem;
|
|
191
|
+
max-width: none;
|
|
117
192
|
}
|
|
118
193
|
|
|
119
|
-
.
|
|
194
|
+
/* S6: a docked card keeps × and its Side toggle; Side brings it back. A
|
|
195
|
+
moved card is kept too: Home, or a drop near its old spot, brings it
|
|
196
|
+
back (D5, D6). */
|
|
197
|
+
.hover-panel:is([data-card-mode='side'], [data-card-mode='moved']) .hover-panel-pin {
|
|
198
|
+
display: none;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.hover-panel-header {
|
|
202
|
+
position: relative;
|
|
203
|
+
display: flex;
|
|
204
|
+
align-items: flex-start;
|
|
205
|
+
gap: 0.5rem;
|
|
206
|
+
/* Logical, so the grip's margin is at the start in either direction. */
|
|
207
|
+
padding-block: 0.5rem 0;
|
|
208
|
+
padding-inline: 1.75rem 0.5rem;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* D1: the grip, in the header's start margin. The only drag handle: the
|
|
212
|
+
rest of the card stays selectable, and only the grip turns off touch
|
|
213
|
+
panning. */
|
|
214
|
+
.hover-panel-grip {
|
|
120
215
|
position: absolute;
|
|
121
|
-
|
|
122
|
-
|
|
216
|
+
inset-block-start: 0.5rem;
|
|
217
|
+
inset-inline-start: 0.35rem;
|
|
218
|
+
width: 1.1rem;
|
|
219
|
+
height: 1.6rem;
|
|
220
|
+
display: flex;
|
|
221
|
+
align-items: center;
|
|
222
|
+
justify-content: center;
|
|
223
|
+
padding: 0;
|
|
224
|
+
border: 0;
|
|
225
|
+
border-radius: 0.35rem;
|
|
226
|
+
color: var(--sl-color-gray-3);
|
|
227
|
+
background: transparent;
|
|
228
|
+
cursor: grab;
|
|
229
|
+
touch-action: none;
|
|
230
|
+
user-select: none;
|
|
231
|
+
-webkit-user-select: none;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.hover-panel-grip svg {
|
|
235
|
+
fill: currentColor;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.hover-panel-grip:hover,
|
|
239
|
+
.hover-panel[data-card-dragged] .hover-panel-grip {
|
|
240
|
+
color: var(--sl-color-text);
|
|
241
|
+
background: var(--sl-color-gray-6);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.hover-panel[data-card-dragged] {
|
|
245
|
+
box-shadow:
|
|
246
|
+
var(--sl-shadow-lg),
|
|
247
|
+
0 0 0 1px var(--sl-color-accent);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.hover-panel-heading {
|
|
251
|
+
flex: 1;
|
|
252
|
+
min-width: 0;
|
|
253
|
+
padding-block-start: 0.2rem;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.hover-panel-tools {
|
|
257
|
+
flex: none;
|
|
258
|
+
display: flex;
|
|
259
|
+
align-items: center;
|
|
260
|
+
gap: 0.15rem;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.hover-panel-side,
|
|
264
|
+
.hover-panel-pin,
|
|
265
|
+
.hover-panel-close {
|
|
123
266
|
width: 1.6rem;
|
|
124
267
|
height: 1.6rem;
|
|
125
268
|
display: flex;
|
|
@@ -130,21 +273,230 @@ const { id, label, class: className, ...rest } = Astro.props;
|
|
|
130
273
|
border-radius: 0.35rem;
|
|
131
274
|
color: var(--sl-color-gray-3);
|
|
132
275
|
background: transparent;
|
|
276
|
+
cursor: pointer;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.hover-panel-close {
|
|
133
280
|
font-size: 1.15rem;
|
|
134
281
|
line-height: 1;
|
|
135
|
-
cursor: pointer;
|
|
136
282
|
}
|
|
137
283
|
|
|
284
|
+
.hover-panel-side:hover,
|
|
285
|
+
.hover-panel-pin:hover,
|
|
138
286
|
.hover-panel-close:hover {
|
|
139
287
|
color: var(--sl-color-text);
|
|
140
288
|
background: var(--sl-color-gray-6);
|
|
141
289
|
}
|
|
142
290
|
|
|
291
|
+
.hover-panel-side svg,
|
|
292
|
+
.hover-panel-pin svg {
|
|
293
|
+
fill: none;
|
|
294
|
+
stroke: currentColor;
|
|
295
|
+
stroke-width: 1.4;
|
|
296
|
+
stroke-linecap: round;
|
|
297
|
+
stroke-linejoin: round;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.hover-panel-side[aria-pressed='true'],
|
|
301
|
+
.hover-panel-pin[aria-pressed='true'] {
|
|
302
|
+
color: var(--sl-color-text-accent);
|
|
303
|
+
background: var(--sl-color-accent-low);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.hover-panel-pin[aria-pressed='true'] .hover-panel-pin-head {
|
|
307
|
+
fill: currentColor;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.hover-panel-side-fill {
|
|
311
|
+
stroke: none;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.hover-panel-side[aria-pressed='true'] .hover-panel-side-fill {
|
|
315
|
+
fill: currentColor;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/* S7: below 72rem there is never a side column, so no Side button. The
|
|
319
|
+
side column is laid out left to right only. */
|
|
320
|
+
@media not all and (min-width: 72rem) {
|
|
321
|
+
.hover-panel-side {
|
|
322
|
+
display: none;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
:global([dir='rtl']) .hover-panel-side {
|
|
327
|
+
display: none;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/* S7: "Collapse a side panel to make room", under the header row. */
|
|
331
|
+
.hover-panel-note {
|
|
332
|
+
margin: 0.35rem 1rem 0;
|
|
333
|
+
padding: 0.25rem 0.5rem;
|
|
334
|
+
border-radius: 0.35rem;
|
|
335
|
+
font-size: var(--sl-text-xs);
|
|
336
|
+
color: var(--sl-color-text);
|
|
337
|
+
background: var(--sl-color-gray-6);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.hover-panel-note[hidden] {
|
|
341
|
+
display: none;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.hover-panel-scroll {
|
|
345
|
+
overflow: auto;
|
|
346
|
+
/* Without these, this flex item's default `auto` minimum size is its
|
|
347
|
+
*content's* size, not the panel's — content wider or taller than the
|
|
348
|
+
panel would inflate the panel itself outward instead of scrolling
|
|
349
|
+
inside it (the same flexbox trap `.float-ref-panel-content` guards
|
|
350
|
+
against with its own `min-width: 0`). */
|
|
351
|
+
min-width: 0;
|
|
352
|
+
min-height: 0;
|
|
353
|
+
padding: 0.35rem 1rem 1rem;
|
|
354
|
+
}
|
|
355
|
+
|
|
143
356
|
/* Slotted fields carry the owning layer's scope, not this component's, so
|
|
144
357
|
the descendant match must be global. */
|
|
145
358
|
.hover-panel :global(:focus-visible) {
|
|
146
359
|
outline: 3px solid var(--sl-color-accent);
|
|
147
360
|
outline-offset: 2px;
|
|
148
361
|
}
|
|
362
|
+
|
|
363
|
+
@media (forced-colors: active) {
|
|
364
|
+
.hover-panel:is([data-card-mode='pinned'], [data-card-mode='side'], [data-card-mode='moved']) {
|
|
365
|
+
border-color: Highlight;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/* D1: while a card is dragged, nothing on the page is selected and the
|
|
371
|
+
pointer shows the grab everywhere. */
|
|
372
|
+
:global(html[data-card-dragging]),
|
|
373
|
+
:global(html[data-card-dragging] *) {
|
|
374
|
+
cursor: grabbing !important;
|
|
375
|
+
user-select: none !important;
|
|
376
|
+
-webkit-user-select: none !important;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/* D3: the docking area's tint from a drag's first movement; once the card
|
|
380
|
+
snaps, a dashed line on the article's edge, the dashed outline of where
|
|
381
|
+
it lands, and a label (`../card-drag.ts`). Fixed to the window at the
|
|
382
|
+
bottom of the card layer: over the article, under every card. */
|
|
383
|
+
:global(.explico-card-dock) {
|
|
384
|
+
position: fixed;
|
|
385
|
+
inset: 0;
|
|
386
|
+
z-index: 0;
|
|
387
|
+
pointer-events: none;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
:global(.explico-card-dock [hidden]) {
|
|
391
|
+
display: none;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
:global(.explico-card-dock-area) {
|
|
395
|
+
position: fixed;
|
|
396
|
+
bottom: 0;
|
|
397
|
+
background: color-mix(in srgb, var(--sl-color-accent) 6%, transparent);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
:global(.explico-card-dock-edge) {
|
|
401
|
+
position: fixed;
|
|
402
|
+
bottom: 0;
|
|
403
|
+
width: 0;
|
|
404
|
+
border-inline-start: 2px dashed var(--sl-color-accent);
|
|
405
|
+
transform: translateX(-1px);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
:global(.explico-card-dock-outline) {
|
|
409
|
+
position: fixed;
|
|
410
|
+
box-sizing: border-box;
|
|
411
|
+
border: 2px dashed var(--sl-color-accent);
|
|
412
|
+
border-radius: var(--ex-radius-meta);
|
|
413
|
+
background: color-mix(in srgb, var(--sl-color-accent) 10%, transparent);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
:global(.explico-card-dock-label) {
|
|
417
|
+
position: fixed;
|
|
418
|
+
transform: translateX(-50%);
|
|
419
|
+
padding: 0.2rem 0.75rem;
|
|
420
|
+
border: 1px solid var(--sl-color-accent);
|
|
421
|
+
border-radius: 999px;
|
|
422
|
+
font-size: var(--sl-text-xs);
|
|
423
|
+
line-height: 1.4;
|
|
424
|
+
white-space: nowrap;
|
|
425
|
+
color: var(--sl-color-text-accent);
|
|
426
|
+
background: var(--sl-color-bg);
|
|
427
|
+
box-shadow: var(--sl-shadow-sm);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
@media (forced-colors: active) {
|
|
431
|
+
:global(.explico-card-dock-area),
|
|
432
|
+
:global(.explico-card-dock-outline) {
|
|
433
|
+
background: transparent;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
:global(.explico-card-dock-edge),
|
|
437
|
+
:global(.explico-card-dock-outline),
|
|
438
|
+
:global(.explico-card-dock-label) {
|
|
439
|
+
border-color: Highlight;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
@media print {
|
|
444
|
+
:global(.explico-card-dock) {
|
|
445
|
+
display: none;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/* S5: the arrow from a kept card to an occurrence of its item
|
|
450
|
+
(`../card-arrow.ts`), at the bottom of the card layer. */
|
|
451
|
+
:global(.explico-card-arrow) {
|
|
452
|
+
transition: opacity var(--explico-card-motion, 100ms) ease-out;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
:global(.explico-card-arrow.is-fading) {
|
|
456
|
+
opacity: 0;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
:global(.explico-card-arrow-line) {
|
|
460
|
+
fill: none;
|
|
461
|
+
stroke: var(--sl-color-accent);
|
|
462
|
+
stroke-width: 1.75;
|
|
463
|
+
stroke-linecap: round;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
:global(.explico-card-arrow-head) {
|
|
467
|
+
fill: var(--sl-color-accent);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
@media (prefers-reduced-motion: reduce) {
|
|
471
|
+
:global(.explico-card-arrow) {
|
|
472
|
+
transition: none;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
@media (forced-colors: active) {
|
|
477
|
+
:global(.explico-card-arrow-line) {
|
|
478
|
+
stroke: Highlight;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
:global(.explico-card-arrow-head) {
|
|
482
|
+
fill: Highlight;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
@media print {
|
|
487
|
+
:global(.explico-card-arrow) {
|
|
488
|
+
display: none;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/* The open mobile menu covers the page; the cards above it would float
|
|
493
|
+
over the menu. */
|
|
494
|
+
:global(body[data-mobile-menu-expanded] .explico-card-layer) {
|
|
495
|
+
display: none;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/* Escape can hand focus back to the article (C10); it needs no ring. */
|
|
499
|
+
:global(main[data-card-focus-return]:focus) {
|
|
500
|
+
outline: none;
|
|
149
501
|
}
|
|
150
502
|
</style>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* The paragraph on a part's overview page that says how the earlier parts
|
|
4
|
+
* lead into this one — which results it reuses, and what they now make
|
|
5
|
+
* possible. Rule S2 requires one on every part after the first, placed before
|
|
6
|
+
* `<PartScope>`; `gate-part-pages.ts` checks that it holds one paragraph within
|
|
7
|
+
* the course's `partPages.bridge` word range.
|
|
8
|
+
*
|
|
9
|
+
* Usage, in `content/docs/<part>/index.mdx`:
|
|
10
|
+
*
|
|
11
|
+
* ```mdx
|
|
12
|
+
* import PartBridge from 'explico/components/PartBridge.astro';
|
|
13
|
+
*
|
|
14
|
+
* <PartBridge>
|
|
15
|
+
*
|
|
16
|
+
* Part 1 gave the position of a point and, for a constant acceleration, its
|
|
17
|
+
* velocity and position at any later time. …
|
|
18
|
+
*
|
|
19
|
+
* </PartBridge>
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* Keep a blank line inside each tag, so the paragraph is parsed as Markdown
|
|
23
|
+
* and its math and `[[key]]` references render.
|
|
24
|
+
*/
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
<div class="part-intro part-bridge" data-part-intro="bridge"><slot /></div>
|