diff --git a/src/features/online-board/components/FullRouteTimeline/FullRouteTimeline.scss b/src/features/online-board/components/FullRouteTimeline/FullRouteTimeline.scss
new file mode 100644
index 00000000..d026d757
--- /dev/null
+++ b/src/features/online-board/components/FullRouteTimeline/FullRouteTimeline.scss
@@ -0,0 +1,105 @@
+.full-route-timeline {
+ background: #fff;
+ border-radius: 8px;
+ padding: 16px 24px;
+ margin-bottom: 16px;
+
+ @media (max-width: 768px) {
+ display: none;
+ }
+}
+
+.timeline {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+
+ &__arrow {
+ background: transparent;
+ border: 1px solid #d0dae5;
+ border-radius: 50%;
+ width: 32px;
+ height: 32px;
+ cursor: pointer;
+ color: #2060c0;
+ font-size: 16px;
+
+ &:disabled { opacity: 0.3; cursor: not-allowed; }
+ }
+
+ &__content {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ }
+
+ &__row {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+
+ &--times { font-size: 18px; font-weight: 500; color: #1a3a5c; }
+ &--stations { font-size: 14px; color: #666; }
+ }
+}
+
+.timeline-section {
+ position: relative;
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ &__separator {
+ flex: 1;
+ height: 1px;
+ background: #d0dae5;
+ }
+
+ &__number {
+ position: absolute;
+ top: -20px;
+ background: #e3f0ff;
+ color: #2060c0;
+ border-radius: 10px;
+ padding: 2px 8px;
+ font-size: 12px;
+ font-weight: 600;
+ }
+
+ &__duration {
+ font-size: 12px;
+ color: #666;
+ padding: 0 8px;
+ background: #fff;
+
+ &--specifying { color: #ff9000; }
+ }
+}
+
+.station {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+
+ &--right { align-items: flex-end; text-align: right; }
+ &--center { align-items: center; text-align: center; }
+
+ &__city { font-size: 14px; font-weight: 500; color: #1a3a5c; }
+ &__code { font-size: 12px; color: #666; }
+ &__terminal { font-size: 11px; color: #999; }
+
+ &--large { .station__city { font-size: 22px; } }
+ &--small { .station__city { font-size: 12px; } }
+}
+
+.station-change {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+
+ &__arrow { color: #2060c0; }
+ &__city { font-size: 12px; color: #666; }
+ &__code { font-size: 14px; font-weight: 500; color: #1a3a5c; }
+}
diff --git a/src/features/online-board/components/FullRouteTimeline/FullRouteTimeline.test.tsx b/src/features/online-board/components/FullRouteTimeline/FullRouteTimeline.test.tsx
new file mode 100644
index 00000000..980237bd
--- /dev/null
+++ b/src/features/online-board/components/FullRouteTimeline/FullRouteTimeline.test.tsx
@@ -0,0 +1,79 @@
+// @vitest-environment jsdom
+import { describe, it, expect, vi } from "vitest";
+import { render, screen } from "@testing-library/react";
+import type { IFlightLeg } from "../../types.js";
+
+vi.mock("@/i18n/provider.js", () => ({
+ useTranslation: () => ({ t: (k: string) => k }),
+}));
+
+import { FullRouteTimeline } from "./FullRouteTimeline.js";
+
+function makeLeg(i: number): IFlightLeg {
+ return {
+ arrival: {
+ scheduled: {
+ airport: "",
+ airportCode: "AAA",
+ city: `City${i}`,
+ cityCode: `C${i}`,
+ countryCode: "RU",
+ },
+ terminal: "",
+ times: {
+ scheduledArrival: {
+ dayChange: { value: 0, title: "" },
+ local: `a${i}`,
+ localTime: `a${i}`,
+ tzOffset: 0,
+ utc: `2026-04-17T0${i}:00:00Z`,
+ },
+ },
+ },
+ departure: {
+ scheduled: {
+ airport: "",
+ airportCode: "BBB",
+ city: `Dep${i}`,
+ cityCode: `D${i}`,
+ countryCode: "RU",
+ },
+ terminal: "",
+ checkingStatus: "",
+ times: {
+ scheduledDeparture: {
+ dayChange: { value: 0, title: "" },
+ local: `d${i}`,
+ localTime: `d${i}`,
+ tzOffset: 0,
+ utc: `2026-04-17T0${i}:00:00Z`,
+ },
+ },
+ },
+ dayChange: 0,
+ equipment: {},
+ flags: { checkinAvailable: false, returnToAirport: false, routeChanged: false },
+ flyingTime: `${i}h`,
+ index: i,
+ operatingBy: {},
+ status: "Scheduled",
+ updated: "",
+ } as IFlightLeg;
+}
+
+describe("FullRouteTimeline", () => {
+ it("returns null when fewer than 2 legs", () => {
+ const { container } = render();
+ expect(container.firstChild).toBeNull();
+ });
+
+ it("renders container with data-testid=full-route-timeline when 2+ legs", () => {
+ render();
+ expect(screen.getByTestId("full-route-timeline")).toBeTruthy();
+ });
+
+ it("renders inner Timeline content (expect d0 visible when 2 legs)", () => {
+ render();
+ expect(screen.getByText("d0")).toBeTruthy();
+ });
+});
diff --git a/src/features/online-board/components/FullRouteTimeline/FullRouteTimeline.tsx b/src/features/online-board/components/FullRouteTimeline/FullRouteTimeline.tsx
new file mode 100644
index 00000000..72a69a33
--- /dev/null
+++ b/src/features/online-board/components/FullRouteTimeline/FullRouteTimeline.tsx
@@ -0,0 +1,18 @@
+import type { FC } from "react";
+import type { IFlightLeg } from "../../types.js";
+import { Timeline } from "./Timeline.js";
+import "./FullRouteTimeline.scss";
+
+export interface FullRouteTimelineProps {
+ legs: IFlightLeg[];
+ viewType: "Onlineboard" | "Schedule";
+}
+
+export const FullRouteTimeline: FC = ({ legs, viewType }) => {
+ if (legs.length < 2) return null;
+ return (
+
+ );
+};
diff --git a/src/features/online-board/components/FullRouteTimeline/index.ts b/src/features/online-board/components/FullRouteTimeline/index.ts
new file mode 100644
index 00000000..3a03c847
--- /dev/null
+++ b/src/features/online-board/components/FullRouteTimeline/index.ts
@@ -0,0 +1,2 @@
+export { FullRouteTimeline } from "./FullRouteTimeline.js";
+export type { FullRouteTimelineProps } from "./FullRouteTimeline.js";