mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-07-26 12:08:15 +00:00
fix(website): mobile comparison cards, hamburger nav, hero symmetry & reveal fallback
- Comparison table: stack into per-feature cards on phones (no more horizontal scroll); bring feature descriptions back - Re-enable mobile hamburger menu (was hidden via display:none !important); keep logo/language/button uncrowded down to ~320px - Fix hero asymmetry: extension mockup forced the grid column wider than the container; make it width:100%/max-width:320px and use minmax(0,1fr) - Add IntersectionObserver guards + <noscript> fallback so reveal-animated content never stays hidden Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+29
-21
@@ -19,31 +19,39 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
// Scroll Reveal Logic (IntersectionObserver for performance)
|
||||
const revealElements = document.querySelectorAll('[data-reveal]');
|
||||
|
||||
const revealObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('revealed');
|
||||
revealObserver.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, {
|
||||
rootMargin: '0px 0px -150px 0px',
|
||||
threshold: 0.1
|
||||
});
|
||||
|
||||
revealElements.forEach(el => revealObserver.observe(el));
|
||||
if ('IntersectionObserver' in window) {
|
||||
const revealObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('revealed');
|
||||
revealObserver.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, {
|
||||
rootMargin: '0px 0px -150px 0px',
|
||||
threshold: 0.1
|
||||
});
|
||||
|
||||
revealElements.forEach(el => revealObserver.observe(el));
|
||||
} else {
|
||||
// Fallback: without IntersectionObserver support, reveal everything
|
||||
// immediately so no content can ever stay hidden.
|
||||
revealElements.forEach(el => el.classList.add('revealed'));
|
||||
}
|
||||
|
||||
// Auto-update URL hash as user scrolls through sections
|
||||
// (preserves position across language switches)
|
||||
const sectionObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
history.replaceState(null, null, '#' + entry.target.id);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.3 });
|
||||
document.querySelectorAll('section[id], header[id]').forEach(el => sectionObserver.observe(el));
|
||||
if ('IntersectionObserver' in window) {
|
||||
const sectionObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
history.replaceState(null, null, '#' + entry.target.id);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.3 });
|
||||
document.querySelectorAll('section[id], header[id]').forEach(el => sectionObserver.observe(el));
|
||||
}
|
||||
|
||||
// Navbar scroll effect
|
||||
const nav = document.querySelector('nav');
|
||||
|
||||
+123
-5
@@ -358,7 +358,8 @@ nav {
|
||||
}
|
||||
|
||||
.extension-mockup {
|
||||
width: 320px;
|
||||
width: 100%;
|
||||
max-width: 320px;
|
||||
height: 520px;
|
||||
background: #0f172a;
|
||||
border-radius: 20px;
|
||||
@@ -1900,7 +1901,7 @@ footer {
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.hero-grid, .step {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
text-align: center;
|
||||
}
|
||||
.hero-text h1 {
|
||||
@@ -1931,7 +1932,7 @@ footer {
|
||||
margin-left: auto;
|
||||
}
|
||||
.hamburger {
|
||||
display: none !important;
|
||||
display: inline-flex !important;
|
||||
}
|
||||
nav .container {
|
||||
padding: 0 0.5rem;
|
||||
@@ -1966,6 +1967,21 @@ footer {
|
||||
}
|
||||
}
|
||||
|
||||
/* Extra-narrow phones: make sure logo, language picker and the menu button
|
||||
never crowd each other in the header (kept comfortable down to ~320px). */
|
||||
@media (max-width: 380px) {
|
||||
nav .container {
|
||||
padding: 0 0.4rem;
|
||||
}
|
||||
.nav-right {
|
||||
gap: 0.35rem;
|
||||
}
|
||||
.logo-area {
|
||||
font-size: 1rem;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- Language Toggle --- */
|
||||
html.lang-de [lang="en"] {
|
||||
display: none !important;
|
||||
@@ -2450,13 +2466,115 @@ html:not(.lang-de) [lang="de"] {
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.comparison-table th,
|
||||
.comparison-table th,
|
||||
.comparison-table td {
|
||||
padding: 1rem;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* On phones the 3-column table is turned into stacked cards so there is
|
||||
no horizontal scrolling — one card per feature, KoalaSync above Teleparty. */
|
||||
@media (max-width: 600px) {
|
||||
.comparison-table-wrapper {
|
||||
overflow-x: visible;
|
||||
background: transparent;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.comparison-table {
|
||||
display: block;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
/* Visually hide the header row but keep it for screen readers. */
|
||||
.comparison-table thead {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.comparison-table tbody,
|
||||
.comparison-table tr,
|
||||
.comparison-table td {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.comparison-table tbody tr {
|
||||
background: rgba(30, 41, 59, 0.35);
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: 14px;
|
||||
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
|
||||
margin-bottom: 1rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.comparison-table tbody tr:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.comparison-table td {
|
||||
padding: 0.85rem 1.1rem;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
.comparison-table tbody tr td:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Feature name acts as the card header. */
|
||||
.comparison-table td.feat-name {
|
||||
background: rgba(15, 23, 42, 0.55);
|
||||
padding: 0.9rem 1.1rem;
|
||||
}
|
||||
|
||||
/* Room is back on the card, so show the description again. */
|
||||
.feat-desc {
|
||||
display: none;
|
||||
display: block;
|
||||
margin-top: 0.15rem;
|
||||
}
|
||||
|
||||
/* Label each value cell with the product it belongs to. */
|
||||
.comparison-table td.check,
|
||||
.comparison-table td.cross {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.comparison-table td.check::before,
|
||||
.comparison-table td.cross::before {
|
||||
flex: 0 0 5.5rem;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--text-muted);
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.comparison-table td.check::before {
|
||||
content: "KoalaSync";
|
||||
}
|
||||
|
||||
.comparison-table td.cross::before {
|
||||
content: "Teleparty";
|
||||
}
|
||||
|
||||
/* Keep the KoalaSync row subtly highlighted, like on desktop. */
|
||||
.comparison-table td.check.highlight {
|
||||
background: rgba(99, 102, 241, 0.08);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -183,6 +183,13 @@
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<noscript>
|
||||
<!-- Without JS the scroll-reveal observer never runs, so make all
|
||||
reveal-animated content visible by default. -->
|
||||
<style>
|
||||
[data-reveal] { opacity: 1 !important; transform: none !important; }
|
||||
</style>
|
||||
</noscript>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user