@davidsouther/jiffies 2026.4.0 → 2026.24.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 (123) hide show
  1. package/README.md +0 -3
  2. package/package.json +13 -6
  3. package/src/404.html +1 -1
  4. package/src/components/accordion.ts +25 -0
  5. package/src/components/alert.ts +47 -0
  6. package/src/components/card.ts +54 -0
  7. package/src/components/children.ts +11 -0
  8. package/src/components/form.ts +25 -0
  9. package/src/components/index.ts +22 -0
  10. package/src/components/link.ts +22 -0
  11. package/src/components/modal.ts +15 -0
  12. package/src/components/nav.ts +42 -0
  13. package/src/components/property.ts +32 -0
  14. package/src/components/tabs.ts +82 -0
  15. package/src/components/virtual_scroll.ts +1 -1
  16. package/src/dom/README.md +8 -3
  17. package/src/dom/SKILL.md +201 -0
  18. package/src/dom/dom.ts +192 -41
  19. package/src/dom/fc.ts +7 -3
  20. package/src/dom/form/form.app.ts +35 -41
  21. package/src/dom/form/form.ts +79 -10
  22. package/src/dom/form/index.html +2 -2
  23. package/src/dom/html.ts +1 -1
  24. package/src/dom/hydrate.ts +206 -0
  25. package/src/dom/navigation/index.ts +349 -0
  26. package/src/dom/render.ts +41 -0
  27. package/src/dom/router/router.ts +1 -1
  28. package/src/dom/svg.ts +6 -2
  29. package/src/fs_node.ts +2 -2
  30. package/src/log.ts +154 -2
  31. package/src/server/http/response.ts +6 -3
  32. package/src/server/http/sitemap.ts +10 -34
  33. package/src/server/http/static.ts +0 -2
  34. package/src/server/live-reload.ts +208 -0
  35. package/src/server/main.ts +14 -7
  36. package/src/server/ws/frame.ts +36 -0
  37. package/src/server/ws/handshake.ts +42 -0
  38. package/src/server/ws/index.ts +100 -0
  39. package/src/ssg/bundle.ts +85 -0
  40. package/src/ssg/copy-public.ts +44 -0
  41. package/src/ssg/discover.ts +143 -0
  42. package/src/ssg/main.ts +168 -0
  43. package/src/ssg/rewrite.ts +18 -0
  44. package/src/ssg/ssg.ts +134 -0
  45. package/src/components/test.ts +0 -5
  46. package/src/components/virtual_scroll.test.ts +0 -30
  47. package/src/context.test.ts +0 -58
  48. package/src/context.ts +0 -67
  49. package/src/diff.test.ts +0 -48
  50. package/src/dom/fc.test.ts +0 -43
  51. package/src/dom/form/form.test.ts +0 -0
  52. package/src/dom/html.test.ts +0 -74
  53. package/src/dom/observable.test.ts +0 -43
  54. package/src/dom/test.ts +0 -11
  55. package/src/equal.test.ts +0 -23
  56. package/src/flags.test.ts +0 -43
  57. package/src/flags.ts +0 -53
  58. package/src/fs.test.ts +0 -106
  59. package/src/fs_win.test.ts +0 -11
  60. package/src/generator.test.ts +0 -27
  61. package/src/index.html +0 -82
  62. package/src/is_browser.js +0 -1
  63. package/src/lock.test.ts +0 -17
  64. package/src/observable/observable.test.ts +0 -73
  65. package/src/pico/_variables.scss +0 -66
  66. package/src/pico/components/_accordion.scss +0 -112
  67. package/src/pico/components/_button-group.scss +0 -51
  68. package/src/pico/components/_card.scss +0 -47
  69. package/src/pico/components/_dropdown.scss +0 -203
  70. package/src/pico/components/_modal.scss +0 -181
  71. package/src/pico/components/_nav.scss +0 -79
  72. package/src/pico/components/_progress.scss +0 -70
  73. package/src/pico/components/_property.scss +0 -34
  74. package/src/pico/content/_button.scss +0 -152
  75. package/src/pico/content/_code.scss +0 -63
  76. package/src/pico/content/_embedded.scss +0 -0
  77. package/src/pico/content/_form-alt.scss +0 -276
  78. package/src/pico/content/_form.scss +0 -259
  79. package/src/pico/content/_misc.scss +0 -0
  80. package/src/pico/content/_table.scss +0 -28
  81. package/src/pico/content/_toggle.scss +0 -132
  82. package/src/pico/content/_typography.scss +0 -232
  83. package/src/pico/layout/_container.scss +0 -40
  84. package/src/pico/layout/_document.scss +0 -0
  85. package/src/pico/layout/_flex.scss +0 -46
  86. package/src/pico/layout/_grid.scss +0 -24
  87. package/src/pico/layout/_scroller.scss +0 -16
  88. package/src/pico/layout/_section.scss +0 -8
  89. package/src/pico/layout/_sectioning.scss +0 -55
  90. package/src/pico/pico.scss +0 -60
  91. package/src/pico/reset/_accessibility.scss +0 -34
  92. package/src/pico/reset/_button.scss +0 -17
  93. package/src/pico/reset/_code.scss +0 -15
  94. package/src/pico/reset/_document.scss +0 -48
  95. package/src/pico/reset/_embedded.scss +0 -39
  96. package/src/pico/reset/_form.scss +0 -97
  97. package/src/pico/reset/_misc.scss +0 -23
  98. package/src/pico/reset/_nav.scss +0 -5
  99. package/src/pico/reset/_progress.scss +0 -4
  100. package/src/pico/reset/_table.scss +0 -8
  101. package/src/pico/reset/_typography.scss +0 -25
  102. package/src/pico/themes/default/_colors.scss +0 -65
  103. package/src/pico/themes/default/_dark.scss +0 -148
  104. package/src/pico/themes/default/_light.scss +0 -149
  105. package/src/pico/themes/default/_styles.scss +0 -272
  106. package/src/pico/themes/default.scss +0 -34
  107. package/src/pico/utilities/_accessibility.scss +0 -3
  108. package/src/pico/utilities/_loading.scss +0 -52
  109. package/src/pico/utilities/_reduce-motion.scss +0 -27
  110. package/src/pico/utilities/_tooltip.scss +0 -101
  111. package/src/result.test.ts +0 -101
  112. package/src/scope/describe.ts +0 -81
  113. package/src/scope/display/console.ts +0 -26
  114. package/src/scope/display/dom.ts +0 -36
  115. package/src/scope/display/junit.ts +0 -64
  116. package/src/scope/execute.ts +0 -110
  117. package/src/scope/expect.ts +0 -169
  118. package/src/scope/fix.ts +0 -30
  119. package/src/scope/index.ts +0 -11
  120. package/src/scope/scope.ts +0 -21
  121. package/src/scope/state.ts +0 -13
  122. package/src/test.mjs +0 -33
  123. package/src/test_all.ts +0 -35
