/* ========================================================================== ZDDC Shared Base — single source of truth for tokens and primitives Included first by every tool's build.sh via ../shared/base.css ========================================================================== */ /* ── CSS custom properties ────────────────────────────────────────────────── */ :root { /* Brand / accent (matches zddc.varasys.io website --accent) */ --primary: #2a5a8a; --primary-hover: #1d4060; --primary-active: #163352; --primary-light: #e8f0f7; /* Semantic colours */ --success: #28a745; --warning: #d97706; --danger: #dc3545; --info: #17a2b8; /* Backgrounds */ --bg: #ffffff; --bg-secondary: #f8f9fa; --bg-hover: #f0f4f8; --bg-selected: var(--primary-light); /* Text */ --text: #212529; --text-muted: #6c757d; --text-light: #ffffff; /* Borders */ --border: #dee2e6; --border-dark: #adb5bd; /* Shape */ --radius: 4px; /* Typography */ --font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; --font-mono: 'SF Mono', 'Fira Code', 'Consolas', 'Courier New', monospace; } /* ── Dark mode tokens ─────────────────────────────────────────────────────── */ /* Applied via: OS preference (auto) or [data-theme="dark"] on */ /* The [data-theme="light"] selector locks light mode regardless of OS pref. */ @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --primary: #4a90c4; --primary-hover: #5ba3d9; --primary-active: #6ab5e8; --primary-light: #1a3550; --bg: #1e1e1e; --bg-secondary: #252526; --bg-hover: #2d2d30; --bg-selected: #1a3550; --text: #d4d4d4; --text-muted: #9d9d9d; --text-light: #ffffff; --border: #3e3e42; --border-dark: #6e6e72; } } /* Manual dark override — wins over media query */ [data-theme="dark"] { --primary: #4a90c4; --primary-hover: #5ba3d9; --primary-active: #6ab5e8; --primary-light: #1a3550; --bg: #1e1e1e; --bg-secondary: #252526; --bg-hover: #2d2d30; --bg-selected: #1a3550; --text: #d4d4d4; --text-muted: #9d9d9d; --text-light: #ffffff; --border: #3e3e42; --border-dark: #6e6e72; } /* ── Reset ────────────────────────────────────────────────────────────────── */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } /* ── Base document ────────────────────────────────────────────────────────── */ html, body { height: 100%; font-family: var(--font); font-size: 16px; line-height: 1.5; color: var(--text); background-color: var(--bg-secondary); } /* ── Typography ───────────────────────────────────────────────────────────── */ h1, h2, h3, h4, h5, h6 { font-weight: 600; line-height: 1.2; } a { color: var(--primary); text-decoration: none; } a:hover { text-decoration: underline; } /* ── Utility ──────────────────────────────────────────────────────────────── */ .hidden { display: none !important; } .truncate { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* ── Scrollbars (webkit) ──────────────────────────────────────────────────── */ ::-webkit-scrollbar { width: 7px; height: 7px; } ::-webkit-scrollbar-track { background: var(--bg-secondary); } ::-webkit-scrollbar-thumb { background: #c1c1c1; border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: #a0a0a0; } /* ── Button primitive ─────────────────────────────────────────────────────── */ .btn { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.4rem 0.85rem; font-family: var(--font); font-size: 0.875rem; font-weight: 500; line-height: 1.4; text-align: center; text-decoration: none; white-space: nowrap; vertical-align: middle; cursor: pointer; border: 1px solid transparent; border-radius: var(--radius); transition: background 0.15s, box-shadow 0.15s, border-color 0.15s, color 0.15s; background: var(--bg-secondary); color: var(--text); } .btn:disabled, .btn[disabled] { opacity: 0.5; cursor: not-allowed; } .btn:not(:disabled):hover { box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12); } .btn:not(:disabled):active { box-shadow: none; } /* Variants */ .btn-primary { background: var(--primary); color: var(--text-light); border-color: var(--primary); } .btn-primary:not(:disabled):hover { background: var(--primary-hover); border-color: var(--primary-hover); color: var(--text-light); } .btn-primary:not(:disabled):active { background: var(--primary-active); border-color: var(--primary-active); } .btn-secondary { background: var(--bg); color: var(--text); border-color: var(--border); } .btn-secondary:not(:disabled):hover { background: var(--bg-secondary); } /* Subdued / de-emphasized variant. Used on the "Add Local Directory" button when a tool is operating in server (online) mode — the local-dir affordance is still available but visually quieter, since the typical user already has the directory loaded from the server. */ .btn.btn--subtle { background: transparent; color: var(--text-muted); border-color: var(--border); box-shadow: none; font-weight: normal; } .btn.btn--subtle:not(:disabled):hover { color: var(--text); background: var(--bg-secondary); } .btn-success { background: var(--success); color: var(--text-light); border-color: var(--success); } .btn-danger { background: var(--danger); color: var(--text-light); border-color: var(--danger); } /* Sizes */ .btn-sm { padding: 0.25rem 0.5rem; font-size: 0.75rem; } .btn-lg { padding: 0.6rem 1.4rem; font-size: 1rem; } .btn-link { background: transparent; border-color: transparent; color: var(--primary); padding-left: 0; padding-right: 0; } .btn-link:not(:disabled):hover { text-decoration: underline; box-shadow: none; } /* ── App header chrome ────────────────────────────────────────────────────── */ .app-header { display: flex; align-items: center; justify-content: space-between; padding: 0.35rem 1rem; background: var(--bg-secondary); border-bottom: 1px solid var(--border); flex-shrink: 0; } /* Left and right groups inside .app-header. Both flex-row so their children (logo, title, action button, theme icon, etc.) lay out horizontally rather than stacking. Left side gets a slightly larger gap because it carries the title group and an action button; right side is just icon buttons. */ .header-left { display: flex; align-items: center; gap: 0.75rem; } .header-right { display: flex; align-items: center; gap: 0.5rem; } /* Tool name inside the header */ .app-header__title { font-size: 17px; font-weight: 600; color: var(--text); letter-spacing: 0.01em; white-space: nowrap; } /* Brand logo — sits left of the title in every tool's app-header. Self-contained: the SVG provides its own dark blue rounded background, so no extra wrapper styling is needed. */ .app-header__logo { width: 26px; height: 26px; flex-shrink: 0; display: block; } /* ── Build timestamp ──────────────────────────────────────────────────────── */ .build-timestamp { font-size: 0.55rem; color: var(--text-muted); opacity: 0.7; font-weight: 300; white-space: nowrap; padding-top: 0.15rem; } /* Title + timestamp stacked vertically on the left side of the header */ .header-title-group { display: flex; flex-direction: column; gap: 0; line-height: 1; } /* ── Icon buttons (help, theme, refresh) ─────────────────────────────────── */ /* Square, centered — overrides the asymmetric text-button padding/line-height */ #help-btn, #theme-btn, #refreshHeaderBtn { width: 2rem; height: 2rem; padding: 0; line-height: 1; display: inline-flex; align-items: center; justify-content: center; font-size: 1rem; } /* The refresh ⟳ glyph renders slightly smaller than ◐ / ? — bump to match. */ #refreshHeaderBtn { font-size: 1.1rem; } /* Toast CSS lives in classifier/css/base.css — only that tool uses toasts. */ /* ── Theme and help icon buttons ─────────────────────────────────────────── */ #theme-btn, #help-btn { font-size: 1rem; } /* ── Help panel (shared slide-out drawer) ─────────────────────────────────── */ /* Used by all four tools. Toggle open/close via shared/help.js. */ .help-panel { position: fixed; top: 0; right: 0; width: min(420px, 85vw); height: 100vh; z-index: 1000; background: var(--bg); border-left: 1px solid var(--border); box-shadow: -2px 0 12px rgba(0, 0, 0, 0.08); display: flex; flex-direction: column; transform: translateX(100%); transition: transform 0.25s ease; } .help-panel:not([hidden]) { transform: translateX(0); } .help-panel[hidden] { display: flex; transform: translateX(100%); pointer-events: none; } .help-panel__header { display: flex; align-items: center; justify-content: space-between; padding: 0.75rem 1rem; border-bottom: 1px solid var(--border); flex-shrink: 0; background: var(--bg); } .help-panel__title { font-size: 1rem; font-weight: 700; color: var(--text); margin: 0; } .help-panel__close { background: none; border: none; color: var(--text-muted); font-size: 1.35rem; cursor: pointer; padding: 0.25rem 0.5rem; border-radius: var(--radius); line-height: 1; transition: background 0.15s, color 0.15s; } .help-panel__close:hover { color: var(--text); background: var(--bg-secondary); } .help-panel__body { flex: 1; overflow-y: auto; padding: 1rem 1rem 2rem; font-size: 0.85rem; line-height: 1.6; color: var(--text); } .help-panel__body h3 { font-size: 0.95rem; font-weight: 700; margin: 1.25rem 0 0.35rem; color: var(--text); border-bottom: 1px solid var(--border); padding-bottom: 0.15rem; } .help-panel__body h3:first-child { margin-top: 0; } .help-panel__body h4 { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; margin: 1.25rem 0 0.3rem; padding-left: 0.5rem; border-left: 3px solid var(--border-dark); color: var(--text-muted); } .help-panel__body p { margin: 0 0 0.5rem; } .help-panel__body ol, .help-panel__body ul { padding-left: 1.5rem; margin: 0.3rem 0 0.5rem; } .help-panel__body li { margin-bottom: 0.3rem; } .help-panel__body dl { margin: 0.3rem 0; } .help-panel__body dt { font-weight: 600; color: var(--text); } .help-panel__body dd { margin: 0 0 0.5rem 1rem; color: var(--text-muted); } .help-panel__body code { font-family: var(--font-mono); font-size: 0.8em; background: var(--bg-secondary); padding: 0.1em 0.3em; border-radius: 3px; } .help-badge { font-size: 0.7rem; font-weight: 600; padding: 0.1rem 0.35rem; border-radius: var(--radius); vertical-align: middle; letter-spacing: 0.02em; } .help-badge--draft { color: #2563eb; background: #eff6ff; } .help-badge--published { color: #7c3aed; background: #f5f3ff; } /* Shrink main content when help panel is open */ body.help-open .app-header { margin-right: min(420px, 85vw); } /* ── Column filter inputs (shared across archive, classifier, transmittal) ─── */ .column-filter { display: block; width: 100%; box-sizing: border-box; margin-top: 0.25rem; padding: 0.2rem 0.4rem; font-size: 0.8rem; font-family: var(--font); border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); color: var(--text); transition: border-color 0.15s; } .column-filter:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 1px rgba(42, 90, 138, 0.35); } .column-filter::placeholder { color: var(--text-muted); }