diff --git a/drb-frontend/components/live/AttentionControls.tsx b/drb-frontend/components/live/AttentionControls.tsx
index 2835c8b..d49d804 100644
--- a/drb-frontend/components/live/AttentionControls.tsx
+++ b/drb-frontend/components/live/AttentionControls.tsx
@@ -173,6 +173,20 @@ export function AttentionControls({ prefs, onChange, armed }: Props) {
if (p === "default") {
try { p = (await Notification.requestPermission()) as NotifyState; } catch { p = notifyState(); }
}
+ if (p === "granted") {
+ // Confirm with one notification (as the tone confirms with a beep). It
+ // doubles as the support check: mobile Chrome grants permission but
+ // throws on `new Notification()` without a service worker, which would
+ // otherwise leave a switched-on control that never delivers anything.
+ try {
+ new Notification("DRB · Notifications on", {
+ body: `Cues will appear here while the live wall tab is hidden.\n${MACHINE_OUTPUT_NOTICE_TEXT}`,
+ tag: "drb-attn:on",
+ });
+ } catch {
+ p = "unsupported";
+ }
+ }
setPerm(p);
if (p === "granted") onChange({ ...prefs, notify: true });
};
@@ -215,7 +229,7 @@ export function AttentionControls({ prefs, onChange, armed }: Props) {
Browser notifications while this tab is hidden
{perm === "denied" && Blocked in this browser's site settings — allow notifications there first.}
- {perm === "unsupported" && This browser doesn't support page notifications.}
+ {perm === "unsupported" && This browser doesn't show notifications from a web page (mobile browsers often only allow them from installed apps).}
diff --git a/drb-frontend/components/live/NewLane.tsx b/drb-frontend/components/live/NewLane.tsx
index 3b8f958..9af27a5 100644
--- a/drb-frontend/components/live/NewLane.tsx
+++ b/drb-frontend/components/live/NewLane.tsx
@@ -8,7 +8,10 @@
*
* Desktop: overlay at the map's top-left, right of the zoom stack and above
* MapView's rail (the rail starts at top-[9.5rem], so the lane is capped
- * just short of it and scrolls). Mobile: a compact chip that expands.
+ * just short of it and its rows scroll). The Gate A notice is pinned below
+ * the rows, never inside the scroll area — same rule as the rail (#46).
+ * Mobile: a compact chip under MapView's centred "Live" chip (same top-3
+ * centre slot would cover it), right of the fit-all button; it expands.
* Hidden when there is nothing new.
*/
import { useState } from "react";
@@ -31,7 +34,7 @@ function Row({ e, now, onSelect }: { e: LaneEntry; now: number; onSelect: (id: s
{ago(e.at, now)}
>
);
- const cls = "w-full flex items-center gap-1.5 px-1.5 py-1 rounded text-[11px] text-left";
+ const cls = "w-full flex items-center gap-1.5 px-1.5 py-1 rounded text-xs text-left";
return (