367 lines
7.8 KiB
SCSS
367 lines
7.8 KiB
SCSS
@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 768–1050px 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;
|
||
}
|
||
}
|
||
}
|