The Element Call tile still appended a synthetic 'Step 4: Router Setup
Needed' to the domain diagnostic checklist, and every port table carried a
'Sovran_SystemsOS Status' column with Ready / Not ready yet verdicts.
Both were misleading: port forwarding happens on the router, which this
computer cannot inspect. A local ss/firewall probe can neither prove nor
disprove that forwarding works — and the LiveKit TURN relay range binds on
demand, so it reported 'Not ready yet' even on a perfectly working system.
- server.py: add ROUTER_FORWARD_ONLY_UNITS ({livekit.service}); skip the
local probe for those units, drop the step-4 append, replace extra_ports
with router_ports (no status field), and exclude router-only ports from
both tile health and /api/ports/health so they can't raise false alarms.
- helpers.js: new shared renderPortForwardGuideHtml() — one intro naming the
internal IP, explicit instructions (same internal/external port, match the
protocol, use port-range fields for 30000-40000), a colour-coded
TCP / UDP / TCP+UDP badge per row, and a closing note that the only real
test is loading the service from a phone on mobile data.
- features.js: enable-time modal uses the shared guide and now always lists
every port to forward (the old local pre-filter hid ports the user still
had to open).
- service-detail.js: tile port section uses the same guide; the SSH/non-domain
branch keeps a small 'not open on this computer yet' hint, which is a real
local fact, separate from router forwarding.
- onboarding.js: step 3 router note reworded to match (same number for
internal/external, notes that Element Call adds UDP ports).
- domain-setup.css: styles for the protocol badges and instruction list.
Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
238 lines
4.6 KiB
CSS
238 lines
4.6 KiB
CSS
/* ── Domain setup modal ──────────────────────────────────────────── */
|
|
|
|
domain-narrow-dialog {
|
|
max-width: 500px;
|
|
}
|
|
|
|
domain-field-group {
|
|
margin-bottom: 14px;
|
|
}
|
|
|
|
domain-field-label {
|
|
display: block;
|
|
font-size: 0.82rem;
|
|
color: var(--text-secondary);
|
|
margin-bottom: 6px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
domain-field-input {
|
|
width: 100%;
|
|
background-color: #0c0f0e;
|
|
color: var(--text-primary);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: 8px;
|
|
padding: 10px 12px;
|
|
font-size: 0.9rem;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
domain-field-input:focus {
|
|
outline: none;
|
|
border-color: var(--accent-color);
|
|
}
|
|
|
|
domain-field-actions {
|
|
display: flex;
|
|
gap: 10px;
|
|
margin-top: 18px;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
/* ── Port Requirements modal ─────────────────────────────────────── */
|
|
|
|
.domain-narrow-dialog {
|
|
max-width: 500px;
|
|
}
|
|
|
|
.domain-setup-intro {
|
|
font-size: 0.88rem;
|
|
color: var(--text-secondary);
|
|
line-height: 1.6;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.domain-setup-intro ol {
|
|
padding-left: 20px;
|
|
margin-top: 8px;
|
|
}
|
|
|
|
.domain-setup-intro li {
|
|
margin-bottom: 6px;
|
|
}
|
|
|
|
.domain-field-group {
|
|
margin-bottom: 14px;
|
|
}
|
|
|
|
.domain-field-label {
|
|
display: block;
|
|
font-size: 0.82rem;
|
|
color: var(--text-secondary);
|
|
margin-bottom: 6px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.domain-field-input {
|
|
width: 100%;
|
|
background-color: #0c0f0e;
|
|
color: var(--text-primary);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: 8px;
|
|
padding: 10px 12px;
|
|
font-size: 0.9rem;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.domain-field-input:focus {
|
|
outline: none;
|
|
border-color: var(--accent-color);
|
|
}
|
|
|
|
.domain-field-hint {
|
|
font-size: 0.75rem;
|
|
color: var(--text-dim);
|
|
margin-top: 4px;
|
|
font-style: italic;
|
|
}
|
|
|
|
.domain-field-actions {
|
|
display: flex;
|
|
gap: 10px;
|
|
margin-top: 18px;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.port-req-intro {
|
|
font-size: 0.88rem;
|
|
color: var(--text-secondary);
|
|
line-height: 1.6;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.port-req-hint {
|
|
font-size: 0.82rem;
|
|
color: var(--text-dim);
|
|
line-height: 1.6;
|
|
margin-top: 10px;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.port-req-internal-ip {
|
|
font-family: 'JetBrains Mono', 'Fira Code', 'Source Code Pro', monospace;
|
|
font-weight: 700;
|
|
color: var(--accent-color);
|
|
}
|
|
|
|
.port-req-table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
font-size: 0.82rem;
|
|
margin-top: 8px;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.port-req-table th {
|
|
text-align: left;
|
|
color: var(--text-dim);
|
|
font-weight: 600;
|
|
font-size: 0.72rem;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.04em;
|
|
padding: 6px 10px;
|
|
border-bottom: 1px solid var(--border-color);
|
|
}
|
|
|
|
.port-req-table td {
|
|
padding: 8px 10px;
|
|
border-bottom: 1px solid rgba(30, 45, 39, 0.5);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.port-req-table tr:last-child td {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.port-req-port {
|
|
font-family: 'JetBrains Mono', 'Fira Code', 'Source Code Pro', monospace;
|
|
font-weight: 600;
|
|
color: var(--accent-color);
|
|
}
|
|
|
|
.port-req-proto {
|
|
text-transform: uppercase;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.port-req-desc {
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.port-req-status {
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* ── Port-forwarding instructions ─────────────────────────────────── */
|
|
|
|
.port-req-steps {
|
|
margin: 4px 0 12px;
|
|
padding-left: 20px;
|
|
font-size: 0.84rem;
|
|
color: var(--text-secondary);
|
|
line-height: 1.65;
|
|
}
|
|
|
|
.port-req-steps li {
|
|
margin-bottom: 5px;
|
|
}
|
|
|
|
.port-proto-badge {
|
|
display: inline-block;
|
|
font-family: 'JetBrains Mono', 'Fira Code', 'Source Code Pro', monospace;
|
|
font-size: 0.72rem;
|
|
font-weight: 700;
|
|
letter-spacing: 0.04em;
|
|
padding: 2px 7px;
|
|
border-radius: 5px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.port-proto-badge--tcp {
|
|
color: #6dbf8b;
|
|
background: rgba(109, 191, 139, 0.12);
|
|
border: 1px solid rgba(109, 191, 139, 0.4);
|
|
}
|
|
|
|
.port-proto-badge--udp {
|
|
color: #6aa9e0;
|
|
background: rgba(106, 169, 224, 0.12);
|
|
border: 1px solid rgba(106, 169, 224, 0.4);
|
|
}
|
|
|
|
.port-proto-badge--both {
|
|
color: #e5a50a;
|
|
background: rgba(229, 165, 10, 0.12);
|
|
border: 1px solid rgba(229, 165, 10, 0.45);
|
|
}
|
|
|
|
.port-proto-note {
|
|
display: block;
|
|
margin-top: 3px;
|
|
font-size: 0.68rem;
|
|
color: var(--text-dim);
|
|
text-transform: none;
|
|
letter-spacing: 0;
|
|
}
|
|
|
|
/* ── Wallet Connections unique-hostname warning ───────────────────── */
|
|
|
|
.domain-nwc-warning {
|
|
margin-bottom: 14px;
|
|
padding: 10px 14px;
|
|
background: rgba(255, 180, 0, 0.10);
|
|
border: 1px solid var(--warning-color, #f59e0b);
|
|
border-radius: 8px;
|
|
font-size: 0.88rem;
|
|
line-height: 1.6;
|
|
}
|