Files
paperclip-docs/site/styles.css
39633c2217 docs: connectors catalog, operator-first third revision (#124)
Connector catalog, setup guides, and shared access documentation,
followed by a final code-accuracy repair pass. This PR does not change
application behavior.

## Final accuracy pass

Checked against shipped Paperclip `v2026.916.0`, commit
`dffc2b3ca1b9e88fa21cb17493083e682dffd1ca`, rather than the dirty local
checkout or the earlier canary baseline.

- Corrects connector/method-specific identity choices, human audiences,
and managed GitHub versus PAT scope and verification.
- Explains that **Always allow** covers different arguments for the same
agent/action/connection, with project scope when present; uses actual
button labels and removes the test-panel control from review
instructions.
- Qualifies new-action quarantine, including safe-default read
exceptions. Removes unconditional approval guarantees.
- Separates provider channel/repository reach from Paperclip sender
authorization.
- Completes sandbox sign-in and model credential-selection instructions
from the current UI implementation.
- Repairs Notion's hub summary, removes incomplete optional
Notion/Sentry client-registration procedures, and corrects Linear's
provider-versus-Paperclip attribution.
- Removes unsupported Postman tier claims, contradictory Cloudinary/Mem0
verification assertions, API-equivalence claims, and overbroad
successful-test assurances.
- Retains Supabase's required project reference: both released method
definitions explicitly require it. An earlier review suggested
otherwise; release code is authoritative here.
- Updates the release baseline and removes draft commit chronology from
the public introduction.

## Availability and remaining runtime gates

- **Google:** Verification is pending. Per the product-owner
clarification, authorization can continue where Google offers an
Advanced option; this is not available for every account and does not
override Workspace policy or other Google prerequisites. Notices on the
hub and all Google guides now distinguish an unverified-app warning from
blocked authorization.
- **Slack is available but not yet fully functional; follow-up fixes are
planned.** For agent tools, the released OAuth endpoint/scope defaults
differ from Slack's documented MCP contract. The page now warns against
treating that route as production-ready and removes the misleading
bot-scope walkthrough. Chat-channel bot setup remains separate.
Engineering must reconcile the integration and run OAuth plus one read
before removing this warning. Source:
https://docs.slack.dev/ai/slack-mcp-server/
- No credentialed connector run was performed in this pass. Code
consistency, provider documentation, UI rendering, and successful live
execution are separate evidence levels. No claim of runtime
certification for all connectors.

## Validation

- Root build: 253 crawlable documentation pages.
- Full `docs:test`: all eight suites passed locally, including
root/subpath routes, sitemap history, fingerprints, navigation, skill
source blocks, crawlable links, doc-link resolution, and SEO metadata.
- Internal-link lint: 258 Markdown files; no broken internal links.
- Latest cleanup: full build, all eight docs:test suites, internal-link
lint and diff whitespace checks passed; 1,878 link-resolution checks.
- Fixed the Calendar MCP reference URL; browser-checked the five
inconclusive external destinations (Miro article loads; Asana, Google
Cloud, OpenAI and xAI reach sign-in/console screens). Authenticated
destinations were not tested beyond those screens.
- Replaced the Sandbox providers editorial TODO with a scope note and
removed the CLI overview's unfinished-guide announcement.
- Browser client navigation: 687 checks passed using installed Chrome.
Initial launch lacked the downloaded Playwright browser; rerun used
`DOCS_CHROMIUM_PATH` without changing the tests.
- Nine representative connector/shared pages at 1440px and 390px: HTTP
200, one article H1, no page-level horizontal overflow. Mobile
screenshot inspected; approval page opened in the Codex browser.
- Navigation audit reports three existing non-connector orphan files;
this patch does not alter those files or their navigation.

The previous revision's provider-page expansion, Google shared setup
guide, navigation additions, and accidental node_modules-symlink cleanup
remain in this PR. Internal review ledgers remain outside the
publication branch. No merge or production deployment authorized.

---------

Co-authored-by: DevRel Gemini <[email protected]>
Co-authored-by: Paperclip <[email protected]>
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
Co-authored-by: Michael Nguyen <[email protected]>
2026-09-16 22:19:14 -10:00

1538 lines
58 KiB
CSS

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
/* Light theme — paperclip.ing "materials" palette */
--white: #ffffff; /* bond / surface */
--linen: #ffffff; /* page background (matches paperclip.ing) */
--parchment: #f0ece7; /* raised surface */
--stone: #e0dcd6; /* rule / border */
--stone-dark: #c8c3bc; /* border hover */
--ink: #0a0a0a; /* primary text */
--graphite: #52585d; /* secondary text */
--ash: #6f6a61; /* muted text */
--void: #141413; /* charcoal */
--green: #22c55e; /* signal / success */
--green-deep: #188a3c; /* success deep */
--mint: #dcfce7; /* success soft tint */
--amber: #f59e0b; /* warning */
--amber-deep: #b45309; /* warning deep */
--blue: #2563eb; /* info */
--blue-deep: #1d4ed8; /* info deep */
--red: #dc2626; /* error */
--red-deep: #991b1b; /* error deep */
--sidebar-w: 288px;
--toc-w: 224px;
--content-max: 760px;
--outer-px: 32px;
--layout-max: 1440px;
--header-h: 60px;
--topbar-h: var(--header-h);
--font-serif: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
--font-body: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
--font-mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
/* Brand radius scale — "each radius signals meaning" */
--radius-xs: 4px; /* status pills, code chips, table cells */
--radius-sm: 10px; /* inputs, small cards, buttons, menus */
--radius: 16px; /* default card / panel / feature block (md) */
--radius-lg: 24px; /* large surfaces */
--radius-pill: 9999px; /* PRIMARY CTA ONLY */
--transition: 0.2s ease;
}
/* ─── Dark theme — warm charcoal + white text ────────────── */
[data-theme="dark"] {
--white: #1f1d1a; /* surface */
--linen: #141413; /* page background — charcoal */
--parchment: #2a2724; /* raised surface */
--stone: #2f2c28; /* rule / border */
--stone-dark: #3a3836; /* border hover */
--ink: #ffffff; /* primary text */
--graphite: #9a958a; /* secondary text (brand --text-2 dark) */
--ash: #8a8579; /* muted text — raised from brand #6E6960 for WCAG AA (~5:1) since --ash is reused for normal-size text */
--void: #0d0d0d;
--mint: rgba(34,197,94,0.12);
}
[data-theme="dark"] #article { color: var(--ink); }
[data-theme="dark"] #article pre { background: #0d0d0d; color: #ffffff; }
[data-theme="dark"] #header { background: rgba(20,20,19,0.92); backdrop-filter: blur(8px); }
html {
font-size: 16px;
scroll-behavior: smooth;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
html:not(.motion-ready) *,
html:not(.motion-ready) *::before,
html:not(.motion-ready) *::after {
transition: none !important;
animation: none !important;
}
body {
background: var(--linen); color: var(--ink);
font-family: var(--font-body); line-height: 1.65;
font-feature-settings: 'ss01' 1, 'cv11' 1;
min-height: 100vh;
transition: background 0.25s, color 0.25s;
}
body, #header, #sidebar, #article, .card, .page-nav-btn, .icon-btn, #search-input {
transition: background 0.25s, color 0.25s, border-color 0.25s;
}
/* ─── Navbar (mirrors paperclip.ing) ─────────────────────── */
.navbar {
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 100;
background: var(--linen);
border-bottom: 1px solid var(--stone);
transition: background 0.3s ease-out, border-color 0.3s ease-out;
}
.navbar-inner {
display: flex;
align-items: center;
justify-content: space-between;
height: 60px;
max-width: var(--layout-max);
margin: 0 auto;
padding: 0 var(--outer-px);
gap: 1.5rem;
}
.navbar-left, .navbar-right {
display: flex;
align-items: center;
gap: 1.5rem;
flex: 1;
}
.navbar-left { justify-content: flex-start; }
.navbar-right { justify-content: flex-end; }
.navbar-logo {
display: flex;
align-items: center;
gap: 0.35rem;
font-family: var(--font-serif);
font-weight: 600;
font-size: 0.95rem;
white-space: nowrap;
}
.navbar-logo-link {
display: inline-flex;
align-items: center;
gap: 0.45rem;
color: var(--ink);
text-decoration: none;
transition: color 0.15s ease;
}
.navbar-logo-link:hover { color: var(--ink); }
.navbar-logo-sub { color: var(--graphite); font-weight: 600; }
[data-theme="dark"] .navbar-logo-sub { color: var(--ash); }
.navbar-logo-sub:hover { color: var(--ink); }
[data-theme="dark"] .navbar-logo-sub:hover { color: var(--ink); }
.navbar-link {
font-size: 0.85rem;
font-weight: 450;
color: var(--graphite);
text-decoration: none;
transition: color 0.15s ease;
}
[data-theme="dark"] .navbar-link { color: var(--ash); }
.navbar-link:hover { color: var(--ink); }
.navbar-link--icon {
display: inline-flex;
align-items: center;
gap: 0.35rem;
}
/* GitHub icon shown next to Star on mobile only (desktop uses the left nav link) */
.navbar-github-mobile { display: none; }
.navbar-github-mobile svg { width: 18px; height: 18px; }
/* Search trigger duplicated on the left for mobile; hidden on desktop.
Scoped to .navbar-left so it beats the base .navbar-search-btn display. */
.navbar-left .navbar-search-mobile { display: none; }
.navbar-cta {
display: inline-flex;
align-items: center;
gap: 0.35rem;
font-size: 0.8rem;
font-weight: 500;
color: var(--linen);
background: var(--ink);
padding: 0.45rem 1rem;
border-radius: 9999px;
border: 1px solid var(--ink);
text-decoration: none;
transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}
.navbar-cta:hover { background: var(--white); color: var(--ink); border-color: var(--ink); }
[data-theme="dark"] .navbar-cta { color: #141413; background: #ffffff; border-color: #ffffff; }
[data-theme="dark"] .navbar-cta:hover { background: transparent; color: #ffffff; border-color: #ffffff; }
.navbar-cta-count { font-size: 0.75rem; font-weight: 600; opacity: 0.7; margin-left: 0.1rem; }
/* ─── Navbar search trigger ──────────────────────────────── */
.navbar-search-btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
height: 32px;
padding: 0 10px 0 10px;
background: transparent;
border: 1px solid var(--stone);
border-radius: var(--radius-sm);
color: var(--graphite);
font-family: var(--font-body);
font-size: 0.85rem;
font-weight: 450;
cursor: pointer;
transition: background var(--transition), border-color var(--transition), color var(--transition);
}
[data-theme="dark"] .navbar-search-btn { color: var(--ash); }
.navbar-search-btn:hover { border-color: var(--stone-dark); color: var(--ink); background: var(--white); }
.navbar-search-btn svg { width: 14px; height: 14px; color: var(--ash); flex-shrink: 0; }
.navbar-search-btn:hover svg { color: var(--ink); }
.navbar-search-label { color: inherit; }
.navbar-search-kbd {
font-family: var(--font-mono);
font-size: 10.5px;
color: var(--ash);
background: var(--linen);
border: 1px solid var(--stone);
border-radius: var(--radius-xs);
padding: 1px 5px;
pointer-events: none;
}
/* ─── Breadcrumb (above article) ─────────────────────────── */
#breadcrumb {
font-size: 13px;
color: var(--ash);
display: flex;
align-items: center;
gap: 6px;
overflow: hidden;
white-space: nowrap;
margin-bottom: 18px;
}
#breadcrumb:empty { display: none; }
#breadcrumb .sep { color: var(--stone-dark); }
#breadcrumb .crumb-current { color: var(--ink); font-weight: 500; }
/* ─── Search modal (⌘K) ──────────────────────────────────── */
#search-modal {
position: fixed;
inset: 0;
z-index: 300;
display: flex;
align-items: flex-start;
justify-content: center;
padding: 14vh 16px 16px;
}
#search-modal[hidden] { display: none; }
#search-modal-backdrop {
position: absolute;
inset: 0;
background: rgba(10, 10, 10, 0.45);
backdrop-filter: blur(4px);
animation: search-fade 0.15s ease-out;
}
[data-theme="dark"] #search-modal-backdrop { background: rgba(0, 0, 0, 0.65); }
#search-modal-panel {
position: relative;
width: 100%;
max-width: 600px;
background: var(--white);
border: 1px solid var(--stone);
border-radius: var(--radius-lg);
box-shadow: 0 20px 60px rgba(0,0,0,0.16), 0 4px 12px rgba(0,0,0,0.08);
overflow: hidden;
animation: search-pop 0.16s var(--transition) both;
}
[data-theme="dark"] #search-modal-panel { box-shadow: 0 20px 60px rgba(0,0,0,0.6), 0 4px 12px rgba(0,0,0,0.4); }
@keyframes search-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes search-pop { from { opacity: 0; transform: translateY(-8px) scale(0.98); } to { opacity: 1; transform: none; } }
#search-wrap { position: relative; width: 100%; }
#search-input {
width: 100%; height: 56px;
padding: 0 60px 0 48px;
border: none;
border-bottom: 1px solid var(--stone);
border-radius: 0;
background: transparent;
font-family: var(--font-body); font-size: 15px; color: var(--ink);
outline: none;
-webkit-appearance: none;
}
#search-input::placeholder { color: var(--ash); }
#search-input::-webkit-search-decoration,
#search-input::-webkit-search-cancel-button { display: none; }
#search-icon { position: absolute; left: 20px; top: 28px; transform: translateY(-50%); width: 16px; height: 16px; color: var(--ash); pointer-events: none; }
#search-kbd {
position: absolute; right: 16px; top: 28px; transform: translateY(-50%);
font-size: 11px; color: var(--ash);
background: var(--linen); border: 1px solid var(--stone);
border-radius: var(--radius-xs); padding: 1px 6px;
font-family: var(--font-mono);
pointer-events: none;
}
/* Search results list (inside modal) */
#search-results {
width: 100%;
background: transparent;
display: none;
max-height: min(420px, 50vh);
overflow-y: auto;
scrollbar-width: thin;
}
#search-results.is-open { display: block; }
.search-result {
display: block;
padding: 9px 14px;
cursor: pointer;
border-bottom: 1px solid var(--linen);
transition: background var(--transition);
}
.search-result:last-child { border-bottom: none; }
.search-result:hover,
.search-result.focused { background: var(--linen); }
.search-result-title {
font-size: 13px; font-weight: 500; color: var(--ink); line-height: 1.4;
}
.search-result-meta {
font-size: 11.5px; color: var(--ash); margin-top: 2px; line-height: 1.4;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.search-result-title mark,
.search-result-meta mark {
background: var(--mint); color: var(--ink); border-radius: 2px; padding: 0 1px;
font-style: normal;
}
.search-empty { padding: 18px 14px; font-size: 13px; color: var(--ash); text-align: center; }
.icon-btn {
width: 34px; height: 34px;
border: 1px solid var(--stone);
border-radius: var(--radius-sm);
background: var(--white);
color: var(--graphite);
cursor: pointer;
display: flex; align-items: center; justify-content: center;
transition: border-color var(--transition), color var(--transition);
flex-shrink: 0;
text-decoration: none;
}
.icon-btn:hover { border-color: var(--stone-dark); color: var(--ink); }
.icon-btn svg { width: 16px; height: 16px; }
/* ─── Floating theme toggle (bottom-right) ───────────────── */
.theme-toggle {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 200;
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 9999px;
background: var(--white);
border: 1px solid var(--stone);
color: var(--graphite);
cursor: pointer;
box-shadow: 0 4px 12px rgba(0,0,0,0.06), 0 2px 4px rgba(0,0,0,0.04);
transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease, transform 0.15s ease;
}
.theme-toggle:hover { background: var(--parchment); color: var(--ink); transform: translateY(-1px); }
[data-theme="dark"] .theme-toggle { box-shadow: 0 4px 12px rgba(0,0,0,0.5), 0 2px 4px rgba(0,0,0,0.3); }
.theme-toggle-icon { display: none; align-items: center; justify-content: center; }
.theme-toggle-moon { display: flex; }
[data-theme="dark"] .theme-toggle-sun { display: flex; }
[data-theme="dark"] .theme-toggle-moon { display: none; }
/* ─── Landing ───────────────────────────────────────────── */
#landing {
max-width: var(--layout-max);
margin: 0 auto;
padding: 80px var(--outer-px) 120px;
display: none;
}
#landing.is-active { display: block; }
#landing-hero { max-width: 620px; margin-bottom: 64px; }
#landing-eyebrow {
font-size: 11px; font-weight: 600; letter-spacing: 0.12em;
text-transform: uppercase; color: var(--ash); margin-bottom: 16px;
}
#landing-title {
font-family: var(--font-serif);
font-size: clamp(40px, 6vw, 64px);
font-weight: 600; line-height: 1.05; letter-spacing: -0.04em;
color: var(--ink); margin-bottom: 20px;
}
#landing-title em { font-style: italic; color: inherit; }
#landing-desc { font-size: 17px; line-height: 1.6; color: var(--graphite); max-width: 560px; }
.card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.card {
background: var(--white);
border: 1px solid var(--stone);
border-radius: var(--radius);
padding: 24px;
text-decoration: none;
color: inherit;
display: flex; flex-direction: column; gap: 10px;
transition: border-color var(--transition), transform var(--transition), box-shadow var(--transition);
position: relative; overflow: hidden;
cursor: pointer;
}
.card:hover { border-color: var(--stone-dark); transform: translateY(-2px); box-shadow: 0 8px 24px rgba(26,26,26,0.04); }
.card-icon {
width: 36px; height: 36px; border-radius: var(--radius-sm);
background: var(--parchment); border: 1px solid var(--stone);
display: flex; align-items: center; justify-content: center;
color: var(--graphite); margin-bottom: 4px;
}
.card-icon svg { width: 18px; height: 18px; }
.card-title { font-family: var(--font-serif); font-size: 22px; font-weight: 600; letter-spacing: -0.02em; color: var(--ink); line-height: 1.2; }
.card-desc { font-size: 13.5px; color: var(--graphite); line-height: 1.55; }
.card-meta { font-size: 11.5px; color: var(--ash); margin-top: 10px; display: flex; align-items: center; gap: 6px; }
.card-meta .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--stone-dark); }
/* ─── Footer (mirrors paperclip.ing — always dark) ───────── */
.footer {
/* Pin to paperclip.ing dark palette regardless of page theme */
--bg: #141413;
--surface: #1F1D1A;
--ink-t: #FFFFFF;
--mono: #9A958A;
--rule: #2F2C28;
background: var(--bg);
color: var(--ink-t);
border-top: 1px solid var(--rule);
margin-top: 80px;
}
.footer-container {
max-width: var(--layout-max);
margin: 0 auto;
padding: 0 var(--outer-px);
}
.footer-wordmark-row {
padding-top: clamp(3rem, 6vw, 5rem);
padding-bottom: clamp(2rem, 4vw, 3.5rem);
}
.footer-wordmark {
font-family: var(--font-serif);
font-size: 28px;
font-weight: 600;
letter-spacing: -0.045em;
line-height: 1;
color: var(--ink-t);
display: block;
}
.footer-columns {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: clamp(2rem, calc(1.5rem + 1.5vw), 3rem);
padding-bottom: clamp(3rem, 6vw, 5rem);
}
.footer-col-heading {
font-family: var(--font-body);
font-size: 0.8rem;
font-weight: 600;
color: var(--ink-t);
letter-spacing: 0.01em;
margin-bottom: 0.75rem;
}
.footer-col a {
display: block;
font-size: 0.875rem;
color: var(--mono);
text-decoration: none;
padding: 0.2rem 0;
transition: color 0.15s ease;
}
.footer-col a:hover { color: var(--ink-t); }
.footer-bottom {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 1rem;
padding-top: 1.5rem;
padding-bottom: 1.5rem;
border-top: 1px solid var(--rule);
}
.footer-copy {
font-family: var(--font-mono);
font-size: 0.75rem;
color: var(--mono);
}
.footer-bottom-links {
display: flex;
gap: 1.5rem;
}
.footer-bottom-links a {
font-size: 0.8rem;
color: var(--mono);
text-decoration: none;
transition: color 0.15s ease;
}
.footer-bottom-links a:hover { color: var(--ink-t); }
@media (max-width: 768px) {
.footer-columns { grid-template-columns: repeat(2, 1fr); gap: clamp(2rem, 4vw, 3rem) 1.5rem; }
}
@media (max-width: 480px) {
.footer-bottom { flex-direction: column; align-items: flex-start; }
}
/* ─── Article view ─────────────────────────────────────── */
#article-view { display: none; }
#article-view.is-active { display: block; }
#body {
max-width: var(--layout-max);
margin: 0 auto;
padding: 0 var(--outer-px);
display: grid;
grid-template-columns: var(--sidebar-w) minmax(0, var(--content-max)) var(--toc-w);
align-items: flex-start;
column-gap: clamp(32px, 4vw, 56px);
}
/* Sidebar */
#sidebar {
width: var(--sidebar-w);
min-width: var(--sidebar-w);
flex-shrink: 0;
position: sticky;
top: var(--topbar-h);
max-height: calc(100vh - var(--topbar-h));
overflow-y: auto;
padding: 32px 0 40px;
scrollbar-width: thin;
}
.sb-back {
display: inline-flex; align-items: center; gap: 6px;
font-size: 12px; color: var(--ash);
text-decoration: none;
padding: 4px 8px; margin-left: -8px; margin-bottom: 20px;
border-radius: 6px;
transition: color var(--transition), background var(--transition);
cursor: pointer;
}
.sb-back:hover { color: var(--ink); background: var(--parchment); }
.sb-back svg { width: 12px; height: 12px; }
/* Desktop sidebar has no horizontal padding + overflow-y forces overflow-x:auto,
which clips a negative margin. Align flush instead so the chevron isn't cut off. */
#sidebar .sb-back { margin-left: 0; padding-left: 10px; }
.sb-section { margin-bottom: 4px; }
.sb-group-label {
display: flex; align-items: center; gap: 10px;
padding: 18px 10px 6px;
font-size: 10.5px; font-weight: 600;
color: var(--ash);
text-transform: uppercase;
letter-spacing: 0.08em;
}
.sb-group-label:first-child { padding-top: 6px; }
.sb-section-btn {
width: 100%;
display: flex; align-items: center; gap: 8px;
padding: 7px 10px;
border: none; background: none; cursor: pointer;
border-radius: 7px;
font-family: var(--font-body);
font-size: 12.5px; font-weight: 600;
color: var(--ink); letter-spacing: 0.01em;
text-align: left;
transition: background var(--transition);
}
.sb-section-btn:hover { background: var(--parchment); }
.sb-section-btn .chev {
width: 11px; height: 11px; color: var(--ash);
transition: transform var(--transition);
flex-shrink: 0;
}
.sb-section[data-open="true"] .sb-section-btn .chev { transform: rotate(90deg); }
.sb-section-icon {
width: 18px; height: 18px; border-radius: 5px;
background: var(--parchment); border: 1px solid var(--stone);
display: flex; align-items: center; justify-content: center;
color: var(--graphite); flex-shrink: 0;
}
.sb-section-icon svg { width: 11px; height: 11px; }
.sb-section-title { flex: 1; }
.sb-section-count { font-size: 10.5px; color: var(--ash); font-weight: 500; }
.sb-pages {
display: none; padding: 2px 0 6px 26px; margin-left: 3px;
border-left: 1px solid var(--stone);
}
.sb-section[data-open="true"] .sb-pages { display: block; }
.sb-group { margin: 2px 0; }
.sb-group-btn {
width: 100%;
display: flex; align-items: center; gap: 7px;
padding: 5px 10px;
border: none; background: none; cursor: pointer;
border-radius: 6px;
font-family: var(--font-body);
font-size: 12px; font-weight: 600;
color: var(--graphite);
text-align: left;
transition: background var(--transition), color var(--transition);
}
.sb-group-btn:hover { color: var(--ink); background: var(--parchment); }
.sb-group-btn .chev {
width: 10px; height: 10px; color: var(--ash);
transition: transform var(--transition);
flex-shrink: 0;
}
.sb-group[data-open="true"] > .sb-group-btn .chev { transform: rotate(90deg); }
.sb-group-title { flex: 1; }
.sb-group-count { font-size: 10px; color: var(--ash); font-weight: 500; }
.sb-group-pages {
display: none;
padding: 1px 0 3px 12px;
margin-left: 5px;
border-left: 1px solid var(--stone);
}
.sb-group[data-open="true"] > .sb-group-pages { display: block; }
.sb-link {
display: block; padding: 5px 10px;
margin-bottom: 2px;
font-size: 12.5px; color: var(--graphite);
text-decoration: none; border-radius: 6px;
line-height: 1.45; cursor: pointer;
transition: background var(--transition), color var(--transition);
}
.sb-link:hover,
.sb-link.active {
color: var(--ink); font-weight: 500;
background: var(--parchment);
}
/* Content */
#content {
min-width: 0;
max-width: var(--content-max);
padding: 48px 0 96px;
}
#toc-rail {
position: sticky;
top: var(--topbar-h);
max-height: calc(100vh - var(--topbar-h));
overflow-y: auto;
padding: 48px 0 40px;
scrollbar-width: thin;
}
#toc-rail.is-empty { visibility: hidden; }
.toc-rail-inner {
border-left: 1px solid var(--stone);
padding-left: 18px;
}
.toc-rail-title {
margin-bottom: 10px;
font-size: 11px;
font-weight: 700;
color: var(--ash);
text-transform: uppercase;
letter-spacing: 0.1em;
}
#toc-rail-links {
display: flex;
flex-direction: column;
gap: 2px;
}
/* Runtime status — populated by app.js only during a client transition. */
#runtime-status[data-state] {
display: flex; flex-direction: column; align-items: center; justify-content: center;
gap: 12px; padding: 80px 0;
color: var(--ash); font-size: 14px;
}
#runtime-status[hidden] { display: none; }
.runtime-status-detail { font-size: 12px; color: var(--ash); margin-top: 4px; }
.spinner {
width: 24px; height: 24px;
border: 2px solid var(--stone); border-top-color: var(--green);
border-radius: 50%; animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
#article { font-size: 15.5px; line-height: 1.75; color: var(--graphite); overflow-wrap: break-word; }
#article h1 {
font-family: var(--font-serif);
font-size: clamp(28px, 4vw, 38px);
font-weight: 600; letter-spacing: -0.03em;
color: var(--ink);
margin-bottom: 20px; line-height: 1.1;
}
.meta-row {
display: flex; align-items: center; gap: 10px;
margin-bottom: 24px; padding: 12px 0 12px;
border-bottom: 1px solid var(--stone);
font-size: 12px; color: var(--ash);
position: sticky;
top: var(--topbar-h);
background: var(--linen);
z-index: 50;
}
.meta-row::before {
content: ''; position: absolute;
left: 0; right: 0; top: -1px; height: 1px;
background: var(--linen);
}
.meta-row .chip {
padding: 2px 8px; border-radius: var(--radius-xs);
background: var(--parchment); border: 1px solid var(--stone);
font-size: 11px; color: var(--graphite);
}
.meta-row .spacer { flex: 1; }
.page-actions { position: relative; display: inline-flex; align-items: stretch; }
.page-actions .pa-btn {
display: inline-flex; align-items: center; gap: 6px;
padding: 5px 10px;
background: var(--white);
border: 1px solid var(--stone);
font-family: var(--font-body);
font-size: 11.5px; font-weight: 500;
color: var(--graphite); cursor: pointer;
transition: border-color var(--transition), color var(--transition), background var(--transition);
}
.page-actions .pa-btn:hover { border-color: var(--stone-dark); color: var(--ink); }
.page-actions .pa-copy { border-radius: var(--radius-sm) 0 0 var(--radius-sm); padding-left: 12px; }
.page-actions .pa-caret {
border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
border-left: none;
padding: 5px 8px;
}
.page-actions .pa-caret svg { width: 12px; height: 12px; color: var(--ash); transition: transform var(--transition); }
.page-actions .pa-caret[aria-expanded="true"] { color: var(--ink); background: var(--parchment); border-color: var(--stone-dark); }
.page-actions .pa-caret[aria-expanded="true"] svg { transform: rotate(180deg); color: var(--ink); }
.page-actions .pa-copy svg { width: 13px; height: 13px; color: var(--ash); }
.page-actions .pa-copy.is-copied { color: var(--green); border-color: var(--green); }
.page-actions .pa-copy.is-copied svg { color: var(--green); }
.pa-menu {
position: absolute; top: calc(100% + 8px); right: 0;
min-width: 220px;
background: var(--white);
border: 1px solid var(--stone);
border-radius: var(--radius-sm);
box-shadow: 0 12px 32px rgba(12,12,12,0.12), 0 2px 6px rgba(12,12,12,0.06);
padding: 6px;
opacity: 0; transform: translateY(-4px) scale(0.98);
pointer-events: none;
transform-origin: top right;
transition: opacity 0.16s ease, transform 0.16s ease;
z-index: 60;
}
[data-theme="dark"] .pa-menu { box-shadow: 0 12px 32px rgba(0,0,0,0.6), 0 2px 6px rgba(0,0,0,0.4); }
.pa-menu.is-open { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.pa-menu button {
display: flex; align-items: center; gap: 10px;
width: 100%;
padding: 7px 10px;
background: none; border: none;
font-family: var(--font-body);
font-size: 13px; color: var(--graphite);
text-align: left; cursor: pointer;
border-radius: 5px;
transition: color var(--transition), background var(--transition);
}
.pa-menu button:hover { color: var(--ink); background: var(--linen); }
.pa-menu button svg { width: 14px; height: 14px; color: var(--ash); flex-shrink: 0; }
.pa-menu button:hover svg { color: var(--ink); }
.page-feedback {
margin-top: 64px;
padding: 20px 22px;
background: var(--parchment);
border: 1px solid var(--stone);
border-radius: var(--radius);
display: flex; flex-wrap: wrap; align-items: center;
gap: 14px 20px;
}
.page-feedback .pf-label {
font-family: var(--font-serif);
font-size: 17px; font-weight: 600;
color: var(--ink);
letter-spacing: -0.02em;
flex: 1 1 auto;
}
.page-feedback .pf-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.page-feedback a {
display: inline-flex; align-items: center; gap: 6px;
padding: 7px 12px;
background: var(--white);
border: 1px solid var(--stone);
border-radius: var(--radius-sm);
font-size: 13px; font-weight: 500;
color: var(--graphite);
text-decoration: none;
transition: border-color 0.15s, color 0.15s, background 0.15s, transform 0.15s;
}
.page-feedback a:hover {
color: var(--ink);
border-color: var(--graphite);
background: var(--linen);
transform: translateY(-1px);
}
.page-feedback a svg {
width: 14px; height: 14px;
stroke: currentColor; stroke-width: 1.75;
fill: none; stroke-linecap: round; stroke-linejoin: round;
}
@media (max-width: 640px) {
.page-feedback { padding: 16px; }
.page-feedback .pf-label { flex-basis: 100%; }
}
.toc-wrap {
position: relative;
display: none;
}
.toc-toggle {
display: inline-flex; align-items: center; gap: 6px;
padding: 5px 10px 5px 12px;
background: var(--white);
border: 1px solid var(--stone);
border-radius: var(--radius-sm);
font-family: var(--font-body);
font-size: 11.5px; font-weight: 500;
color: var(--graphite); cursor: pointer;
transition: border-color var(--transition), color var(--transition), background var(--transition);
}
.toc-toggle:hover { border-color: var(--stone-dark); color: var(--ink); }
.toc-toggle[aria-expanded="true"] {
color: var(--ink); background: var(--parchment); border-color: var(--stone-dark);
}
.toc-toggle > svg { width: 12px; height: 12px; color: var(--ash); transition: transform var(--transition); }
.toc-toggle .toc-icon { width: 13px; height: 13px; color: var(--ash); transition: none; }
.toc-toggle[aria-expanded="true"] .toc-icon { color: var(--ink); transform: none; }
.toc-toggle > svg:last-of-type { /* chevron */ }
.toc-toggle[aria-expanded="true"] > svg:last-of-type { transform: rotate(180deg); color: var(--ink); }
.toc-toggle .count {
font-size: 10px; color: var(--ash);
background: var(--parchment); border-radius: var(--radius-xs);
padding: 1px 6px; font-variant-numeric: tabular-nums;
}
.toc-toggle[aria-expanded="true"] .count { background: var(--white); }
.toc-panel {
position: absolute; top: calc(100% + 8px); right: 0;
width: 280px; max-width: calc(100vw - 48px);
max-height: min(60vh, 420px); overflow-y: auto;
background: var(--white);
border: 1px solid var(--stone);
border-radius: var(--radius-sm);
box-shadow: 0 12px 32px rgba(12,12,12,0.12), 0 2px 6px rgba(12,12,12,0.06);
padding: 8px;
opacity: 0; transform: translateY(-4px) scale(0.98);
pointer-events: none;
transform-origin: top right;
transition: opacity 0.16s ease, transform 0.16s ease;
z-index: 60;
}
[data-theme="dark"] .toc-panel { box-shadow: 0 12px 32px rgba(0,0,0,0.6), 0 2px 6px rgba(0,0,0,0.4); }
.toc-panel.is-open { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; }
.toc-panel-label { display: none; }
.toc-link {
display: block;
padding: 6px 10px;
margin-bottom: 2px;
font-size: 13px;
line-height: 1.45;
color: var(--graphite);
text-decoration: none;
cursor: pointer;
border-radius: 5px;
position: relative;
transition: color var(--transition), background var(--transition), transform var(--transition);
}
.toc-link::before {
content: '';
position: absolute;
left: 0;
top: 7px;
bottom: 7px;
width: 2px;
border-radius: 999px;
background: var(--green);
opacity: 0;
transform: scaleY(0.45);
transition: opacity 0.18s ease, transform 0.18s ease;
}
.toc-link.level-3 {
padding-left: 22px;
font-size: 12.5px;
color: var(--ash);
}
.toc-link:hover,
.toc-link.active {
color: var(--ink);
background: var(--linen);
font-weight: 500;
}
.toc-link.active::before {
opacity: 1;
transform: scaleY(1);
}
#toc-rail-links .toc-link {
padding: 5px 8px 5px 12px;
margin-bottom: 0;
background: transparent;
}
#toc-rail-links .toc-link:hover,
#toc-rail-links .toc-link.active {
background: transparent;
}
#toc-rail-links .toc-link.active {
transform: translateX(2px);
}
#toc-rail-links .toc-link.level-3 {
padding-left: 24px;
}
#article h2 {
font-family: var(--font-serif);
font-size: 24px; font-weight: 600; letter-spacing: -0.02em;
color: var(--ink);
margin-top: 40px; margin-bottom: 14px;
line-height: 1.25;
padding-bottom: 8px;
border-bottom: 1px solid var(--stone);
}
#article h3 { font-size: 15.5px; font-weight: 600; color: var(--ink); margin-top: 28px; margin-bottom: 8px; }
#article h4 {
font-size: 11px; font-weight: 600; color: var(--ash);
text-transform: uppercase; letter-spacing: 0.08em;
margin-top: 20px; margin-bottom: 6px;
}
#article h1, #article h2, #article h3, #article h4, #article h5, #article h6 { position: relative; scroll-margin-top: 128px; }
#article .heading-anchor {
display: inline-flex; align-items: center; justify-content: center;
width: 22px; height: 22px; margin-left: 8px;
border-bottom: none; color: var(--ash);
opacity: 0; vertical-align: middle;
border-radius: 6px; cursor: pointer;
transition: opacity var(--transition), color var(--transition), background var(--transition), transform var(--transition);
}
#article .heading-anchor svg { width: 14px; height: 14px; }
#article h1:hover .heading-anchor,
#article h2:hover .heading-anchor,
#article h3:hover .heading-anchor,
#article h4:hover .heading-anchor,
#article h5:hover .heading-anchor,
#article h6:hover .heading-anchor,
#article .heading-anchor:focus-visible { opacity: 1; }
#article .heading-anchor:hover { color: var(--ink); background: var(--parchment); transform: translateY(-1px); }
#article .heading-anchor.is-copied { color: var(--green); opacity: 1; background: var(--mint); }
@media (hover: none) { #article .heading-anchor { opacity: 0.5; } }
/* Code block with copy button */
.code-wrap { position: relative; margin-bottom: 20px; }
.code-wrap pre { margin-bottom: 0; }
.code-copy, .code-download {
position: absolute; top: 8px;
width: 30px; height: 30px;
display: inline-flex; align-items: center; justify-content: center;
border: 1px solid rgba(255,255,255,0.12);
background: rgba(255,255,255,0.06);
color: #d4d4d4;
border-radius: 7px; cursor: pointer;
opacity: 0;
transition: opacity var(--transition), background var(--transition), color var(--transition);
}
.code-copy { right: 8px; }
.code-download { right: 46px; }
.code-copy svg, .code-download svg { width: 14px; height: 14px; }
.code-wrap:hover .code-copy,
.code-wrap:hover .code-download,
.code-copy:focus-visible,
.code-download:focus-visible { opacity: 1; }
.code-copy:hover, .code-download:hover { background: rgba(255,255,255,0.12); color: #fff; }
.code-copy.is-copied, .code-download.is-copied { opacity: 1; color: var(--green); border-color: rgba(34,197,94,0.4); background: rgba(34,197,94,0.12); }
@media (hover: none) { .code-copy, .code-download { opacity: 0.75; } }
#article p { margin-bottom: 16px; }
#article a {
color: var(--ink);
text-decoration: underline;
text-decoration-color: color-mix(in srgb, var(--ink) 45%, transparent);
text-decoration-thickness: 1px;
text-underline-offset: 0.18em;
transition: color var(--transition);
overflow-wrap: anywhere;
}
#article a:hover {
color: var(--graphite);
text-decoration-color: currentColor;
}
#article .heading-anchor {
text-decoration: none;
}
#article strong { color: var(--ink); font-weight: 600; }
#article em { font-style: italic; }
#article ul, #article ol { padding-left: 22px; margin-bottom: 16px; }
#article li { margin-bottom: 6px; }
#article li > p { margin-bottom: 8px; }
#article ol > li { margin-bottom: 20px; }
#article hr { border: none; border-top: 1px solid transparent; margin: 36px 0; }
#article code {
font-family: var(--font-mono); font-size: 0.87rem;
font-variant-numeric: tabular-nums;
background: var(--parchment); border: 1px solid var(--stone);
border-radius: var(--radius-xs); padding: 1px 6px; color: var(--ink);
/* Long unbreakable tokens (paths, keys, identifiers) must wrap so they
don't force the whole page wider than the viewport on mobile. */
overflow-wrap: anywhere; word-break: break-word;
}
#article pre {
background: var(--void); color: #d4d4d4;
border-radius: var(--radius-sm); padding: 18px 20px;
overflow-x: auto; margin-bottom: 20px;
font-family: var(--font-mono); font-size: 0.87rem; line-height: 1.6;
font-variant-numeric: tabular-nums;
}
#article pre code { background: none; border: none; padding: 0; color: inherit; font-size: inherit;
/* Block code keeps its own horizontal scroll (pre is overflow-x:auto); don't force-wrap it. */
overflow-wrap: normal; word-break: normal; }
/* A full SKILL.md is prose-like source rather than a short command snippet.
Preserve its line breaks and indentation, but wrap long lines so the
source stays readable without horizontal scrolling on narrow screens. */
#article pre code[data-skill-download="SKILL.md"] {
white-space: pre-wrap;
overflow-wrap: anywhere;
word-break: break-word;
}
/* Tables */
.table-wrap {
margin-bottom: 20px;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
border: 1px solid var(--stone);
border-radius: var(--radius-sm);
background:
linear-gradient(to right, var(--white) 30%, rgba(255,255,255,0)),
linear-gradient(to right, rgba(255,255,255,0), var(--white) 70%) 100% 0,
radial-gradient(farthest-side at 0 50%, rgba(26,26,26,0.12), rgba(255,255,255,0)),
radial-gradient(farthest-side at 100% 50%, rgba(26,26,26,0.12), rgba(255,255,255,0)) 100% 0;
background-repeat: no-repeat;
background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
background-attachment: local, local, scroll, scroll;
}
[data-theme="dark"] .table-wrap {
background:
linear-gradient(to right, var(--white) 30%, rgba(18,18,22,0)),
linear-gradient(to right, rgba(18,18,22,0), var(--white) 70%) 100% 0,
radial-gradient(farthest-side at 0 50%, rgba(0,0,0,0.4), rgba(0,0,0,0)),
radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,0.4), rgba(0,0,0,0)) 100% 0;
background-repeat: no-repeat;
background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
background-attachment: local, local, scroll, scroll;
}
#article table {
width: 100%; border-collapse: collapse;
margin-bottom: 0; font-size: 14px;
min-width: 520px;
}
.table-wrap > table { border-radius: 0; border: none; }
#article th {
background: var(--parchment);
border-bottom: 1px solid var(--stone);
border-right: 1px solid var(--stone);
padding: 8px 14px; text-align: left;
font-weight: 600; font-size: 11px;
text-transform: uppercase; letter-spacing: 0.06em;
color: var(--graphite);
}
#article td {
background: var(--linen);
border-bottom: 1px solid var(--stone);
border-right: 1px solid var(--stone);
padding: 8px 14px; color: var(--graphite); vertical-align: top;
}
#article tr:last-child td { border-bottom: none; }
#article th:last-child, #article td:last-child { border-right: none; }
#article tbody tr:hover td { background: var(--white); }
/* Connector catalog tables.
The catalog is one list broken up by category headings, so every one of
those tables gets the same fixed grid: a reader scanning down the page
reads one set of columns instead of eleven differently proportioned ones.
Tagged by header row in postProcessTables (app.js) and tagCatalogTable
(build-release.mjs), never by page, so the rule follows the content. */
#article table.catalog-table {
table-layout: fixed;
/* Fixed layout plus wrapping cells means nothing overflows, so the
generic 520px floor — and the scroll shadows that go with it — would
only ever be noise here. */
min-width: 0;
}
.table-wrap-catalog {
overflow-x: visible;
background: var(--linen);
}
/* The description earns the space; the name and the methods are short and
repetitive, and holding them narrow keeps all three columns in view. */
#article table.catalog-table th:nth-child(1),
#article table.catalog-table td:nth-child(1) { width: 22%; }
#article table.catalog-table th:nth-child(2),
#article table.catalog-table td:nth-child(2) { width: 52%; }
#article table.catalog-table th:nth-child(3),
#article table.catalog-table td:nth-child(3) { width: 26%; }
/* Horizontal rules alone are enough separation once the columns are
aligned; the vertical ones just add lines to look past. */
#article table.catalog-table th,
#article table.catalog-table td {
border-right: none;
padding: 10px 14px;
overflow-wrap: break-word;
}
#article table.catalog-table td:first-child { font-weight: 500; }
/* One method per line, so the column breaks between methods instead of
inside one. Set by splitMethodList in app.js and build-release.mjs. */
#article table.catalog-table .method-item { display: block; }
#article table.catalog-table .method-item + .method-item { margin-top: 2px; }
/* --linen and --white are the same white in light theme, so the inherited
hover reads as nothing. A parchment tint works in both themes. */
#article table.catalog-table tbody tr:hover td { background: var(--parchment); }
@media (max-width: 640px) {
/* Three columns cannot hold a sentence at this width without either
horizontal scrolling or a one-word-per-line description, so each row
becomes a block that keeps the name, the description and the methods
together. The header row goes visually hidden rather than removed, and
the explicit roles set alongside these classes keep the table's
structure in the accessibility tree, so each cell is still announced
with its column. */
#article table.catalog-table,
#article table.catalog-table thead,
#article table.catalog-table tbody,
#article table.catalog-table tr,
#article table.catalog-table th,
#article table.catalog-table td {
display: block;
width: auto;
}
/* The percentage widths above are set per column, so they outrank the
blanket `width: auto` and would keep a stacked description in a 52%
gutter. Release each column by the same selector that claimed it. */
#article table.catalog-table th:nth-child(1),
#article table.catalog-table td:nth-child(1),
#article table.catalog-table th:nth-child(2),
#article table.catalog-table td:nth-child(2),
#article table.catalog-table th:nth-child(3),
#article table.catalog-table td:nth-child(3) { width: auto; }
#article table.catalog-table thead {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
#article table.catalog-table tbody tr {
border-bottom: 1px solid var(--stone);
padding: 4px 0 12px;
}
#article table.catalog-table tbody tr:last-child { border-bottom: none; }
#article table.catalog-table td {
border-bottom: none;
padding: 4px 14px;
}
#article table.catalog-table td::before {
content: attr(data-label);
display: block;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--ash);
margin-bottom: 2px;
}
/* The linked connector name is the row's heading at this width. */
#article table.catalog-table td:first-child {
font-size: 16px;
padding-top: 10px;
}
#article table.catalog-table td:first-child::before { display: none; }
}
/* Images */
#article img {
max-width: 100%; border-radius: var(--radius-sm);
border: 1px solid var(--stone); display: block;
height: auto;
margin: 24px 0;
box-shadow: 0 2px 8px rgba(26,26,26,0.06);
}
#article img.responsive-screenshot {
width: 100%;
object-fit: contain;
}
.img-placeholder {
background: var(--parchment);
border: 1.5px dashed var(--stone-dark);
border-radius: var(--radius-sm);
padding: 16px 18px; margin: 24px 0;
display: flex; align-items: center; gap: 12px;
color: var(--ash); font-size: 13px;
}
/* Callouts */
.callout {
border-radius: var(--radius-sm);
padding: 12px 16px;
margin-bottom: 20px;
font-size: 14px; line-height: 1.65;
display: flex; gap: 11px; align-items: flex-start;
}
.callout-icon { flex-shrink: 0; margin-top: 3px; display: inline-flex; }
.callout-icon svg { width: 16px; height: 16px; }
.callout-note .callout-icon { color: var(--graphite); }
.callout-info .callout-icon { color: #1d4ed8; }
.callout-tip .callout-icon { color: #188a3c; }
.callout-warning .callout-icon { color: #b45309; }
.callout-danger .callout-icon { color: #991b1b; }
.callout-body { flex: 1; min-width: 0; }
.callout-body p { color: inherit; margin-bottom: 0 !important; }
.callout-body p + p { margin-top: 12px; }
.callout-note { background: var(--parchment); border: 1px solid var(--stone-dark); }
.callout-info { background: rgba(37,99,235,0.08); border: 1px solid rgba(37,99,235,0.28); }
.callout-tip { background: var(--mint); border: 1px solid rgba(34,197,94,0.30); }
.callout-warning { background: rgba(245,158,11,0.1); border: 1px solid rgba(245,158,11,0.30); }
.callout-danger { background: rgba(220,38,38,0.08); border: 1px solid rgba(220,38,38,0.28); }
.callout-note .callout-label { color: var(--graphite); font-weight: 600; }
.callout-info .callout-label { color: #1d4ed8; font-weight: 600; }
.callout-tip .callout-label { color: #188a3c; font-weight: 600; }
.callout-warning .callout-label { color: #b45309; font-weight: 600; }
.callout-danger .callout-label { color: #991b1b; font-weight: 600; }
[data-theme="dark"] .callout-info .callout-icon,
[data-theme="dark"] .callout-info .callout-label { color: #60a5fa; }
[data-theme="dark"] .callout-tip .callout-icon,
[data-theme="dark"] .callout-tip .callout-label { color: #22c55e; }
[data-theme="dark"] .callout-warning .callout-icon,
[data-theme="dark"] .callout-warning .callout-label { color: #f59e0b; }
[data-theme="dark"] .callout-danger .callout-icon,
[data-theme="dark"] .callout-danger .callout-label { color: #f87171; }
/* Accordion — native <details>/<summary> disclosure */
details.accordion {
border: 1px solid var(--stone);
border-radius: var(--radius-sm);
background: var(--white);
margin-bottom: 12px;
overflow: hidden;
}
details.accordion + details.accordion { margin-top: -4px; }
details.accordion > summary {
list-style: none;
cursor: pointer;
padding: 13px 16px;
display: flex; align-items: center; gap: 10px;
font-family: var(--font-serif);
font-size: 15px; font-weight: 600; letter-spacing: -0.01em;
color: var(--ink);
user-select: none;
transition: background var(--transition);
}
details.accordion > summary::-webkit-details-marker { display: none; }
details.accordion > summary:hover { background: var(--parchment); }
details.accordion > summary::before {
content: "";
flex-shrink: 0;
width: 8px; height: 8px;
border-right: 2px solid var(--ash);
border-bottom: 2px solid var(--ash);
transform: rotate(-45deg);
transition: transform var(--transition);
}
details.accordion[open] > summary::before { transform: rotate(45deg); }
details.accordion[open] > summary { border-bottom: 1px solid var(--stone); }
details.accordion .accordion-meta {
margin-left: auto;
font-family: var(--font-body);
font-size: 12px; font-weight: 500;
color: var(--ash);
}
details.accordion > .accordion-body { padding: 4px 16px 8px; }
details.accordion > .accordion-body > :first-child { margin-top: 12px; }
details.accordion > .accordion-body > :last-child { margin-bottom: 4px; }
/* Tabs */
.tabs-container { margin-bottom: 24px; }
.tabs-bar {
display: flex; border-bottom: 1px solid var(--stone);
/* Many tabs (e.g. one per provider) must scroll horizontally rather than
widen the page past the viewport on mobile. */
overflow-x: auto; scrollbar-width: none;
}
.tabs-bar::-webkit-scrollbar { display: none; }
.tab-btn {
padding: 7px 18px;
font-size: 13px;
font-family: var(--font-body); font-weight: 500;
background: none; border: none;
border-bottom: 2px solid transparent;
color: var(--ash); cursor: pointer;
transition: color var(--transition), border-color var(--transition);
margin-bottom: -1px;
white-space: nowrap; flex-shrink: 0;
}
.tab-btn:hover { color: var(--graphite); }
.tab-btn.active { color: var(--ink); border-bottom-color: var(--green); }
.tab-panel { display: none; padding: 20px 0 0; }
.tab-panel.active { display: block; }
.tab-panel > *:last-child { margin-bottom: 0; }
.tabs-container.code-tabs {
border: 1px solid var(--stone);
border-radius: var(--radius-sm);
overflow: hidden; background: var(--void);
margin-bottom: 24px;
}
.tabs-container.code-tabs .tabs-bar {
gap: 6px; padding: 8px 10px 0;
border-bottom: 1px solid var(--stone);
background: color-mix(in srgb, var(--void) 88%, var(--stone) 12%);
overflow-x: auto; scrollbar-width: none;
}
.tabs-container.code-tabs .tabs-bar::-webkit-scrollbar { display: none; }
.tabs-container.code-tabs .tab-btn {
padding: 6px 10px;
border: 1px solid transparent;
border-radius: 8px 8px 0 0;
font-size: 12px; color: #aeb6cf;
margin-bottom: 0; white-space: nowrap;
}
.tabs-container.code-tabs .tab-btn:hover { color: #eef2ff; background: rgba(255,255,255,0.04); }
.tabs-container.code-tabs .tab-btn.active {
color: #f8fafc; background: rgba(255,255,255,0.06);
border-color: rgba(255,255,255,0.08);
border-bottom-color: rgba(255,255,255,0.06);
}
.tabs-container.code-tabs .tab-panel { padding: 0; }
.tabs-container.code-tabs .tab-panel > pre,
.tabs-container.code-tabs .tab-panel > .code-wrap > pre {
margin: 0; border: none; border-radius: 0;
}
.tabs-container.code-tabs .code-wrap { margin: 0; }
/* Prev/next */
#page-nav {
display: flex; justify-content: space-between; gap: 16px;
padding-top: 40px; margin-top: 48px;
border-top: 1px solid var(--stone);
}
.page-nav-btn {
flex: 1; max-width: 280px;
display: flex; flex-direction: column; gap: 4px;
padding: 14px 18px;
background: var(--white);
border: 1px solid var(--stone);
border-radius: var(--radius-sm);
cursor: pointer;
transition: border-color var(--transition), transform var(--transition);
text-align: left;
font-family: var(--font-body);
text-decoration: none;
}
.page-nav-btn:hover { border-color: var(--stone-dark); transform: translateY(-1px); }
.page-nav-btn.next { text-align: right; margin-left: auto; }
.page-nav-label { font-size: 10px; color: var(--ash); text-transform: uppercase; letter-spacing: 0.1em; font-weight: 600; }
.page-nav-title { font-size: 14px; color: var(--ink); font-weight: 500; }
.page-nav-spacer { flex: 1; max-width: 280px; }
/* Heading highlight (search jump) */
@keyframes heading-flash {
0% { background-color: var(--mint); }
40% { background-color: var(--mint); }
100% { background-color: transparent; }
}
.heading-highlight {
animation: heading-flash 2s ease-out forwards;
border-radius: 4px;
padding-left: 6px;
margin-left: -6px;
}
@media (prefers-reduced-motion: reduce) {
.toc-link,
.toc-link::before,
.heading-highlight {
transition: none;
animation: none;
}
#toc-rail-links .toc-link.active {
transform: none;
}
}
/* Mobile drawer */
#hamburger { display: none; }
#drawer-backdrop {
display: none;
position: fixed; inset: 0;
background: rgba(12,12,12,0.4);
z-index: 200;
opacity: 0;
transition: opacity 0.2s ease;
}
#drawer-backdrop.is-open { display: block; opacity: 1; }
#drawer {
position: fixed;
top: 0; left: 0; bottom: 0;
width: min(320px, 86vw);
background: var(--linen);
border-right: 1px solid var(--stone);
z-index: 201;
transform: translateX(-100%);
transition: transform 0.25s ease;
overflow-y: auto;
padding: 16px 16px 32px;
display: flex; flex-direction: column;
}
#drawer.is-open { transform: translateX(0); }
#drawer-head {
display: flex; align-items: center; justify-content: space-between;
padding: 4px 4px 16px;
border-bottom: 1px solid var(--stone);
margin-bottom: 12px;
}
#drawer-head .label {
font-size: 11px; font-weight: 600; text-transform: uppercase;
letter-spacing: 0.1em; color: var(--ash);
}
/* Responsive */
#hamburger { display: none; }
@media (max-width: 1320px) {
:root {
--outer-px: 24px;
}
#body {
grid-template-columns: var(--sidebar-w) minmax(0, 920px);
column-gap: clamp(28px, 4vw, 40px);
max-width: 1280px;
}
#content {
max-width: 920px;
}
#toc-rail {
display: none;
}
.toc-wrap {
display: block;
}
}
@media (max-width: 820px) {
.card-grid { grid-template-columns: 1fr 1fr; }
#sidebar { display: none; }
#body { grid-template-columns: minmax(0, 1fr); }
#hamburger { display: flex; }
.navbar-link { font-size: 0.8rem; }
.navbar-cta { font-size: 0.75rem; padding: 0.35rem 0.75rem; }
.navbar-inner { height: 52px; gap: 0.75rem; }
.navbar-left, .navbar-right { gap: 0.85rem; }
.navbar-search-btn { height: 30px; }
:root { --header-h: 52px; }
}
@media (max-width: 560px) {
.card-grid { grid-template-columns: 1fr; }
#landing { padding: 48px 24px 80px; }
#content { padding: 28px 0 64px; }
#body { padding: 0 24px; }
.navbar-inner { padding: 0 16px; }
.navbar-left .navbar-link { display: none; } /* hide Blog, Docs, desktop GitHub */
.navbar-github-mobile { display: inline-flex; } /* GitHub icon left of Star */
.navbar-right .navbar-search-btn { display: none; } /* desktop search hidden... */
.navbar-left .navbar-search-mobile { display: inline-flex; } /* ...moved left, next to hamburger */
.navbar-search-label, .navbar-search-kbd { display: none; }
.navbar-search-btn { padding: 0 9px; width: 32px; }
/* Balanced sides (hamburger+search | logo | GitHub+Star) let the logo centre on its own */
.navbar-cta-count { display: none; } /* drop star count to balance the bar */
.navbar-cta { padding: 0.35rem 0.7rem; }
.theme-toggle { bottom: 14px; right: 14px; }
#search-input { font-size: 16px; }
}
@media (max-width: 360px) {
/* Very narrow phones: drop the "Docs" suffix so hamburger+search | logo | GitHub+Star
fits without the header overflowing (min content width is ~352px otherwise). */
.navbar-logo-sub { display: none; }
}
@media (max-width: 820px) {
.page-actions .pa-copy-label,
.toc-toggle .toc-label { display: none; }
.page-actions .pa-copy { padding-left: 10px; padding-right: 10px; }
.toc-toggle { padding: 5px 10px; }
}
/* ─── IA: tier headers (sidebar) and tier groupings (landing) ──────── */
.sb-tier-header {
display: block;
padding: 20px 10px 8px;
margin-top: 4px;
font-size: 11px;
font-weight: 700;
color: var(--ash);
text-transform: uppercase;
letter-spacing: 0.1em;
}
.sb-tier-header:first-child { margin-top: 0; padding-top: 6px; }
.landing-tier { margin-top: 28px; }
.landing-tier:first-child { margin-top: 0; }
.landing-tier > h2 {
margin: 0 0 14px;
font-size: 13px;
font-weight: 700;
color: var(--ash);
text-transform: uppercase;
letter-spacing: 0.1em;
}
.landing-tier-cards {
display: grid;
grid-template-columns: repeat(var(--tier-cols, 3), 1fr);
gap: 14px;
}
#landing-cards.card-grid {
display: block;
}
@media (max-width: 900px) {
.landing-tier-cards { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
.landing-tier-cards { grid-template-columns: 1fr; }
}