Files
flights_web/src/ui/flights/FlightCard.scss
T

367 lines
7.8 KiB
SCSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@use "../../styles/variables" as vars;
@use "../../styles/colors" as colors;
@use "../../styles/fonts" as fonts;
@use "../../styles/screen" as screen;
.flight-card {
display: flex;
flex-direction: column;
background: transparent;
transition: background-color 120ms ease;
& + & {
border-top: 1px dashed colors.$border;
}
&--expanded {
background: colors.$blue-extra-light;
border-left: 3px solid colors.$blue;
}
&--clickable .flight-card__row {
cursor: pointer;
&:hover {
background-color: rgba(46, 87, 255, 0.04);
}
&:focus-visible {
outline: 2px solid colors.$blue;
outline-offset: -2px;
}
}
// Matches Angular's board-flight-header grid (8 named tracks, no row
// gap, 15px column gap):
// [number] 80px [logo] 120px [dep-time] 100px
// [dep-station] minmax(45px, 145px) [status] minmax(85px, 145px)
// [arr-time] 120px [arr-station] minmax(45px, 145px) [arrow] 10px
// Mirrors Angular `flight-details-row-part-header :host` grid exactly:
// [number] 60px [logo] 120px [dep-time] 100px
// [dep-station] 1fr [status] minmax(85px, 145px)
// [arr-time] 120px [arr-station] 1fr
// plus `padding: $space-l $space-xl` (15px / 20px) instead of the
// uniform 20px React was using — makes rows ~10px shorter per card.
&__row {
display: grid;
grid-template-columns:
60px 120px 100px 1fr minmax(85px, 145px) 120px 1fr 10px;
align-items: center;
gap: 0 vars.$space-l;
padding: vars.$space-l vars.$space-xl;
min-height: 68px;
}
// Schedule mode swaps the central status column for a wider duration
// pill — Angular's grid widens the station/duration tracks to fit.
&--schedule .flight-card__row {
grid-template-columns: 80px 120px 100px minmax(80px, 1fr) 100px 100px minmax(80px, 1fr) 16px;
gap: 0 vars.$space-l;
}
&__number {
font-weight: fonts.$font-medium;
color: colors.$text-color;
font-size: 14px;
}
&__aircraft {
font-size: 11px;
color: colors.$light-gray;
font-weight: normal;
margin-top: 4px;
}
&__operator {
display: flex;
align-items: center;
gap: 6px;
}
&__time {
// TimeGroup owns its own 30px/300 typography; just align it.
text-align: left;
&--arrival {
text-align: left;
}
}
&__station {
min-width: 0;
text-align: left;
&--arrival {
text-align: right;
.station {
align-items: flex-start;
}
}
}
&__status {
display: flex;
justify-content: center;
}
&__chevron {
color: colors.$blue;
font-size: 18px;
transition: transform 150ms ease;
&--open {
transform: rotate(180deg);
}
}
&__inline-actions {
display: flex;
align-items: center;
gap: vars.$space-s;
}
&__duration {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
font-size: 12px;
color: colors.$light-gray;
white-space: nowrap;
}
&__duration-icon {
width: 18px;
height: 18px;
display: inline-block;
background: url("/assets/img/time-blue.svg") no-repeat center / contain;
}
&__duration-text {
line-height: 1.1;
}
&__expanded {
padding: 0 vars.$space-xl vars.$space-xl;
display: flex;
flex-direction: column;
gap: vars.$space-m;
background: colors.$blue-extra-light;
}
&__detail-row {
display: grid;
grid-template-columns: 140px 1fr 1fr;
gap: vars.$space-xl;
padding: vars.$space-m 0;
border-bottom: 1px dashed colors.$border;
align-items: flex-start;
&:last-child {
border-bottom: none;
}
}
&__detail-label {
color: colors.$light-gray;
font-size: 14px;
}
&__detail-group {
display: flex;
gap: vars.$space-xl;
flex-wrap: wrap;
> div {
display: flex;
flex-direction: column;
gap: 2px;
}
}
&__detail-caption {
font-size: 12px;
color: colors.$light-gray;
}
&__detail-value {
font-weight: 500;
color: colors.$text-color;
font-size: 14px;
}
&__detail-status {
display: inline-flex;
align-items: center;
gap: 6px;
color: colors.$text-color;
// Angular shows a leading dot whose colour matches the boarding state.
// Default is grey ('Уточняется' / 'Запланирован'); active states get
// coloured dots.
&--finished .flight-card__status-dot { background: colors.$green; }
&--inprogress .flight-card__status-dot { background: colors.$blue; }
&--expected .flight-card__status-dot { background: colors.$orange; }
&--specified .flight-card__status-dot { background: #8a8a8a; }
&--scheduled .flight-card__status-dot { background: #8a8a8a; }
}
&__status-dot {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
background: #8a8a8a;
flex-shrink: 0;
}
&__actions {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: vars.$space-s;
}
&__share-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
padding: 0;
background: transparent;
border: none;
border-radius: vars.$border-radius;
cursor: pointer;
transition: background-color 120ms ease;
img {
width: 20px;
height: 20px;
}
&:hover {
background-color: rgba(46, 87, 255, 0.08);
}
}
&__status-btn {
background: transparent;
color: colors.$blue;
border: 1px solid colors.$blue;
border-radius: vars.$border-radius;
padding: 9px 22px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
text-decoration: none;
transition: background-color 150ms ease;
&:hover { background: rgba(46, 87, 255, 0.06); }
}
&__buy-btn {
background: colors.$orange;
color: colors.$white;
border: none;
border-radius: vars.$border-radius;
padding: 10px 24px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
text-decoration: none;
transition: background-color 150ms ease;
&:hover { background: colors.$orange--hover; }
}
&__details-btn {
background: colors.$blue;
color: colors.$white;
border: none;
border-radius: vars.$border-radius;
padding: 10px 24px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: background-color 150ms ease;
&:hover {
background: colors.$blue--hover;
}
}
// Tablet breakpoint narrows the grid to fit the sidebar + results
// column at 7681050px widths. Mirrors Angular's tablets() override
// in board-flight-header.component.tablets.scss.
@include screen.tablets {
&__row {
grid-template-columns:
70px 90px 90px 1fr 85px 90px 1fr 10px;
gap: 0 vars.$space-m;
padding: vars.$space-l;
}
}
@include screen.mobile {
&__row {
grid-template-columns: 1fr auto 1fr;
grid-template-areas:
"operator status number"
"time-dep status time-arr"
"station-dep . station-arr";
gap: vars.$space-s vars.$space-m;
padding: vars.$space-m vars.$space-l;
align-items: start;
}
&__chevron { display: none; }
&__number {
grid-area: number;
text-align: right;
}
&__operator {
grid-area: operator;
align-items: flex-start;
}
&__time {
grid-area: time-dep;
text-align: left;
&--arrival {
grid-area: time-arr;
text-align: right;
}
}
&__station {
grid-area: station-dep;
text-align: left;
&--arrival {
grid-area: station-arr;
text-align: left;
.station {
align-items: flex-start;
}
}
}
&__status {
grid-area: status;
align-self: center;
justify-content: center;
}
&__detail-row {
grid-template-columns: 1fr;
}
}
}