3 Commits

Author SHA1 Message Date
cff62fa343 Remove 'checked' values from incomplete maps 2026-02-11 21:03:55 +00:00
f359938d78 Standardize junction abbreviation to Jn 2026-02-11 21:02:14 +00:00
7e68192312 Standardise & styles and improve performance on small displays.
Add inter-route linking from Junctions.
2026-02-11 20:58:01 +00:00
11 changed files with 144 additions and 75 deletions

View File

@@ -7,6 +7,7 @@
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"
/>
<link rel="manifest" href="/manifest.webmanifest" />
<title>OwlBoard Maps</title>
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">

View File

@@ -1,12 +1,19 @@
<script lang="ts">
import { components } from '$lib/mapRegistry';
import type { ElecType } from '$lib/railStyles';
import { IconArrowNarrowRight } from '@tabler/icons-svelte';
export let feature: any; // Raw Object
export let activeElec: string; // Active Electrification Type
type featureType = "station" | "junction" | "crossovers" | "siteof" | "bridge" | "minorBridge" | "crossover" | "crossing" | "loop" | "loops" | "signallerChange" | "electrificationChange" | "default" | "tunnel";
export let feature: {name: string; type: featureType; goto?: string; entryPoint?: string; miles: number; chains: number; description?: string}; // Raw Object
export let activeElec: ElecType; // Active Electrification Type
export let reversed: boolean = false;
$: Icon = components[feature.type] || components.default;
// Linking Logic
$: isLinkable = !!(feature.goto && feature.entryPoint);
$: href = `/map/${feature.goto}#${feature.entryPoint}`;
const slugify = (str?: string) =>
str?.toLocaleLowerCase().trim().replace(/\s+/g, '-') ?? 'unknown';
</script>
@@ -18,9 +25,10 @@
</div>
<div class="icon-col">
<svelte:component this={Icon} {feature} {activeElec} {reversed} />
<svelte:component this={Icon} feature={feature as any} {activeElec} {reversed} />
</div>
<svelte:element this={isLinkable ? 'a' : 'div'} {...(isLinkable ? { href } : {})} class="link-wrapper">
<div class="label-col">
{#if feature.name}
<div class="feature-name">{feature.name}</div>
@@ -29,18 +37,31 @@
<div class="feature-desc">{feature.description}</div>
{/if}
</div>
{#if isLinkable}
<div class="link-indicator">
<IconArrowNarrowRight />
</div>
{/if}
</svelte:element>
</div>
<style>
a {
cursor: pointer;
text-decoration: none;
}
.row-container {
display: grid;
/* Balanced columns: 1fr on both sides keeps the 64px icon in the dead center */
grid-template-columns: 3.5rem 64px 1fr;
width: 100%;
height: 64px;
max-height: 64px;
align-items: center;
margin: 0;
padding: 0;
overflow: hidden;
}
.mileage-col {
@@ -50,7 +71,7 @@
padding-right: 12px;
font-family: 'Courier New', Courier, monospace;
font-size: 0.85rem;
color: #64748b; /* Adjusted slightly for contrast */
color: #64748b;
}
.miles {
@@ -62,13 +83,46 @@
font-size: 0.7rem;
}
.icon-col {
width: 64px;
height: 64px;
/* Ensure the icon itself is centered if the SVG is smaller than 64px */
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.link-wrapper {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
height: 100%;
text-decoration: none;
color: inherit;
padding: 0;
box-sizing: border-box;
}
.link-indicator {
display: flex;
align-items: center;
margin-left: 5px;
margin-right: 8px;
flex-shrink: 0;
color: #e1ebeb;
background-color: #3c6f79;
padding: 2px 2px;
border-radius: 999px;
transition: all 0.3s ease;
}
.link-wrapper:hover .link-indicator {
background-color: #404c55;
transform: rotate(-45deg);
}
.label-col {
@@ -76,20 +130,16 @@
display: flex;
flex-direction: column;
justify-content: center;
/* FIX: Allow children to manage their own wrapping */
overflow: hidden;
/* min-width: 0 is critical for flex children to allow truncation */
min-width: 0;
}
.feature-name {
font-weight: 700;
font-family: sans-serif;
color: #1e293b;
font-size: 0.8rem;
text-transform: capitalize;
/* Allow the title to wrap naturally onto multiple lines */
white-space: normal;
line-height: 1.2;
margin-bottom: 2px;
@@ -98,12 +148,11 @@
.feature-desc {
display: -webkit-box;
-webkit-box-orient: vertical;
font-family: sans-serif;
-webkit-line-clamp: 2;
line-clamp: 2;
overflow: hidden;
/* Firefox Fix: Ensure white-space is normal here too */
white-space: normal;
line-height: 1.2rem;
max-height: 2.4rem;
font-size: 0.75rem;
@@ -111,21 +160,26 @@
word-break: break-word;
}
/* Tablet and Desktop scaling */
@media (max-width: 320px) {
.feature-desc {
display: none;
}
}
@media (min-width: 480px) {
.feature-name {
font-size: 1rem; /* The larger title you requested */
font-size: 1rem;
margin-bottom: 4px;
}
.feature-desc {
font-size: 0.85rem; /* Slightly larger desc to match */
font-size: 0.85rem;
line-height: 1.3rem;
max-height: 2.6rem;
}
.label-col {
padding-left: 24px; /* More "breathing room" on big screens */
padding-left: 24px;
}
}
</style>

View File

@@ -9,10 +9,9 @@
$: type = feature.kind.toLowerCase();
$: isFoot = type === 'foot';
$: filterCategory = isFoot ? 'foot' : type === 'uwc' ? 'uwc' : 'level-crossing';
</script>
<svg viewBox="0 0 64 64" width="64" height="64" class={filterCategory}>
<svg viewBox="0 0 64 64" width="64" height="64">
<BaseTrack {activeElec} height={64} />
{#if type === 'foot'}

View File

@@ -6,6 +6,8 @@
direction: 'up' | 'down';
diverges: 'left' | 'right' | 'both';
elecBranch?: string;
goto?: string;
entryPoint?: string;
};
export let activeElec: any;
export let reversed: boolean = false;

View File

@@ -1,4 +1,5 @@
<script lang="ts">
import { IconArrowNarrowRight } from '@tabler/icons-svelte';
export let feature: {
routeName: string;
routeId: string;
@@ -17,16 +18,7 @@
</div>
<div class="icon-circle">
<svg viewBox="0 0 24 24" width="20" height="20">
<path
d="M5 12h14M12 5l7 7-7 7"
fill="none"
stroke="currentColor"
stroke-width="3"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<IconArrowNarrowRight />
</div>
</a>
</div>
@@ -69,12 +61,14 @@
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
font-family: "urwgothic";
color: #64748b;
}
.route-id-chip {
font-size: 0.6rem;
font-weight: 800;
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
background: #f1f5f9;
color: #475569;
padding: 2px 6px;
@@ -83,6 +77,7 @@
}
.main-text {
font-family: "urwgothic";
font-size: 1rem;
font-weight: 800;
color: #0f172a;
@@ -92,16 +87,15 @@
}
.icon-circle {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
background: #f8fafc;
border-radius: 50%;
color: #94a3b8;
color: #e1ebeb;
background-color: #3c6f79;
padding: 4px 4px;
border-radius: 999px;
transition: all 0.3s ease;
margin-left: 12px;
}
.wide-button:hover {
@@ -111,8 +105,7 @@
}
.wide-button:hover .icon-circle {
background: #4f46e5;
color: #ffffff;
background-color: #404c55;
transform: rotate(-45deg);
}

View File

@@ -22,7 +22,8 @@
electrificationChange: true,
siteof: true,
junction: true,
tunnel: true
tunnel: true,
crossing: true,
};
let showFilters = false;
@@ -75,7 +76,8 @@
{reversed ? data.route.routeEnd : data.route.routeStart}
</h1>
<span class="secondary-station">
to {reversed ? data.route.routeStart : data.route.routeEnd}
<span class="route-stack-to">
to</span> {reversed ? data.route.routeStart : data.route.routeEnd}
</span>
{/if}
</div>
@@ -186,6 +188,8 @@
height: 52px;
padding-left: 0;
margin-left: 15px;
margin-right: 0;
padding-right: 0;
flex-shrink: 0;
transition: all 0.3s ease;
}
@@ -208,8 +212,14 @@
.route-stack {
display: flex;
font-family: "urwgothic";
flex-direction: column;
min-width: 0;
margin-left: 0;
}
.route-stack-to {
text-transform: lowercase;
}
.primary-station {
@@ -225,7 +235,7 @@
.secondary-station {
font-size: 0.7rem;
color: #cce9e9;
text-transform: uppercase;
text-transform: capitalize;
font-weight: 600;
}
@@ -365,7 +375,7 @@
transition: all 0.3s ease;
}
@media (max-width: 350px) {
@media (max-width: 390px) {
.icon-btn {
padding: 0.3rem 0.3rem;
}

View File

@@ -52,7 +52,7 @@ routeDetail:
chains: 52
- type: crossovers
name: Subway Junction
name: Subway Jn
miles: 0
chains: 61
@@ -85,7 +85,7 @@ routeDetail:
chains: 18
- type: junction
name: Westbourne Park Junction
name: Westbourne Park Jn
diverges: left
direction: up
description: to Crossrail Core Operating Section
@@ -93,7 +93,7 @@ routeDetail:
chains: 21
- type: crossovers
name: Portobello Junction
name: Portobello Jn
miles: 1
chains: 33
@@ -120,7 +120,7 @@ routeDetail:
chains: 73
- type: junction
name: Kensal Green East Junction
name: Kensal Green East Jn
diverges: both
direction: down
description: to Crossrail & North Pole Depots
@@ -177,7 +177,7 @@ routeDetail:
chains: 45
- type: junction
name: Friars Junction
name: Friars Jn
diverges: left
direction: up
elecBranch: none
@@ -207,7 +207,7 @@ routeDetail:
chains: 80
- type: junction
name: Acton East Junction
name: Acton East Jn
diverges: left
direction: up
description: Up/Dn Poplar to Acton Wells Jn
@@ -312,7 +312,7 @@ routeDetail:
chains: 46
- type: junction
name: West Ealing Junction
name: West Ealing Jn
diverges: left
direction: down
elecBranch: none
@@ -328,7 +328,7 @@ routeDetail:
chains: 71
- type: junction
name: Hanwell Junction
name: Hanwell Jn
diverges: left
direction: up
elecBranch: none
@@ -394,7 +394,7 @@ routeDetail:
chains: 46
- type: junction
name: Southall East Junction
name: Southall East Jn
diverges: right
direction: up
elecBranch: none
@@ -423,7 +423,7 @@ routeDetail:
chains: 53
- type: crossovers
name: Southall West Junction
name: Southall West Jn
description: Southall Sidings Diverge
miles: 9
chains: 70
@@ -490,7 +490,7 @@ routeDetail:
chains: 77
- type: junction
name: Heathrow Airport Junction
name: Heathrow Airport Jn
diverges: both
direction: down
miles: 11
@@ -506,7 +506,7 @@ routeDetail:
chains: 28
- type: crossovers
name: Stockley Bridge Junction
name: Stockley Bridge Jn
miles: 12
chains: 9
@@ -519,7 +519,7 @@ routeDetail:
chains: 22
- type: crossovers
name: West Drayton East Junction
name: West Drayton East Jn
miles: 12
chains: 67
@@ -544,7 +544,7 @@ routeDetail:
chains: 56
- type: junction
name: West Drayton Junction
name: West Drayton Jn
diverges: left
direction: down
description: Colnbrook Freight (near Heathrow)
@@ -725,7 +725,7 @@ routeDetail:
chains: 42
- type: junction
name: Windsor Branch Junction
name: Windsor Branch Jn
diverges: right
direction: down
description: Windsor Branch from platforms 1 & 2 Only
@@ -1048,7 +1048,7 @@ routeDetail:
chains: 1
- type: junction
name: Henley Branch Junction
name: Henley Branch Jn
diverges: left
direction: down
description: Henley-on-Thames from Platform 4 only
@@ -1169,7 +1169,7 @@ routeDetail:
chains: 77
- type: crossovers
name: Kennet Bridge Junction
name: Kennet Bridge Jn
miles: 35
chains: 10
@@ -1182,7 +1182,7 @@ routeDetail:
chains: 28
- type: junction
name: Reading New Junction
name: Reading New Jn
diverges: right
direction: up
elecBranch: none
@@ -1199,7 +1199,7 @@ routeDetail:
chains: 40
- type: junction
name: Reading East Junction
name: Reading East Jn
diverges: left
direction: up
elecBranch: none
@@ -1222,3 +1222,4 @@ routeDetail:
- type: continues
routeName: Reading - Bristol TM
routeId: '0002'
entryPoint: reading

View File

@@ -14,6 +14,7 @@ routeDetail:
- type: continues
routeName: Paddington - Reading
routeId: '0001'
entryPoint: reading
- type: station
name: Reading
@@ -30,21 +31,25 @@ routeDetail:
- type: junction
diverges: right
direction: down
name: Westbury Line Junction
name: Westbury Line Jn
description: to Oxford Road Jn
goto: "0201"
entryPoint: "oxford-road-jn"
miles: 36
chains: 17
- type: junction
diverges: right
direction: down
name: Caversham Road Junction
name: Caversham Road Jn
description: Reading Feeder Main/Relief diverge and pass under Reading Viaduct to Oxford Rd Jn
goto: "0201"
entryPoint: "oxford-road-jn"
miles: 36
chains: 22
- type: crossovers
name: Reading High Level Junction
name: Reading High Level Jn
description: Down Reading Festival Connects to Down Main
miles: 36
chains: 47
@@ -52,7 +57,9 @@ routeDetail:
- type: junction
diverges: right
direction: up
name: Reading West Junction
name: Reading West Jn
description: to Oxford Road Junction (From relief lines only)
goto: "0201"
entryPoint: "oxford-road-jn"
miles: 37
chains: 17

View File

@@ -2,7 +2,7 @@ routeStart: Swindon Junction
routeEnd: Standish Junction
routeId: 0230
updated: 2026-02-11
checked: 2026-02-11
checked:
signallerStart: TVSC Swindon WS
signallerEnd: Gloucester PSB
elecStart:

View File

@@ -1,5 +1,5 @@
routeStart: Wootton Bassett Junction
routeEnd: Stoke Gifford Junction
routeStart: Wootton Bassett Jn
routeEnd: Stoke Gifford Jn
routeId: 0240
updated: 2026-02-11
checked: 2026-02-11
@@ -14,14 +14,16 @@ elecEnd:
routeDetail:
- type: continues
routeName: Reading - Bristol TM
entryPoint: wootton-bassett-junction
entryPoint: wootton-bassett-jn
routeId: '0002'
- type: junction
diverges: right
direction: down
name: Wootton Basset Junction
name: Wootton Basset Jn
description: to Chippenham & Bristol via Bath
goto: "0002"
entryPoint: wootton-bassett-jn
miles: 83
chains: 7
@@ -486,7 +488,7 @@ routeDetail:
- type: junction
diverges: left
direction: up
name: Westerleigh Junction
name: Westerleigh Jn
miles: 107
chains: 14
description: Up/Dn Charfield towards Gloucester
@@ -614,7 +616,7 @@ routeDetail:
chains: 14
- type: crossovers
name: Stoke Gifford East Junction
name: Stoke Gifford East Jn
miles: 111
chains: 20
@@ -639,7 +641,7 @@ routeDetail:
chains: 77
- type: junction
name: Stoke Gifford No.1 Junction
name: Stoke Gifford No.1 Jn
diverges: right
direction: down
description: Up/Dn Filton & Bristol TM

View File

@@ -1,8 +1,8 @@
routeStart: Westerleigh Junction
routeStart: Westerleigh Jn
routeEnd: Gloucester
routeId: 2420
updated: 2026-02-11
checked: 2026-02-11
checked:
signallerStart: TVSC Swindon WS
signallerEnd: Gloucester PSB
elecStart: