Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ function App() {
<div className="ambient ambient-a" aria-hidden="true" />
<div className="ambient ambient-b" aria-hidden="true" />

<header className="topbar" role="banner">
<header className="topbar no-print" role="banner">
<div>
<p className="eyebrow">Callora Vault</p>
<p className="brand">Secure USDC funding for premium API usage</p>
Expand Down Expand Up @@ -600,7 +600,7 @@ function App() {
<p className="eyebrow">Deposit USDC to Vault</p>
<h1>Review every number before you approve.</h1>
</div>
<button className="primary-button" onClick={openDeposit}>
<button className="primary-button no-print" onClick={openDeposit}>
Open deposit modal
</button>
</div>
Expand Down Expand Up @@ -733,7 +733,7 @@ function App() {
</Routes>
</main>

<footer className="surface app-footer" role="contentinfo">
<footer className="surface app-footer no-print" role="contentinfo">
<div>
<p className="eyebrow">Callora</p>
<p className="footer-copy">
Expand Down
1 change: 1 addition & 0 deletions src/components/CodeExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export default function CodeExample({
>
{/* Header Section: Contains Language Tabs and Copy Button */}
<div
className="no-print"
style={{
display: "flex",
justifyContent: "space-between",
Expand Down
2 changes: 1 addition & 1 deletion src/components/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default function Dashboard({ vaultBalance, walletBalance, openDeposit }:

{/* Quick actions */}
<div className="dashboard-actions">
<button className="primary-button" onClick={openDeposit}>Deposit</button>
<button className="primary-button no-print" onClick={openDeposit}>Deposit</button>
<button className="secondary-button" onClick={() => navigate('/marketplace')}>Browse APIs</button>
<button className="secondary-button" onClick={() => navigate('/api-usage')}>View Usage</button>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/EndpointGroupHover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default function EndpointGroupHover({
onBlurCapture={handleBlurCapture}
>
<div
className="endpoint-group-hover__triggers"
className="endpoint-group-hover__triggers no-print"
role="list"
aria-label="Endpoint groups"
>
Expand Down
17 changes: 17 additions & 0 deletions src/components/MANUAL_TEST_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,20 @@
## Accessibility checks
- [ ] Route shell sets `aria-busy="true"` while the destination is pending
- [ ] Reduced motion removes shimmer from skeleton surfaces

# ApiDetailPage Print Preview Manual Test Plan

## Setup
- [ ] Open `/details/weather-001` in Chrome
- [ ] Open the same page in Firefox

## Print preview checks
- [ ] Global nav, footer, deposit CTA, in-page tabs, and sidebar are hidden
- [ ] Background is white and body text is black/dark gray
- [ ] Provider and other inline links show the full URL in parentheses after the link text
- [ ] Long code snippets wrap without horizontal scrollbar or clipped content
- [ ] Endpoint cards, parameter tables, and documentation content remain visible

## Regression checks
- [ ] Screen layout is unchanged when not printing
- [ ] Interactive controls still work normally on screen after print stylesheet changes
2 changes: 1 addition & 1 deletion src/components/RouteProgressBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function RouteProgressBar() {

return (
<div
className={`route-progress-bar${isLoading ? " route-progress-bar--active" : ""}`}
className={`route-progress-bar no-print${isLoading ? " route-progress-bar--active" : ""}`}
role="progressbar"
aria-label="Page loading"
aria-busy={isLoading}
Expand Down
240 changes: 240 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -3968,3 +3968,243 @@ code,
.api-marketplace-card:focus-within .api-card__compare-btn {
opacity: 1 !important;
}

/* ─── Print stylesheet (ApiDetailPage docs printout) ─────────────────────
Pure CSS. Hides chrome via .no-print, forces light theme, expands code,
appends URLs after inline links. See src/print.test.ts for contract tests.
─────────────────────────────────────────────────────────────────────── */

@page {
margin: 1.5cm;
size: auto;
}

@media print {
/* ── Chrome hide utility ───────────────────────────────────────────────── */
.no-print {
display: none !important;
}

/* ── Force light theme (black on white) ──────────────────────────────── */
html,
html[data-theme="dark"],
html[data-theme="light"] {
--page-bg: #f5f7fa !important;
--surface: #ffffff !important;
--surface-strong: rgba(255, 255, 255, 0.92) !important;
--surface-soft: rgba(0, 0, 0, 0.06) !important;
--line: rgba(0, 0, 0, 0.08) !important;
--line-strong: rgba(0, 0, 0, 0.12) !important;
--text: #1a2332 !important;
--muted: #64748b !important;
--accent: #2563eb !important;
--accent-strong: #059669 !important;
--danger: #dc2626 !important;
--success: #10b981 !important;
--shadow: none !important;
--ambient-a: transparent !important;
--ambient-b: transparent !important;
--backdrop: transparent !important;
--modal-bg: #ffffff !important;

--method-get-color: #1e40af !important;
--method-post-color: #065f46 !important;
--method-put-color: #92400e !important;
--method-delete-color: #991b1b !important;
--method-patch-color: #5b21b6 !important;

color-scheme: light !important;
}

/* ── Remove decorative / background effects ──────────────────────────── */
.ambient,
.api-detail-hero {
backdrop-filter: none !important;
}

* {
backdrop-filter: none !important;
box-shadow: none !important;
text-shadow: none !important;
}

body {
background: #ffffff !important;
color: #1a2332 !important;
}

/* ── Hide non-markup chrome (decorative / modal overlays) ────────────── */
.skip-link,
.modal-backdrop,
.skeleton,
.ambient,
.button-spinner,
input[type="range"],
.route-progress-bar {
display: none !important;
}

/* ── Single-column layout ────────────────────────────────────────────── */
.api-detail-content-grid {
grid-template-columns: 1fr !important;
gap: 0 !important;
}

.api-detail-hero {
grid-template-columns: 1fr !important;
padding: 0 0 12px 0 !important;
}

.api-detail-price-panel {
text-align: left !important;
border-top: 1px solid var(--line);
padding-top: 12px !important;
margin-top: 12px;
}

.api-detail-price {
font-size: 1.25rem !important;
}

.api-detail-two-column,
.api-detail-pricing-grid,
.api-detail-metrics {
grid-template-columns: 1fr !important;
}

.endpoint-section-header,
.endpoint-card-header,
.api-detail-calculator-total,
.api-detail-reviews-header {
flex-direction: column !important;
align-items: flex-start !important;
}

.api-detail-sidebar-inner {
position: static !important;
}

.content-left {
max-width: 100% !important;
}

/* ── Page-break avoidance ──────────────────────────────────────────── */
.preview-card,
.stat-card,
.stat-card-skeleton,
.preview-card-skeleton,
.endpoint-section-header,
.endpoint-card-header,
.endpoint-table-wrap,
.api-detail-pricing-grid > *,
.api-detail-calculator-total,
.api-detail-plan-price,
.api-detail-two-column > *,
.api-detail-metrics > *,
.tab-content section,
.billing-panel,
.prototype-panel,
.vault-balance-card,
.info-card,
.marketplace-sidebar,
.filters-sidebar,
.marketplace-results,
.lp-section,
.lp-card,
h2,
h3,
h4,
table {
break-inside: avoid !important;
page-break-inside: avoid !important;
}

/* ── Content polish ──────────────────────────────────────────────────── */
.tab-content {
animation: none !important;
}

.tab-content section {
display: block !important;
margin-bottom: 24px;
}

.preview-card {
border: 1px solid #ddd !important;
background: #ffffff !important;
border-radius: 8px !important;
overflow: visible !important;
}

.api-detail-logo {
background: rgba(0, 0, 0, 0.04) !important;
color: #1a2332 !important;
}

.endpoint-card-header {
background: rgba(0, 0, 0, 0.03) !important;
}

.endpoint-table-wrap {
overflow: visible !important;
}

.endpoint-table-wrap table {
min-width: auto !important;
width: 100% !important;
}

.api-detail-calculator-total {
background: rgba(0, 0, 0, 0.03) !important;
border-radius: 8px !important;
}

.api-detail-metrics .stat-card {
background: rgba(0, 0, 0, 0.03) !important;
border-radius: 8px !important;
}

.api-detail-sidebar-inner > * {
margin-bottom: 0 !important;
}

/* ── Code samples: expand and wrap (no horizontal clip) ──────────────── */
.code-block,
pre,
code,
.response-json,
.endpoint-url {
background: #f4f4f5 !important;
border: 1px solid #ddd !important;
color: #1a2332 !important;
white-space: pre-wrap !important;
word-break: break-word !important;
overflow: visible !important;
overflow-x: visible !important;
max-width: 100% !important;
}

.api-detail-page {
padding: 0 !important;
}

.api-detail-container {
max-width: 100% !important;
}

.breadcrumb {
margin-bottom: 8px !important;
}

/* ── Links: show full URL after anchor text ──────────────────────────── */
a {
color: #1a2332 !important;
text-decoration: underline !important;
}

a[href]:not([href=""]):not([href^="#"]):not([href^="javascript:"]):after {
content: " (" attr(href) ")";
font-size: 0.85em;
color: #444;
}
}
1 change: 0 additions & 1 deletion src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import RouteProgressBar from "./components/RouteProgressBar";
import { startRouteLoading, stopRouteLoading } from "./hooks/useRouteLoading";
import { ToastProvider } from "./components/Toast";
import "./index.css";
import "./styles/print.css";
import "./styles/tokens.css";
import { ThemeProvider } from "./ThemeContext";
import { CollectionsProvider } from "./state/collectionsStore";
Expand Down
4 changes: 2 additions & 2 deletions src/pages/ApiDetailPage.skeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default function ApiDetailPageSkeleton() {

<div className="api-detail-content-grid">
<div className="content-left">
<nav className="api-detail-tabs" aria-hidden="true" style={{ display: "flex", gap: 24, flexWrap: "wrap" }}>
<nav className="api-detail-tabs no-print" aria-hidden="true" style={{ display: "flex", gap: 24, flexWrap: "wrap" }}>
{Array.from({ length: 5 }).map((_, index) => (
<Skeleton key={index} width={88} height={20} />
))}
Expand All @@ -68,7 +68,7 @@ export default function ApiDetailPageSkeleton() {
</div>
</div>

<aside className="api-detail-sidebar" aria-hidden="true">
<aside className="api-detail-sidebar no-print" aria-hidden="true">
<div className="api-detail-sidebar-inner" style={{ display: "grid", gap: 20 }}>
<SidebarCardSkeleton />
<SidebarCardSkeleton />
Expand Down
Loading