a reactive (signals based) hypermedia web framework (wip)
stormlightlabs.github.io/volt/
hypermedia
frontend
signals
1/* ========================================================================== */
2/* Base Rules & Reset */
3/* ========================================================================== */
4
5*, *::before, *::after {
6 box-sizing: border-box;
7}
8
9* {
10 margin: 0;
11 padding: 0;
12}
13
14html {
15 font-size: var(--font-size-base);
16 -webkit-text-size-adjust: 100%;
17 -webkit-font-smoothing: antialiased;
18 -moz-osx-font-smoothing: grayscale;
19 text-rendering: optimizeLegibility;
20}
21
22body {
23 font-family: var(--font-sans);
24 font-size: 1rem;
25 line-height: var(--line-height-base);
26 color: var(--color-text);
27 background-color: var(--color-bg);
28
29 /* Center content with optimal reading width */
30 max-width: calc(var(--content-width) + var(--sidenote-width) + var(--sidenote-gap) * 2);
31 margin: 0 auto;
32 padding: var(--space-2xl) var(--space-lg);
33}
34
35
36/**
37 * Sidenotes using <small> elements
38 * On desktop: positioned in right margin
39 * On mobile: inline with reduced emphasis
40 *
41 * Usage: Place <small> inside <p> where you want the note to appear
42 * Example: <p>Main text here <small>This appears in margin</small> more text.</p>
43 */
44@media (min-width: 768px) {
45 /**
46 * Parent paragraph must be positioned for absolute children
47 */
48 p:has(small) {
49 position: relative;
50 }
51
52 /**
53 * Pull small elements into the right margin
54 * Creates classic Tufte-style sidenote layout
55 */
56 p small {
57 position: absolute;
58 left: calc(100% + var(--sidenote-gap));
59 width: var(--sidenote-width);
60 font-size: 0.85rem;
61 line-height: var(--line-height-base);
62 margin-top: 0;
63 padding: var(--space-sm);
64 background-color: var(--color-bg-alt);
65 border-left: 2px solid var(--color-accent);
66 border-radius: var(--radius-sm);
67 }
68}
69
70
71
72article, section {
73 margin-bottom: var(--space-3xl);
74}
75
76aside {
77 padding: var(--space-lg);
78 margin: var(--space-xl) 0;
79 background-color: var(--color-bg-alt);
80 border-left: 4px solid var(--color-accent);
81 border-radius: var(--radius-sm);
82 max-width: var(--content-width);
83}
84
85header {
86 margin-bottom: var(--space-2xl);
87 padding-bottom: var(--space-xl);
88 border-bottom: 1px solid var(--color-border);
89}
90
91footer {
92 margin-top: var(--space-3xl);
93 padding-top: var(--space-xl);
94 border-top: 1px solid var(--color-border);
95 font-size: var(--font-size-sm);
96 color: var(--color-text-muted);
97}
98
99nav {
100 margin: var(--space-lg) 0;
101}
102
103nav ul {
104 list-style: none;
105 padding: 0;
106 display: flex;
107 gap: var(--space-md);
108 flex-wrap: wrap;
109}
110
111nav li {
112 margin: 0;
113}
114
115/**
116 * Screen reader only
117 *
118 * Hides content visually but keeps it accessible to assistive technology
119 */
120.sr-only {
121 position: absolute;
122 width: 1px;
123 height: 1px;
124 padding: 0;
125 margin: -1px;
126 overflow: hidden;
127 clip: rect(0, 0, 0, 0);
128 white-space: nowrap;
129 border-width: 0;
130}
131
132@media print {
133 body {
134 font-size: 12pt;
135 line-height: 1.5;
136 color: #000;
137 background: #fff;
138 }
139
140 a {
141 text-decoration: underline;
142 color: #000;
143 }
144
145 /* Display URLs after links */
146 a[href^="http"]::after {
147 content: " (" attr(href) ")";
148 font-size: 0.8em;
149 }
150
151 /* Hide sidenotes positioning, show inline */
152 @media (min-width: 768px) {
153 p small {
154 position: static;
155 width: auto;
156 left: auto;
157 }
158 }
159
160 /* Avoid page breaks inside elements */
161 h1, h2, h3, h4, h5, h6, p, li, blockquote {
162 page-break-inside: avoid;
163 }
164
165 /* Ensure images fit page */
166 img {
167 max-width: 100% !important;
168 }
169}
170
171
172
173@media (max-width: 768px) {
174 :root {
175 --font-size-base: 16px;
176 --space-2xl: 2rem;
177 --space-3xl: 3rem;
178 }
179
180 body {
181 padding: var(--space-lg) var(--space-md);
182 }
183
184 h1 {
185 font-size: var(--font-size-4xl);
186 }
187
188 h2 {
189 font-size: var(--font-size-3xl);
190 }
191
192 /* Stack navigation vertically */
193 nav ul {
194 flex-direction: column;
195 gap: var(--space-sm);
196 }
197
198 /**
199 * Mobile sidenotes - Inline with subtle styling
200 */
201 p small {
202 display: block;
203 margin-top: var(--space-sm);
204 margin-bottom: var(--space-sm);
205 padding: var(--space-sm);
206 background-color: var(--color-bg-alt);
207 border-left: 2px solid var(--color-accent);
208 border-radius: var(--radius-sm);
209 font-size: 0.9rem;
210 }
211}
212
213@media (max-width: 480px) {
214 :root {
215 --font-size-base: 15px;
216 }
217
218 body {
219 padding: var(--space-md) var(--space-sm);
220 }
221
222 h1 {
223 font-size: var(--font-size-3xl);
224 }
225
226 /* Reduce horizontal padding on smaller screens */
227 pre {
228 padding: var(--space-md);
229 }
230
231 table {
232 font-size: var(--font-size-sm);
233 }
234}
235