1/* Theme bridge: maps our --alc-* design tokens onto Starlight's --sl-color-*
2 tokens. Each --alc-* token already adapts per `[data-theme]` (see tokens.css),
3 so most of this mapping is mode-agnostic. The walnut neutral scale is the
4 exception — its numeric steps don't flip semantically, so we override the
5 gray scale and `--sl-color-black` per-mode below. */
6
7:root {
8 --sl-font: var(--alc-font-sans);
9 --sl-font-mono: var(--alc-font-mono);
10 --sl-font-headings: var(--alc-font-serif);
11 /* Widen the docs sidebar (Starlight default is 18rem) so long generated
12 provider entries (e.g. GitHubRepositoryEventSourcePolicy) don't wrap. */
13 --sl-sidebar-width: 20rem;
14 /* The docs header is two rows: the marketing nav (64px, matching landing
15 pages pixel-for-pixel) plus the horizontal docs tab bar below it (see
16 components/starlight/Header.astro). Starlight offsets the sidebar and
17 content by --sl-nav-height, so it covers both rows. */
18 --alc-nav-row-height: 4rem;
19 --alc-tabs-height: 2.5rem;
20 --sl-nav-height: calc(var(--alc-nav-row-height) + var(--alc-tabs-height));
21 --sl-nav-pad-x: 2rem;
22 --sl-nav-pad-y: 0;
23 /* Cap the whole docs shell (sidebar + content + TOC) and center it,
24 bun.com/nextjs-style, instead of pinning the sidebar and TOC to the
25 viewport edges on wide screens. */
26 --alc-shell-max: 96rem;
27 --alc-shell-gutter: max(0rem, calc((100vw - var(--alc-shell-max)) / 2));
28 color-scheme: light;
29}
30
31/* The tab row is desktop-only (mobile navigation lives in the hamburger
32 drawer's product switcher), so collapse its reserved height on mobile —
33 otherwise the header keeps a dead 2.5rem band where the row used to be.
34 Everything offset by --sl-nav-height (sidebar pane, content top,
35 scroll-padding, menu-button centering) follows automatically. */
36@media (max-width: 50rem) {
37 :root {
38 --alc-tabs-height: 0rem;
39 }
40}
41
42/* Starlight shows the sticky "On this page" bar everywhere below 72rem —
43 including the 50–72rem range where the tab bar and left sidebar are
44 already up, which reads as stray mobile chrome on a desktop layout.
45 Align it with the rest of the chrome: mobile-only (< 50rem). The
46 right-rail TOC still appears from 72rem, as before. */
47@media (min-width: 50rem) {
48 :root {
49 --sl-mobile-toc-height: 0rem;
50 }
51 mobile-starlight-toc {
52 display: none;
53 }
54}
55
56/* Faint accent wash across the top of the whole docs page — sidebar,
57 content, and TOC alike (bun.com-style), fading into the page background.
58 The fixed sidebar goes transparent on desktop so the wash shows through
59 it; on mobile it stays an opaque overlay. */
60.page {
61 background: linear-gradient(
62 to bottom,
63 color-mix(in srgb, var(--alc-accent) 5%, transparent),
64 transparent 24rem
65 );
66}
67
68@media (min-width: 50rem) {
69 /* Shift Starlight's fixed sidebar off the viewport edge by the gutter;
70 division comes from the hairline, not a contrasting panel color. */
71 .sidebar-pane {
72 inset-inline-start: var(--alc-shell-gutter);
73 background: transparent;
74 }
75 /* …offset the main column to match (Starlight derives the content inset
76 from this var)… */
77 [data-has-sidebar] .page {
78 --sl-content-inline-start: calc(
79 var(--sl-sidebar-width) + var(--alc-shell-gutter)
80 );
81 }
82 /* …and mirror the gutter on the right so the TOC pulls in too. */
83 .main-frame {
84 padding-inline-end: var(--alc-shell-gutter);
85 }
86 /* The fixed header keeps its full-width background; its content (nav row +
87 tab bar) is capped to the same shell. */
88 .alc-docs-header {
89 max-width: var(--alc-shell-max);
90 margin-inline: auto;
91 }
92}
93
94/* Pin Starlight's floating mobile hamburger to the first header row — it
95 centers itself against the full --sl-nav-height, which is now two rows. */
96starlight-menu-button button {
97 top: calc(
98 (var(--alc-nav-row-height) - var(--sl-menu-button-size)) / 2
99 ) !important;
100}
101
102/* The tab bar already links Docs and Blog on docs pages; the nav row's own
103 Docs/Blog text links are redundant there (they stay on marketing pages). */
104.alc-nav--docs .alc-nav__link:not(.alc-nav__link--icon) {
105 display: none;
106}
107
108/* On phones the 2rem desktop gutter is too generous: the docs header has to
109 fit the brand, the Docs/Blog links, the theme toggle AND the room Starlight
110 reserves on the right for its floating hamburger. Trim it to 1rem below the
111 `md` (50rem) breakpoint. `--sl-nav-pad-x` drives the header padding, the
112 hamburger inset and Starlight's reservation together, so they stay aligned
113 and the toggle clears the hamburger. */
114@media (max-width: 50rem) {
115 :root {
116 --sl-nav-pad-x: 1rem;
117 }
118}
119
120[data-theme="dark"] {
121 color-scheme: dark;
122}
123
124:root,
125[data-theme="dark"],
126[data-theme="light"] {
127 /* Page surfaces */
128 --sl-color-bg: var(--alc-bg);
129 --sl-color-bg-nav: var(--alc-bg-nav);
130 /* Sidebar shares the page background (bun.com-style: division comes from
131 the hairline + a faint gradient wash, not a contrasting panel). */
132 --sl-color-bg-sidebar: var(--alc-bg);
133 --sl-color-bg-inline-code: var(--alc-bg-sunk);
134 --sl-color-bg-accent: var(--alc-accent);
135
136 /* Walnut neutral scale — light-mode convention: gray-1 = darkest text,
137 gray-7 = lightest surface. Starlight's hero `.tagline`, body copy,
138 and muted prose all read off this scale.
139
140 IMPORTANT: Starlight uses `--sl-color-white` as the darkest text token
141 and `--sl-color-black` as the lightest surface token in light mode
142 (the names refer to their dark-mode roles; the values flip in light).
143 The mobile sidebar pane and mobile TOC dropdown both paint their
144 background with `--sl-color-black`, so it MUST resolve to a light
145 surface — otherwise we get dark walnut text on a dark walnut panel. */
146 --sl-color-white: var(--alc-fg-1);
147 --sl-color-black: var(--alc-bg-nav);
148 --sl-color-gray-1: var(--alc-walnut-900);
149 --sl-color-gray-2: var(--alc-walnut-700);
150 /* Starlight uses gray-3 for muted text (Edit page, meta); fg-3 keeps it
151 at AAA 7:1 on the parchment surfaces. */
152 --sl-color-gray-3: var(--alc-fg-3);
153 --sl-color-gray-4: var(--alc-walnut-500);
154 --sl-color-gray-5: var(--alc-walnut-300);
155 --sl-color-gray-6: var(--alc-walnut-100);
156 --sl-color-gray-7: var(--alc-bg-nav);
157
158 /* Text */
159 --sl-color-text: var(--alc-fg-2);
160 --sl-color-text-accent: var(--alc-accent-deep);
161 --sl-color-text-invert: var(--alc-fg-invert);
162
163 /* Accent (moss) */
164 --sl-color-accent: var(--alc-accent);
165 --sl-color-accent-high: var(--alc-accent-deep);
166 --sl-color-accent-low: var(--alc-accent-12);
167 --sl-color-accent-light: var(--alc-accent-40);
168
169 /* Hairlines */
170 --sl-color-hairline-light: var(--alc-hairline);
171 --sl-color-hairline: var(--alc-hairline-2);
172 --sl-color-hairline-shade: var(--alc-hairline-3);
173
174 /* Selection */
175 --sl-color-selection-bg: var(--alc-accent-soft);
176 --sl-color-selection-text: var(--alc-fg-1);
177}
178
179/* Dark mode: flip the walnut gray scale so gray-1 = lightest text and
180 gray-7 = darkest surface (Starlight's convention, with the values inverted).
181 `--sl-color-black` is reused by Starlight as the mobile sidebar and TOC
182 panel background, so it must resolve to a surface that is *visible* against
183 the page bg — we use bg-elev-1 (one step lifted from the page). */
184[data-theme="dark"] {
185 --sl-color-white: var(--alc-fg-1);
186 --sl-color-black: var(--alc-bg-elev-1);
187 --sl-color-gray-1: var(--alc-walnut-50);
188 --sl-color-gray-2: var(--alc-walnut-200);
189 --sl-color-gray-3: var(--alc-walnut-300);
190 --sl-color-gray-4: var(--alc-walnut-400);
191 --sl-color-gray-5: var(--alc-walnut-700);
192 --sl-color-gray-6: var(--alc-walnut-800);
193 --sl-color-gray-7: var(--alc-bg-nav);
194 /* Starlight paints the selected sidebar entry with `--sl-color-text-accent`
195 as background and `--sl-color-text-invert` as text. In dark mode the
196 accent lifts to a bright lime (`--alc-accent-deep` ≈ #a3c473) — cream
197 (`--alc-fg-invert`) on lime is ~1.7:1, well below AA. Flip the invert
198 token to the dark page background so the selected pill reads as dark
199 text on lime (~10:1, AAA). */
200 --sl-color-text-invert: var(--alc-bg);
201}
202
203/* ── Headings: serif for h1/h2, sans for h3/h4 (matches alc-h* scale) ── */
204.sl-markdown-content :is(h1, h2),
205h1.hero-title,
206.hero h1 {
207 font-family: var(--alc-font-serif);
208 font-weight: 500;
209 letter-spacing: -0.015em;
210 color: var(--alc-fg-1);
211}
212.sl-markdown-content :is(h3, h4, h5, h6) {
213 font-family: var(--alc-font-sans);
214 font-weight: 600;
215 letter-spacing: -0.01em;
216 color: var(--alc-fg-1);
217}
218
219/* ── Hero "Effects" italic-serif accent ── deep moss, the design-system
220 "alc-text-accent" treatment used in the Claude landing variants. */
221.text-gradient {
222 font-family: var(--alc-font-serif);
223 font-style: italic;
224 font-weight: 500;
225 color: var(--alc-accent-deep);
226 background: none;
227 -webkit-text-fill-color: currentColor;
228}
229
230/* ── Starlight hero refinements (splash template) ── */
231.hero h1 {
232 font-family: var(--alc-font-serif);
233 font-weight: 500;
234 font-size: clamp(44px, 7vw, 76px);
235 line-height: 1.02;
236 letter-spacing: -0.02em;
237 color: var(--alc-fg-1);
238}
239.hero .tagline {
240 font-family: var(--alc-font-sans);
241 font-size: clamp(17px, 1.8vw, 20px);
242 line-height: 1.55;
243 color: var(--alc-fg-2);
244 max-width: 36rem;
245}
246.hero .actions a[data-variant="primary"] {
247 background: var(--alc-accent);
248 color: var(--alc-fg-on-accent);
249 border-color: var(--alc-accent);
250}
251.hero .actions a[data-variant="primary"]:hover {
252 background: var(--alc-accent-deep);
253 border-color: var(--alc-accent-deep);
254 color: var(--alc-fg-on-accent);
255}
256.hero .actions a[data-variant="secondary"] {
257 background: transparent;
258 color: var(--alc-fg-1);
259 border: 1px solid var(--alc-hairline-3);
260}
261.hero .actions a[data-variant="secondary"]:hover {
262 background: var(--alc-bg-elev-1);
263 border-color: var(--alc-accent);
264 color: var(--alc-fg-1);
265}
266
267/* ── Section eyebrow (mono uppercase, deep moss) ── */
268.section-eyebrow {
269 font-family: var(--alc-font-mono);
270 font-size: 12px;
271 line-height: 1;
272 letter-spacing: 0.12em;
273 text-transform: uppercase;
274 font-weight: 500;
275 color: var(--alc-accent-deep);
276 display: block;
277 margin: 0 0 0.75rem;
278}
279
280/* Serif H2 for section headers on the landing page. */
281.section-title {
282 font-family: var(--alc-font-serif);
283 font-size: clamp(28px, 3vw, 34px);
284 line-height: 1.15;
285 letter-spacing: -0.01em;
286 font-weight: 500;
287 color: var(--alc-fg-1);
288 margin: 0 0 1rem;
289}
290.section-lede {
291 font-family: var(--alc-font-sans);
292 font-size: 1rem;
293 line-height: 1.65;
294 color: var(--alc-fg-2);
295 max-width: 36rem;
296 margin: 0 auto 2.25rem;
297}
298
299/* Centered intro block above a section grid (features, providers, etc). */
300.section-intro {
301 text-align: center;
302 max-width: 48rem;
303 margin: 0 auto 3rem;
304}
305.section-intro .section-lede {
306 margin-bottom: 0;
307}
308
309/* ── Landing page ── */
310
311.landing {
312 max-width: 72rem;
313 margin: 0 auto;
314 padding: 0 1.5rem;
315}
316.landing :is(pre, .expressive-code, figure) {
317 max-width: 100%;
318 overflow-x: auto;
319}
320.landing pre code {
321 white-space: pre;
322}
323/* Allow grid/flex items to shrink below their content width so long code blocks
324 scroll internally instead of forcing the page wider than the viewport. */
325.hero-code-grid > *,
326.features > *,
327.provider-grid > * {
328 min-width: 0;
329}
330.landing {
331 overflow-x: clip;
332}
333/* Hide the auto-generated heading anchor link icon on the landing page —
334 these are marketing headings, not navigable anchors. */
335.landing .sl-anchor-link {
336 display: none;
337}
338@media (max-width: 480px) {
339 .landing {
340 padding: 0 1rem;
341 }
342}
343@media (max-width: 640px) {
344 .landing pre code {
345 font-size: 0.8rem;
346 line-height: 1.5;
347 }
348 .hero-code {
349 margin: 2.5rem 0 3rem;
350 }
351 .hero-code-grid {
352 gap: 1.25rem;
353 }
354 .hero-code-text h3 {
355 font-size: 1.35rem;
356 margin-bottom: 0.75rem;
357 }
358 .hero-code-text p {
359 font-size: 0.95rem;
360 }
361 .features {
362 gap: 1.75rem;
363 margin-bottom: 3rem;
364 }
365 .feature h3 {
366 font-size: 1.05rem;
367 }
368 .providers-section {
369 margin-bottom: 3rem;
370 }
371 .providers-section h3,
372 .cta-section h3 {
373 font-size: 1.25rem;
374 }
375 .cta-section {
376 padding: 2rem 0 2.5rem;
377 }
378}
379@media (max-width: 420px) {
380 .cta-buttons {
381 flex-direction: column;
382 align-items: stretch;
383 }
384 .cta-buttons > * {
385 justify-content: center;
386 text-align: center;
387 }
388}
389
390/* ── Hero overrides: center on mobile/tablet, keep 3 actions on one row ── */
391
392@media (max-width: 60rem) {
393 .hero .stack {
394 text-align: center;
395 }
396 .hero .copy {
397 align-items: center;
398 }
399 .hero .copy > * {
400 margin-inline: auto;
401 }
402 .hero .actions {
403 justify-content: center;
404 gap: 0.75rem;
405 }
406 .hero .actions > a {
407 padding-inline: 1rem;
408 }
409}
410
411@media (max-width: 30rem) {
412 .hero .actions {
413 gap: 0.5rem;
414 }
415 .hero .actions > a {
416 padding-inline: 0.75rem;
417 font-size: 0.9rem;
418 }
419}
420
421.hero-code {
422 margin: 2rem 0 5rem;
423}
424.hero-code-grid {
425 display: grid;
426 grid-template-columns: 1fr 1fr;
427 gap: 3rem;
428 align-items: center;
429}
430.hero-code-text h3 {
431 font-family: var(--alc-font-serif);
432 font-size: 1.75rem;
433 font-weight: 500;
434 letter-spacing: -0.015em;
435 margin: 0 0 1rem;
436 color: var(--alc-fg-1);
437}
438.hero-code-text p {
439 color: var(--alc-fg-2);
440 line-height: 1.7;
441 margin: 0 0 0.75rem;
442}
443@media (max-width: 768px) {
444 .hero-code-grid {
445 grid-template-columns: 1fr;
446 gap: 2rem;
447 }
448}
449
450/* Features grid: .feature uses display: contents so each feature's three
451 children (heading / body / code) become direct grid items of .features.
452 We then explicitly pin each child to a grid row and column. This guarantees
453 headings, paragraphs, and code blocks all align across the two columns in
454 a visual row, regardless of content height. */
455.features {
456 display: grid;
457 grid-template-columns: 1fr 1fr;
458 column-gap: 3rem;
459 row-gap: 0.75rem;
460 margin: 0 0 5rem;
461}
462.feature {
463 display: contents;
464}
465.features > .feature > * {
466 margin: 0 !important;
467 min-width: 0;
468}
469.features > .feature > :nth-child(1) {
470 /* heading row */
471 font-family: var(--alc-font-sans);
472 font-size: 1.15rem;
473 font-weight: 600;
474 color: var(--alc-fg-1);
475}
476.features > .feature > :nth-child(2) {
477 /* body row */
478 color: var(--alc-fg-2);
479 line-height: 1.6;
480 font-size: 0.95rem;
481}
482.features > .feature > :nth-child(3) {
483 /* code row – anchor to the top of the row so terminals and code blocks
484 sit directly under the paragraph, regardless of snippet height. */
485 align-self: start;
486 width: 100%;
487}
488
489/* Explicit row/column placement for each of the 6 features.
490 Visual row 1 (features 1,2) occupies grid rows 1-3,
491 visual row 2 (features 3,4) occupies rows 5-7 (row 4 is the gap),
492 visual row 3 (features 5,6) occupies rows 9-11 (row 8 is the gap). */
493.features > .feature:nth-of-type(odd) > * {
494 grid-column: 1;
495}
496.features > .feature:nth-of-type(even) > * {
497 grid-column: 2;
498}
499
500.features > .feature:nth-of-type(1) > :nth-child(1),
501.features > .feature:nth-of-type(2) > :nth-child(1) {
502 grid-row: 1;
503}
504.features > .feature:nth-of-type(1) > :nth-child(2),
505.features > .feature:nth-of-type(2) > :nth-child(2) {
506 grid-row: 2;
507}
508.features > .feature:nth-of-type(1) > :nth-child(3),
509.features > .feature:nth-of-type(2) > :nth-child(3) {
510 grid-row: 3;
511}
512
513.features > .feature:nth-of-type(3) > :nth-child(1),
514.features > .feature:nth-of-type(4) > :nth-child(1) {
515 grid-row: 5;
516}
517.features > .feature:nth-of-type(3) > :nth-child(2),
518.features > .feature:nth-of-type(4) > :nth-child(2) {
519 grid-row: 6;
520}
521.features > .feature:nth-of-type(3) > :nth-child(3),
522.features > .feature:nth-of-type(4) > :nth-child(3) {
523 grid-row: 7;
524}
525
526.features > .feature:nth-of-type(5) > :nth-child(1),
527.features > .feature:nth-of-type(6) > :nth-child(1) {
528 grid-row: 9;
529}
530.features > .feature:nth-of-type(5) > :nth-child(2),
531.features > .feature:nth-of-type(6) > :nth-child(2) {
532 grid-row: 10;
533}
534.features > .feature:nth-of-type(5) > :nth-child(3),
535.features > .feature:nth-of-type(6) > :nth-child(3) {
536 grid-row: 11;
537}
538
539/* Larger gap between visual rows via empty tracks 4 and 8. */
540.features {
541 grid-template-rows: auto auto auto /* row 1: h, p, code */
542 3rem /* gap */
543 auto auto auto /* row 2 */
544 3rem /* gap */
545 auto auto auto; /* row 3 */
546}
547
548@media (max-width: 768px) {
549 /* Collapse to single column: each .feature stacks naturally. */
550 .features {
551 grid-template-columns: 1fr;
552 grid-template-rows: none;
553 row-gap: 2.5rem;
554 }
555 .feature {
556 display: flex;
557 flex-direction: column;
558 gap: 0.75rem;
559 }
560 .features > .feature > * {
561 grid-row: auto !important;
562 grid-column: auto !important;
563 }
564}
565
566.providers-section {
567 margin: 0 0 5rem;
568 text-align: center;
569}
570.providers-section h3 {
571 font-family: var(--alc-font-serif);
572 font-size: 1.75rem;
573 font-weight: 500;
574 letter-spacing: -0.015em;
575 color: var(--alc-fg-1);
576 margin: 0 0 1rem;
577}
578.providers-section > p {
579 color: var(--alc-fg-2);
580 max-width: 36rem;
581 margin: 0 auto 2rem;
582 line-height: 1.6;
583}
584.provider-grid {
585 display: grid;
586 grid-template-columns: repeat(3, 1fr);
587 gap: 1.5rem;
588 align-items: stretch;
589}
590.provider-card {
591 display: flex;
592 flex-direction: column;
593 gap: 0.5rem;
594 background: var(--alc-bg-elev-1);
595 border: 1px solid var(--alc-hairline-2);
596 border-radius: var(--alc-radius);
597 padding: 1.5rem;
598 text-align: left;
599 height: 100%;
600 box-shadow: var(--alc-shadow-sm);
601 transition:
602 border-color var(--alc-dur) var(--alc-ease),
603 box-shadow var(--alc-dur) var(--alc-ease);
604}
605.provider-card:hover {
606 border-color: var(--alc-accent);
607 box-shadow: var(--alc-shadow);
608}
609.provider-card > * {
610 margin: 0;
611}
612.provider-card strong {
613 color: var(--alc-fg-1);
614 font-size: 1.05rem;
615 font-weight: 600;
616}
617.provider-card p {
618 color: var(--alc-fg-2);
619 font-size: 0.9rem;
620 line-height: 1.5;
621}
622@media (max-width: 768px) {
623 .provider-grid {
624 grid-template-columns: 1fr;
625 }
626}
627
628/* 4-column variant for the AB-test "Explore alternate framings" cards. */
629.explore-section .provider-grid {
630 grid-template-columns: repeat(4, 1fr);
631}
632.explore-section a.provider-card {
633 text-decoration: none;
634 color: inherit;
635}
636@media (max-width: 1024px) {
637 .explore-section .provider-grid {
638 grid-template-columns: repeat(2, 1fr);
639 }
640}
641@media (max-width: 540px) {
642 .explore-section .provider-grid {
643 grid-template-columns: 1fr;
644 }
645}
646
647.cta-section {
648 text-align: center;
649 padding: 3rem 0 4rem;
650 border-top: 1px solid var(--alc-hairline-2);
651}
652.cta-section h3 {
653 font-family: var(--alc-font-serif);
654 font-size: 1.75rem;
655 font-weight: 500;
656 letter-spacing: -0.015em;
657 color: var(--alc-fg-1);
658 margin: 0 0 1rem;
659}
660.cta-section > p {
661 color: var(--alc-fg-2);
662 max-width: 36rem;
663 margin: 0 auto 2rem;
664 line-height: 1.6;
665}
666.cta-buttons {
667 display: flex;
668 gap: 1rem;
669 justify-content: center;
670 flex-wrap: wrap;
671}
672/* Neutralize Starlight's default LinkButton margins inside .sl-markdown-content
673 so our flex container controls spacing. */
674.cta-buttons .sl-link-button,
675.cta-buttons > p {
676 margin: 0 !important;
677}
678.cta-buttons > p {
679 display: contents;
680}
681/* MDX wraps loose JSX children in <p> (and sometimes emits an empty
682 <p> sibling when JSX sits between paragraphs). Use :has() to flatten
683 any paragraph that contains an `.alc-btn`, and hide empty wrapper
684 paragraphs anywhere inside the outro CTA — the User Agent's default
685 1em block margin on those empty <p>s is what was making the
686 "Read the tutorial" row look chunky. */
687p:has(> .alc-btn) {
688 margin: 0;
689 display: contents;
690}
691.alc-cta > p:empty {
692 display: none;
693}
694
695/* ── Getting Started next-steps cards ── */
696
697.next-steps {
698 display: grid;
699 grid-template-columns: 1fr 1fr;
700 gap: 1rem;
701 margin-top: 1rem;
702}
703.next-card {
704 display: block;
705 padding: 1.25rem 1.5rem;
706 background: var(--alc-bg-elev-1);
707 border: 1px solid var(--alc-hairline-2);
708 border-radius: var(--alc-radius);
709 text-decoration: none;
710 transition:
711 border-color var(--alc-dur) var(--alc-ease),
712 box-shadow var(--alc-dur) var(--alc-ease);
713 box-shadow: var(--alc-shadow-sm);
714}
715.next-card:hover {
716 border-color: var(--alc-accent);
717 box-shadow: var(--alc-shadow);
718}
719.next-card strong {
720 display: block;
721 color: var(--alc-fg-1);
722 font-size: 1.05rem;
723 font-weight: 600;
724 margin-bottom: 0.35rem;
725}
726.next-card span {
727 color: var(--alc-fg-2);
728 font-size: 0.9rem;
729 line-height: 1.5;
730}
731/* A small tab sits on the top edge of the recommended card, outside the
732 content, so it never collides with the title or description. */
733.next-card--recommended {
734 position: relative;
735 border-color: color-mix(
736 in srgb,
737 var(--alc-accent) 45%,
738 var(--alc-hairline-2)
739 );
740}
741.next-card--recommended::before {
742 content: "Recommended";
743 position: absolute;
744 top: 0;
745 right: 1.25rem;
746 transform: translateY(-50%);
747 padding: 0.15rem 0.6rem;
748 border-radius: 999px;
749 background: var(--alc-accent);
750 color: var(--alc-fg-on-accent);
751 font-size: 0.66rem;
752 font-weight: 600;
753 letter-spacing: 0.04em;
754 text-transform: uppercase;
755 line-height: 1.4;
756 pointer-events: none;
757}
758/* Provider brand marks in place of a description on the directory card. */
759.next-card .provider-icons {
760 display: flex;
761 flex-wrap: wrap;
762 gap: 0.75rem 0.9rem;
763 margin-top: 0.6rem;
764 color: var(--alc-fg-2);
765}
766.next-card .provider-icons svg {
767 flex: none;
768 transition: color var(--alc-dur) var(--alc-ease);
769}
770.next-card:hover .provider-icons {
771 color: var(--alc-fg-1);
772}
773@media (max-width: 600px) {
774 .next-steps {
775 grid-template-columns: 1fr;
776 }
777}
778
779/* ============================================================
780 Starlight Asides (Note / Tip / Caution / Danger)
781
782 Starlight's defaults use saturated info-blue / yellow / red
783 panels that clash with the warm parchment + moss palette.
784 Override to match the design-system callout spec from
785 claude/design-system/preview/components-callouts.html:
786 - tip: moss green
787 - note: slate teal (--alc-info)
788 - caution: honey amber (--alc-warn)
789 - danger: brick red (--alc-danger)
790 ============================================================ */
791
792.sl-markdown-content .starlight-aside {
793 border-radius: 8px;
794 border-width: 1px;
795 border-style: solid;
796 padding: 12px 14px;
797 margin: 1rem 0;
798 background: var(--aside-tint, var(--alc-bg-elev-1));
799 border-color: var(--aside-border, var(--alc-hairline-2));
800 color: var(--alc-fg-2);
801 font-family: var(--alc-font-sans);
802}
803
804.sl-markdown-content .starlight-aside__title {
805 color: var(--aside-accent, var(--alc-fg-1));
806 font-family: var(--alc-font-sans);
807 font-weight: 600;
808 font-size: 13.5px;
809 letter-spacing: 0;
810 text-transform: none;
811 display: flex;
812 align-items: center;
813 gap: 8px;
814}
815
816.sl-markdown-content .starlight-aside__icon {
817 color: var(--aside-accent, var(--alc-fg-1));
818 font-size: 1rem;
819}
820
821.sl-markdown-content .starlight-aside__content {
822 color: var(--alc-fg-2);
823 font-size: 14px;
824 line-height: 1.55;
825}
826.sl-markdown-content .starlight-aside__content > :first-child {
827 margin-top: 4px;
828}
829.sl-markdown-content .starlight-aside__content > :last-child {
830 margin-bottom: 0;
831}
832.sl-markdown-content .starlight-aside__content a {
833 color: var(--aside-accent, var(--alc-accent-deep));
834 text-decoration: underline;
835 text-underline-offset: 2px;
836}
837.sl-markdown-content .starlight-aside__content a:hover {
838 color: var(--alc-accent-deep);
839}
840/* Inline-code only — must NOT match the per-token <code> elements that
841 Expressive Code emits inside <pre>, otherwise the dark walnut code-block
842 background and bright sunrise syntax tokens get repainted to cream + walnut
843 and the whole block bleaches out. */
844.sl-markdown-content .starlight-aside__content :not(pre) > code {
845 background: var(--alc-bg-sunk);
846 border: 1px solid var(--alc-hairline);
847 color: var(--alc-fg-1);
848}
849.sl-markdown-content .starlight-aside__content strong {
850 color: var(--alc-fg-1);
851}
852
853/* ── Variants ── */
854.sl-markdown-content .starlight-aside--note {
855 --aside-accent: var(--alc-info);
856 --aside-tint: color-mix(in srgb, var(--alc-info) 14%, transparent);
857 --aside-border: color-mix(in srgb, var(--alc-info) 45%, transparent);
858}
859.sl-markdown-content .starlight-aside--tip {
860 --aside-accent: var(--alc-accent-deep);
861 --aside-tint: color-mix(in srgb, var(--alc-accent) 14%, transparent);
862 --aside-border: color-mix(in srgb, var(--alc-accent) 45%, transparent);
863}
864.sl-markdown-content .starlight-aside--caution {
865 --aside-accent: color-mix(in srgb, var(--alc-warn) 75%, var(--alc-fg-1));
866 --aside-tint: color-mix(in srgb, var(--alc-warn) 16%, transparent);
867 --aside-border: color-mix(in srgb, var(--alc-warn) 50%, transparent);
868}
869.sl-markdown-content .starlight-aside--danger {
870 --aside-accent: var(--alc-danger);
871 --aside-tint: color-mix(in srgb, var(--alc-danger) 14%, transparent);
872 --aside-border: color-mix(in srgb, var(--alc-danger) 45%, transparent);
873}
874
875/* ============================================================
876 Starlight Tabs (Code/Tabs component used on Getting Started
877 for bun / npm / pnpm / yarn).
878
879 - Tab labels use a soft mushroom for inactive and deep moss
880 for the active tab; the active underline is the moss accent.
881 - Icons are sized larger (1.25em) and painted with each
882 product's official brand color via positional selectors
883 (the package-manager tab order is bun → npm → pnpm → yarn,
884 and is consistent across the docs).
885 ============================================================ */
886
887starlight-tabs [role="tablist"] {
888 border-bottom-color: var(--alc-hairline-2);
889}
890
891starlight-tabs [role="tab"] {
892 color: var(--alc-fg-3);
893 font-family: var(--alc-font-sans);
894 font-size: 14px;
895 font-weight: 500;
896 letter-spacing: 0;
897 border-bottom-color: transparent;
898 gap: 0.45rem;
899 transition:
900 color 160ms ease,
901 border-color 160ms ease;
902}
903
904starlight-tabs [role="tab"]:hover {
905 color: var(--alc-accent-deep);
906}
907
908starlight-tabs [role="tab"][aria-selected="true"] {
909 color: var(--alc-accent-deep);
910 border-bottom-color: var(--alc-accent);
911}
912
913/* Icon sizing — undo Starlight's tight 1em so the package-manager
914 marks read at glance, and lock dimensions so the SVG can't shrink
915 below this when the tab text is small. */
916starlight-tabs [role="tab"] > svg {
917 width: 1.25em;
918 height: 1.25em;
919 flex: 0 0 auto;
920 font-size: inherit;
921}
922
923/* ── Per-package brand colors ──
924 The Tabs.astro markup wraps each tab anchor in <li class="tab">,
925 so we color the SVG icon inside each LI by position. Order on
926 our docs is bun(1), npm(2), pnpm(3), yarn(4). Colors come from
927 each project's brand guidelines, tuned slightly for contrast
928 on the warm cream surface. */
929
930/* Bun: Starlight's built-in `bun` icon is a single-path silhouette —
931 painting it any single color loses the eyes, cheeks and mouth that
932 make the mascot recognizable. We hide that path and overlay the
933 official multi-color mascot from bun.com/logo.svg (saved locally as
934 /bun-logo.svg) via a background image. */
935starlight-tabs [role="tablist"] > li:nth-child(1) [role="tab"] > svg {
936 color: transparent;
937 background-image: url("/bun-logo.svg");
938 background-repeat: no-repeat;
939 background-position: center;
940 background-size: contain;
941}
942starlight-tabs [role="tablist"] > li:nth-child(2) [role="tab"] > svg {
943 color: #cb3837; /* npm — npm red */
944}
945starlight-tabs [role="tablist"] > li:nth-child(3) [role="tab"] > svg {
946 color: #f59f00; /* pnpm — orange */
947}
948starlight-tabs [role="tablist"] > li:nth-child(4) [role="tab"] > svg {
949 color: #2c8ebb; /* yarn — yarn blue */
950}
951
952/* Match Starlight's docs <header> chrome to the marketing <header>: same
953 translucent cream + backdrop-blur + hairline border. Defined in custom.css
954 (rather than scoped to a single component) so the docs layout picks it up
955 without a Page/Header override.
956
957 IMPORTANT: must be scoped to the <header> element, not bare `.header`.
958 Expressive Code emits a <div class="header"> for its terminal titlebar
959 inside every shell/sh code block, and an unscoped `.header` rule with
960 !important repaints that titlebar in cream parchment instead of the
961 intended dark walnut, leaving an ugly cream strip above shell snippets. */
962header.header {
963 /* Same surface as the page + sidebar (bun.com-style — hairlines divide,
964 not contrasting panels), translucent for the blur under scroll. */
965 background: color-mix(in srgb, var(--alc-bg) 92%, transparent) !important;
966 backdrop-filter: saturate(140%) blur(8px);
967 border-bottom: 1px solid var(--alc-hairline) !important;
968}
969
970/* ── Docs sidebar: elide long entries with an ellipsis instead of wrapping
971 onto a second line (the generated provider pages have long names like
972 GitHubRepositoryEventSourcePolicy). ── */
973.sidebar-content .top-level a {
974 display: block;
975 white-space: nowrap;
976 overflow: hidden;
977 text-overflow: ellipsis;
978}
979
980/* ── Docs sidebar restyle (redesign mockups): small-caps group headings,
981 flat sections instead of accordion rows, active page = accent bar +
982 tinted background instead of a filled pill. ── */
983
984/* Group labels read as small-caps section headings. */
985#starlight__sidebar .top-level > li > details > summary .group-label .large {
986 font-size: 11px;
987 font-weight: 600;
988 letter-spacing: 0.07em;
989 text-transform: uppercase;
990 color: var(--alc-fg-4);
991}
992#starlight__sidebar .top-level > li > details {
993 margin-top: 0.9rem;
994}
995
996/* Hub-tab groups contain only links — render them as flat, always-open
997 sections: no caret, no collapse affordance. Reference's provider groups
998 nest further groups (categories → services) and keep the caret. */
999#starlight__sidebar .top-level > li > details:not(:has(details)) > summary {
1000 pointer-events: none;
1001}
1002#starlight__sidebar
1003 .top-level
1004 > li
1005 > details:not(:has(details))
1006 > summary
1007 .caret {
1008 display: none;
1009}
1010
1011/* Entries: tighter and smaller, with a reserved rail for the accent bar. */
1012#starlight__sidebar .sidebar-content .top-level a {
1013 font-size: 13px;
1014 padding-block: 0.22rem;
1015 border-inline-start: 3px solid transparent;
1016 border-radius: 0;
1017}
1018#starlight__sidebar .sidebar-content .top-level a.large {
1019 font-size: 13px;
1020 font-weight: 400;
1021 color: var(--sl-color-gray-2);
1022}
1023#starlight__sidebar .sidebar-content .top-level a:hover {
1024 color: var(--alc-accent-deep);
1025}
1026
1027/* Nested group labels (Resources categories/services, the Reference tree)
1028 read like regular entries, not headings — only top-level group summaries
1029 get the small-caps heading treatment above. */
1030#starlight__sidebar .sidebar-content ul ul .group-label .large {
1031 font-size: 13px;
1032 font-weight: 400;
1033 color: var(--sl-color-gray-2);
1034}
1035#starlight__sidebar .sidebar-content ul ul summary:hover .group-label .large {
1036 color: var(--alc-accent-deep);
1037}
1038
1039/* Active page: left accent bar + tint, mockup-style. */
1040#starlight__sidebar .sidebar-content .top-level a[aria-current="page"] {
1041 background: var(--alc-accent-12);
1042 color: var(--alc-accent-deep);
1043 border-inline-start-color: var(--alc-accent-deep);
1044 font-weight: 500;
1045}
1046
1047/* ============================================================
1048 Blog index: starlight-blog hides the title panel with
1049 `display: none`, which drops the page's only <h1>. Keep it
1050 visually hidden but available to assistive tech instead.
1051 ============================================================ */
1052.content-panel:first-of-type:has(+ .content-panel .sl-blog-posts) {
1053 display: block !important;
1054 position: absolute !important;
1055 width: 1px;
1056 height: 1px;
1057 padding: 0;
1058 margin: -1px;
1059 overflow: hidden;
1060 clip-path: inset(50%);
1061 white-space: nowrap;
1062 border: 0;
1063}