diff --git a/src/components/StationsView/StationFilterCard.vue b/src/components/StationsView/StationFilterCard.vue
index 20878fb..50b6a60 100644
--- a/src/components/StationsView/StationFilterCard.vue
+++ b/src/components/StationsView/StationFilterCard.vue
@@ -101,7 +101,14 @@
{{ $t('filters.save') }}
-
+
@@ -121,6 +128,7 @@ import { useStore } from '../../store/store';
import ActionButton from '../Global/ActionButton.vue';
import FilterOption from './FilterOption.vue';
+import { filterInitStates } from '../../store/constants/initFilterStates';
export default defineComponent({
components: { ActionButton, FilterOption },
@@ -304,7 +312,7 @@ export default defineComponent({
}
&_content {
- padding: 0.5em;
+ padding: 1em 0.5em;
display: flex;
flex-direction: column;
@@ -392,7 +400,7 @@ export default defineComponent({
&_actions {
width: 100%;
- padding: 0.25em;
+ padding: 0.5em;
.filter-option {
max-width: 50%;
@@ -412,8 +420,7 @@ export default defineComponent({
padding: 0.5em;
&[data-selected='true'] {
- background-color: lightgreen;
- color: black;
+ background-color: forestgreen;
}
}
}
diff --git a/src/locales/en.json b/src/locales/en.json
index 264301a..5b5dac2 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -129,7 +129,7 @@
"filter-active": "ACTIVE"
},
"filters": {
- "desc": " • Left mouse click: select / unselect chosen filter
• Double left click: unselect all filters but chosen from group
• RESET: reset all filters from group",
+ "desc": " • Left mouse click: select / unselect chosen filter
• Double left click: unselect all filters but chosen from a group
• RESET: reset all filters from a group",
"sections": {
"reality": "SCENERY REALITY",
@@ -138,7 +138,7 @@
"control": "CONTROLS",
"signals": "SIGNALLING",
"addons": "ADDITIONAL PROGRAMS",
- "blockades": "BLOCKADE TYPE",
+ "blockades": "BLOCK SIGNALLING",
"status": "ONLINE STATUS"
},
@@ -170,8 +170,8 @@
"SUP": "SUP (RASP-UZK)",
"noSUP": "NO SUP",
- "SBL": "ABS (SBL)",
- "PBL": "NO ABS (PBL)",
+ "SBL": "AUTOMATIC (SBL)",
+ "PBL": "SEMIAUTOMATIC (PBL)",
"modern": "MODERN",
"semaphores": "SEMAPHORES",
diff --git a/src/locales/pl.json b/src/locales/pl.json
index ebd2977..455c7e9 100644
--- a/src/locales/pl.json
+++ b/src/locales/pl.json
@@ -171,8 +171,8 @@
"SUP": "SUP (RASP-UZK)",
"noSUP": "BEZ SUP",
- "SBL": "SBL",
- "PBL": "PBL",
+ "SBL": "SAMOCZYNNA",
+ "PBL": "PÓŁSAMOCZYNNA",
"mechanical": "MECHANICZNE",
"modern": "WSPÓŁCZESNA",
diff --git a/src/main.ts b/src/main.ts
index 0382cfc..b29c074 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -12,6 +12,7 @@ import { registerSW } from 'virtual:pwa-register';
const i18n = createI18n({
locale: 'pl',
legacy: false,
+ warnHtmlMessage: false,
fallbackLocale: 'pl',
messages: {
en: enLang,
diff --git a/src/store/constants/initFilterStates.ts b/src/store/constants/initFilterStates.ts
new file mode 100644
index 0000000..9e2aa83
--- /dev/null
+++ b/src/store/constants/initFilterStates.ts
@@ -0,0 +1,49 @@
+import Filter from "../../scripts/interfaces/Filter";
+
+export const filterInitStates: Filter = {
+ default: false,
+ notDefault: false,
+ real: false,
+ fictional: false,
+ SPK: false,
+ SCS: false,
+ SPE: false,
+ SUP: false,
+ noSUP: false,
+ ręczne: false,
+ 'ręczne+SPK': false,
+ 'ręczne+SCS': false,
+ mechaniczne: false,
+ 'mechaniczne+SPK': false,
+ 'mechaniczne+SCS': false,
+ współczesna: false,
+ kształtowa: false,
+ historyczna: false,
+ mieszana: false,
+ SBL: false,
+ PBL: false,
+ minLevel: 0,
+ maxLevel: 20,
+ minOneWayCatenary: 0,
+ minOneWay: 0,
+ minTwoWayCatenary: 0,
+ minTwoWay: 0,
+ 'include-selected': false,
+ 'no-1track': false,
+ 'no-2track': false,
+ free: true,
+ occupied: false,
+ ending: false,
+ nonPublic: false,
+ unavailable: true,
+ abandoned: true,
+ afkStatus: false,
+ endingStatus: false,
+ noSpaceStatus: false,
+ unavailableStatus: false,
+ unsignedStatus: false,
+
+ authors: '',
+
+ onlineFromHours: 0,
+};
diff --git a/src/store/stationFiltersStore.ts b/src/store/stationFiltersStore.ts
index 8d9f95b..ca48eb9 100644
--- a/src/store/stationFiltersStore.ts
+++ b/src/store/stationFiltersStore.ts
@@ -4,221 +4,8 @@ import Filter from '../scripts/interfaces/Filter';
import Station from '../scripts/interfaces/Station';
import StorageManager from '../scripts/managers/storageManager';
import { useStore } from './store';
-
-const sortStations = (a: Station, b: Station, sorter: { index: number; dir: number }) => {
- switch (sorter.index) {
- case 0:
- return sorter.dir == 1 ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name);
-
- case 1:
- if ((a.generalInfo?.reqLevel || 0) > (b.generalInfo?.reqLevel || 0)) return sorter.dir;
- if ((a.generalInfo?.reqLevel || 0) < (b.generalInfo?.reqLevel || 0)) return -sorter.dir;
- break;
-
- case 2:
- if ((a.onlineInfo?.statusTimestamp || 0) > (b.onlineInfo?.statusTimestamp || 0)) return sorter.dir;
- if ((a.onlineInfo?.statusTimestamp || 0) < (b.onlineInfo?.statusTimestamp || 0)) return -sorter.dir;
- break;
-
- case 3:
- if ((a.onlineInfo?.dispatcherName.toLowerCase() || '') > (b.onlineInfo?.dispatcherName.toLowerCase() || ''))
- return sorter.dir;
- if ((a.onlineInfo?.dispatcherName.toLowerCase() || '') < (b.onlineInfo?.dispatcherName.toLowerCase() || ''))
- return -sorter.dir;
- break;
-
- case 4:
- if ((a.onlineInfo?.dispatcherExp || 0) > (b.onlineInfo?.dispatcherExp || 0)) return sorter.dir;
- if ((a.onlineInfo?.dispatcherExp || 0) < (b.onlineInfo?.dispatcherExp || 0)) return -sorter.dir;
- break;
-
- case 7:
- if ((a.onlineInfo?.currentUsers || 0) > (b.onlineInfo?.currentUsers || 0)) return sorter.dir;
- if ((a.onlineInfo?.currentUsers || 0) < (b.onlineInfo?.currentUsers || 0)) return -sorter.dir;
-
- if ((a.onlineInfo?.maxUsers || 0) > (b.onlineInfo?.maxUsers || 0)) return sorter.dir;
- if ((a.onlineInfo?.maxUsers || 0) < (b.onlineInfo?.maxUsers || 0)) return -sorter.dir;
- break;
-
- case 8:
- if ((a.onlineInfo?.spawns.length || 0) > (b.onlineInfo?.spawns.length || 0)) return sorter.dir;
- if ((a.onlineInfo?.spawns.length || 0) < (b.onlineInfo?.spawns.length || 0)) return -sorter.dir;
-
- break;
-
- case 9:
- if ((a.onlineInfo?.scheduledTrains?.length || 0) > (b.onlineInfo?.scheduledTrains?.length || 0))
- return sorter.dir;
- if ((a.onlineInfo?.scheduledTrains?.length || 0) < (b.onlineInfo?.scheduledTrains?.length || 0))
- return -sorter.dir;
-
- default:
- break;
- }
-
- return a.name.localeCompare(b.name);
-};
-
-const filterStations = (station: Station, filters: Filter, isOffline = false) => {
- const returnMode = false;
-
- if ((station.generalInfo?.availability == 'nonPublic' || !station.generalInfo) && filters['nonPublic'])
- return returnMode;
-
- if (station.onlineInfo?.statusID == 'ending' && filters['ending']) return returnMode;
-
- if (
- station.onlineInfo &&
- station.onlineInfo.statusTimestamp > 0 &&
- filters['onlineFromHours'] < 8 &&
- station.onlineInfo.statusTimestamp <= Date.now() + filters['onlineFromHours'] * 3600000
- )
- return returnMode;
-
- if (filters['onlineFromHours'] > 0 && station.onlineInfo && station.onlineInfo.statusTimestamp <= 0)
- return returnMode;
- if (filters['onlineFromHours'] == 8 && station.onlineInfo?.statusID != 'no-limit') return returnMode;
-
- if (station.onlineInfo?.statusID == 'ending' && filters['endingStatus']) return returnMode;
- if (
- (station.onlineInfo?.statusID == 'not-signed' || station.onlineInfo?.statusID == 'unavailable') &&
- filters['unavailableStatus']
- )
- return returnMode;
- if (station.onlineInfo?.statusID == 'brb' && filters['afkStatus']) return returnMode;
- if (station.onlineInfo?.statusID == 'no-space' && filters['noSpaceStatus']) return returnMode;
-
- if (station.onlineInfo && filters['occupied']) return returnMode;
- if (!station.onlineInfo && filters['free']) return returnMode;
- if (station.generalInfo?.availability == 'unavailable' && filters['unavailable'] && !station.onlineInfo)
- return returnMode;
-
- if (station.generalInfo) {
- const { routes, availability, controlType, lines, reqLevel, signalType, SUP, authors } = station.generalInfo;
-
- if (availability == 'abandoned' && filters['abandoned'] && !station.onlineInfo) return returnMode;
-
- if (availability == 'default' && filters['default']) return returnMode;
-
- if (
- availability != 'default' &&
- filters['notDefault'] &&
- !(availability == 'abandoned' || availability == 'unavailable')
- )
- return returnMode;
-
- if (filters['real'] && lines) return returnMode;
- if (filters['fictional'] && !lines) return returnMode;
-
- if (
- reqLevel + (availability == 'nonPublic' || availability == 'unavailable' || availability == 'abandoned' ? 1 : 0) <
- filters['minLevel']
- )
- return returnMode;
-
- if (
- reqLevel + (availability == 'nonPublic' || availability == 'unavailable' || availability == 'abandoned' ? 1 : 0) >
- filters['maxLevel']
- )
- return returnMode;
-
- if (
- filters['no-1track'] &&
- (routes.oneWayCatenaryRouteNames.length != 0 || routes.oneWayNoCatenaryRouteNames.length != 0)
- )
- return returnMode;
- if (
- filters['no-2track'] &&
- (routes.twoWayCatenaryRouteNames.length != 0 || routes.twoWayNoCatenaryRouteNames.length != 0)
- )
- return returnMode;
-
- if (routes.oneWayCatenaryRouteNames.length < filters['minOneWayCatenary']) return returnMode;
- if (routes.oneWayNoCatenaryRouteNames.length < filters['minOneWay']) return returnMode;
-
- if (routes.twoWayCatenaryRouteNames.length < filters['minTwoWayCatenary']) return returnMode;
- if (routes.twoWayNoCatenaryRouteNames.length < filters['minTwoWay']) return returnMode;
-
- if (filters[controlType]) return returnMode;
- if (filters[signalType]) return returnMode;
-
- if (filters['SPK'] && controlType === 'SPK') return returnMode;
- if (filters['SCS'] && controlType === 'SCS') return returnMode;
- if (filters['SPE'] && controlType === 'SPE') return returnMode;
- if (filters['SUP'] && SUP) return returnMode;
- if (filters['noSUP'] && !SUP) return returnMode;
-
- // if (filters['SCS'] && filters['SPK'] && (controlType.includes('SPK') || controlType.includes('SCS')))
- // return returnMode;
-
- if (filters['mechaniczne'] && controlType == 'mechaniczne') return returnMode;
- if (filters['mechaniczne+SPK'] && controlType == 'mechaniczne+SPK') return returnMode;
- if (filters['mechaniczne+SCS'] && controlType == 'mechaniczne+SCS') return returnMode;
-
- if (filters['ręczne'] && controlType == 'ręczne') return returnMode;
- if (filters['ręczne+SPK'] && controlType == 'ręczne+SPK') return returnMode;
- if (filters['ręczne+SCS'] && controlType == 'ręczne+SCS') return returnMode;
-
- if (filters['SBL'] && routes.sblRouteNames.length > 0) return returnMode;
- if (filters['PBL'] && routes.sblRouteNames.length == 0) return returnMode;
-
- if (
- filters['authors'].length > 3 &&
- !authors?.map((a) => a.toLocaleLowerCase()).includes(filters['authors'].toLocaleLowerCase())
- )
- return returnMode;
- }
-
- return true;
-};
-
-const filterInitStates: Filter = {
- default: false,
- notDefault: false,
- real: false,
- fictional: false,
- SPK: false,
- SCS: false,
- SPE: false,
- SUP: false,
- noSUP: false,
- ręczne: false,
- 'ręczne+SPK': false,
- 'ręczne+SCS': false,
- mechaniczne: false,
- 'mechaniczne+SPK': false,
- 'mechaniczne+SCS': false,
- współczesna: false,
- kształtowa: false,
- historyczna: false,
- mieszana: false,
- SBL: false,
- PBL: false,
- minLevel: 0,
- maxLevel: 20,
- minOneWayCatenary: 0,
- minOneWay: 0,
- minTwoWayCatenary: 0,
- minTwoWay: 0,
- 'include-selected': false,
- 'no-1track': false,
- 'no-2track': false,
- free: true,
- occupied: false,
- ending: false,
- nonPublic: false,
- unavailable: true,
- abandoned: true,
- afkStatus: false,
- endingStatus: false,
- noSpaceStatus: false,
- unavailableStatus: false,
- unsignedStatus: false,
-
- authors: '',
-
- onlineFromHours: 0,
-};
+import { filterInitStates } from './constants/initFilterStates';
+import { filterStations, sortStations } from './utils/filterUtils';
export const useStationFiltersStore = defineStore('stationFiltersStore', {
state() {
@@ -231,6 +18,12 @@ export const useStationFiltersStore = defineStore('stationFiltersStore', {
};
},
+ getters: {
+ areFiltersAtDefault(state) {
+ return Object.keys(state.filters).every((f) => state.filters[f] === filterInitStates[f]);
+ },
+ },
+
actions: {
getFilteredStationList(stationList: Station[], region: string): Station[] {
return stationList
@@ -241,7 +34,7 @@ export const useStationFiltersStore = defineStore('stationFiltersStore', {
return station;
})
- .filter((station) => filterStations(station, this.filters, this.store.isOffline))
+ .filter((station) => filterStations(station, this.filters))
.sort((a, b) => sortStations(a, b, this.sorterActive));
},
@@ -249,10 +42,10 @@ export const useStationFiltersStore = defineStore('stationFiltersStore', {
if (!StorageManager.isRegistered('options_saved')) return;
this.inputs.options.forEach((option) => {
- if (!StorageManager.isRegistered(option.id)) return;
- const savedValue = StorageManager.getBooleanValue(option.id);
+ if (!StorageManager.isRegistered(option.name)) return;
+ const savedValue = StorageManager.getBooleanValue(option.name);
- this.filters[option.id] = savedValue;
+ this.filters[option.name] = savedValue;
option.value = !savedValue;
});
diff --git a/src/store/utils/filterUtils.ts b/src/store/utils/filterUtils.ts
index 1c19a31..02a3c7b 100644
--- a/src/store/utils/filterUtils.ts
+++ b/src/store/utils/filterUtils.ts
@@ -1,3 +1,4 @@
+import Filter from '../../scripts/interfaces/Filter';
import Station from '../../scripts/interfaces/Station';
export const sortStations = (a: Station, b: Station, sorter: { index: number; dir: number }) => {
@@ -54,131 +55,86 @@ export const sortStations = (a: Station, b: Station, sorter: { index: number; di
return a.name.localeCompare(b.name);
};
-export const filterStations = (station: Station, filters: { [key: string]: any }, isOffline = false) => {
- const returnMode = false;
+export const filterStations = (station: Station, filters: Filter) => {
+ if (!station.onlineInfo && filters['free']) return false;
- if ((station.generalInfo?.availability == 'nonPublic' || !station.generalInfo) && filters['nonPublic'])
- return returnMode;
+ if (station.onlineInfo) {
+ const { statusID, statusTimestamp } = station.onlineInfo;
- if (station.onlineInfo?.statusID == 'ending' && filters['ending']) return returnMode;
+ const isEnding = statusID == 'ending' && filters['endingStatus'];
+ const isNotSigned = (statusID == 'not-signed' || statusID == 'unavailable') && filters['unavailableStatus'];
+ const isAFK = statusID == 'brb' && filters['afkStatus'];
+ const isNoSpace = statusID == 'no-space' && filters['noSpaceStatus'];
+ const isOccupied = station.onlineInfo && filters['occupied'];
- if (
- station.onlineInfo &&
- station.onlineInfo.statusTimestamp > 0 &&
- filters['onlineFromHours'] < 8 &&
- station.onlineInfo.statusTimestamp <= Date.now() + filters['onlineFromHours'] * 3600000
- )
- return returnMode;
+ const isOnlineInBounds =
+ (filters['onlineFromHours'] < 8 &&
+ statusTimestamp > 0 &&
+ statusTimestamp <= Date.now() + filters['onlineFromHours'] * 3600000) ||
+ (filters['onlineFromHours'] > 0 && statusTimestamp <= 0) ||
+ (filters['onlineFromHours'] == 8 && statusID != 'no-limit');
- if (filters['onlineFromHours'] > 0 && station.onlineInfo && station.onlineInfo.statusTimestamp <= 0)
- return returnMode;
- if (filters['onlineFromHours'] == 8 && station.onlineInfo?.statusID != 'no-limit') return returnMode;
+ if (isEnding || isOnlineInBounds || isNotSigned || isAFK || isNoSpace || isOccupied) return false;
+ }
- if (station.onlineInfo?.statusID == 'ending' && filters['endingStatus']) return returnMode;
- if (
- (station.onlineInfo?.statusID == 'not-signed' || station.onlineInfo?.statusID == 'unavailable') &&
- filters['unavailableStatus']
- )
- return returnMode;
- if (station.onlineInfo?.statusID == 'brb' && filters['afkStatus']) return returnMode;
- if (station.onlineInfo?.statusID == 'no-space' && filters['noSpaceStatus']) return returnMode;
-
- if (station.onlineInfo && filters['occupied']) return returnMode;
- if (!station.onlineInfo && filters['free']) return returnMode;
- if (station.generalInfo?.availability == 'unavailable' && filters['unavailable'] && !station.onlineInfo)
- return returnMode;
+ if ((station.generalInfo?.availability == 'nonPublic' || !station.generalInfo) && filters['nonPublic']) return false;
if (station.generalInfo) {
- const routes = station.generalInfo.routes;
- const availability = station.generalInfo.availability;
+ const { routes, availability, controlType, lines, reqLevel, signalType, SUP, authors } = station.generalInfo;
- if (filters['abandoned'] && availability == 'abandoned' && !station.onlineInfo) return returnMode;
+ if (availability == 'unavailable' && filters['unavailable'] && !station.onlineInfo) return false;
+ if (availability == 'abandoned' && filters['abandoned'] && !station.onlineInfo) return false;
+ if (availability == 'default' && filters['default']) return false;
- if (availability == 'default' && filters['default']) return returnMode;
if (
availability != 'default' &&
filters['notDefault'] &&
!(availability == 'abandoned' || availability == 'unavailable')
)
- return returnMode;
+ return false;
- if (filters['real'] && station.generalInfo.lines != '') return returnMode;
- if (
- filters['fictional'] &&
- station.generalInfo.lines == '' &&
- availability != 'abandoned' &&
- availability != 'unavailable'
- )
- return returnMode;
+ if (filters['real'] && lines) return false;
+ if (filters['fictional'] && !lines) return false;
- if (
- station.generalInfo.reqLevel +
- (availability == 'nonPublic' || availability == 'unavailable' || availability == 'abandoned' ? 1 : 0) <
- filters['minLevel']
- )
- return returnMode;
- if (
- station.generalInfo.reqLevel +
- (availability == 'nonPublic' || availability == 'unavailable' || availability == 'abandoned' ? 1 : 0) >
- filters['maxLevel']
- )
- return returnMode;
+ const otherAvailability =
+ availability == 'nonPublic' || availability == 'unavailable' || availability == 'abandoned';
+
+ if (reqLevel + (otherAvailability ? 1 : 0) < filters['minLevel']) return false;
+
+ if (reqLevel + (otherAvailability ? 1 : 0) > filters['maxLevel']) return false;
if (
filters['no-1track'] &&
(routes.oneWayCatenaryRouteNames.length != 0 || routes.oneWayNoCatenaryRouteNames.length != 0)
)
- return returnMode;
+ return false;
+
if (
filters['no-2track'] &&
(routes.twoWayCatenaryRouteNames.length != 0 || routes.twoWayNoCatenaryRouteNames.length != 0)
)
- return returnMode;
+ return false;
- if (routes.oneWayCatenaryRouteNames.length < filters['minOneWayCatenary']) return returnMode;
- if (routes.oneWayNoCatenaryRouteNames.length < filters['minOneWay']) return returnMode;
+ if (routes.oneWayCatenaryRouteNames.length < filters['minOneWayCatenary']) return false;
+ if (routes.oneWayNoCatenaryRouteNames.length < filters['minOneWay']) return false;
- if (routes.twoWayCatenaryRouteNames.length < filters['minTwoWayCatenary']) return returnMode;
- if (routes.twoWayNoCatenaryRouteNames.length < filters['minTwoWay']) return returnMode;
+ if (routes.twoWayCatenaryRouteNames.length < filters['minTwoWayCatenary']) return false;
+ if (routes.twoWayNoCatenaryRouteNames.length < filters['minTwoWay']) return false;
- if (filters[station.generalInfo.controlType]) return returnMode;
- if (filters[station.generalInfo.signalType]) return returnMode;
+ if (filters[controlType]) return false;
+ if (filters[signalType]) return false;
- if (
- filters['SPK'] &&
- (station.generalInfo.controlType === 'SPK' || station.generalInfo.controlType.includes('+SPK'))
- )
- return returnMode;
- if (
- filters['SCS'] &&
- (station.generalInfo.controlType === 'SCS' || station.generalInfo.controlType.includes('+SCS'))
- )
- return returnMode;
- if (
- filters['SPE'] &&
- (station.generalInfo.controlType === 'SPE' || station.generalInfo.controlType.includes('+SPE'))
- )
- return returnMode;
- if (filters['SUP'] && station.generalInfo.SUP) return returnMode;
+ if (filters['SUP'] && SUP) return false;
+ if (filters['noSUP'] && !SUP) return false;
- if (
- filters['SCS'] &&
- filters['SPK'] &&
- (station.generalInfo.controlType.includes('SPK') || station.generalInfo.controlType.includes('SCS'))
- )
- return returnMode;
-
- if (filters['mechaniczne'] && station.generalInfo.controlType.includes('mechaniczne')) return returnMode;
-
- if (filters['ręczne'] && station.generalInfo.controlType.includes('ręczne')) return returnMode;
-
- if (filters['SBL'] && routes.sblRouteNames.length > 0) return returnMode;
+ if (filters['SBL'] && routes.sblRouteNames.length > 0) return false;
+ if (filters['PBL'] && routes.sblRouteNames.length == 0) return false;
if (
filters['authors'].length > 3 &&
- !station.generalInfo.authors?.map((a) => a.toLocaleLowerCase()).includes(filters['authors'].toLocaleLowerCase())
+ !authors?.map((a) => a.toLocaleLowerCase()).includes(filters['authors'].toLocaleLowerCase())
)
- return returnMode;
+ return false;
}
return true;
diff --git a/src/styles/card.scss b/src/styles/card.scss
index 0906d22..9739d44 100644
--- a/src/styles/card.scss
+++ b/src/styles/card.scss
@@ -24,7 +24,8 @@
overflow: hidden;
background: #202020e8;
- box-shadow: 0 0 15px 5px #303030;
+ box-shadow: 0 0 15px 0 black;
+ border: 1px solid #202020e8;
width: 95%;
max-width: 700px;
@@ -44,3 +45,9 @@
cursor: pointer;
}
}
+
+@include smallScreen {
+ .card {
+ max-height: 85vh;
+ }
+}