diff --git a/docker/frontend/src/Landing.tsx b/docker/frontend/src/Landing.tsx
index bf5dca7..5bcc0e9 100644
--- a/docker/frontend/src/Landing.tsx
+++ b/docker/frontend/src/Landing.tsx
@@ -722,13 +722,12 @@ export function Landing() {
{/* The trial notice: the last shelf of the bar, under the menu line. It
scrolls because it is one long sentence that would otherwise wrap on
- a phone and stand as a paragraph. The sentence is rendered twice —
- the second copy is the one that walks in as the first walks out, and
- is hidden from screen readers so the news is announced once. */}
+ a phone and stand as a paragraph. One copy only, and it walks the
+ whole way — in past the right edge, out past the left — so exactly
+ one sentence is in flight at any moment, phone included. */}
{t('notice.trial')}
- {t('notice.trial')}
{menu ? (
diff --git a/docker/frontend/src/styles/landing.css b/docker/frontend/src/styles/landing.css
index c60b87b..de32a50 100644
--- a/docker/frontend/src/styles/landing.css
+++ b/docker/frontend/src/styles/landing.css
@@ -143,13 +143,14 @@ html { scroll-behavior: smooth; scroll-padding-top: 148px; }
.lp-subnav-link:hover { color: var(--lp-text); border-color: var(--accent-line); }
/* The trial notice: the bar's third shelf, under the menu line. One line, so it
never wraps and the bar keeps a fixed height the hero's padding can match.
- The sentence is printed twice and the track slides exactly half its own width
- — the second copy arrives where the first left, so the loop has no seam and
- the gap lives in each copy's right padding rather than between them. */
+ One copy of the sentence, which enters past the right edge of the window and
+ leaves past its left edge — so exactly one is in flight at any moment, and
+ the trip covers the same screen-relative distance on a phone. The 30s is a
+ compromise: the journey is 100vw plus the sentence, which CSS cannot measure,
+ so the phone walks it slower than the desktop. */
.lp-notice { border-top: 1px solid var(--lp-line); overflow: hidden; padding: 6px 0; }
-.lp-notice-track { display: flex; width: max-content; animation: lp-notice-roll 40s linear infinite; }
+.lp-notice-track { display: flex; width: max-content; animation: lp-notice-roll 30s linear infinite; }
.lp-notice-track span {
- padding-right: 72px;
white-space: nowrap;
font-size: 12px;
/* The theme's own ink, not the page's amber: on the light theme the plain
@@ -160,8 +161,12 @@ html { scroll-behavior: smooth; scroll-padding-top: 148px; }
color: color-mix(in srgb, var(--lp-ink-amber) 78%, var(--lp-text));
letter-spacing: 0.02em;
}
-@keyframes lp-notice-roll { to { transform: translateX(-50%); } }
+@keyframes lp-notice-roll {
+ from { transform: translateX(100vw); }
+ to { transform: translateX(-100%); }
+}
@media (prefers-reduced-motion: reduce) {
+ .lp-notice { overflow-x: auto; }
.lp-notice-track { animation: none; }
}
.lp-nav .lp-spacer { flex: 1 1 auto; }