package/src/index.html DELETED
@@ -1,82 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>Jiffies Tests</title>
5
- <base href="/" />
6
- <link rel="stylesheet" href="/pico/pico.css?$enable-viewport=none" />
7
- </head>
8
- <body>
9
- <header></header>
10
-
11
- <main>
12
- <article id="test_output"></article>
13
- </main>
14
-
15
- <div style="display: none" id="status"></div>
16
- <div style="display: none" id="json"></div>
17
- <div style="display: none" id="xml"></div>
18
-
19
- <script type="module">
20
- await Promise.all([
21
- import("./test_all.js"),
22
- import("./dom/test.js"),
23
- import("./components/test.js"),
24
- ]);
25
-
26
- import { onConsole } from "./scope/display/console.ts";
27
- import { displayStatistics } from "./scope/display/dom.ts";
28
- import { asXML } from "./scope/display/junit.ts";
29
- import { execute } from "./scope/execute.ts";
30
-
31
- function write(id, value) {
32
- const start = `--- START_${id.toUpperCase()} ---`;
33
- const end = `--- END ---`;
34
- document.getElementById(
35
- id
36
- ).innerHTML = `\n${start}\n${value}\n${end}\n`;
37
- }
38
-
39
- (async () => {
40
- const results = await execute();
41
- displayStatistics(results, document.getElementById("test_output"));
42
- onConsole(results);
43
- write("status", results.failed);
44
- write("json", JSON.stringify(results));
45
- write("xml", asXML(results));
46
- })();
47
- </script>
48
- <script type="module">
49
- import { li, nav, strong, ul } from "./dom/html.ts";
50
- import { link } from "./dom/router/link.ts";
51
-
52
- const getUrls = async () => {
53
- const sitemap = await fetch("/sitemap.json");
54
- if (sitemap.ok) {
55
- return await sitemap.json();
56
- } else {
57
- return [
58
- "/index.html",
59
- "/apps/computron5k/index.html",
60
- "/apps/chess/index.html",
61
- ];
62
- }
63
- };
64
-
65
- const urls = (await getUrls()).map((url) => ({
66
- href: url.replace("index.html", ""),
67
- link:
68
- url.match(/\/(?<link>[^/]+)(\/index\.html)?$/)?.groups.link ??
69
- url.replace("index.html", ""),
70
- }));
71
-
72
- document
73
- .querySelector("body > header")
74
- .appendChild(
75
- nav(
76
- ul(li(strong("Jiffy Apps"))),
77
- ul(...urls.map((url) => li(link(url))))
78
- )
79
- );
80
- </script>
81
- </body>
82
- </html>
package/src/is_browser.js DELETED
@@ -1 +0,0 @@
1
- export const IsBrowser = typeof window !== "undefined";
package/src/lock.test.ts DELETED
@@ -1,17 +0,0 @@
1
- import { lock } from "./lock.ts";
2
- import { describe, expect, it } from "./scope/index.ts";
3
-
4
- describe("Lock", () => {
5
- it("prevents reentry", () => {
6
- let count = 0;
7
- const inc = lock(() => {
8
- if (count > 4) {
9
- return;
10
- }
11
- inc();
12
- count++;
13
- });
14
- inc();
15
- expect(count).toBe(1);
16
- });
17
- });
@@ -1,73 +0,0 @@
1
- import { describe, expect, it } from "../scope/index.ts";
2
- import { filter, map, Observable, Subject } from "./observable.ts";
3
-
4
- describe("Observables", () => {
5
- describe("basics", () => {
6
- it("can create and observe a scalar subject", async () => {
7
- const subject = new Subject<number>();
8
-
9
- let resolved = 42;
10
-
11
- subject.subscribe({
12
- next: (n) => {
13
- resolved = n;
14
- },
15
- });
16
-
17
- expect(resolved).toBe(42);
18
- await subject.next(64);
19
- expect(resolved).toBe(64);
20
- });
21
- });
22
-
23
- describe("creation", () => {
24
- it("builds an observable of items", async () => {
25
- const stream = Observable.of(2, 4, 8, 16);
26
- const values: number[] = [];
27
- await new Promise<void>((resolve) => {
28
- stream.subscribe({
29
- next: (n) => {
30
- values.unshift(n);
31
- },
32
- complete: () => {
33
- resolve();
34
- },
35
- });
36
- });
37
- expect(values).toEqual([16, 8, 4, 2]);
38
- });
39
- });
40
-
41
- describe("pipes", () => {
42
- it("runs a pipe", async () => {
43
- const subject = new Subject<number>();
44
-
45
- let resolved = 0;
46
- const inflate = (i: number) => (n: number) => n + i;
47
- const biggerThan = (i: number) => (n: number) => n > i;
48
- const assign = (n: number) => {
49
- resolved = n;
50
- };
51
-
52
- subject.pipe(map(inflate(22)), filter(biggerThan(70))).subscribe(assign);
53
-
54
- expect(resolved).toBe(0);
55
- await subject.next(42);
56
- expect(resolved).toBe(0);
57
- await subject.next(50);
58
- expect(resolved).toBe(72);
59
- });
60
- });
61
-
62
- describe("Subject", () => {
63
- it("is callable", async () => {
64
- const subject = new Subject<number>();
65
- let resolved = 0;
66
- subject.subscribe((n) => {
67
- resolved = n;
68
- });
69
- await subject.next(42);
70
- expect(resolved).toBe(42);
71
- });
72
- });
73
- });
@@ -1,66 +0,0 @@
1
- // Config
2
- // ––––––––––––––––––––
3
-
4
- // Enable <header>, <main>, <footer> inside <body> as a container
5
- $enable-semantic-container: true !default;
6
-
7
- // Enable .container and .container-fluid
8
- $enable-class-container: false !default;
9
-
10
- // Enable a centered viewport for <header>, <main>, <footer> inside <body>
11
- // Options are "all" to center all, "main" to only center main, and "none" to treat all as fluid.
12
- $enable-viewport: "none" !default;
13
-
14
- // Enable responsive spacings for <header>, <main>, <footer>, <section>, <article>
15
- // Fixed spacings if disabled
16
- $enable-responsive-spacings: true !default;
17
-
18
- // Enable responsive typography
19
- // Fixed root element size if disabled
20
- $enable-responsive-typography: true !default;
21
-
22
- // Enable .classes
23
- // .classless version if disabled
24
- $enable-classes: true !default;
25
-
26
- // Enable .grid class
27
- $enable-grid: true !default;
28
-
29
- // Enable transitions
30
- $enable-transitions: true !default;
31
-
32
- // Enable overriding with !important
33
- $enable-important: true !default;
34
-
35
- // Responsive
36
- // ––––––––––––––––––––
37
-
38
- // xs: Extra small (portrait phones)
39
- // sm: Small (landscape phones)
40
- // md: Medium (tablets)
41
- // lg: Large (desktops)
42
- // xl: Extra large (large desktops, TVs)
43
-
44
- // NOTE:
45
- // To provide an easy and fine styling on each breakpoint
46
- // we didn't use @each, @mixin or @include.
47
- // That means you need to edit each CSS selector file to add a breakpoint
48
-
49
- // Breakpoints
50
- // 'null' disable the breakpoint
51
- $breakpoints: (
52
- xs: 0,
53
- sm: 576px,
54
- md: 768px,
55
- lg: 992px,
56
- xl: 1200px,
57
- ) !default;
58
-
59
- // Viewports
60
- $viewports: (
61
- // 'null' disable the viewport on a breakpoint
62
- sm: 510px,
63
- md: 700px,
64
- lg: 920px,
65
- xl: 1130px
66
- ) !default;
@@ -1,112 +0,0 @@
1
- details {
2
- display: block;
3
- margin-bottom: var(--spacing);
4
- padding-bottom: var(--spacing);
5
- border-bottom: var(--border-width) solid var(--accordion-border-color);
6
-
7
- summary {
8
- line-height: 1rem;
9
- list-style-type: none;
10
- cursor: pointer;
11
-
12
- &:not([role]) {
13
- color: var(--accordion-close-summary-color);
14
- }
15
-
16
- @if $enable-transitions {
17
- transition: color var(--transition);
18
- }
19
-
20
- // Reset marker
21
- &::-webkit-details-marker {
22
- display: none;
23
- }
24
-
25
- &::marker {
26
- display: none;
27
- }
28
-
29
- &::-moz-list-bullet {
30
- list-style-type: none;
31
- }
32
-
33
- // Marker
34
- &::after {
35
- display: block;
36
- width: 1rem;
37
- height: 1rem;
38
- margin-inline-start: calc(var(--spacing, 1rem) * 0.5);
39
- float: right;
40
- transform: rotate(-90deg);
41
- background-image: var(--icon-chevron);
42
- background-position: right center;
43
- background-size: 1rem auto;
44
- background-repeat: no-repeat;
45
- content: "";
46
-
47
- @if $enable-transitions {
48
- transition: transform var(--transition);
49
- }
50
- }
51
-
52
- &:focus {
53
- outline: none;
54
-
55
- &:not([role="button"]) {
56
- color: var(--accordion-active-summary-color);
57
- }
58
- }
59
-
60
- // Type button
61
- &[role="button"] {
62
- width: 100%;
63
- text-align: left;
64
-
65
- // Marker
66
- &::after {
67
- height: calc(1rem * var(--line-height, 1.5));
68
- background-image: var(--icon-chevron-button);
69
- }
70
-
71
- @if $enable-classes {
72
- // .contrast
73
- &:not(.outline).contrast {
74
- // Marker
75
- &::after {
76
- background-image: var(--icon-chevron-button-inverse);
77
- }
78
- }
79
- }
80
- }
81
- }
82
-
83
- // Open
84
- &[open] {
85
- > summary {
86
- margin-bottom: calc(var(--spacing));
87
-
88
- &:not([role]) {
89
- &:not(:focus) {
90
- color: var(--accordion-open-summary-color);
91
- }
92
- }
93
-
94
- &::after {
95
- transform: rotate(0);
96
- }
97
- }
98
- }
99
- }
100
-
101
- [dir="rtl"] {
102
- details {
103
- summary {
104
- text-align: right;
105
-
106
- &::after {
107
- float: left;
108
- background-position: left center;
109
- }
110
- }
111
- }
112
- }
@@ -1,51 +0,0 @@
1
- /**
2
- * Input group and button group
3
- */
4
-
5
- .button-group,
6
- .input-group {
7
- // Stick buttons together
8
- display: flex;
9
- flex-direction: row;
10
-
11
- // Buttons have no margin-bottom set
12
- & > button,
13
- & > label,
14
- & > select,
15
- & > input:not([type="checkbox"]):not([type="radio"]) {
16
- margin-bottom: 0;
17
- }
18
-
19
- // No round corners in button groups
20
- & > button:not(:last-child),
21
- & > [role="button"]:not(:last-child),
22
- & > input:not(:last-child),
23
- & > select:not(:last-child) {
24
- border-top-right-radius: 0;
25
- border-bottom-right-radius: 0;
26
- /* border-right: 0;*/
27
- }
28
-
29
- & > [role="button"]:not(:first-child),
30
- & > input:not(:first-child),
31
- & > button:not(:first-child),
32
- & > select:not(:first-child) {
33
- border-top-left-radius: 0;
34
- border-bottom-left-radius: 0;
35
- border-left: 0;
36
- }
37
- }
38
-
39
- // Radio groups need a text label
40
- .input-group > [type="radio"] ~ label {
41
- margin-right: 0;
42
- }
43
-
44
- // The selected radio button will be outlined when outline class is choose and in reverse
45
- .input-group:not(.outline)
46
- > input[type="radio"]:not(:checked)
47
- + label[role="button"],
48
- .input-group.outline > input[type="radio"]:checked + label[role="button"] {
49
- --background-color: transparent;
50
- --color: var(--primary);
51
- }
@@ -1,47 +0,0 @@
1
- article {
2
- display: flex;
3
- flex-direction: column;
4
- margin: var(--block-spacing-vertical) 0;
5
- padding: var(--block-spacing-vertical) var(--block-spacing-horizontal);
6
- border-radius: var(--border-radius);
7
- background: var(--card-background-color);
8
- box-shadow: var(--card-box-shadow);
9
-
10
- > header,
11
- > footer {
12
- display: flex;
13
- flex-direction: row;
14
- justify-content: space-between;
15
- margin-right: calc(var(--block-spacing-horizontal) * -1);
16
- margin-left: calc(var(--block-spacing-horizontal) * -1);
17
- padding: calc(var(--block-spacing-vertical) * 0.66)
18
- var(--block-spacing-horizontal);
19
- background-color: var(--card-sectionning-background-color);
20
- }
21
-
22
- > header {
23
- margin-top: calc(var(--block-spacing-vertical) * -1);
24
- margin-bottom: var(--block-spacing-vertical);
25
- border-bottom: var(--border-width) solid var(--card-border-color);
26
-
27
- nav ul {
28
- &:first-of-type {
29
- margin: inherit;
30
- }
31
-
32
- li {
33
- padding: 0 calc(var(--nav-element-spacing-horizontal) / 2);
34
- }
35
- }
36
- }
37
-
38
- > main {
39
- flex: 1;
40
- }
41
-
42
- > footer {
43
- margin-top: var(--block-spacing-vertical);
44
- margin-bottom: calc(var(--block-spacing-vertical) * -1);
45
- border-top: var(--border-width) solid var(--card-border-color);
46
- }
47
- }
@@ -1,203 +0,0 @@
1
- details[role="list"],
2
- li[role="list"] {
3
- position: relative;
4
- }
5
-
6
- details[role="list"] summary + ul,
7
- li[role="list"] > ul {
8
- display: flex;
9
- z-index: 99;
10
- position: absolute;
11
- top: auto;
12
- right: 0;
13
- left: 0;
14
- flex-direction: column;
15
- margin: 0;
16
- padding: 0;
17
- border: var(--border-width) solid var(--dropdown-border-color);
18
- border-radius: var(--border-radius);
19
- border-top-right-radius: 0;
20
- border-top-left-radius: 0;
21
- background-color: var(--dropdown-background-color);
22
- box-shadow: var(--card-box-shadow);
23
- color: var(--dropdown-color);
24
- white-space: nowrap;
25
-
26
- li {
27
- width: 100%;
28
- margin-bottom: 0;
29
- padding: calc(var(--form-element-spacing-vertical) * 0.5)
30
- var(--form-element-spacing-horizontal);
31
- list-style: none;
32
-
33
- &:first-of-type {
34
- margin-top: calc(var(--form-element-spacing-vertical) * 0.5);
35
- }
36
-
37
- &:last-of-type {
38
- margin-bottom: calc(var(--form-element-spacing-vertical) * 0.5);
39
- }
40
-
41
- a {
42
- display: block;
43
- margin: calc(var(--form-element-spacing-vertical) * -0.5)
44
- calc(var(--form-element-spacing-horizontal) * -1);
45
- padding: calc(var(--form-element-spacing-vertical) * 0.5)
46
- var(--form-element-spacing-horizontal);
47
- overflow: hidden;
48
- color: var(--dropdown-color);
49
- text-decoration: none;
50
- text-overflow: ellipsis;
51
-
52
- &:hover {
53
- background-color: var(--dropdown-hover-background-color);
54
- }
55
- }
56
- }
57
- }
58
-
59
- // Marker
60
- details[role="list"] summary,
61
- li[role="list"] > a {
62
- &::after {
63
- display: block;
64
- width: 1rem;
65
- height: calc(1rem * var(--line-height, 1.5));
66
- margin-inline-start: 0.5rem;
67
- float: right;
68
- transform: rotate(0deg);
69
- background-position: right center;
70
- background-size: 1rem auto;
71
- background-repeat: no-repeat;
72
- content: "";
73
- }
74
- }
75
-
76
- // Global dropdown only
77
- details[role="list"] {
78
- padding: 0;
79
- border-bottom: none;
80
-
81
- // Style <summary> as <select>
82
- summary {
83
- margin-bottom: 0;
84
-
85
- &:not([role]) {
86
- height: calc(
87
- 1rem * var(--line-height) + var(--form-element-spacing-vertical) * 2 +
88
- var(--border-width) * 2
89
- );
90
- padding: var(--form-element-spacing-vertical)
91
- var(--form-element-spacing-horizontal);
92
- border: var(--border-width) solid var(--form-element-border-color);
93
- border-radius: var(--border-radius);
94
- background-color: var(--form-element-background-color);
95
- color: var(--form-element-placeholder-color);
96
- line-height: inherit;
97
- cursor: pointer;
98
-
99
- @if $enable-transitions {
100
- transition: background-color var(--transition),
101
- border-color var(--transition), color var(--transition),
102
- box-shadow var(--transition);
103
- }
104
-
105
- &:active,
106
- &:focus {
107
- border-color: var(--form-element-active-border-color);
108
- background-color: var(--form-element-active-background-color);
109
- }
110
-
111
- &:focus {
112
- box-shadow: 0 0 0 var(--outline-width) var(--form-element-focus-color);
113
- }
114
- }
115
- }
116
-
117
- // Close for details[role="list"]
118
- &[open] summary {
119
- border-bottom-right-radius: 0;
120
- border-bottom-left-radius: 0;
121
-
122
- &::before {
123
- display: block;
124
- z-index: 1;
125
- position: fixed;
126
- top: 0;
127
- right: 0;
128
- bottom: 0;
129
- left: 0;
130
- background: none;
131
- content: "";
132
- cursor: default;
133
- }
134
- }
135
- }
136
-
137
- // All Dropdowns inside <nav>
138
- nav details[role="list"] summary,
139
- nav li[role="list"] a {
140
- display: flex;
141
- direction: ltr;
142
- }
143
-
144
- nav details[role="list"] summary + ul,
145
- nav li[role="list"] > ul {
146
- min-width: fit-content;
147
- border-radius: var(--border-radius);
148
-
149
- li a {
150
- border-radius: 0;
151
- }
152
- }
153
-
154
- // Dropdowns inside <nav> as nested <details>
155
- nav details[role="list"] {
156
- summary,
157
- summary:not([role]) {
158
- height: auto;
159
- padding: var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal);
160
- }
161
-
162
- &[open] summary {
163
- border-radius: var(--border-radius);
164
- }
165
-
166
- summary + ul {
167
- margin-top: var(--outline-width);
168
- margin-inline-start: 0;
169
- }
170
-
171
- summary[role="link"] {
172
- margin-bottom: calc(var(--nav-link-spacing-vertical) * -1);
173
- line-height: var(--line-height);
174
-
175
- + ul {
176
- margin-top: calc(var(--nav-link-spacing-vertical) + var(--outline-width));
177
- margin-inline-start: calc(var(--nav-link-spacing-horizontal) * -1);
178
- }
179
- }
180
- }
181
-
182
- // Dropdowns inside a <nav> without using <details>
183
- li[role="list"] {
184
- // Open on hover (for mobile)
185
- // or on active/focus (for keyboard navigation)
186
- &:hover > ul,
187
- a:active ~ ul,
188
- a:focus ~ ul {
189
- display: flex;
190
- }
191
-
192
- > ul {
193
- display: none;
194
- margin-top: calc(var(--nav-link-spacing-vertical) + var(--outline-width));
195
- margin-inline-start: calc(
196
- var(--nav-element-spacing-horizontal) - var(--nav-link-spacing-horizontal)
197
- );
198
- }
199
-
200
- > a::after {
201
- background-image: var(--icon-chevron);
202
- }
203
- }