/* JSON Schema Viewer - Pure CSS with CSS Custom Properties */ /* ======================================== Theme Variables - Light Mode (default) Define at :root so portaled elements inherit them ======================================== */ :root { --jsv-font-sans: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; --jsv-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; --jsv-font-size: 0.875rem; /* Colors - Light Mode defaults */ --jsv-color-body: #1a1a1a; --jsv-color-muted: #6b7280; --jsv-color-border: #e5e7eb; --jsv-color-canvas: #f4f4f5; --jsv-color-canvas-tint: #f4f4f5; --jsv-color-bg: #ffffff; /* Semantic colors - Cloudflare orange as primary */ --jsv-color-primary: #f6821f; --jsv-color-danger: #dc2626; --jsv-color-warning: #f97316; --jsv-color-success: #16a34a; } /* ======================================== Theme Variables - Dark Mode Cloudflare docs dark theme colors ======================================== */ :root[data-theme="dark"], [data-theme="dark"] { --jsv-color-body: #e4e4e7; --jsv-color-muted: #a1a1aa; --jsv-color-border: #3f3f46; --jsv-color-canvas: #27272a; --jsv-color-canvas-tint: #3f3f46; --jsv-color-bg: #18181b; --jsv-color-primary: #f6821f; --jsv-color-danger: #f87171; --jsv-color-warning: #fb923c; --jsv-color-success: #4ade80; } /* ======================================== Base Styles ======================================== */ .jsv-root { font-size: var(--jsv-font-size); font-family: var(--jsv-font-sans); color: var(--jsv-color-body); line-height: 1.5; position: relative; } .jsv-content { padding-left: 2rem; padding-right: 1rem; padding-bottom: 0.5rem; padding-top: 0.375rem; } /* ======================================== Schema Row ======================================== */ .jsv-row { position: relative; padding-top: 0.25rem; padding-bottom: 0.25rem; display: flex; align-items: flex-start; max-width: 100%; } .jsv-row-content { display: flex; flex-direction: column; gap: 0.125rem; max-width: 100%; flex: 1; min-width: 0; } .jsv-row-header { display: flex; align-items: center; max-width: 100%; gap: 0.25rem; } /* Nubbin - horizontal connector from left border to property */ .jsv-nubbin { width: 0.75rem; height: 0; border-top: 1px solid var(--jsv-color-border); flex-shrink: 0; margin-top: 0.5rem; margin-right: 0.5rem; margin-left: -1rem; } .jsv-nubbin-short { width: 0.25rem; } /* ======================================== Child Stack (nested content with left border) ======================================== */ .jsv-child-stack { font-size: var(--jsv-font-size); } .jsv-child-stack-nested { border-left: 1px solid var(--jsv-color-border); margin-left: 0.5rem; padding-left: 1rem; margin-top: 0.25rem; } /* ======================================== Property Name ======================================== */ .jsv-property-name { font-family: var(--jsv-font-mono); font-weight: 600; margin-right: 0.5rem; flex-shrink: 0; } /* ======================================== Type Display ======================================== */ .jsv-type { color: var(--jsv-color-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .jsv-types-container { display: flex; align-items: baseline; font-size: var(--jsv-font-size); min-width: 0; } /* ======================================== Badges (required, deprecated, read-only) ======================================== */ .jsv-badges { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; } .jsv-badge { font-size: 0.75rem; } .jsv-badge-required { color: var(--jsv-color-warning); } .jsv-badge-deprecated { color: var(--jsv-color-warning); } .jsv-badge-readonly { color: var(--jsv-color-muted); } /* ======================================== Divider (horizontal line on hover) ======================================== */ .jsv-divider { height: 1px; flex: 1; margin-left: 0.75rem; margin-right: 0.75rem; min-width: 1rem; background-color: transparent; transition: background-color 0.15s ease; } .jsv-divider-visible { background-color: var(--jsv-color-border); } /* ======================================== Description ======================================== */ .jsv-description { font-size: var(--jsv-font-size); color: var(--jsv-color-muted); margin-top: 0.0625rem; line-height: 1.4; } /* ======================================== Validations ======================================== */ .jsv-validations { display: flex; flex-wrap: wrap; gap: 0.25rem; align-items: center; margin-top: 0.125rem; } .jsv-validations-row { display: flex; flex-wrap: wrap; gap: 0.25rem; align-items: center; } .jsv-validation { display: flex; align-items: baseline; gap: 0.375rem; color: var(--jsv-color-muted); font-size: 0.75rem; } .jsv-validation-label { flex-shrink: 0; } .jsv-validation-values { display: flex; flex-wrap: wrap; gap: 0.25rem; flex: 1; } .jsv-validation-value { padding: 0.0625rem 0.375rem; background-color: var(--jsv-color-canvas-tint); color: var(--jsv-color-muted); border: 1px solid var(--jsv-color-border); border-radius: 0.25rem; font-family: var(--jsv-font-mono); font-size: 0.75rem; word-break: break-all; } /* ======================================== Caret (expand/collapse icon) ======================================== */ .jsv-caret { width: 1.25rem; height: 1.25rem; margin-left: -1.5rem; margin-right: 0.25rem; color: var(--jsv-color-muted); display: flex; justify-content: center; align-items: center; cursor: pointer; flex-shrink: 0; transition: transform 0.15s ease; } .jsv-caret:hover { color: var(--jsv-color-body); } .jsv-caret-expanded { transform: rotate(90deg); } /* ======================================== Error Display ======================================== */ .jsv-error { color: var(--jsv-color-danger); display: flex; align-items: center; gap: 0.25rem; font-size: 0.75rem; } /* ======================================== Change Annotations (added/removed/modified) ======================================== */ .jsv-annotation { position: absolute; width: 0.25rem; height: 1rem; border-radius: 0.125rem; top: 50%; transform: translateY(-50%); } .jsv-annotation-added { background-color: var(--jsv-color-success); } .jsv-annotation-removed { background-color: var(--jsv-color-danger); } .jsv-annotation-modified { background-color: var(--jsv-color-warning); } /* ======================================== Path Crumbs (sticky breadcrumb header) Wrapper is sticky with height:0 (no layout impact) Inner crumbs div is absolute, overlays content ======================================== */ .jsv-crumbs { height: 2rem; padding-left: 2rem; padding-right: 1rem; font-family: var(--jsv-font-mono); font-size: var(--jsv-font-size); line-height: 1; z-index: 20; background-color: var(--sl-color-bg, var(--jsv-color-bg, #fff)); color: var(--jsv-color-muted); display: flex; align-items: center; gap: 0.25rem; border-bottom: 1px solid var(--jsv-color-border); border-top-left-radius: 0.5rem; border-top-right-radius: 0.5rem; box-sizing: border-box; /* Hidden by default */ opacity: 0; pointer-events: none; } [data-theme="dark"] .jsv-crumbs, :root[data-theme="dark"] .jsv-crumbs { border-bottom-color: var(--sl-color-gray-5, #52525b); } .jsv-crumbs[data-visible="true"] { opacity: 1; pointer-events: auto; } .jsv-crumb-current { color: var(--jsv-color-body); font-weight: 600; } /* ======================================== Select / Menu Dropdown ======================================== */ .jsv-select-trigger { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.125rem 0.5rem; font-size: var(--jsv-font-size); font-family: var(--jsv-font-sans); background-color: transparent; border: 1px solid var(--jsv-color-border); border-radius: 0.25rem; cursor: pointer; color: var(--jsv-color-muted); line-height: 1.4; transition: background-color 0.15s ease, border-color 0.15s ease; } .jsv-select-trigger:hover { background-color: var(--jsv-color-canvas); border-color: var(--jsv-color-muted); } .jsv-select-trigger:focus { outline: none; box-shadow: 0 0 0 2px var(--jsv-color-primary); } .jsv-select-positioner { z-index: 9999 !important; position: relative; } .jsv-select-popup { background-color: var(--jsv-color-bg); border: 1px solid var(--jsv-color-border); border-radius: 0.375rem; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1); padding: 0.25rem 0; min-width: 10rem; overflow: hidden; font-family: var(--jsv-font-sans); font-size: var(--jsv-font-size); } .jsv-select-item { padding: 0.5rem 0.75rem; padding-left: 2rem; font-size: var(--jsv-font-size); cursor: pointer; display: flex; align-items: center; gap: 0.5rem; outline: none; color: var(--jsv-color-body); background-color: var(--jsv-color-bg); position: relative; transition: background-color 0.1s ease; } .jsv-select-item:hover, .jsv-select-item:focus, .jsv-select-item[data-highlighted] { background-color: var(--jsv-color-canvas); } .jsv-select-item[data-selected] { font-weight: 600; } .jsv-select-item-indicator { position: absolute; left: 0.625rem; top: 50%; transform: translateY(-50%); display: flex; align-items: center; justify-content: center; color: var(--jsv-color-primary); } /* ======================================== Top Level Styles ======================================== */ .jsv-top-label { font-family: var(--jsv-font-mono); font-weight: 600; font-size: var(--jsv-font-size); padding-bottom: 0.5rem; } .jsv-top-section { display: flex; align-items: center; gap: 0.75rem; padding-bottom: 0.5rem; } .jsv-combiner-label { display: flex; align-items: center; color: var(--jsv-color-muted); font-size: var(--jsv-font-size); } /* ======================================== Link Styles ======================================== */ .jsv-link { color: var(--jsv-color-primary); cursor: pointer; text-decoration: none; margin-left: 0.5rem; } .jsv-link:hover { text-decoration: underline; } /* ======================================== Misc Helpers ======================================== */ .jsv-cursor-pointer { cursor: pointer; } .jsv-ml-2 { margin-left: 0.5rem; }