diff --git a/css/cdn.css b/css/cdn.css index 6b8db74..002ee41 100644 --- a/css/cdn.css +++ b/css/cdn.css @@ -1,227 +1,8 @@ -/* ── Design Tokens ── */ -:root { - --bg-deep: #100b09; - --bg: #1c1310; - --bg-raised: #251a15; - --bg-card: #2e2018; - --border: #3d2b1f; - --border-hover: #5c3d28; - --text: #f4deb8; - --text-muted: #e8c28a; - --text-dim: #b37a48; - --accent: #d4975c; - --accent-bright:#e8c28a; - --accent-dim: rgba(212, 151, 92, 0.14); - --accent-glow: rgba(212, 151, 92, 0.08); - --green: #4caf7d; - --red: #e06c6c; - --font-serif: 'Lota', Georgia, 'Times New Roman', serif; - --font-mono: 'Sometype Mono', 'Monaco', 'Courier New', monospace; - --font-sans: 'DM Sans', system-ui, sans-serif; - --radius: 10px; - --transition: 0.2s ease; - --max-w: 680px; -} - -*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } - -html { scroll-behavior: smooth; } - -body { - font-family: var(--font-serif); - font-size: 16px; - line-height: 1.7; - color: var(--text); - background-color: var(--bg); - -webkit-font-smoothing: antialiased; -} - -/* ── Typography ── */ - -h1, h2, h3 { - font-family: var(--font-mono); - font-weight: 600; - line-height: 1.2; -} - -a { - color: var(--accent); - text-decoration: none; - transition: opacity var(--transition); -} -a:hover { opacity: 0.75; } - -code { - font-family: var(--font-mono); - font-size: 0.875em; - background: var(--bg-raised); - padding: 0.15em 0.4em; - border-radius: 4px; - color: var(--accent); - word-break: break-all; -} - -/* ── Header ── */ - -.site-header { - position: sticky; - top: 0; - z-index: 100; - background: var(--bg); - backdrop-filter: blur(12px); - border-bottom: 1px solid var(--border); -} - -.nav-container { - max-width: var(--max-w); - margin: 0 auto; - padding: 0.875rem 1.5rem; - display: flex; - justify-content: space-between; - align-items: center; -} - -.nav-logo { - font-family: var(--font-serif); - font-style: italic; - font-size: 1.25rem; - color: var(--text); -} -.nav-logo:hover { opacity: 0.6; } - -.nav-menu { - list-style: none; - display: flex; - gap: 1.5rem; -} - -.nav-menu a { - font-size: 0.875rem; - color: var(--text-muted); - letter-spacing: 0.01em; -} -.nav-menu a:hover { color: var(--text); opacity: 1; } - -.nav-dropdown { - position: relative; -} -.nav-dropdown details { - position: relative; -} -.nav-dropdown summary { - list-style: none; - cursor: pointer; - font-size: 0.875rem; - color: var(--text-muted); - letter-spacing: 0.01em; - display: inline-flex; - align-items: center; - gap: 0.25rem; -} -.nav-dropdown summary::-webkit-details-marker { display: none; } -.nav-dropdown summary:hover, -.nav-dropdown details[open] summary { - color: var(--text); -} -.nav-dropdown .dropdown-menu { - position: absolute; - left: 0; - top: calc(100% + 0.5rem); - min-width: 220px; - margin: 0; - padding: 0.5rem 0; - background: var(--bg); - border: 1px solid var(--border); - border-radius: 0.75rem; - box-shadow: 0 18px 40px rgba(0, 0, 0, 0.08); - list-style: none; - z-index: 200; - display: none; -} -.nav-dropdown details[open] .dropdown-menu { display: block; } -.nav-dropdown .dropdown-menu li { white-space: nowrap; } -.nav-dropdown .dropdown-menu a, -.nav-dropdown .dropdown-disabled { - display: block; - padding: 0.5rem 1rem; - color: var(--text-muted); - font-size: 0.875rem; -} -.nav-dropdown .dropdown-menu a:hover { - background: rgba(255,255,255,0.04); - color: var(--text); -} -.nav-dropdown .dropdown-disabled { cursor: default; color: var(--text-dim); } -.nav-dropdown summary:focus { outline: none; } -@media (max-width: 600px) { - .nav-dropdown .dropdown-menu { - position: static; - box-shadow: none; - border: none; - } -} - -/* ── Main ── */ - -.main-content { - max-width: var(--max-w); - margin: 0 auto; - padding: 0 1.5rem; -} - -/* ── Hero ── */ - -.hero { - padding: 4rem 0 3rem; -} - -.hero-eyebrow { - font-size: 0.875rem; - color: var(--text-muted); - margin-bottom: 0.25rem; - letter-spacing: 0.04em; -} - -.hero-title { - font-size: clamp(2.5rem, 6vw, 3.5rem); - color: var(--text); - margin-bottom: 1.25rem; - letter-spacing: -0.02em; -} - -.hero-bio { - font-size: 1.0625rem; - color: var(--text-muted); - line-height: 1.8; - max-width: 560px; - margin-bottom: 1.5rem; -} - -.hero-bio a { - color: var(--accent); - border-bottom: 1px solid var(--accent-dim); - transition: border-color var(--transition), opacity var(--transition); -} -.hero-bio a:hover { - opacity: 1; - border-bottom-color: var(--accent); -} - -/* ── Sections ── */ - -.content-section { - padding: 2.5rem 0; - border-top: 1px solid var(--border); -} - -.section-label { - font-family: var(--font-sans); - font-size: 0.75rem; - font-weight: 500; - text-transform: uppercase; - letter-spacing: 0.1em; - color: var(--text-dim); - margin-bottom: 1.25rem; +/* CDN-only presentation */ +.main-content, +.nav-container, +.site-footer { + max-width: 680px; } /* ── Stats ── */ diff --git a/css/core.css b/css/core.css index 18889ab..a738c6e 100644 --- a/css/core.css +++ b/css/core.css @@ -1,3 +1,4 @@ +/* Shared shell and theme tokens for the site */ :root { --core-bg: #1c1310; --core-bg-raised: #251a15; @@ -12,41 +13,236 @@ --core-radius: 10px; --core-transition: 0.2s ease; --core-max-w: 720px; + + --accent-dim: rgba(212, 151, 92, 0.14); + --accent-glow: rgba(212, 151, 92, 0.08); + --green: #4caf7d; + --red: #e06c6c; + --font-serif: 'Lota', Georgia, 'Times New Roman', serif; + --font-mono: 'Sometype Mono', 'Monaco', 'Courier New', monospace; + --font-sans: 'DM Sans', system-ui, sans-serif; + + --bg: var(--core-bg); + --bg-raised: var(--core-bg-raised); + --bg-card: var(--core-bg-card); + --border: var(--core-border); + --border-hover: var(--core-border-hover); + --text: var(--core-text); + --text-muted: var(--core-text-muted); + --text-dim: var(--core-text-dim); + --accent: var(--core-accent); + --accent-bright: var(--core-accent-bright); + --radius: var(--core-radius); + --transition: var(--core-transition); + --max-w: var(--core-max-w); +} + +body[data-theme="default"] { + --core-bg: #1c1310; + --core-bg-raised: #251a15; + --core-bg-card: #2e2018; + --core-border: #3d2b1f; + --core-border-hover: #5c3d28; + --core-text: #f4deb8; + --core-text-muted: #e8c28a; + --core-text-dim: #b37a48; + --core-accent: #d4975c; + --core-accent-bright: #e8c28a; + --accent-dim: rgba(212, 151, 92, 0.14); + --accent-glow: rgba(212, 151, 92, 0.08); + color-scheme: dark; +} + +body[data-theme="black"] { + --core-bg: #050505; + --core-bg-raised: #111111; + --core-bg-card: #171717; + --core-border: #2b2b2b; + --core-border-hover: #4a4a4a; + --core-text: #f7f1e8; + --core-text-muted: #d8d0bf; + --core-text-dim: #9a8d78; + --core-accent: #f0c27b; + --core-accent-bright: #ffe4a8; + --accent-dim: rgba(240, 194, 123, 0.16); + --accent-glow: rgba(240, 194, 123, 0.1); + color-scheme: dark; +} + +body[data-theme="white"] { + --core-bg: #f7f2e9; + --core-bg-raised: #fdf8f0; + --core-bg-card: #efe3d0; + --core-border: #d7c1a7; + --core-border-hover: #b98f57; + --core-text: #2c221a; + --core-text-muted: #5d4731; + --core-text-dim: #8a5f35; + --core-accent: #a55a1f; + --core-accent-bright: #7b3d11; + --accent-dim: rgba(165, 90, 31, 0.14); + --accent-glow: rgba(165, 90, 31, 0.08); + color-scheme: light; +} + +/* Base reset and typography */ +*, *::before, *::after { + box-sizing: border-box; + margin: 0; + padding: 0; } -::-webkit-scrollbar { - width: 6px; - height: 6pxpx; +html { + scroll-behavior: smooth; } -::-webkit-scrollbar-track { - background: var(--core-bg); - border-radius: 6px; + +body { + font-family: var(--font-serif); + font-size: 16px; + line-height: 1.7; + color: var(--core-text); + background-color: var(--core-bg); + -webkit-font-smoothing: antialiased; + transition: background-color var(--core-transition), color var(--core-transition); } -::-webkit-scrollbar-thumb { - background: var(--core-accent); - border-radius: 0px; + +#css-error { + display: none; } -::-webkit-scrollbar-thumb:hover { - background: var(--core-accent-bright); + +.theme-toggle-wrap { + position: fixed; + left: 1.25rem; + bottom: 1.25rem; + z-index: 170; } -.hero-subtitle { - font-size: 1rem; - font-style: italic; + +.theme-toggle { + display: inline-flex; + align-items: center; + justify-content: center; + border: 1px solid var(--core-border) !important; + border-radius: 999px; + background: var(--core-bg-card); + color: var(--core-text); + padding: 0.45rem; + cursor: pointer; + box-shadow: 0 12px 24px rgba(0, 0, 0, 0.16); + appearance: none; + transition: border-color var(--core-transition), transform var(--core-transition), background-color var(--core-transition); +} + +.theme-toggle:hover { + border-color: var(--core-border-hover); + transform: translateY(-1px); +} + +.theme-toggle:focus-visible { + outline: 2px solid var(--core-accent); + outline-offset: 3px; +} + +.theme-toggle-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 1.05rem; + height: 1.05rem; + border-radius: 999px; + background: var(--accent-dim); color: var(--core-accent); - margin: 0.5rem 0 1.75rem; - line-height: 1.6; - letter-spacing: 0.01em; - max-width: 560px; + font-size: 0.8rem; +} + +.theme-toggle-label { + font-family: var(--font-sans); + font-size: 0.82rem; + font-weight: 600; + letter-spacing: 0.04em; + text-transform: uppercase; +} + +.theme-menu { + position: absolute; + left: 0; + bottom: calc(100% + 0.6rem); + display: none; + flex-direction: column; + gap: 0.35rem; + min-width: 9rem; + padding: 0.55rem; + border: 1px solid var(--core-border); + border-radius: var(--core-radius); + background: var(--core-bg-card); + box-shadow: 0 18px 32px rgba(0, 0, 0, 0.18); +} + +.theme-toggle-wrap.open .theme-menu { + display: flex; +} + +.theme-option { + display: flex; + align-items: center; + justify-content: space-between; + border: 1px solid transparent; + border-radius: 0.6rem; + background: transparent; + color: var(--core-text-muted); + padding: 0.55rem 0.7rem; + font: inherit; + cursor: pointer; + text-align: left; + transition: background-color var(--core-transition), color var(--core-transition), border-color var(--core-transition); +} + +.theme-option:hover { + background: var(--accent-dim); + color: var(--core-text); +} + +.theme-option.active { + background: var(--accent-dim); + color: var(--core-accent); + border-color: var(--core-accent); +} + +@media (max-width: 600px) { + .theme-toggle-wrap { + left: 1rem; + bottom: 1rem; + } +} + +a { + color: var(--core-accent); + text-decoration: none; + transition: opacity var(--core-transition); +} + +a:hover { + opacity: 0.75; +} + +code { + font-family: var(--font-mono); + font-size: 0.875em; + background: var(--core-bg-raised); + padding: 0.15em 0.4em; + border-radius: 4px; } + p { - color: var(--text-muted) + color: var(--core-text-muted); } + h1, h2, h3 { font-family: var(--font-mono); font-weight: 600; line-height: 1.2; color: var(--core-accent); } + hr { border: 0; border-top: 1px solid var(--core-accent); @@ -54,6 +250,85 @@ hr { opacity: 0.8; } +/* Scrollbars */ +::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +::-webkit-scrollbar-track { + background: var(--core-bg); + border-radius: 6px; +} + +::-webkit-scrollbar-thumb { + background: var(--core-accent); + border-radius: 6px; +} + +::-webkit-scrollbar-thumb:hover { + background: var(--core-accent-bright); +} + +/* Shared layout shell */ +.main-content { + max-width: var(--core-max-w); + margin: 0 auto; + padding: 0 1.5rem; +} + +.hero { + padding: 4rem 0 3rem; +} + +.hero-eyebrow { + font-size: 0.875rem; + color: var(--core-text-muted); + margin-bottom: 0.25rem; + letter-spacing: 0.04em; +} + +.hero-title { + font-size: clamp(2.5rem, 6vw, 3.5rem); + color: var(--core-text); + margin-bottom: 1.25rem; + letter-spacing: -0.02em; +} + +.hero-bio { + font-size: 1.0625rem; + color: var(--core-text-muted); + line-height: 1.8; + max-width: 560px; + margin-bottom: 1.5rem; +} + +.hero-bio a { + color: var(--core-accent); + border-bottom: 1px solid var(--accent-dim); + transition: border-color var(--core-transition), opacity var(--core-transition); +} + +.hero-bio a:hover { + opacity: 1; + border-bottom-color: var(--core-accent); +} + +.content-section { + padding: 2.5rem 0; + border-top: 1px solid var(--core-border); +} + +.section-label { + font-family: var(--font-sans); + font-size: 0.75rem; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--core-text-dim); + margin-bottom: 1.25rem; +} + .site-header { position: sticky; top: 0; @@ -228,10 +503,11 @@ hr { } .site-footer a:hover { - color: var(--core-dim); + color: var(--core-text); opacity: 1; } +/* Privacy notice */ .privacy-notice { position: fixed; bottom: 1.5rem; @@ -299,7 +575,6 @@ hr { display: inline-flex; } - /* the whole nav collapses into one panel below the logo row */ .nav-container { flex-wrap: wrap; } @@ -312,8 +587,6 @@ hr { margin-top: 0.875rem; padding: 0.5rem 0; border-top: 1px solid var(--core-border); - /* the panel lives in a sticky header, so cap it to the viewport and - scroll internally once the dropdowns are expanded */ max-height: calc(100vh - 10rem); max-height: calc(100dvh - 10rem); overflow-y: auto; @@ -325,7 +598,6 @@ hr { display: flex; } - /* keep rows at full height so the panel scrolls instead of squashing them */ .nav-menu > li { flex-shrink: 0; } @@ -343,7 +615,6 @@ hr { width: 100%; } - /* hover must not open sections here — only the tapped one expands */ .nav-dropdown:hover .dropdown-menu, .nav-dropdown:focus-within .dropdown-menu { display: none; diff --git a/css/index.css b/css/index.css index f249231..4d1ebd8 100644 --- a/css/index.css +++ b/css/index.css @@ -1,101 +1,12 @@ -:root { - --bg-deep: #100b09; /* espresso — deepest bg */ - --bg: #1c1310; /* dark roast — page bg */ - --bg-raised: #251a15; /* raised surface */ - --bg-card: #2e2018; /* card bg */ - --border: #3d2b1f; /* default border */ - --border-hover:#5c3d28; /* hover border */ - --text: #f4deb8; /* cream — primary text */ - --text-muted: #e8c28a; /* latte — secondary text */ - --text-dim: #b37a48; /* placeholder / disabled */ - --accent: #d4975c; /* caramel — primary accent*/ - --accent-bright:#e8c28a; /* accent hover/focus */ - --accent-dim: rgba(212, 151, 92, 0.14); - --font-serif: 'Lota', Georgia, 'Times New Roman', serif; - --font-mono: 'Sometype Mono', 'Monaco', 'Courier New', monospace; - --font-sans: 'DM Sans', system-ui, sans-serif; - --radius: 10px; - --transition: 0.2s ease; - --max-w: 720px; -} - -*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } - -html { scroll-behavior: smooth; } - -body { - font-family: var(--font-serif); - font-size: 16px; - line-height: 1.7; - color: var(--text); - background-color: var(--bg); - -webkit-font-smoothing: antialiased; -} - -#css-error { - display:none; -} -/* ── Typography ── */ - -a { +/* Homepage-only presentation */ +.hero-subtitle { + font-size: 1rem; + font-style: italic; color: var(--accent); - text-decoration: none; - transition: opacity var(--transition); -} -a:hover { opacity: 0.75; } - -code { - font-family: var(--font-mono); - font-size: 0.875em; - background: var(--bg-raised); - padding: 0.15em 0.4em; - border-radius: 4px; -} - -/* ── Main ── */ - -.main-content { - max-width: var(--max-w); - margin: 0 auto; - padding: 0 1.5rem; -} - -/* ── Hero ── */ - -.hero { - padding: 4rem 0 3rem; -} - -.hero-eyebrow { - font-size: 0.875rem; - color: var(--text-muted); - margin-bottom: 0.25rem; - letter-spacing: 0.04em; -} - -.hero-title { - font-size: clamp(2.5rem, 6vw, 3.5rem); - color: var(--text); - margin-bottom: 1.25rem; - letter-spacing: -0.02em; -} - -.hero-bio { - font-size: 1.0625rem; - color: var(--text-muted); - line-height: 1.8; + margin: 0.5rem 0 1.75rem; + line-height: 1.6; + letter-spacing: 0.01em; max-width: 560px; - margin-bottom: 1.5rem; -} - -.hero-bio a { - color: var(--accent); - border-bottom: 1px solid var(--accent-dim); - transition: border-color var(--transition), opacity var(--transition); -} -.hero-bio a:hover { - opacity: 1; - border-bottom-color: var(--accent); } .visitor-badge { @@ -113,21 +24,6 @@ code { /* ── Sections ── */ -.content-section { - padding: 2.5rem 0; - border-top: 1px solid var(--border); -} - -.section-label { - font-family: var(--font-sans); - font-size: 0.75rem; - font-weight: 500; - text-transform: uppercase; - letter-spacing: 0.1em; - color: var(--text-dim); - margin-bottom: 1.25rem; -} - .note { font-size: 0.75rem; color: var(--text-dim); diff --git a/js/core.js b/js/core.js index d9cbd84..e67b3bc 100644 --- a/js/core.js +++ b/js/core.js @@ -1,4 +1,35 @@ (() => { + const THEME_COOKIE_NAME = 'site_theme'; + const THEME_OPTIONS = ['default', 'black', 'white']; + + const getCookie = (name) => { + const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`)); + return match ? decodeURIComponent(match[1]) : ''; + }; + + const setThemeCookie = (theme) => { + const expires = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toUTCString(); + document.cookie = `${THEME_COOKIE_NAME}=${encodeURIComponent(theme)}; expires=${expires}; path=/; SameSite=Lax`; + }; + + const applyTheme = (theme) => { + const normalizedTheme = THEME_OPTIONS.includes(theme) ? theme : 'default'; + document.body.dataset.theme = normalizedTheme; + + document.querySelectorAll('[data-theme-option]').forEach((option) => { + const isActive = option.getAttribute('data-theme-option') === normalizedTheme; + option.classList.toggle('active', isActive); + option.setAttribute('aria-pressed', isActive ? 'true' : 'false'); + }); + + const themeToggle = document.getElementById('theme-toggle'); + if (themeToggle) { + themeToggle.setAttribute('data-active-theme', normalizedTheme); + } + + setThemeCookie(normalizedTheme); + }; + const getHeroEyebrowLabel = () => { const { hostname, pathname, port } = window.location; const normalizedHost = hostname.replace(/^www\./, ''); @@ -146,6 +177,53 @@ document.body.insertAdjacentHTML('beforeend', statcounterMarkup); } + if (!document.getElementById('theme-toggle-wrap')) { + const themeToggleHtml = ` +
+ + +
+ `; + document.body.insertAdjacentHTML('beforeend', themeToggleHtml); + } + + const savedTheme = getCookie(THEME_COOKIE_NAME) || 'default'; + applyTheme(savedTheme); + + const themeToggleWrap = document.getElementById('theme-toggle-wrap'); + const themeToggle = document.getElementById('theme-toggle'); + const themeMenu = document.getElementById('theme-menu'); + const themeOptions = themeMenu ? themeMenu.querySelectorAll('[data-theme-option]') : []; + + if (themeToggle && themeMenu && themeToggleWrap) { + themeToggle.addEventListener('click', (event) => { + event.stopPropagation(); + const isOpen = themeToggleWrap.classList.toggle('open'); + themeToggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false'); + }); + + themeOptions.forEach((option) => { + option.addEventListener('click', () => { + applyTheme(option.getAttribute('data-theme-option')); + themeToggleWrap.classList.remove('open'); + themeToggle.setAttribute('aria-expanded', 'false'); + }); + }); + + document.addEventListener('click', (event) => { + if (!themeToggleWrap.contains(event.target)) { + themeToggleWrap.classList.remove('open'); + themeToggle.setAttribute('aria-expanded', 'false'); + } + }); + } + const isCompactNav = () => window.matchMedia('(max-width: 600px)').matches; const navToggle = document.querySelector('.nav-toggle'); diff --git a/mbdcs.html b/mbdcs.html new file mode 100644 index 0000000..cb16498 --- /dev/null +++ b/mbdcs.html @@ -0,0 +1 @@ +MBD Cloud Services. \ No newline at end of file