diff --git a/app/styles/global.css b/app/styles/global.css index c78aa81f..049cfddd 100644 --- a/app/styles/global.css +++ b/app/styles/global.css @@ -47,6 +47,24 @@ body { a { color: inherit; } +.skip-link { + position: fixed; + z-index: 100; + top: 0.5rem; + left: 0.5rem; + transform: translateY(-160%); + padding: 0.75rem 1rem; + border-radius: 0.5rem; + color: white; + background: var(--brand-strong); +} +.skip-link:focus { + transform: translateY(0); +} +:focus-visible { + outline: 3px solid var(--brand); + outline-offset: 3px; +} .docs-shell { position: relative; isolation: isolate; @@ -153,6 +171,129 @@ a { border-color 0.18s ease, box-shadow 0.18s ease; } +.preview-pill { + justify-self: end; + color: var(--brand-strong); + font-size: 0.78rem; + font-weight: 800; + text-decoration: none; +} +.mobile-doc-nav { + display: none; + padding: 0.75rem 20px; + border-bottom: 1px solid var(--border); + background: var(--surface); +} +.mobile-doc-nav summary { + cursor: pointer; + font-weight: 700; +} +.mobile-doc-nav nav { + display: grid; + gap: 0.6rem; + padding: 1rem 0 0.25rem; +} +.portal-main { + width: min(1240px, 100%); + margin: 0 auto; + padding: 1rem clamp(20px, 4vw, 72px) 6rem; +} +.breadcrumbs { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + padding: 1rem 0; + color: var(--muted); + font-size: 0.8rem; +} +.portal-hero { + min-height: 650px; +} +.status { + display: inline-flex; + align-items: center; + gap: 0.45rem; + width: fit-content; + border: 1px solid var(--border); + border-radius: 999px; + padding: 0.35rem 0.65rem; + font-size: 0.75rem; + font-weight: 800; +} +.status-beta { + color: #7c3aed; + background: color-mix(in srgb, #8b5cf6 10%, var(--surface)); +} +.status-planned { + color: #a16207; + background: color-mix(in srgb, #eab308 12%, var(--surface)); +} +.access-note { + font-size: 0.86rem !important; +} +.access-callout { + margin: 2rem 0; + border: 1px solid var(--brand); + border-radius: 14px; + padding: 1.25rem; + background: color-mix(in srgb, var(--brand) 7%, var(--surface)); +} +.access-callout h2 { + margin-top: 0; + font-size: 1.2rem; +} +.lifecycle { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 0.75rem; + padding: 0; + list-style: none; +} +.lifecycle li { + display: grid; + gap: 0.45rem; + border: 1px solid var(--border); + border-radius: 12px; + padding: 1rem; + background: var(--surface); +} +.lifecycle span { + color: var(--muted); + font-size: 0.82rem; +} +.coverage-list { + display: grid; + gap: 0.75rem; +} +.coverage-list article { + display: flex; + justify-content: space-between; + gap: 1rem; + align-items: center; + border-bottom: 1px solid var(--border); +} +.local-toc { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; + border: 1px solid var(--border); + border-radius: 12px; + padding: 1rem; +} +.copy-button { + min-width: 44px; + min-height: 44px; + border: 1px solid #64748b; + border-radius: 8px; + color: white; + background: #334155; +} +footer nav { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 1rem; +} .theme-button:hover { transform: translateY(-2px); border-color: var(--brand); @@ -713,6 +854,12 @@ footer { .topbar nav { display: none; } + .preview-pill { + display: none; + } + .mobile-doc-nav { + display: block; + } .feature-grid, .package-grid { grid-template-columns: repeat(2, 1fr); diff --git a/wrnexus.config.ts b/wrnexus.config.ts index 2e8cd144..b878e38a 100644 --- a/wrnexus.config.ts +++ b/wrnexus.config.ts @@ -28,6 +28,25 @@ const config: AppConfig = { themeColor: "#6366f1", }, + security: { + headers: { + hsts: true, + noSniff: true, + referrerPolicy: "strict-origin-when-cross-origin", + permissionsPolicy: "camera=(), microphone=(), geolocation=()", + }, + csp: { + enabled: true, + directives: { + "default-src": ["'self'"], + "img-src": ["'self'", "data:", "https:"], + "font-src": ["'self'", "https://fonts.gstatic.com"], + "style-src": ["'self'", "https://fonts.googleapis.com"], + "connect-src": ["'self'"], + }, + }, + }, + styles: { entry: "app/styles/global.css",