From f343ced979b9ae5eac2094c7d1b383dd683d42ba Mon Sep 17 00:00:00 2001 From: Blake Ridgway Date: Thu, 16 Jul 2026 17:34:03 -0500 Subject: [PATCH] LAND-2: Redesign website overhaul --- static/css/style.css | 1219 ++++++++++++++++++++++++------------- static/js/theme-toggle.js | 61 ++ templates/base.html | 1 + templates/index.html | 146 ++++- 4 files changed, 976 insertions(+), 451 deletions(-) create mode 100644 static/js/theme-toggle.js diff --git a/static/css/style.css b/static/css/style.css index fa3082a..0ab599a 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -1,67 +1,152 @@ +/* ═══════════════════════════════════════════════ + Arcline Project — Fedora-inspired Stylesheet + ═══════════════════════════════════════════════ */ +/* ── Reset ── */ *, *::before, -*::after { box-sizing: border-box; margin: 0; padding: 0; } - -:root { - --bg: #0d0e10; - --bg-raised: #15171b; - --bg-card: #1a1c22; - --bg-card-hover: #1f2128; - --border: hsl(225 7% 18%); - --border-hover: hsl(225 8% 26%); - --text: hsl(223 8% 88%); - --text-soft: hsl(223 6% 65%); - --text-faint: hsl(223 5% 41%); - --accent: #0acf97; - --accent-dim: hsl(162 88% 33%); - --accent-bg: hsla(162 88% 43% / 0.09); - --accent-border: hsla(162 88% 43% / 0.18); - --amber: #f09d51; - --amber-bg: hsla(28 84% 63% / 0.07); - --mono: "JetBrains Mono", "Fira Code", "SF Mono", "Cascadia Code", monospace; - --sans: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; - --pad-card: 22px; - --w-main: 1040px; - --w-narrow: 680px; +*::after { + box-sizing: border-box; + margin: 0; + padding: 0; } -html { scroll-behavior: smooth; } +/* ── Design Tokens ── */ +/* Dark mode is the default */ +:root { + /* Colors */ + --color-bg: #0d1117; + --color-bg-alt: #161b22; + --color-bg-card: #161b22; + --color-bg-card-hover: #1c2333; + --color-bg-dark: #0b0c0e; + + --color-border: #30363d; + --color-border-hover: #484f58; + --color-border-light: #21262d; + + --color-text: #e6edf3; + --color-text-soft: #8b949e; + --color-text-faint: #6e7681; + --color-text-inverse: #e6edf3; + + --color-accent: #0acf97; + --color-accent-dim: hsl(162 88% 43%); + --color-accent-bg: hsla(162 88% 43% / 0.10); + --color-accent-border: hsla(162 88% 43% / 0.22); + + --color-cta-text: #0b0c0e; + + --color-nav-bg: rgba(13, 17, 23, 0.92); + --color-hero-gradient: linear-gradient(180deg, #0d1117 0%, #161b22 50%, #0d1117 100%); + + /* Typography */ + --font-sans: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + --font-mono: "JetBrains Mono", "Fira Code", "SF Mono", "Cascadia Code", monospace; + + /* Spacing */ + --w-main: 1120px; + --w-narrow: 720px; + --pad-section: 80px; + --pad-card: 28px; + + /* Radii */ + --radius-sm: 6px; + --radius-md: 10px; + --radius-lg: 14px; + + /* Shadows */ + --shadow-card: 0 1px 3px rgba(0,0,0,0.24), 0 1px 2px rgba(0,0,0,0.16); + --shadow-hover: 0 4px 14px rgba(0,0,0,0.32), 0 2px 4px rgba(0,0,0,0.16); + --shadow-nav: 0 1px 3px rgba(0,0,0,0.24); + + /* Transitions */ + --ease: 0.2s cubic-bezier(0.4, 0, 0.2, 1); +} + +/* Light mode overrides */ +[data-theme="light"] { + --color-bg: #ffffff; + --color-bg-alt: #f5f6f8; + --color-bg-card: #ffffff; + --color-bg-card-hover: #f8f9fb; + + --color-border: #e2e4e8; + --color-border-hover: #c8cad0; + --color-border-light: #eeeff2; + + --color-text: #1a1c22; + --color-text-soft: #4a4e58; + --color-text-faint: #7c808a; + --color-text-inverse: #ffffff; + + --color-accent: #0acf97; + --color-accent-dim: hsl(162 88% 33%); + --color-accent-bg: hsla(162 88% 43% / 0.07); + --color-accent-border: hsla(162 88% 43% / 0.18); + + --color-cta-text: #0d1117; + + --color-nav-bg: rgba(255, 255, 255, 0.92); + --color-hero-gradient: linear-gradient(180deg, #f8f9fb 0%, #ffffff 100%); + + --shadow-card: 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04); + --shadow-hover: 0 4px 14px rgba(0,0,0,0.08), 0 2px 4px rgba(0,0,0,0.04); + --shadow-nav: 0 1px 3px rgba(0,0,0,0.06); +} + +/* ── Base ── */ +html { + scroll-behavior: smooth; + -webkit-text-size-adjust: 100%; +} body { - font-family: var(--sans); - background: var(--bg); - color: var(--text); + font-family: var(--font-sans); + background: var(--color-bg); + color: var(--color-text); line-height: 1.65; -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } -body::after { - content: ""; - position: fixed; - inset: 0; - z-index: 9999; - pointer-events: none; - opacity: 0.022; - background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); +/* ── Skip to Content ── */ +.skip-link { + position: absolute; + top: -100%; + left: 16px; + z-index: 1000; + padding: 10px 18px; + background: var(--color-accent); + color: var(--color-cta-text); + font-size: 0.85rem; + font-weight: 600; + text-decoration: none; + border-radius: var(--radius-sm); + transition: top 0.2s; } -/* Nav */ +.skip-link:focus { + top: 8px; +} + +/* ── Navigation ── */ .nav { position: sticky; top: 0; z-index: 100; - background: hsl(225 6% 6% / 0.88); - backdrop-filter: blur(18px); - -webkit-backdrop-filter: blur(18px); - border-bottom: 1px solid var(--border); + background: var(--color-nav-bg); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border-bottom: 1px solid var(--color-border); + box-shadow: var(--shadow-nav); } .nav-inner { max-width: var(--w-main); margin: 0 auto; padding: 0 28px; - height: 58px; + height: 64px; display: flex; align-items: center; justify-content: space-between; @@ -70,106 +155,113 @@ body::after { .logo { display: flex; align-items: center; - gap: 11px; - font-family: var(--mono); + gap: 10px; + font-family: var(--font-mono); font-size: 1.05rem; - font-weight: 600; - color: var(--text); + font-weight: 650; + color: var(--color-text); text-decoration: none; letter-spacing: -0.01em; } -.logo-icon { flex-shrink: 0; } +.logo-icon { + flex-shrink: 0; + border-radius: 4px; +} -.nav nav { display: flex; gap: 2px; } +.nav nav { + display: flex; + gap: 4px; + align-items: center; +} .nav nav a { - color: var(--text-soft); + color: var(--color-text-soft); text-decoration: none; - padding: 7px 14px; - border-radius: 5px; - font-size: 0.825rem; - font-weight: 470; - transition: color 0.18s, background 0.18s; + padding: 8px 16px; + border-radius: var(--radius-sm); + font-size: 0.875rem; + font-weight: 500; + transition: color var(--ease), background var(--ease); } -.nav nav a:hover { - color: var(--text); - background: hsl(225 6% 14%); +.nav nav a:hover, +.nav nav a:focus-visible { + color: var(--color-text); + background: var(--color-bg-alt); } -/* Hero */ +.nav-cta { + background: var(--color-accent) !important; + color: var(--color-cta-text) !important; + font-weight: 600 !important; + margin-left: 8px; +} + +.nav-cta:hover { + background: var(--color-accent-dim) !important; + color: var(--color-cta-text) !important; +} + +/* ── Theme Toggle ── */ +.theme-toggle { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 8px; + border: none; + border-radius: var(--radius-sm); + background: transparent; + color: var(--color-text-soft); + cursor: pointer; + transition: color var(--ease), background var(--ease); + margin-left: 8px; +} + +.theme-toggle:hover { + color: var(--color-text); + background: var(--color-bg-alt); +} + +/* Show the sun icon (toggle to light) in dark mode, moon icon (toggle to dark) in light mode */ +.theme-icon-dark { display: none; } +.theme-icon-light { display: block; } + +[data-theme="light"] .theme-icon-dark { display: block; } +[data-theme="light"] .theme-icon-light { display: none; } + +/* ── Hero ── */ .hero { - padding: 130px 28px 110px; + padding: 90px 28px 70px; text-align: center; - position: relative; - overflow: hidden; -} - -.hero::before { - content: ""; - position: absolute; - top: -40%; - left: 30%; - width: 960px; - height: 960px; - background: radial-gradient(ellipse at center, hsla(162 88% 43% / 0.075) 0%, transparent 60%); - pointer-events: none; -} - -.hero::after { - content: ""; - position: absolute; - inset: 0; - pointer-events: none; - opacity: 0.03; - background: - linear-gradient(25deg, transparent 48%, var(--border) 48%, var(--border) 52%, transparent 52%), - linear-gradient(25deg, transparent 48%, var(--border) 48%, var(--border) 52%, transparent 52%); - background-size: 90px 90px; - background-position: 0 0, 45px 45px; + background: var(--color-hero-gradient); + border-bottom: 1px solid var(--color-border-light); } .hero-inner { max-width: var(--w-narrow); margin: 0 auto; - position: relative; - z-index: 1; -} - -.hero-kicker { - display: inline-block; - font-family: var(--mono); - font-size: 0.72rem; - color: var(--accent); - background: hsla(162 88% 43% / 0.06); - border: 1px solid var(--accent-border); - padding: 5px 14px; - margin-bottom: 32px; -} - -.hero-kicker::before { - content: "$ "; - color: var(--text-faint); } .hero h1 { - font-size: clamp(2.4rem, 6vw, 4rem); + font-size: clamp(2.2rem, 5vw, 3.4rem); font-weight: 750; - letter-spacing: -0.035em; - line-height: 1.08; - margin-bottom: 26px; - color: var(--text); + letter-spacing: -0.03em; + line-height: 1.12; + margin-bottom: 20px; + color: var(--color-text); } -.hero-highlight { color: var(--accent); } +.hero-highlight { + color: var(--color-accent); +} .tagline { - font-size: 1.05rem; - color: var(--text-soft); - margin-bottom: 42px; + font-size: 1.1rem; + color: var(--color-text-soft); + margin-bottom: 36px; line-height: 1.7; - max-width: 520px; + max-width: 530px; margin-left: auto; margin-right: auto; } @@ -184,47 +276,55 @@ body::after { .cta { display: inline-flex; align-items: center; - background: var(--accent); - color: hsl(0 0% 8%); - padding: 13px 30px; - font-size: 0.92rem; + background: var(--color-accent); + color: var(--color-cta-text); + padding: 14px 32px; + font-size: 0.95rem; font-weight: 620; text-decoration: none; - transition: background 0.18s, transform 0.14s; - font-family: var(--mono); + border-radius: var(--radius-sm); + transition: background var(--ease), transform var(--ease), box-shadow var(--ease); + font-family: var(--font-mono); letter-spacing: -0.01em; + box-shadow: 0 2px 8px hsla(162 88% 43% / 0.25); } .cta:hover { - background: var(--accent-dim); - transform: translateY(-1px); + background: var(--color-accent-dim); + transform: translateY(-2px); + box-shadow: 0 4px 16px hsla(162 88% 43% / 0.35); } .cta-secondary { display: inline-flex; align-items: center; - color: var(--text-soft); - padding: 13px 30px; - font-size: 0.92rem; - font-weight: 470; + color: var(--color-text-soft); + padding: 14px 32px; + font-size: 0.95rem; + font-weight: 500; text-decoration: none; - border: 1px solid var(--border); - transition: border-color 0.18s, color 0.18s; + border: 1.5px solid var(--color-border); + border-radius: var(--radius-sm); + transition: border-color var(--ease), color var(--ease), background var(--ease); } .cta-secondary:hover { - border-color: var(--border-hover); - color: var(--text); + border-color: var(--color-border-hover); + color: var(--color-text); + background: var(--color-bg-alt); } -/* Sections */ +/* ── Sections ── */ .section { - padding: 105px 28px; - position: relative; + padding: var(--pad-section) 28px; text-align: center; } -.section-alt { background: var(--bg-raised); } +.section-alt { + background: var(--color-bg-alt); + border-top: 1px solid var(--color-border-light); + border-bottom: 1px solid var(--color-border-light); +} .section-inner { max-width: var(--w-main); @@ -232,153 +332,272 @@ body::after { } .section-label { - display: block; - font-family: var(--mono); - font-size: 0.7rem; - color: var(--accent); + display: inline-block; + font-family: var(--font-mono); + font-size: 0.72rem; + font-weight: 600; + color: var(--color-accent); + text-transform: uppercase; + letter-spacing: 0.08em; margin-bottom: 14px; - text-transform: lowercase; - letter-spacing: 0.04em; + padding: 5px 14px; + background: var(--color-accent-bg); + border-radius: 20px; } -.section-label::before { content: "// "; color: var(--text-faint); } - .section-inner h2 { - font-size: clamp(1.6rem, 3.6vw, 2.35rem); - font-weight: 680; + font-size: clamp(1.6rem, 3.2vw, 2.2rem); + font-weight: 720; margin-bottom: 18px; margin-left: auto; margin-right: auto; letter-spacing: -0.02em; - line-height: 1.22; - color: var(--text); - max-width: 680px; + line-height: 1.25; + color: var(--color-text); + max-width: 640px; } .section-desc { - color: var(--text-soft); - font-size: 1rem; - max-width: 590px; - margin-bottom: 52px; + color: var(--color-text-soft); + font-size: 1.02rem; + max-width: 600px; + margin-bottom: 48px; margin-left: auto; margin-right: auto; line-height: 1.7; } -/* Principles */ +/* ── Edition Cards ── */ +.editions-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); + gap: 20px; + margin-bottom: 32px; +} + +.edition-card { + display: flex; + flex-direction: column; + align-items: center; + background: var(--color-bg-card); + border: 1px solid var(--color-border); + border-radius: var(--radius-lg); + padding: 36px 28px 28px; + box-shadow: var(--shadow-card); + transition: border-color var(--ease), box-shadow var(--ease), transform var(--ease); + text-align: center; +} + +.edition-card:hover { + border-color: var(--color-accent-border); + box-shadow: var(--shadow-hover); + transform: translateY(-2px); +} + +.edition-icon { + width: 64px; + height: 64px; + display: flex; + align-items: center; + justify-content: center; + background: var(--color-accent-bg); + border-radius: var(--radius-md); + margin-bottom: 20px; + color: var(--color-accent); +} + +.edition-card h3 { + font-size: 1.12rem; + font-weight: 680; + margin-bottom: 10px; + color: var(--color-text); + letter-spacing: -0.01em; +} + +.edition-card p { + color: var(--color-text-soft); + font-size: 0.9rem; + line-height: 1.6; + margin-bottom: 22px; + flex: 1; +} + +.edition-card .card-actions { + display: flex; + gap: 10px; + flex-wrap: wrap; + justify-content: center; +} + +.card-btn { + display: inline-flex; + align-items: center; + padding: 9px 22px; + font-size: 0.85rem; + font-weight: 600; + text-decoration: none; + border-radius: var(--radius-sm); + transition: background var(--ease), color var(--ease), border-color var(--ease); + font-family: var(--font-mono); + letter-spacing: -0.01em; +} + +.card-btn-primary { + background: var(--color-accent); + color: var(--color-cta-text); +} + +.card-btn-primary:hover { + background: var(--color-accent-dim); +} + +.card-btn-secondary { + color: var(--color-text-soft); + border: 1.5px solid var(--color-border); + background: transparent; +} + +.card-btn-secondary:hover { + border-color: var(--color-border-hover); + color: var(--color-text); + background: var(--color-bg-alt); +} + +/* ── Feature Grid ── */ +.features-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); + gap: 16px; +} + +.feature-card { + display: flex; + flex-direction: column; + align-items: flex-start; + background: var(--color-bg-card); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); + padding: 24px; + text-decoration: none; + box-shadow: var(--shadow-card); + transition: border-color var(--ease), box-shadow var(--ease); + text-align: left; +} + +.feature-card:hover { + border-color: var(--color-accent-border); + box-shadow: var(--shadow-hover); +} + +.feature-card h4 { + font-size: 0.94rem; + font-weight: 650; + color: var(--color-text); + margin-bottom: 6px; + letter-spacing: -0.01em; +} + +.feature-card p { + font-size: 0.84rem; + color: var(--color-text-soft); + line-height: 1.55; +} + +/* ── Principles Grid ── */ .principles-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(302px, 1fr)); - gap: 10px; + grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); + gap: 16px; } .principle { display: flex; - gap: 17px; - background: var(--bg-card); - border: 1px solid var(--border); + gap: 18px; + background: var(--color-bg-card); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); padding: var(--pad-card); - transition: border-color 0.22s; - position: relative; - overflow: hidden; + box-shadow: var(--shadow-card); + transition: border-color var(--ease), box-shadow var(--ease); + text-align: left; } -.principle::after { - content: ""; - position: absolute; - inset: -1px; - background: var(--accent-bg); - opacity: 0; - transition: opacity 0.25s; - pointer-events: none; +.principle:hover { + border-color: var(--color-accent-border); + box-shadow: var(--shadow-hover); } -.principle:hover { border-color: var(--accent-border); } -.principle:hover::after { opacity: 1; } - .principle-icon { flex-shrink: 0; - width: 38px; - height: 38px; + width: 42px; + height: 42px; display: flex; align-items: center; justify-content: center; - color: var(--accent); + background: var(--color-accent-bg); + color: var(--color-accent); + border-radius: var(--radius-sm); margin-top: 2px; } .principle h3 { - font-family: var(--mono); - font-size: 0.83rem; - font-weight: 620; - margin-bottom: 4px; - color: var(--text); + font-family: var(--font-mono); + font-size: 0.86rem; + font-weight: 640; + margin-bottom: 5px; + color: var(--color-text); letter-spacing: -0.01em; } .principle p { - color: var(--text-soft); - font-size: 0.845rem; + color: var(--color-text-soft); + font-size: 0.86rem; line-height: 1.6; } -/* Stack Grid */ +/* ── Stack Grid ── */ .stack-grid { display: grid; grid-template-columns: repeat(4, 1fr); - gap: 10px; + gap: 16px; } .stack-card { - background: var(--bg-card); - border: 1px solid var(--border); + background: var(--color-bg-card); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); overflow: hidden; - transition: border-color 0.22s; - position: relative; + box-shadow: var(--shadow-card); + transition: border-color var(--ease), box-shadow var(--ease); + text-align: left; } -.stack-card::before { - content: ""; - position: absolute; - top: 0; left: 0; bottom: 0; - width: 3px; - transition: width 0.2s; +.stack-card:hover { + border-color: var(--color-accent-border); + box-shadow: var(--shadow-hover); } -.stack-card:nth-child(1)::before { background: var(--accent); } -.stack-card:nth-child(2)::before { background: hsl(280 45% 55%); } -.stack-card:nth-child(3)::before { background: hsl(200 60% 52%); } -.stack-card:nth-child(4)::before { background: var(--amber); } - -.stack-card:hover { border-color: var(--border-hover); } -.stack-card:hover::before { width: 5px; } - .stack-header { - font-family: var(--mono); + font-family: var(--font-mono); font-size: 0.7rem; font-weight: 650; - text-transform: lowercase; - letter-spacing: 0.05em; - padding: 20px 22px 10px 22px; - color: var(--text-faint); + text-transform: uppercase; + letter-spacing: 0.06em; + padding: 22px 24px 10px 24px; + color: var(--color-accent); } -.stack-card:nth-child(1) .stack-header { color: var(--accent); } -.stack-card:nth-child(2) .stack-header { color: hsl(280 45% 65%); } -.stack-card:nth-child(3) .stack-header { color: hsl(200 60% 58%); } -.stack-card:nth-child(4) .stack-header { color: var(--amber); } - .stack-card ul { list-style: none; - padding: 0 22px 22px 22px; + padding: 0 24px 24px 24px; margin: 0; } .stack-card li { position: relative; - padding: 6px 0 6px 16px; - color: var(--text-soft); - font-size: 0.83rem; + padding: 7px 0 7px 18px; + color: var(--color-text-soft); + font-size: 0.84rem; line-height: 1.5; } @@ -386,249 +605,275 @@ body::after { content: ""; position: absolute; left: 0; - top: 12px; + top: 13px; width: 5px; height: 5px; + border-radius: 50%; + background: var(--color-accent); + opacity: 0.5; } -.stack-card:nth-child(1) li::before { background: var(--accent); opacity: 0.55; } -.stack-card:nth-child(2) li::before { background: hsl(280 45% 55%); opacity: 0.55; } -.stack-card:nth-child(3) li::before { background: hsl(200 60% 52%); opacity: 0.55; } -.stack-card:nth-child(4) li::before { background: var(--amber); opacity: 0.55; } - /* Edition Teaser */ .edition-teaser { - margin-top: 30px; - padding: 20px 24px; - border: 1px dashed var(--accent-border); - background: hsla(162 88% 43% / 0.04); - position: relative; + margin-top: 24px; + padding: 20px 28px; + border: 1px dashed var(--color-accent-border); + border-radius: var(--radius-md); + background: var(--color-accent-bg); + text-align: left; } .edition-teaser-badge { display: inline-block; - font-family: var(--mono); - font-size: 0.64rem; - color: var(--accent-dim); + font-family: var(--font-mono); + font-size: 0.66rem; + font-weight: 600; + color: var(--color-accent-dim); margin-bottom: 8px; + text-transform: uppercase; + letter-spacing: 0.04em; } .edition-teaser p { - color: var(--text-soft); - font-size: 0.88rem; + color: var(--color-text-soft); + font-size: 0.9rem; line-height: 1.7; max-width: 700px; - margin-left: auto; - margin-right: auto; } -.edition-teaser strong { color: var(--text); font-weight: 660; } +.edition-teaser strong { + color: var(--color-text); + font-weight: 660; +} -/* Tool Grid */ +/* ── Tool Grid ── */ .tool-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(296px, 1fr)); - gap: 8px; + grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); + gap: 12px; } .tool { display: flex; flex-direction: column; - gap: 5px; - background: var(--bg-card); - border: 0 solid var(--accent-border); - border-left-width: 2px; - padding: 19px 22px; - transition: border-color 0.2s, background 0.18s, border-left-width 0.2s; + gap: 6px; + background: var(--color-bg-card); + border: 1px solid var(--color-border); + border-radius: var(--radius-sm); + padding: 20px 24px; + text-align: left; + transition: border-color var(--ease), box-shadow var(--ease); } .tool:hover { - border-left-width: 4px; - border-left-color: var(--accent); - background: var(--bg-card-hover); + border-color: var(--color-accent-border); + box-shadow: var(--shadow-card); } .tool code { - font-family: var(--mono); - font-size: 0.82rem; - font-weight: 580; - color: var(--accent); + font-family: var(--font-mono); + font-size: 0.84rem; + font-weight: 600; + color: var(--color-accent-dim); letter-spacing: -0.01em; } .tool span { - color: var(--text-soft); - font-size: 0.81rem; + color: var(--color-text-soft); + font-size: 0.83rem; line-height: 1.55; } -/* Compare Grid */ +/* ── Compare Grid ── */ .compare-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); - gap: 10px; + grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); + gap: 14px; } .compare-card { - background: var(--bg-card); - border: 1px solid var(--border); - padding: 26px 22px; - transition: border-color 0.22s, background 0.2s; + background: var(--color-bg-card); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); + padding: 28px 24px; + text-align: left; + box-shadow: var(--shadow-card); + transition: border-color var(--ease), box-shadow var(--ease); } -.compare-card:hover { border-color: var(--border-hover); } +.compare-card:hover { + border-color: var(--color-accent-border); + box-shadow: var(--shadow-hover); +} .compare-highlight { - border-color: var(--accent-border); - background: linear-gradient(155deg, var(--bg-card) 0%, hsla(162 88% 43% / 0.06) 100%); + border-color: var(--color-accent-border); + border-width: 2px; + background: linear-gradient(160deg, var(--color-bg-card) 0%, var(--color-accent-bg) 100%); } .compare-label { - font-family: var(--mono); - font-size: 0.72rem; - font-weight: 620; - text-transform: lowercase; - letter-spacing: 0.02em; + font-family: var(--font-mono); + font-size: 0.74rem; + font-weight: 630; + text-transform: uppercase; + letter-spacing: 0.04em; margin-bottom: 10px; - color: var(--text-faint); + color: var(--color-text-faint); } -.compare-highlight .compare-label { color: var(--accent); } +.compare-highlight .compare-label { + color: var(--color-accent); +} .compare-desc { - color: var(--text-soft); - font-size: 0.88rem; + color: var(--color-text-soft); + font-size: 0.89rem; line-height: 1.6; } -/* Contribute Grid */ +/* ── Contribute Grid ── */ .contribute-grid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); - gap: 10px; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: 16px; } .contribute-card { display: flex; flex-direction: column; - gap: 10px; - background: var(--bg-card); - border: 1px solid var(--border); - padding: 28px 22px; - color: var(--text); + gap: 12px; + background: var(--color-bg-card); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); + padding: 28px 24px; + color: var(--color-text); text-decoration: none; - transition: border-color 0.22s, background 0.2s; + box-shadow: var(--shadow-card); + transition: border-color var(--ease), box-shadow var(--ease), transform var(--ease); + text-align: left; position: relative; } +.contribute-card:hover { + border-color: var(--color-accent-border); + box-shadow: var(--shadow-hover); + transform: translateY(-2px); +} + .contribute-card::after { content: " →"; position: absolute; - right: 22px; + right: 24px; top: 28px; - font-family: var(--mono); - color: var(--accent); + font-family: var(--font-mono); + color: var(--color-accent); opacity: 0; transform: translateX(-8px); - transition: opacity 0.2s, transform 0.2s; + transition: opacity var(--ease), transform var(--ease); } -.contribute-card:hover { border-color: var(--accent-border); } -.contribute-card:hover::after { opacity: 1; transform: translateX(0); } +.contribute-card:hover::after { + opacity: 1; + transform: translateX(0); +} .contribute-card span { - font-size: 0.96rem; - font-weight: 640; + font-size: 0.98rem; + font-weight: 650; letter-spacing: -0.01em; } .contribute-card small { - color: var(--text-soft); - font-size: 0.82rem; + color: var(--color-text-soft); + font-size: 0.84rem; line-height: 1.5; } .contribute-icon { - width: 34px; - height: 34px; + width: 36px; + height: 36px; display: flex; align-items: center; justify-content: center; - background: hsla(162 88% 43% / 0.07); - color: var(--accent); + background: var(--color-accent-bg); + color: var(--color-accent); + border-radius: var(--radius-sm); margin-bottom: 2px; } -/* Inline Link */ +/* ── Inline Link ── */ .inline-link { - color: var(--accent); + color: var(--color-accent-dim); text-decoration: none; - border-bottom: 1px solid var(--accent-border); + border-bottom: 1.5px solid var(--color-accent-border); padding-bottom: 1px; - transition: border-color 0.18s; + transition: border-color var(--ease), color var(--ease); } -.inline-link:hover { border-bottom-color: var(--accent); } +.inline-link:hover { + border-bottom-color: var(--color-accent); + color: var(--color-accent-dim); +} -/* Sponsor */ -.sponsor-section .section-inner { text-align: left; } +/* ── Sponsor ── */ +.sponsor-section .section-inner { + text-align: left; +} .sponsor-content { display: flex; flex-direction: column; gap: 22px; - max-width: 620px; + max-width: 640px; } .sponsor-desc { - max-width: 600px; - color: var(--text-soft); - font-size: 0.94rem; + color: var(--color-text-soft); + font-size: 0.95rem; line-height: 1.7; } -.sponsor-desc strong { color: var(--text); font-weight: 660; } - -.sponsor-tagline { - font-family: var(--mono); - font-size: 0.78rem; - color: var(--text-faint); - padding: 8px 0; +.sponsor-desc strong { + color: var(--color-text); + font-weight: 660; } -.sponsor-tagline::before { content: "# "; color: var(--border-hover); } +.sponsor-tagline { + font-family: var(--font-mono); + font-size: 0.8rem; + color: var(--color-text-faint); + padding: 8px 0; + border-left: 3px solid var(--color-accent); + padding-left: 14px; +} -/* Waitlist */ +/* ── Waitlist Form ── */ .waitlist-form { display: flex; flex-direction: column; - gap: 18px; - margin-top: 6px; + gap: 16px; max-width: 480px; - margin-left: auto; - margin-right: auto; + margin: 0 auto; } -.waitlist-form .input, -.waitlist-form .btn { - width: 100%; -} - -/* Edition Checkboxes */ .edition-checkboxes { border: none; padding: 0; display: flex; - gap: 22px; + gap: 24px; + justify-content: center; } .edition-checkboxes legend { - font-size: 0.83rem; - color: var(--text-soft); + font-size: 0.85rem; + font-weight: 500; + color: var(--color-text-soft); margin-bottom: 10px; padding: 0; float: left; width: 100%; + text-align: center; } .edition-checkbox { @@ -636,185 +881,303 @@ body::after { align-items: center; gap: 8px; cursor: pointer; - font-size: 0.88rem; - color: var(--text-soft); + font-size: 0.9rem; + color: var(--color-text-soft); user-select: none; - transition: color 0.18s; + transition: color var(--ease); } -.edition-checkbox:hover { color: var(--text); } +.edition-checkbox:hover { + color: var(--color-text); +} .edition-checkbox input[type="checkbox"] { appearance: none; -webkit-appearance: none; - width: 18px; - height: 18px; - border: 2px solid var(--border); - background: var(--bg-card); + width: 20px; + height: 20px; + border: 2px solid var(--color-border); + border-radius: 4px; + background: var(--color-bg); cursor: pointer; position: relative; flex-shrink: 0; - transition: border-color 0.18s, background 0.18s; + transition: border-color var(--ease), background var(--ease); } .edition-checkbox input[type="checkbox"]:checked { - border-color: var(--accent); - background: var(--accent); + border-color: var(--color-accent); + background: var(--color-accent); } .edition-checkbox input[type="checkbox"]:checked::after { content: ""; position: absolute; - left: 4px; + left: 5px; top: 2px; width: 5px; - height: 9px; - border: solid hsl(0 0% 8%); + height: 10px; + border: solid var(--color-cta-text); border-width: 0 2px 2px 0; transform: rotate(45deg); } -/* Waitlist Form Row */ -.waitlist-row { - display: flex; - gap: 11px; -} - .input { padding: 13px 18px; - border: 1px solid var(--border); - border-radius: 3px; - background: var(--bg-card); - color: var(--text); - font-size: 0.9rem; - min-width: 310px; + border: 1.5px solid var(--color-border); + border-radius: var(--radius-sm); + background: var(--color-bg); + color: var(--color-text); + font-size: 0.92rem; outline: none; - transition: border-color 0.18s, box-shadow 0.18s; - font-family: var(--mono); + transition: border-color var(--ease), box-shadow var(--ease); + font-family: var(--font-mono); } -.input::placeholder { color: var(--text-faint); font-family: var(--mono); } +.input::placeholder { + color: var(--color-text-faint); + font-family: var(--font-mono); +} .input:focus { - border-color: var(--accent); - box-shadow: 0 0 0 3px var(--accent-bg); + border-color: var(--color-accent); + box-shadow: 0 0 0 3px var(--color-accent-bg); } .btn { padding: 13px 30px; border: none; - border-radius: 3px; - background: var(--accent); - color: hsl(0 0% 8%); - font-size: 0.9rem; + border-radius: var(--radius-sm); + background: var(--color-accent); + color: var(--color-cta-text); + font-size: 0.92rem; font-weight: 620; cursor: pointer; - transition: background 0.18s; - font-family: var(--mono); + transition: background var(--ease), transform var(--ease); + font-family: var(--font-mono); letter-spacing: -0.01em; } -.btn:hover { background: var(--accent-dim); } +.btn:hover { + background: var(--color-accent-dim); + transform: translateY(-1px); +} .confirmation { margin-top: 18px; - padding: 12px 20px; - color: var(--accent); - background: var(--accent-bg); - border: 1px solid var(--accent-border); + padding: 14px 22px; + color: var(--color-accent-dim); + background: var(--color-accent-bg); + border: 1px solid var(--color-accent-border); + border-radius: var(--radius-sm); font-weight: 520; - font-size: 0.88rem; + font-size: 0.9rem; display: inline-block; - font-family: var(--mono); + font-family: var(--font-mono); } .waitlist-note { - margin-top: 22px; - font-size: 0.8rem; - color: var(--text-faint); + margin-top: 20px; + font-size: 0.82rem; + color: var(--color-text-faint); } -/* Footer */ +/* ── Footer ── */ .footer { - padding: 44px 28px 30px; - border-top: 1px solid var(--border); + background: var(--color-bg-dark); + color: var(--color-text-inverse); + padding: 56px 28px 32px; } -.footer-inner { +.footer-grid { max-width: var(--w-main); - margin: 0 auto; - display: flex; - justify-content: space-between; - align-items: flex-start; - flex-wrap: wrap; - gap: 22px; + margin: 0 auto 36px; + display: grid; + grid-template-columns: 2fr 1fr 1fr 1fr; + gap: 40px; } -.footer-brand p { - color: var(--text-soft); - font-size: 0.84rem; - margin-top: 5px; +.footer-col h4 { + font-family: var(--font-mono); + font-size: 0.7rem; + font-weight: 650; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--color-accent); + margin-bottom: 16px; +} + +.footer-col p { + color: hsla(0 0% 100% / 0.6); + font-size: 0.88rem; + line-height: 1.7; +} + +.footer-col ul { + list-style: none; + padding: 0; + margin: 0; +} + +.footer-col li { + margin-bottom: 8px; +} + +.footer-col a { + color: hsla(0 0% 100% / 0.55); + text-decoration: none; + font-size: 0.87rem; + transition: color var(--ease); +} + +.footer-col a:hover { + color: var(--color-accent); } .footer-logo { - font-family: var(--mono); - font-size: 1rem; - font-weight: 620; - color: var(--text); + font-family: var(--font-mono); + font-size: 1.1rem; + font-weight: 650; + color: #ffffff; text-decoration: none; + letter-spacing: -0.01em; + display: inline-block; + margin-bottom: 10px; } -.footer-links { display: flex; gap: 22px; } - -.footer-links a { - color: var(--text-soft); - text-decoration: none; - font-size: 0.84rem; - transition: color 0.18s; -} - -.footer-links a:hover { color: var(--text); } - .footer-bottom { max-width: var(--w-main); - margin: 28px auto 0; - padding-top: 18px; - border-top: 1px solid var(--border); - text-align: left; + margin: 0 auto; + padding-top: 24px; + border-top: 1px solid hsla(0 0% 100% / 0.08); + text-align: center; } .footer-bottom p { - font-family: var(--mono); - color: var(--text-faint); - font-size: 0.74rem; + font-family: var(--font-mono); + color: hsla(0 0% 100% / 0.3); + font-size: 0.76rem; } -/* Responsive */ +/* ── Responsive ── */ @media (max-width: 920px) { - .stack-grid { grid-template-columns: repeat(2, 1fr); } + .stack-grid { + grid-template-columns: repeat(2, 1fr); + } + + .footer-grid { + grid-template-columns: 1fr 1fr; + gap: 32px; + } + + .footer-col:first-child { + grid-column: 1 / -1; + } } @media (max-width: 768px) { - .hero { padding: 90px 22px 72px; } - .section { padding: 68px 22px; } - .hero-actions { flex-direction: column; align-items: stretch; } - .cta, .cta-secondary { justify-content: center; text-align: center; } - .principles-grid { grid-template-columns: 1fr; } - .tool-grid { grid-template-columns: 1fr; } + :root { + --pad-section: 56px; + } + + .hero { + padding: 60px 22px 50px; + } + + .section { + padding: var(--pad-section) 22px; + } + + .hero-actions { + flex-direction: column; + align-items: stretch; + } + + .cta, + .cta-secondary { + justify-content: center; + text-align: center; + } + + .nav nav { + gap: 0; + } + + .nav nav a { + padding: 6px 10px; + font-size: 0.8rem; + } + + .principles-grid { + grid-template-columns: 1fr; + } + + .tool-grid { + grid-template-columns: 1fr; + } + + .editions-grid { + grid-template-columns: 1fr; + } + + .features-grid { + grid-template-columns: repeat(2, 1fr); + } } @media (max-width: 580px) { - .hero { padding: 62px 18px 50px; } - .hero h1 { font-size: 1.85rem; } - .section { padding: 50px 18px; } - .section-inner h2 { font-size: 1.4rem; } - .nav nav a { padding: 7px 9px; font-size: 0.76rem; } - .input { min-width: 100%; } - .btn { width: 100%; } - .stack-grid { grid-template-columns: 1fr; } - .compare-grid { grid-template-columns: 1fr; } - .contribute-grid { grid-template-columns: 1fr; } - .footer-inner { flex-direction: column; } + .hero { + padding: 44px 18px 36px; + } + + .hero h1 { + font-size: 1.75rem; + } + + .section { + padding: 42px 18px; + } + + .section-inner h2 { + font-size: 1.35rem; + } + + .nav-inner { + padding: 0 14px; + } + + .nav nav a { + padding: 6px 7px; + font-size: 0.74rem; + } + + .input { + min-width: 100%; + } + + .btn { + width: 100%; + } + + .stack-grid { + grid-template-columns: 1fr; + } + + .compare-grid { + grid-template-columns: 1fr; + } + + .contribute-grid { + grid-template-columns: 1fr; + } + + .features-grid { + grid-template-columns: 1fr; + } + + .footer-grid { + grid-template-columns: 1fr; + gap: 28px; + } } - diff --git a/static/js/theme-toggle.js b/static/js/theme-toggle.js new file mode 100644 index 0000000..99ed71e --- /dev/null +++ b/static/js/theme-toggle.js @@ -0,0 +1,61 @@ +// ── Theme Toggle ── +// Dark mode is the default. No data-theme attribute means dark mode. +// Light mode is [data-theme="light"]. + +(function () { + const STORAGE_KEY = "arcline-theme"; + const LIGHT = "light"; + const DARK = "dark"; + + function applyTheme(theme) { + if (theme === LIGHT) { + document.documentElement.setAttribute("data-theme", LIGHT); + } else { + document.documentElement.removeAttribute("data-theme"); + } + } + + // Read saved preference, default to dark + function getSavedTheme() { + try { + const stored = localStorage.getItem(STORAGE_KEY); + if (stored === LIGHT || stored === DARK) return stored; + } catch (_) { + // localStorage unavailable — ignore + } + return DARK; + } + + function saveTheme(theme) { + try { + localStorage.setItem(STORAGE_KEY, theme); + } catch (_) { + // localStorage unavailable — ignore + } + } + + // Apply the saved theme immediately (before page render) + const current = getSavedTheme(); + applyTheme(current); + + // Wire up toggle button(s) once the DOM is ready + function initToggle() { + const buttons = document.querySelectorAll("[data-theme-toggle]"); + buttons.forEach(function (btn) { + btn.addEventListener("click", function () { + const next = document.documentElement.hasAttribute("data-theme") + ? DARK + : LIGHT; + applyTheme(next); + saveTheme(next); + }); + }); + } + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", initToggle); + } else { + initToggle(); + } +})(); + diff --git a/templates/base.html b/templates/base.html index acfc256..54e4972 100644 --- a/templates/base.html +++ b/templates/base.html @@ -11,6 +11,7 @@ + {{template "content" .}} diff --git a/templates/index.html b/templates/index.html index b2b79f6..74a71f6 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,4 +1,6 @@ {{define "content"}} + + -
+
+
@@ -37,10 +63,71 @@
+ +
+
+ +

Our flagship Arcline OS variants
for different use cases.

+

+ Pick the edition that matches your workload. All share the same + hardened Debian base and zero-telemetry guarantee. +

+
+
+
+ + + + +
+

Arcline Server

+

A hardened, production-ready server OS with built-in observability and zero telemetry. Run applications on bare metal or the cloud.

+ +
+ +
+
+ + + + + +
+

Arcline Workstation

+

Same hardened base, with a lightweight KDE Plasma desktop, pre-configured dev toolchains, and privacy-hardened browser profiles.

+ +
+ +
+
+ + + + + + +
+

Arcline Cloud

+

Minimal base images optimized for cloud infrastructures. Ready for AWS, GCP, Azure, or your own private cloud.

+ +
+
+
+
+
- +

A Debian-derived OS that doesn't
make you start from scratch.

Debian gives you a rock-solid base. Arcline OS hardens it, layers on a @@ -132,7 +219,7 @@

- +

Production-ready from first boot.

Arcline OS layers pre-configured infrastructure tooling on top of a hardened @@ -179,21 +266,13 @@

-
-
// arcline workstation — in development
-

- Arcline Workstation — same hardened base, with a lightweight KDE Plasma desktop, - pre-configured dev toolchains, and privacy-hardened browser profiles. - One ISO. Two targets. Pick yours at install time. -

-
- +

11 Go tools. Built in production.
Yours to use.

Every Arcline tool was built to solve real infrastructure problems. @@ -251,7 +330,7 @@

- +

No major Linux distro ships
pre-hardened for production.

Debian gives you the packages. Arcline OS assembles them into a finished @@ -283,7 +362,7 @@

- +

Built in the open. Shaped by the
people who use it.

Arcline OS is open-source under the GPL. The code lives on @@ -329,7 +408,7 @@

- +

Arcline OS is in active development.
Be there at the start.

We're packaging the tools, building the ISO pipeline, and hardening the defaults. @@ -369,7 +448,7 @@

+