landing: full mobile responsiveness pass
- Sticky first table column (feature names stay visible while scrolling horizontally)
with opaque background to properly cover scrolled content
- body: align-items flex-start on mobile to prevent vertical clipping
- ≤540px breakpoint: reduced logo, h1, padding, table font/cell sizes,
homeserver code word-break, client card tags stack vertically
- ≤380px breakpoint: further compression for very small phones
- Swipe hint ("← swipe to compare →") shown on touch devices above table,
auto-hides after first scroll via JS
- Privacy strip stacks vertically on small screens
- Footer/legal tighter spacing on mobile
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -411,13 +411,96 @@
|
||||
.footer a { color: #444; transition: color 0.2s; }
|
||||
.footer a:hover { color: #777; }
|
||||
|
||||
/* ─── Responsive ─── */
|
||||
@media (max-width: 600px) {
|
||||
.logo { width: 110px; height: 110px; }
|
||||
h1 { font-size: 1.5rem; }
|
||||
.card { padding: 24px 18px; }
|
||||
/* ─── Sticky first table column (all screen sizes) ─── */
|
||||
td:first-child {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
background: #0d0d0d;
|
||||
}
|
||||
th:first-child {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
background: #111;
|
||||
}
|
||||
tr.section-header td {
|
||||
/* section headers span full width — override sticky bg */
|
||||
position: static;
|
||||
background: rgba(152,0,0,0.06);
|
||||
}
|
||||
|
||||
/* Scroll hint — visible only on mobile via JS class */
|
||||
.scroll-hint {
|
||||
display: none;
|
||||
font-size: 0.72rem;
|
||||
color: #3a3a3a;
|
||||
padding: 0 16px 10px;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
/* ─── Tablet (≤ 700px) ─── */
|
||||
@media (max-width: 700px) {
|
||||
body { align-items: flex-start; }
|
||||
}
|
||||
|
||||
/* ─── Mobile (≤ 540px) ─── */
|
||||
@media (max-width: 540px) {
|
||||
body { padding: 20px 12px 40px; }
|
||||
|
||||
.logo { width: 100px; height: 100px; margin-bottom: 20px; }
|
||||
h1 { font-size: 1.5rem; letter-spacing: 0.1em; }
|
||||
.subtitle { font-size: 0.78rem; letter-spacing: 0.18em; margin-bottom: 26px; }
|
||||
|
||||
.card { padding: 22px 16px; }
|
||||
.step-text { font-size: 0.88rem; }
|
||||
.homeserver { font-size: 0.75rem; word-break: break-all; }
|
||||
.or-divider, .option-block { margin-left: 0; }
|
||||
.client-card-top { flex-direction: column; align-items: flex-start; }
|
||||
|
||||
.client-card-top { flex-direction: column; align-items: flex-start; gap: 6px; }
|
||||
.client-card-desc { font-size: 0.79rem; }
|
||||
.client-card-tags { gap: 4px; }
|
||||
|
||||
.also-available { font-size: 0.75rem; }
|
||||
|
||||
/* Table */
|
||||
.scroll-hint { display: block; }
|
||||
table { font-size: 0.71rem; min-width: 520px; }
|
||||
th { padding: 8px 5px; font-size: 0.6rem; }
|
||||
th:first-child { min-width: 100px; padding-left: 10px; }
|
||||
td { padding: 7px 5px; }
|
||||
td:first-child { font-size: 0.71rem; padding-left: 10px; }
|
||||
td small, th small { font-size: 0.58rem; }
|
||||
.yes { font-size: 0.88rem; }
|
||||
.part { font-size: 0.82rem; }
|
||||
.no { font-size: 0.88rem; }
|
||||
.comparison-title { font-size: 0.7rem; padding: 12px 14px 8px; letter-spacing: 0.1em; }
|
||||
.security-note { margin: 10px 12px 4px; font-size: 0.71rem; }
|
||||
.legend { padding: 8px 12px 12px; gap: 12px; font-size: 0.68rem; }
|
||||
|
||||
/* Server info */
|
||||
.server-info-title { font-size: 0.7rem; padding: 12px 14px 8px; }
|
||||
.info-item { padding: 10px 14px; }
|
||||
.info-label { font-size: 0.65rem; }
|
||||
.info-value { font-size: 0.82rem; }
|
||||
.privacy-strip { flex-direction: column; align-items: center; gap: 8px; padding: 10px 14px; }
|
||||
.privacy-badge { font-size: 0.71rem; }
|
||||
|
||||
/* Legal / footer */
|
||||
.legal-note { font-size: 0.72rem; padding: 11px 14px; }
|
||||
.contact { padding: 14px; }
|
||||
.footer { gap: 8px; font-size: 0.68rem; }
|
||||
}
|
||||
|
||||
/* ─── Very small (≤ 380px) ─── */
|
||||
@media (max-width: 380px) {
|
||||
h1 { font-size: 1.3rem; }
|
||||
.logo { width: 84px; height: 84px; }
|
||||
.card { padding: 18px 12px; }
|
||||
table { font-size: 0.66rem; min-width: 480px; }
|
||||
th { font-size: 0.55rem; padding: 7px 4px; }
|
||||
td { padding: 6px 4px; }
|
||||
td:first-child { font-size: 0.66rem; min-width: 90px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -576,6 +659,7 @@
|
||||
<!-- ── Feature Comparison Table ── -->
|
||||
<div class="comparison-section">
|
||||
<p class="comparison-title">Client Feature Comparison — March 2026</p>
|
||||
<p class="scroll-hint" id="scrollHint">← swipe to compare →</p>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
@@ -894,5 +978,17 @@
|
||||
</p>
|
||||
|
||||
</div><!-- container -->
|
||||
<script>
|
||||
// Show scroll hint only on touch devices; hide once table is scrolled
|
||||
if ('ontouchstart' in window || navigator.maxTouchPoints > 0) {
|
||||
var hint = document.getElementById('scrollHint');
|
||||
if (hint) hint.style.display = 'block';
|
||||
var wrap = hint && hint.nextElementSibling;
|
||||
if (wrap) wrap.addEventListener('scroll', function hide() {
|
||||
hint.style.display = 'none';
|
||||
wrap.removeEventListener('scroll', hide);
|
||||
}, { passive: true });
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user