/**
 * The airline ticket details modal: shell, header, map frame and footer.
 *
 * A centred sheet with a fixed header and footer and one scrolling middle, so the
 * route it belongs to and the price it costs stay on screen however long the
 * itinerary is. On phones it becomes a bottom sheet, which is the gesture the rest
 * of the site's popups already teach.
 *
 * It carries its own copy of the ticket palette because it is mounted on `body`,
 * outside any card — brand teal keeps the sheet aligned with the rest of the site.
 */

.tbo-modal {
    --tt-accent: #445def;
    --tt-accent-soft: rgba(68, 93, 239, 0.1);
    --tt-accent-line: rgba(68, 93, 239, 0.28);
    --tt-bg: var(--color-surface);
    --tt-hairline: rgba(60, 60, 67, 0.13);
    --tt-chip: rgba(60, 60, 67, 0.06);
    --tt-good: #157f52;
    --tt-warn: #9a5b00;
    --tt-alert: #b3261e;
    --tt-rail: rgba(68, 93, 239, 0.3);

    /* Above the flight details popup, which is 10000: only one can be open, and
       this one was opened last. Sized with dvh so iOS Safari's collapsing chrome
       cannot make the sheet taller than the pixels the user can see. */
    position: fixed;
    inset: 0;
    z-index: 10001;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    max-height: 100vh;
    max-height: 100dvh;
    padding: 28px 20px;
    overflow: hidden;
}

.tbo-modal[hidden] {
    display: none;
}

.tbo-modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.62);
    opacity: 0;
    transition: opacity 0.22s ease;
    backdrop-filter: blur(5px);
    -webkit-backdrop-filter: blur(5px);
}

.tbo-modal.is-open .tbo-modal__backdrop {
    opacity: 1;
}

.tbo-modal__dialog {
    position: relative;
    display: flex;
    flex-direction: column;
    width: min(960px, 100%);
    max-height: min(92vh, 940px);
    max-height: min(92dvh, 940px);
    min-height: 0;
    overflow: hidden;
    color: var(--color-text);
    background: var(--tt-bg);
    border: 0.5px solid var(--tt-hairline);
    border-radius: 24px;
    box-shadow: 0 32px 80px rgba(0, 0, 0, 0.32);
    opacity: 0;
    transform: translateY(14px) scale(0.99);
    transition:
        opacity 0.22s ease,
        transform 0.22s ease;
}

.tbo-modal.is-open .tbo-modal__dialog {
    opacity: 1;
    transform: none;
}

.tbo-modal__dialog:focus {
    outline: none;
}

/* Header: which trip this is, and how to leave.
 *
 * Close sits in the flex row as a non-shrinking sibling. Absolute positioning was
 * a false fix: when Safari's large `vh` pushed the sheet under the browser chrome,
 * the button went with the head. Keeping it in flow and sizing the sheet to `dvh`
 * with a safe-area pad is what the rest of the site's mobile sheets already do.
 */

.tbo-modal__head {
    display: flex;
    flex: 0 0 auto;
    gap: 12px;
    align-items: flex-start;
    padding: 18px 22px 15px;
    border-bottom: 1px solid var(--tt-hairline);
}

.tbo-modal__kind {
    flex: 0 0 auto;
    margin-top: 5px;
    font-size: 10px;
    font-weight: 650;
    letter-spacing: 0.09em;
    color: var(--tt-accent);
    text-transform: uppercase;
    white-space: nowrap;
}

.tbo-modal__identity {
    display: flex;
    flex: 1 1 auto;
    gap: 13px;
    align-items: center;
    min-width: 0;
}

.tbo-modal__marks {
    display: inline-flex;
    flex: 0 0 auto;
    gap: 4px;
    align-items: center;
}

.tbo-modal__titles {
    min-width: 0;
}

