diff --git a/client/src/components/Tours/ski/skiMarks.test.tsx b/client/src/components/Tours/ski/skiMarks.test.tsx
index 2dec2b266..02e9bb768 100644
--- a/client/src/components/Tours/ski/skiMarks.test.tsx
+++ b/client/src/components/Tours/ski/skiMarks.test.tsx
@@ -2,9 +2,17 @@ import { render, screen } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { TourDayRowAvatar } from '../TourDayRowFacts';
import { TourGradeTile } from '../tourParts';
-import { SkiCornerMark, SkiHeadPill, skiClassificationText, skiDisciplineOf, skiTechniqueOf } from './skiMarks';
+import { WINTER_ACTIVITY_ICON } from '../winter/winterMarks';
+import {
+ SKI_DISCIPLINE_ICON,
+ SkiCornerMark,
+ SkiHeadPill,
+ skiClassificationText,
+ skiDisciplineOf,
+ skiTechniqueOf,
+} from './skiMarks';
-// FE-TOUR-SKI-MARK-001 to FE-TOUR-SKI-MARK-005
+// FE-TOUR-SKI-MARK-001 to FE-TOUR-SKI-MARK-006
const t = (key: string) => key;
const skiTrack = {
@@ -39,6 +47,8 @@ describe('ski marks (SKI-02)', () => {
const mark = screen.getByRole('img', { name: 'tours.ski.discipline.snowboard' });
expect(mark).toHaveAttribute('data-testid', 'tour-ski-mark');
expect(mark).toHaveStyle({ width: '20px', height: '20px' });
+ expect(mark.querySelector('svg.lucide-snowboard')).not.toBeNull();
+ expect(mark.querySelector('svg.lucide-snowflake')).toBeNull();
});
it('FE-TOUR-SKI-MARK-003: the head pill names the discipline with a cross-country technique inside it', () => {
@@ -68,4 +78,9 @@ describe('ski marks (SKI-02)', () => {
rerender();
expect(screen.getByTestId('tour-ski-mark')).toHaveStyle({ width: '22px' });
});
+
+ it('FE-TOUR-SKI-MARK-006: no discipline shares its corner glyph with another, nor with a winter label', () => {
+ const icons = [...Object.values(SKI_DISCIPLINE_ICON), ...Object.values(WINTER_ACTIVITY_ICON)];
+ expect(new Set(icons).size).toBe(icons.length);
+ });
});
diff --git a/client/src/components/Tours/ski/skiMarks.tsx b/client/src/components/Tours/ski/skiMarks.tsx
index 5e3a38ddd..fcec7511c 100644
--- a/client/src/components/Tours/ski/skiMarks.tsx
+++ b/client/src/components/Tours/ski/skiMarks.tsx
@@ -1,18 +1,32 @@
import type { SkiDiscipline, SkiTechnique, TourListItem } from '@trek/shared';
-import { CableCar, Snowflake, Spline, TrendingUp, type LucideIcon } from 'lucide-react';
+import { CableCar, createLucideIcon, Spline, TrendingUp, type LucideIcon } from 'lucide-react';
import { useTranslation } from '../../../i18n';
import { fs } from '../../shared/DialogShell';
import { Tooltip } from '../../shared/Tooltip';
import { TourCornerMark } from '../TourCornerMark';
/**
- * SKI-02: the icon each discipline goes by: a lift for alpine skiing, a
- * snowflake for the board, a winding trail for cross-country and the climb on
- * skins for ski touring.
+ * SKI-02: a snowboard seen from above, laid across the square with its two
+ * bindings. Lucide has no board, and the snowflake is the winter hike's mark
+ * (HIK-01): both sit in the same corner badge, so the board needs a glyph of
+ * its own to be told apart there.
+ */
+const BOARD = 'rotate(-45 12 12)';
+const Snowboard = createLucideIcon('snowboard', [
+ ['rect', { x: '1.5', y: '8.5', width: '21', height: '7', rx: '3.5', transform: BOARD, key: 'board' }],
+ ['path', { d: 'M8.5 10v4', transform: BOARD, key: 'binding-front' }],
+ ['path', { d: 'M15.5 10v4', transform: BOARD, key: 'binding-back' }],
+]);
+
+/**
+ * SKI-02: the icon each discipline goes by: a lift for alpine skiing, a board
+ * for snowboarding, a winding trail for cross-country and the climb on skins
+ * for ski touring. None of them is the winter hike's snowflake, which takes
+ * the same corner of a tile.
*/
export const SKI_DISCIPLINE_ICON: Record = {
alpine: CableCar,
- snowboard: Snowflake,
+ snowboard: Snowboard,
cross_country: Spline,
touring: TrendingUp,
};