diff --git a/opencd.css b/opencd.css index a114199..1995e70 100644 --- a/opencd.css +++ b/opencd.css @@ -1,712 +1,310 @@ -/* ========================================================================== - OpenCD — CD Jewel Case CSS Framework (Production) - Author: B.A. Baracus - Base: Open Props v2 via unpkg - Principle: Zero magic numbers — every value is a --cd-* custom property - ASW Semantic: surface layers, grid overlays, data-attribute API - ========================================================================== */ - +/* OpenCD — CD Jewel Case CSS Framework */ @import "https://unpkg.com/open-props"; -/* ========================================================================== - 1. Custom Properties — All --cd-* Tokens - Components MUST NOT reference Open Props directly. - Users override these on :root or a scoped container to theme. - ========================================================================== */ - +/* 1. Tokens — all --cd-* custom properties */ :root { - /* ═══════════════════════════════════════════════════════════════════════ - Physical CD Dimensions (at 2× scale, ISO 15727) - Formula: calc( * 2px / 1mm) = - ═══════════════════════════════════════════════════════════════════════ */ + /* Physical dimensions (ISO 15727, 2× scale): scale=1 = 2×, 0.5 = 1×, 2 = 4× */ --cd-scale: 1; - /* --cd-scale: 1 = default 2× display scale. 0.5 = 1×, 2 = 4×, etc. */ - - --cd-jewel-width: calc(280px * var(--cd-scale)); /* 142 mm × 2 */ - --cd-jewel-height: calc(245px * var(--cd-scale)); /* 125 mm × 2 */ - --cd-jewel-open-width: calc(560px * var(--cd-scale)); /* 284 mm × 2 */ - --cd-disc-diameter: calc(240px * var(--cd-scale)); /* 120 mm × 2 */ - --cd-disc-hole: calc(30px * var(--cd-scale)); /* Ø15 mm × 2 */ - --cd-leaflet-size: calc(240px * var(--cd-scale)); /* 120 mm sq × 2 */ - --cd-spine-width: calc(14px * var(--cd-scale)); /* ~7 mm × 2 */ - --cd-tray-width: calc(260px * var(--cd-scale)); /* ~130 mm × 2 */ - - /* ── Derived aspect ratios ── */ - --cd-aspect-jewel: 280 / 245; - --cd-aspect-leaflet: 1 / 1; - --cd-aspect-disc: 1 / 1; - - /* ═══════════════════════════════════════════════════════════════════════ - Surface Colors (ASW-style, oklch — NOT from Open Props) - ═══════════════════════════════════════════════════════════════════════ */ - --cd-surface-1: oklch(30% .015 265); /* tray paper base */ - --cd-surface-2: oklch(35% .015 265); /* tray raised panel */ - --cd-surface-3: oklch(40% .015 265); /* leaflet inner area */ - --cd-surface-4: oklch(15% .01 265); /* spine background — darkest */ - - /* ── Surface 0 — lightest, used for jewel case body & leaflet pages ── */ + --cd-jewel-width: calc(280px * var(--cd-scale)); + --cd-jewel-height: calc(245px * var(--cd-scale)); + --cd-jewel-open-width: calc(560px * var(--cd-scale)); + --cd-disc-diameter: calc(240px * var(--cd-scale)); + --cd-disc-hole: calc(30px * var(--cd-scale)); + --cd-leaflet-size: calc(240px * var(--cd-scale)); + --cd-spine-width: calc(14px * var(--cd-scale)); + --cd-tray-width: calc(260px * var(--cd-scale)); + --cd-tray-height: calc(236px * var(--cd-scale)); + /* Surface layers (custom oklch) */ --cd-surface-0: var(--gray-0); - - /* ═══════════════════════════════════════════════════════════════════════ - Typography - ═══════════════════════════════════════════════════════════════════════ */ + --cd-surface-1: oklch(30% .015 265); + --cd-surface-2: oklch(35% .015 265); + --cd-surface-3: oklch(40% .015 265); + --cd-surface-4: oklch(15% .01 265); + /* Typography */ --cd-font-neo-grotesque: 'Inter', 'Roboto', 'Helvetica Neue', 'Arial', sans-serif; - --cd-font-label: var(--cd-font-neo-grotesque); /* spine, metadata, credits */ - --cd-font-body: var(--font-serif); /* leaflet prose */ - --cd-font-mono: var(--font-mono-code, var(--font-mono)); - - --cd-font-size-body: var(--font-size-fluid-1); - --cd-font-size-title: var(--font-size-fluid-2); - --cd-font-size-display: var(--font-size-fluid-3); - - /* ── Font weights ── */ - --cd-font-weight-semibold: 600; - - /* ── Spine font sizes ── */ - --cd-spine-font-xs: var(--font-size-0); - --cd-spine-font-sm: var(--font-size-1); - --cd-spine-font-md: var(--font-size-2); - --cd-spine-font-lg: var(--font-size-3); - - /* ═══════════════════════════════════════════════════════════════════════ - Spacing - ═══════════════════════════════════════════════════════════════════════ */ - --cd-space-inset: var(--size-fluid-1); - --cd-space-stack: var(--size-fluid-2); - --cd-space-gutter: var(--size-fluid-3); - - --cd-space-xs: var(--size-1); /* 4–5px */ - --cd-space-sm: var(--size-2); /* 8–10px */ - - /* ═══════════════════════════════════════════════════════════════════════ - Semantic Text Colors - ═══════════════════════════════════════════════════════════════════════ */ + --cd-font-label: var(--cd-font-neo-grotesque); + --cd-font-body: var(--font-serif); + --cd-font-mono: var(--font-mono-code, var(--font-mono)); + /* Semantic colors */ --cd-text-primary: var(--gray-9); --cd-text-secondary: var(--gray-7); --cd-text-muted: var(--gray-5); --cd-text-on-spine: var(--gray-1); - --cd-text-opacity-muted: 0.8; - - /* ═══════════════════════════════════════════════════════════════════════ - Surface / Tray Mappings - ═══════════════════════════════════════════════════════════════════════ */ - --cd-tray-bg: var(--cd-surface-1); - --cd-tray-bg-raised: var(--cd-surface-2); - --cd-tray-bg-sunken: var(--cd-surface-3); - --cd-spine-bg: var(--cd-surface-4); - - /* ═══════════════════════════════════════════════════════════════════════ - Grid Colors (custom — NOT Open Props tokens) - ═══════════════════════════════════════════════════════════════════════ */ - --cd-grid-color: var(--gray-3); - --cd-grid-color-alt: var(--gray-2); - --cd-grid-fine: 4px; - --cd-grid-coarse: 8px; - - /* ═══════════════════════════════════════════════════════════════════════ - Advisory Badge - ═══════════════════════════════════════════════════════════════════════ */ --cd-advisory-red: var(--red-6); --cd-advisory-red-dark: var(--red-7); --cd-advisory-bg: var(--red-0); --cd-advisory-fg: #000; --cd-advisory-fg-inv: #fff; - --cd-advisory-border: 2px solid var(--cd-advisory-fg); --cd-advisory-font: 'Impact', 'Arial Black', var(--cd-font-label), sans-serif; - - /* ═══════════════════════════════════════════════════════════════════════ - Jewel Case Decorations - ═══════════════════════════════════════════════════════════════════════ */ - --cd-jewel-radius: var(--radius-2); /* 5px */ + --cd-text-opacity-muted: 0.8; + /* Surface/tray */ + --cd-tray-bg: var(--cd-surface-1); + --cd-tray-bg-raised: var(--cd-surface-2); + --cd-tray-bg-sunken: var(--cd-surface-3); + --cd-spine-bg: var(--cd-surface-4); + /* Grid */ + --cd-grid-color: var(--gray-3); + --cd-grid-color-alt: var(--gray-2); + --cd-grid-fine: 4px; + --cd-grid-coarse: 8px; + /* Decorations */ + --cd-jewel-radius: var(--radius-2); --cd-jewel-shadow: var(--shadow-2); --cd-jewel-shadow-raised: var(--shadow-3); - --cd-leaflet-radius: var(--radius-3); /* 1rem */ - - /* ═══════════════════════════════════════════════════════════════════════ - Component Shadows (all rgba/rgb values defined here, not inline) - ═══════════════════════════════════════════════════════════════════════ */ + --cd-leaflet-radius: var(--radius-3); --cd-page-shadow: 0 1px 3px rgb(0 0 0 / 0.08); --cd-disc-hole-shadow: inset 0 0 3px rgb(0 0 0 / 0.15); --cd-disc-shadow: inset 0 0 8px rgb(0 0 0 / 0.12); - - /* ═══════════════════════════════════════════════════════════════════════ - Borders & Dividers - ═══════════════════════════════════════════════════════════════════════ */ + --cd-advisory-border: 2px solid var(--cd-advisory-fg); + /* Borders */ --cd-tray-border-top: 1px solid var(--cd-grid-color); --cd-track-border-bot: 1px solid var(--cd-grid-color-alt); --cd-track-num-min-w: 2.5ch; - --cd-print-border: 1px solid #ccc; - - /* ═══════════════════════════════════════════════════════════════════════ - Letter Spacing Scale - ═══════════════════════════════════════════════════════════════════════ */ + /* Spacing */ + --cd-space-inset: var(--size-fluid-1); + --cd-space-stack: var(--size-fluid-2); + --cd-space-gutter: var(--size-fluid-3); + --cd-space-xs: var(--size-1); + --cd-space-sm: var(--size-2); + /* Font sizes */ + --cd-font-size-body: var(--font-size-fluid-1); + --cd-font-size-title: var(--font-size-fluid-2); + --cd-font-size-display: var(--font-size-fluid-3); + /* Spine */ + --cd-spine-font-xs: var(--font-size-0); + --cd-spine-font-sm: var(--font-size-1); + --cd-spine-font-md: var(--font-size-2); + --cd-spine-font-lg: var(--font-size-3); + --cd-font-weight-semibold: 600; --cd-letter-spacing-1: 0.05em; --cd-letter-spacing-2: 0.075em; --cd-letter-spacing-3: 0.1em; - - /* ═══════════════════════════════════════════════════════════════════════ - Motion & Easing - ═══════════════════════════════════════════════════════════════════════ */ + /* Motion */ --cd-transition-duration: 200ms; --cd-ease-flip: cubic-bezier(0.34, 1.56, 0.64, 1); --cd-ease-default: var(--ease-3); - - /* ═══════════════════════════════════════════════════════════════════════ - Print Dimensions - ═══════════════════════════════════════════════════════════════════════ */ - --cd-print-jewel-width: 142mm; - --cd-print-jewel-height: 125mm; - - /* ═══════════════════════════════════════════════════════════════════════ - Grain Texture - ═══════════════════════════════════════════════════════════════════════ */ + /* Breakpoints */ + --cd-break-sm: 350px; + --cd-break-md-min: 351px; + --cd-break-md-max: 549px; + /* Disc */ + --cd-disc-hole-scale: 0.6; + --cd-disc-hole-font-scale: 0.5; + /* Grain */ --cd-grain-size-1: 120px; --cd-grain-size-2: 200px; --cd-grain-opacity-1: 0.02; --cd-grain-opacity-2: 0.015; - - /* ═══════════════════════════════════════════════════════════════════════ - Responsive Breakpoints (container query widths) - ═══════════════════════════════════════════════════════════════════════ */ - --cd-break-sm: 350px; - --cd-break-md-min: 351px; - --cd-break-md-max: 549px; - - /* ═══════════════════════════════════════════════════════════════════════ - Disc Decoration Ratios - ═══════════════════════════════════════════════════════════════════════ */ - --cd-disc-hole-scale: 0.6; /* decorative ring inside the hole */ - --cd-disc-hole-font-scale: 0.5; /* icon character in the hole */ - - /* ═══════════════════════════════════════════════════════════════════════ - Z-Index Stacking - ═══════════════════════════════════════════════════════════════════════ */ - --cd-z-stack-base: 1; /* disc hole above disc art */ + /* Misc */ + --cd-z-stack-base: 1; + --cd-print-jewel-width: 142mm; + --cd-print-jewel-height: 125mm; + --cd-aspect-jewel: 280 / 245; + --cd-aspect-leaflet: 1 / 1; + --cd-aspect-disc: 1 / 1; } -/* ========================================================================== - 2. Reset - ========================================================================== */ - -*, *::before, *::after { - box-sizing: border-box; - margin: 0; - padding: 0; -} - -/* ========================================================================== - 3. Jewel Case Container (.cd-jewel-case) - ========================================================================== */ +/* 2. Reset */ +*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } +html { font-size: 100%; line-height: 1.5; -webkit-text-size-adjust: 100%; } +body { font-family: inherit; } +img, svg, video, canvas { display: block; max-width: 100%; } +button, input, select, textarea { font: inherit; border: 0; background: transparent; } +a { color: inherit; text-decoration: none; } +ul, ol { list-style: none; } +h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; } +/* 3. Jewel Case */ .cd-jewel-case { - display: grid; - grid-template-columns: var(--cd-spine-width) 1fr; - grid-template-rows: auto 1fr; - width: var(--cd-jewel-width); - min-height: var(--cd-jewel-height); - background: var(--cd-surface-0); - border-radius: var(--cd-jewel-radius); - box-shadow: var(--cd-jewel-shadow); - overflow: hidden; - position: relative; + display: grid; grid-template-columns: var(--cd-spine-width) 1fr; grid-template-rows: auto 1fr; + width: min(var(--cd-jewel-width), 100% - 2rem); min-height: var(--cd-jewel-height); + background: var(--cd-surface-0); border-radius: var(--cd-jewel-radius); + box-shadow: var(--cd-jewel-shadow); overflow: hidden; position: relative; transition: width var(--cd-transition-duration) var(--cd-ease-default); - font-family: var(--cd-font-body); - color: var(--cd-text-primary); + font-family: var(--cd-font-body); color: var(--cd-text-primary); container-type: inline-size; } - -.cd-jewel-case--open, -.cd-jewel-case[data-jewel-state="open"] { - width: var(--cd-jewel-open-width); +.cd-jewel-case--open, .cd-jewel-case[data-jewel-state="open"] { + width: min(var(--cd-jewel-open-width), 100% - 2rem); } - -/* ── Internal layout wrapper ── */ .cd-jewel-case > .cd-jewel-inner { - grid-column: 2; - grid-row: 1 / -1; - display: flex; - flex-direction: column; - padding: var(--cd-space-inset); - gap: var(--cd-space-stack); - min-height: 0; + grid-column: 2; grid-row: 1 / -1; display: flex; flex-direction: column; + padding: var(--cd-space-inset); gap: var(--cd-space-stack); min-height: 0; } -/* ========================================================================== - 4. Spine (.cd-spine, .spine-label, .spine-track) - ========================================================================== */ - +/* 4. Spine */ .cd-spine { - grid-column: 1; - grid-row: 1 / -1; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - background: var(--cd-spine-bg); - color: var(--cd-text-on-spine); - font-family: var(--cd-font-label); - padding: var(--cd-space-sm) var(--cd-space-xs); - gap: var(--cd-space-sm); - writing-mode: vertical-rl; - text-orientation: mixed; - user-select: none; + grid-column: 1; grid-row: 1 / -1; display: flex; flex-direction: column; + align-items: center; justify-content: center; background: var(--cd-spine-bg); + color: var(--cd-text-on-spine); font-family: var(--cd-font-label); + padding: var(--cd-space-sm) var(--cd-space-xs); gap: var(--cd-space-sm); + writing-mode: vertical-rl; text-orientation: mixed; user-select: none; } - .cd-spine .spine-label { - font-size: var(--cd-spine-font-sm); - font-weight: var(--cd-font-weight-semibold); - letter-spacing: var(--cd-letter-spacing-3); - text-transform: uppercase; + font-size: var(--cd-spine-font-sm); font-weight: var(--cd-font-weight-semibold); + letter-spacing: var(--cd-letter-spacing-3); text-transform: uppercase; } - .cd-spine .spine-track { - font-size: var(--cd-spine-font-xs); - letter-spacing: var(--cd-letter-spacing-1); + font-size: var(--cd-spine-font-xs); letter-spacing: var(--cd-letter-spacing-1); opacity: var(--cd-text-opacity-muted); } +.cd-spine--side { /* keep vertical-rl from base */ } -/* ── Side spine variant ── */ -.cd-spine--side { - writing-mode: horizontal-tb; - flex-direction: row; -} - -/* ========================================================================== - 5. Leaflet Content & Pages (.leaflet-content, .leaflet-page) - ========================================================================== */ - +/* 5. Leaflet */ .leaflet-content { - display: flex; - flex-direction: column; - gap: var(--cd-space-stack); - max-width: var(--cd-leaflet-size); - position: relative; - background: - repeating-linear-gradient( - 0deg, - transparent 0 calc(var(--cd-grid-coarse) * 3 - 1px), - var(--cd-grid-color) calc(var(--cd-grid-coarse) * 3 - 1px) calc(var(--cd-grid-coarse) * 3) - ), - var(--cd-tray-bg); - border-radius: var(--cd-leaflet-radius); - padding: var(--cd-space-inset); + display: flex; flex-direction: column; gap: var(--cd-space-stack); + max-width: var(--cd-leaflet-size); position: relative; + background: repeating-linear-gradient(0deg, transparent 0 calc(var(--cd-grid-coarse)*3 - 1px), var(--cd-grid-color) calc(var(--cd-grid-coarse)*3 - 1px) calc(var(--cd-grid-coarse)*3)), var(--cd-tray-bg); + border-radius: var(--cd-leaflet-radius); padding: var(--cd-space-inset); } - .leaflet-page { - aspect-ratio: var(--cd-aspect-leaflet); - background: var(--cd-surface-0); - border-radius: calc(var(--cd-leaflet-radius) / 2); - padding: var(--cd-space-inset); - display: flex; - flex-direction: column; - gap: var(--cd-space-sm); + aspect-ratio: var(--cd-aspect-leaflet); background: var(--cd-surface-0); + border-radius: calc(var(--cd-leaflet-radius) / 2); padding: var(--cd-space-inset); + display: flex; flex-direction: column; gap: var(--cd-space-sm); box-shadow: var(--cd-page-shadow); - transition: transform var(--cd-transition-duration) var(--cd-ease-flip); - position: relative; + transition: transform var(--cd-transition-duration) var(--cd-ease-flip); position: relative; } - -.leaflet-page[data-leaflet-active="true"] { - box-shadow: var(--cd-jewel-shadow); +.leaflet-page[data-leaflet-active="true"] { box-shadow: var(--cd-jewel-shadow); } +.leaflet-page[data-leaflet-direction="rtl"] { direction: rtl; } +.leaflet-page h1, .leaflet-page h2 { + font-family: var(--cd-font-label); font-size: var(--cd-font-size-title); + color: var(--cd-text-primary); line-height: 1.2; } - -.leaflet-page[data-leaflet-direction="rtl"] { - direction: rtl; -} - -.leaflet-page h1, -.leaflet-page h2 { - font-family: var(--cd-font-label); - font-size: var(--cd-font-size-title); - color: var(--cd-text-primary); - line-height: 1.2; -} - .leaflet-page p { - font-family: var(--cd-font-body); - font-size: var(--cd-font-size-body); - color: var(--cd-text-secondary); - line-height: 1.6; + font-family: var(--cd-font-body); font-size: var(--cd-font-size-body); + color: var(--cd-text-secondary); line-height: 1.6; } - .leaflet-page .leaflet-meta { - font-family: var(--cd-font-mono); - font-size: var(--cd-spine-font-xs); - color: var(--cd-text-muted); - margin-top: auto; + font-family: var(--cd-font-mono); font-size: var(--cd-spine-font-xs); + color: var(--cd-text-muted); margin-top: auto; } +.cd-jewel-case--leaflet { + width: min(var(--cd-leaflet-size), 100% - 2rem); box-shadow: none; background: transparent; +} +.cd-jewel-case--leaflet .cd-jewel-inner { grid-column: 2; gap: var(--cd-space-inset); } +.leaflet-page ul { margin-left: 1rem; color: var(--cd-text-secondary); line-height: 1.6; } +.leaflet-page dl { margin-top: .5rem; display: grid; gap: .25rem; font-size: var(--cd-font-size-body); } +.leaflet-page dt { font-family: var(--cd-font-mono); color: var(--cd-text-muted); } +.leaflet-page dd { color: var(--cd-text-secondary); } +.leaflet-page p + p { margin-top: .5rem; } -/* ========================================================================== - 6. Disc Art (.disc-art, .disc-hole) - ========================================================================== */ - +/* 6. Disc Art */ .disc-art { - width: var(--cd-disc-diameter); - aspect-ratio: var(--cd-aspect-disc); - border-radius: 50%; - background: - radial-gradient( - circle at 30% 30%, - var(--gray-4) 0%, - var(--gray-2) 40%, - var(--gray-6) 70%, - var(--gray-2) 100% - ); - display: flex; - align-items: center; - justify-content: center; - position: relative; + width: var(--cd-disc-diameter); aspect-ratio: var(--cd-aspect-disc); border-radius: 50%; + background: radial-gradient(circle at 30% 30%, var(--gray-4) 0%, var(--gray-2) 40%, var(--gray-6) 70%, var(--gray-2) 100%); + display: flex; align-items: center; justify-content: center; position: relative; box-shadow: var(--cd-disc-shadow); } - .disc-art::before { - content: ""; - position: absolute; - width: var(--cd-disc-hole); - aspect-ratio: 1; - border-radius: 50%; - background: var(--cd-surface-0); - box-shadow: var(--cd-disc-hole-shadow); + content: ""; position: absolute; width: var(--cd-disc-hole); aspect-ratio: 1; + border-radius: 50%; background: var(--cd-surface-0); box-shadow: var(--cd-disc-hole-shadow); } - .disc-hole { - position: absolute; - width: calc(var(--cd-disc-hole) * var(--cd-disc-hole-scale)); - aspect-ratio: 1; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; + position: absolute; width: calc(var(--cd-disc-hole) * var(--cd-disc-hole-scale)); + aspect-ratio: 1; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: calc(var(--cd-disc-hole) * var(--cd-disc-hole-font-scale)); - color: var(--gray-4); - z-index: var(--cd-z-stack-base); - pointer-events: none; + color: var(--gray-4); z-index: var(--cd-z-stack-base); pointer-events: none; } - -/* ── Disc sheen variant ── */ .disc-art--sheen { - background: - radial-gradient( - circle at 25% 25%, - var(--gray-4) 0%, - var(--gray-2) 35%, - var(--gray-5) 50%, - transparent 65% - ), - radial-gradient( - circle at 75% 75%, - var(--gray-7) 0%, - var(--gray-3) 40%, - transparent 70% - ), - repeating-radial-gradient( - circle at 50%, - transparent 0 calc(var(--cd-disc-hole) * 0.5), - var(--gray-3) calc(var(--cd-disc-hole) * 0.5) calc(var(--cd-disc-hole) * 0.5 + 1px) - ); + background: radial-gradient(circle at 25% 25%, var(--gray-4) 0%, var(--gray-2) 35%, var(--gray-5) 50%, transparent 65%), + radial-gradient(circle at 75% 75%, var(--gray-7) 0%, var(--gray-3) 40%, transparent 70%); } -/* ========================================================================== - 7. Human Advisory Badge (.human-advisory) - ========================================================================== */ - +/* 7. Human Advisory */ .human-advisory { - display: flex; - flex-direction: column; - align-items: center; - background: var(--cd-advisory-fg); - color: var(--cd-advisory-fg-inv); - border: var(--cd-advisory-border); - font-family: var(--cd-advisory-font); - text-transform: uppercase; - text-align: center; - padding: 0; - width: fit-content; - max-width: 100%; - position: absolute; - bottom: var(--cd-space-inset); - right: var(--cd-space-inset); + display: flex; flex-direction: column; align-items: center; + background: var(--cd-advisory-fg); color: var(--cd-advisory-fg-inv); + border: var(--cd-advisory-border); font-family: var(--cd-advisory-font); + text-transform: uppercase; text-align: center; padding: 0; width: fit-content; + max-width: 100%; position: absolute; bottom: var(--cd-space-inset); right: var(--cd-space-inset); } - .human-advisory .advisory-row { - width: 100%; - padding: var(--cd-space-xs) var(--cd-space-sm); - font-size: var(--cd-spine-font-sm); - letter-spacing: var(--cd-letter-spacing-3); - line-height: 1.2; - white-space: nowrap; + width: 100%; padding: var(--cd-space-xs) var(--cd-space-sm); + font-size: var(--cd-spine-font-sm); letter-spacing: var(--cd-letter-spacing-3); + line-height: 1.2; white-space: nowrap; } +.human-advisory .advisory-row--black { background: var(--cd-advisory-fg); color: var(--cd-advisory-fg-inv); } +.human-advisory .advisory-row--white { background: var(--cd-advisory-fg-inv); color: var(--cd-advisory-fg); } +.human-advisory--red .advisory-row--black { background: var(--cd-advisory-red-dark); color: var(--cd-advisory-fg-inv); } +.human-advisory--red .advisory-row--white { background: var(--cd-advisory-red); color: var(--cd-advisory-fg-inv); } +.human-advisory--inline { position: static; align-self: flex-end; } -.human-advisory .advisory-row--black { - background: var(--cd-advisory-fg); - color: var(--cd-advisory-fg-inv); -} - -.human-advisory .advisory-row--white { - background: var(--cd-advisory-fg-inv); - color: var(--cd-advisory-fg); -} - -.human-advisory .advisory-row--red { - background: var(--cd-advisory-red); - color: var(--cd-advisory-fg-inv); -} - -/* ── Advisory badge red variant ── */ -.human-advisory--red .advisory-row--black { - background: var(--cd-advisory-red-dark); - color: var(--cd-advisory-fg-inv); -} - -.human-advisory--red .advisory-row--white { - background: var(--cd-advisory-red); - color: var(--cd-advisory-fg-inv); -} - -/* ========================================================================== - 8. Back Tray (.back-tray, .tray-credits) - ========================================================================== */ - +/* 8. Back Tray */ .back-tray { - display: grid; - grid-template-columns: var(--cd-spine-width) 1fr var(--cd-spine-width); - background: var(--cd-tray-bg); - border-top: var(--cd-tray-border-top); - padding: 0; - position: relative; + display: grid; grid-template-columns: var(--cd-spine-width) 1fr var(--cd-spine-width); + background: var(--cd-tray-bg); border-top: var(--cd-tray-border-top); + padding: 0; max-height: var(--cd-tray-height); overflow-y: auto; position: relative; } - .back-tray .tray-credits { - grid-column: 2; - padding: var(--cd-space-inset); - display: flex; - flex-direction: column; - gap: var(--cd-space-stack); - background: var(--cd-tray-bg-raised); + grid-column: 2; padding: var(--cd-space-inset); display: flex; flex-direction: column; + gap: var(--cd-space-stack); background: var(--cd-tray-bg-raised); border-radius: 0 0 var(--cd-leaflet-radius) var(--cd-leaflet-radius); } - .tray-credits h2 { - font-family: var(--cd-font-label); - font-size: var(--cd-font-size-title); - color: var(--cd-text-primary); - text-transform: uppercase; - letter-spacing: var(--cd-letter-spacing-2); + font-family: var(--cd-font-label); font-size: var(--cd-font-size-title); + color: var(--cd-text-primary); text-transform: uppercase; letter-spacing: var(--cd-letter-spacing-2); } - -.tray-credits ol { - list-style: none; - counter-reset: track; - display: flex; - flex-direction: column; - gap: var(--cd-space-xs); -} - +.tray-credits ol { list-style: none; counter-reset: track; display: flex; flex-direction: column; gap: var(--cd-space-xs); } .tray-credits ol li { - counter-increment: track; - font-family: var(--cd-font-label); - font-size: var(--cd-font-size-body); - color: var(--cd-text-secondary); - padding: var(--cd-space-xs) 0; - border-bottom: var(--cd-track-border-bot); - display: flex; - gap: var(--cd-space-sm); + counter-increment: track; font-family: var(--cd-font-label); font-size: var(--cd-font-size-body); + color: var(--cd-text-secondary); padding: var(--cd-space-xs) 0; + border-bottom: var(--cd-track-border-bot); display: flex; gap: var(--cd-space-sm); } - .tray-credits ol li::before { content: counter(track, decimal-leading-zero) "."; - font-family: var(--cd-font-mono); - color: var(--cd-text-muted); - min-width: var(--cd-track-num-min-w); + font-family: var(--cd-font-mono); color: var(--cd-text-muted); min-width: var(--cd-track-num-min-w); } - .tray-credits .credits-label { - font-family: var(--cd-font-mono); - font-size: var(--cd-spine-font-xs); - color: var(--cd-text-muted); - text-transform: uppercase; - letter-spacing: var(--cd-letter-spacing-1); + font-family: var(--cd-font-mono); font-size: var(--cd-spine-font-xs); + color: var(--cd-text-muted); text-transform: uppercase; letter-spacing: var(--cd-letter-spacing-1); } +.tray-credits p { font-family: var(--cd-font-body); font-size: var(--cd-font-size-body); color: var(--cd-text-secondary); line-height: 1.5; } +.back-tray .cd-spine { grid-row: 1; background: var(--cd-spine-bg); } -.tray-credits p { - font-family: var(--cd-font-body); - font-size: var(--cd-font-size-body); - color: var(--cd-text-secondary); - line-height: 1.5; -} - -/* ── Back tray spine labels ── */ -.back-tray .cd-spine { - grid-row: 1; - background: var(--cd-spine-bg); -} - -/* ========================================================================== - 9. Grid Overlay Utility (.cd-grid) - ========================================================================== */ - +/* 9. Grid Overlay */ .cd-grid { - background-image: - repeating-linear-gradient( - 0deg, - transparent 0 calc(var(--cd-grid-coarse) - 1px), - var(--cd-grid-color) calc(var(--cd-grid-coarse) - 1px) var(--cd-grid-coarse) - ); + background-image: repeating-linear-gradient(0deg, transparent 0 calc(var(--cd-grid-coarse) - 1px), var(--cd-grid-color) calc(var(--cd-grid-coarse) - 1px) var(--cd-grid-coarse)); } - .cd-grid--fine { - background-image: - repeating-linear-gradient( - 0deg, - transparent 0 calc(var(--cd-grid-fine) - 1px), - var(--cd-grid-color) calc(var(--cd-grid-fine) - 1px) var(--cd-grid-fine) - ); + background-image: repeating-linear-gradient(0deg, transparent 0 calc(var(--cd-grid-fine) - 1px), var(--cd-grid-color) calc(var(--cd-grid-fine) - 1px) var(--cd-grid-fine)); } - -.cd-grid--coarse { - background-image: - repeating-linear-gradient( - 0deg, - transparent 0 calc(var(--cd-grid-coarse) - 1px), - var(--cd-grid-color) calc(var(--cd-grid-coarse) - 1px) var(--cd-grid-coarse) - ); -} - .cd-grid--crosshatch { - background-image: - repeating-linear-gradient( - 0deg, - transparent 0 calc(var(--cd-grid-fine) - 1px), - var(--cd-grid-color-alt) calc(var(--cd-grid-fine) - 1px) var(--cd-grid-fine) - ), - repeating-linear-gradient( - 90deg, - transparent 0 calc(var(--cd-grid-coarse) - 1px), - var(--cd-grid-color) calc(var(--cd-grid-coarse) - 1px) var(--cd-grid-coarse) - ); + background-image: repeating-linear-gradient(0deg, transparent 0 calc(var(--cd-grid-fine) - 1px), var(--cd-grid-color-alt) calc(var(--cd-grid-fine) - 1px) var(--cd-grid-fine)), + repeating-linear-gradient(90deg, transparent 0 calc(var(--cd-grid-coarse) - 1px), var(--cd-grid-color) calc(var(--cd-grid-coarse) - 1px) var(--cd-grid-coarse)); } -/* ========================================================================== - 10. Open / Closed State Transitions - ========================================================================== */ - -.cd-jewel-case .back-tray { - display: none; -} - -.cd-jewel-case--open .back-tray, -.cd-jewel-case[data-jewel-state="open"] .back-tray { - display: grid; -} - -/* ========================================================================== - 11. Responsive Breakpoints (container queries) - ========================================================================== */ +/* 10. Open / Closed */ +.cd-jewel-case .back-tray { display: none; } +.cd-jewel-case--open .back-tray, .cd-jewel-case[data-jewel-state="open"] .back-tray { display: grid; } +/* 11. Responsive */ @container (max-width: var(--cd-break-sm)) { - .cd-jewel-case { - width: 100% !important; - grid-template-columns: 1fr; - } - - .cd-spine { - writing-mode: horizontal-tb; - flex-direction: row; - padding: var(--cd-space-xs) var(--cd-space-sm); - grid-column: 1; - grid-row: 1; - } - - .cd-jewel-inner { - grid-column: 1; - grid-row: 2; - } - - .disc-art { - width: 100% !important; - max-width: var(--cd-disc-diameter); - margin: 0 auto; - } - - .leaflet-content { - max-width: 100%; - } - - .human-advisory { - position: static; - margin-top: var(--cd-space-stack); - align-self: center; - } + .cd-jewel-case { width: 100% !important; grid-template-columns: 1fr; } + .cd-spine { writing-mode: horizontal-tb; flex-direction: row; padding: var(--cd-space-xs) var(--cd-space-sm); grid-column: 1; grid-row: 1; } + .cd-jewel-inner { grid-column: 1; grid-row: 2; } + .disc-art { width: 100% !important; max-width: var(--cd-disc-diameter); margin: 0 auto; } + .leaflet-content { max-width: 100%; } + .human-advisory { position: static; margin-top: var(--cd-space-stack); align-self: center; } } - @container (min-width: var(--cd-break-md-min)) and (max-width: var(--cd-break-md-max)) { - .cd-jewel-case { - width: 100% !important; - max-width: var(--cd-jewel-width); - } - - .leaflet-content { - gap: var(--cd-space-sm); - } - - .human-advisory .advisory-row { - font-size: var(--cd-spine-font-xs); - padding: var(--cd-space-xs) var(--cd-space-sm); - } + .cd-jewel-case { width: 100% !important; max-width: var(--cd-jewel-width); } + .leaflet-content { gap: var(--cd-space-sm); } + .human-advisory .advisory-row { font-size: var(--cd-spine-font-xs); padding: var(--cd-space-xs) var(--cd-space-sm); } } -/* ========================================================================== - 12. Print Styles - ========================================================================== */ - +/* 12. Print */ @media print { - .cd-jewel-case { - width: var(--cd-print-jewel-width); - height: var(--cd-print-jewel-height); - box-shadow: none; - border: var(--cd-print-border); - } - - .cd-jewel-case--open { - width: calc(var(--cd-print-jewel-width) * 2); - } - - .back-tray { - display: grid !important; - } - - .human-advisory { - position: absolute; - } - - .disc-art { - box-shadow: none; - } - - .cd-jewel-case, - .leaflet-page, - .back-tray { - border-radius: 0; - } + .cd-jewel-case { width: var(--cd-print-jewel-width); height: var(--cd-print-jewel-height); box-shadow: none; border: 1px solid #ccc; } + .cd-jewel-case--open { width: calc(var(--cd-print-jewel-width) * 2); } + .back-tray { display: grid !important; } + .human-advisory { position: absolute; } + .disc-art { box-shadow: none; } + .cd-jewel-case, .leaflet-page, .back-tray { border-radius: 0; } } -/* ========================================================================== - 13. Grain Texture Utility (.cd-grain) - ========================================================================== */ - +/* 13. Grain */ .cd-grain { - background-image: - repeating-radial-gradient( - circle at 50% 50%, - transparent 0 1px, - rgb(0 0 0 / var(--cd-grain-opacity-1)) 1px 2px, - transparent 2px 4px - ), - repeating-radial-gradient( - circle at 100% 100%, - transparent 0 3px, - rgb(0 0 0 / var(--cd-grain-opacity-2)) 3px 4px, - transparent 4px 8px - ); - background-size: var(--cd-grain-size-1) var(--cd-grain-size-1), - var(--cd-grain-size-2) var(--cd-grain-size-2); + background-image: repeating-radial-gradient(circle at 50% 50%, transparent 0 1px, rgb(0 0 0 / var(--cd-grain-opacity-1)) 1px 2px, transparent 2px 4px), + repeating-radial-gradient(circle at 100% 100%, transparent 0 3px, rgb(0 0 0 / var(--cd-grain-opacity-2)) 3px 4px, transparent 4px 8px); + background-size: var(--cd-grain-size-1) var(--cd-grain-size-1), var(--cd-grain-size-2) var(--cd-grain-size-2); } \ No newline at end of file diff --git a/templates/back-tray.html b/templates/back-tray.html index a6c4ec9..4bd2f1b 100644 --- a/templates/back-tray.html +++ b/templates/back-tray.html @@ -5,59 +5,7 @@ OpenCD · Back Tray - + diff --git a/templates/demo.css b/templates/demo.css new file mode 100644 index 0000000..e2ae4e0 --- /dev/null +++ b/templates/demo.css @@ -0,0 +1,116 @@ +/* OpenCD — Demo page chrome (not framework component CSS) + Shared by jewel-case.html, back-tray.html, leaflet.html + All --cd-* tokens defined in opencd.css */ + + +/* ── Shared demo layout ── */ + +body { + min-height: 100dvh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 2rem; + padding: 2rem; + background: oklch(92% .012 85); + font-family: var(--cd-font-label); +} + +.demo-controls { + display: flex; + gap: 1rem; + align-items: center; + font-size: .875rem; +} + +.demo-controls label { + display: flex; + align-items: center; + gap: .5rem; + cursor: pointer; + user-select: none; +} + +.demo-controls input[type="checkbox"] { + accent-color: var(--cd-advisory-red); +} + +.demo-controls select { + padding: .25rem .5rem; + border: 1px solid var(--cd-text-muted); + border-radius: var(--cd-jewel-radius); + font-family: inherit; +} + +.demo-footnote { + font-size: .75rem; + color: var(--cd-text-muted); + text-align: center; + max-width: 480px; + line-height: 1.5; +} + + +/* ── Back-tray demo wrapper ── */ + +.demo-tray-container { + width: var(--cd-jewel-width); + max-height: var(--cd-tray-height); + border-radius: var(--cd-jewel-radius); + box-shadow: var(--cd-jewel-shadow); + overflow: hidden; +} + + +/* ── Leaflet-specific demo overrides ── */ + +.demo-controls { + flex-wrap: wrap; +} + +.demo-controls button { + padding: .5rem 1rem; + border: 1px solid var(--cd-text-muted); + border-radius: var(--cd-jewel-radius); + background: var(--cd-surface-0); + font-family: inherit; + cursor: pointer; + transition: background var(--cd-transition-duration); +} + +.demo-controls button:hover { + background: var(--cd-grid-color); +} + +.demo-controls button:disabled { + opacity: .4; + cursor: not-allowed; +} + +.demo-controls .page-indicator { + font-family: var(--cd-font-mono); + font-size: .875rem; + color: var(--cd-text-muted); + min-width: 8ch; + text-align: center; +} + +.leaflet-content--multi { + max-width: calc(var(--cd-leaflet-size) + var(--cd-space-inset) * 2); +} + +.leaflet-pages { + display: flex; + gap: var(--cd-space-stack); + flex-direction: column; + position: relative; +} + +.leaflet-pages .leaflet-page { + display: none; +} + +.leaflet-pages .leaflet-page[data-leaflet-active="true"] { + display: flex; +} \ No newline at end of file diff --git a/templates/jewel-case.html b/templates/jewel-case.html index 47ed3ae..eaa484a 100644 --- a/templates/jewel-case.html +++ b/templates/jewel-case.html @@ -5,54 +5,7 @@ OpenCD · Jewel Case - + diff --git a/templates/leaflet.html b/templates/leaflet.html index b75b41a..8cb79b7 100644 --- a/templates/leaflet.html +++ b/templates/leaflet.html @@ -5,94 +5,16 @@ OpenCD · Leaflet - + -
+
-
+
@@ -107,7 +29,7 @@

Architecture

OpenCD is built on Open Props — a design token framework by Adam Argyle. Every dimension, color, and spacing value maps to a custom property, with fallback values for standalone use. The framework includes:

-
    +
    • CD dimension tokens at 2× scale
    • Semantic color aliases on Open Props
    • ASW-inspired surface layers
    • @@ -119,13 +41,13 @@

      Token System

      The variable layer defines ~40 custom properties organized into semantic groups:

      -
      -
      --cd-jewel-width
      -
      280px × scale
      -
      --cd-surface-1
      -
      oklch(30% .015 265)
      -
      --cd-font-label
      -
      --cd-font-neo-grotesque
      +
      +
      --cd-jewel-width
      +
      280px × scale
      +
      --cd-surface-1
      +
      oklch(30% .015 265)
      +
      --cd-font-label
      +
      --cd-font-neo-grotesque
      Page 3 of 4 · v0.1.0
      @@ -133,15 +55,15 @@

      Credits

      OpenCD is a project of the A-Team design collective — a framework for physical-digital design artifacts that bridge the gap between print packaging and web implementations.

      -

      Design: Hannibal & Face
      Engineering: Murdock & B.A.
      Quality: Amy

      +

      Design: Hannibal & Face
      Engineering: Murdock & B.A.
      Quality: Amy

      Page 4 of 4 · MMXXV
- -