.tbo-modal__title {
    margin: 0;
    overflow: hidden;
    font-size: 20px;
    font-weight: 650;
    letter-spacing: -0.025em;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.tbo-modal__subtitle {
    margin: 3px 0 0;
    overflow: hidden;
    font-size: 12.5px;
    line-height: 1.35;
    color: var(--color-text-secondary);
    white-space: nowrap;
    text-overflow: ellipsis;
}

.tbo-modal__close {
    display: grid;
    flex: 0 0 auto;
    place-items: center;
    width: 36px;
    height: 36px;
    min-width: 36px;
    max-width: 36px;
    min-height: 36px;
    max-height: 36px;
    padding: 0;
    margin-left: auto;
    aspect-ratio: 1;
    color: var(--color-text-secondary);
    cursor: pointer;
    background: var(--tt-chip);
    border: none;
    border-radius: 50%;
    transition:
        background 0.15s ease,
        color 0.15s ease;
    -webkit-tap-highlight-color: transparent;
}

/* Sized in px so the X cannot collapse when an inherited em icon rule shrinks. */
.tbo-modal__close .tbo-icon {
    display: block;
    width: 18px;
    height: 18px;
}

.tbo-modal__close:hover {
    color: var(--color-text);
    background: var(--tt-accent-soft);
}

.tbo-modal__close:focus-visible {
    outline: 2px solid var(--tt-accent);
    outline-offset: 2px;
}

/* The scrolling middle. */

.tbo-modal__scroll {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 22px;
    min-height: 0;
    padding: 20px 22px 24px;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}

/* Map shell only — city path sits on the itinerary heading with the cabin chip. */
.tbo-modal__route-panel {
    display: flex;
    flex: 0 0 auto;
    flex-direction: column;
    min-width: 0;
}

/*
 * The route map.
 *
 * It shows the shape of the journey and its stops. No distance and no flying time
 * are drawn on it: every figure about this ticket comes from the airline, and a
 * number computed here would contradict one of theirs.
 */
.tbo-modal__map {
    position: relative;
    flex: 0 0 auto;
    height: 260px;
    overflow: hidden;
    background: var(--tt-chip);
    border: 1px solid var(--tt-hairline);
    border-radius: 16px;
}

.tbo-map__canvas {
    position: absolute;
    inset: 0;
}

/* Marker labels are "D", "A" or a three-letter code, so the pill grows to fit. */
.tbo-map__marker {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 5px;
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--color-map-marker-text, #fff);
    border: 3px solid var(--color-map-marker-surface, #fff);
    border-radius: var(--radius-full, 999px);
    box-shadow: var(--shadow-map-marker, 0 2px 6px rgba(0, 0, 0, 0.35));
}

/* Footer: the total on the left, the one decision on the right. */

.tbo-modal__foot {
    display: flex;
    flex: 0 0 auto;
    gap: 18px;
    align-items: center;
    justify-content: space-between;
    padding: 14px 22px;
    border-top: 1px solid var(--tt-hairline);
}

.tbo-modal__price {
    display: flex;
    flex-direction: column;
    gap: 2px;
    align-items: flex-start;
    min-width: 0;
}

.tbo-modal__amount {
    font-size: 24px;
    font-weight: 650;
    line-height: 1.1;
    letter-spacing: -0.04em;
    font-variant-numeric: tabular-nums;
}

.tbo-modal__price-note {
    font-size: 12px;
    line-height: 1.3;
    color: var(--color-text-muted);
}

/* Seat urgency sits above Buy ticket — the decision it is meant to hurry. */
.tbo-modal__seats {
    margin: 0;
    font-size: 12px;
    font-weight: 650;
    line-height: 1.25;
    color: var(--tt-alert);
    white-space: nowrap;
    text-align: center;
}

/* The purchase block: urgency, buy control, room under it for an error. */

.tbo-modal__purchase {
    display: flex;
    flex: 0 0 auto;
    flex-direction: column;
    gap: 6px;
    align-items: stretch;
}

.tbo-modal__buy {
    padding: 12px 26px;
    font: inherit;
    font-size: 15px;
    font-weight: 650;
    color: #fff;
    background: var(--tt-accent);
    border: none;
    border-radius: 12px;
    cursor: pointer;
    transition:
        filter 0.15s ease,
        transform 0.15s ease;
}

.tbo-modal__buy:hover:not(:disabled) {
    filter: brightness(1.08);
}

.tbo-modal__buy:active:not(:disabled) {
    transform: translateY(1px);
}

.tbo-modal__buy:disabled {
    cursor: progress;
    opacity: 0.65;
}

.tbo-modal__buy:focus-visible {
    outline: 2px solid var(--tt-accent);
    outline-offset: 3px;
}

.tbo-modal__purchase-error {
    margin: 0;
    font-size: 12px;
    line-height: 1.4;
    font-weight: 550;
    color: var(--tt-alert);
    text-align: right;
}

/* Dark theme. */

:root[data-theme="dark"] .tbo-modal {
    --tt-accent: #445def;
    --tt-accent-soft: rgba(68, 93, 239, 0.16);
    --tt-accent-line: rgba(68, 93, 239, 0.38);
    --tt-bg: #1b1d23;
    --tt-hairline: rgba(255, 255, 255, 0.12);
    --tt-chip: rgba(255, 255, 255, 0.07);
    --tt-good: #6ee7a8;
    --tt-warn: #f6c177;
    --tt-alert: #ff938c;
    --tt-rail: rgba(68, 93, 239, 0.38);
}

:root[data-theme="dark"] .tbo-modal__dialog {
    box-shadow: 0 32px 80px rgba(0, 0, 0, 0.6);
}
