/*
 * Every `font-size` here is multiplied by `--geex-type-scale`, the panel's type
 * multiplier from resources/css/geex-theme.css. The literals are still the
 * design sizes — 0.8125rem is "13px in the reference" — so the ramp stays
 * readable and one number in the theme moves the whole panel at once. The `, 1`
 * fallback keeps these components at their design size if the theme stylesheet
 * is ever not loaded, rather than collapsing them.
 */

/*
 * ============================================================================
 * Product information tab
 * ============================================================================
 *
 * The page is a grid, not a column of cards: the form sits beside a fixed
 * completeness rail, and inside the form the basics/booking/contacts stack
 * sits beside the destination and pricing pair.
 *
 * The switch is a *container* query, not a media query. Filament's own
 * `xl:`-style column spans key off the viewport, which here is the wrong
 * number by the width of the panel sidebar — on a 1500px window the form only
 * gets about 1100px, so a viewport rule either fires when there is no room or
 * fails to fire when there is. Measuring the form itself is exact, and it keeps
 * working if the sidebar is collapsed or the browser is zoomed.
 *
 * Filament writes its track counts and spans into `--cols-*` / `--col-span-*`,
 * so the query restates both rather than trying to override the variables.
 * Below the threshold none of this applies and Filament's single column stands.
 */
.travel-basics {
    container-name: travel-basics;
    container-type: inline-size;
}

.travel-basics > .fi-sc {
    align-items: start;
}

@container travel-basics (min-width: 60rem) {
    .travel-basics > .fi-sc {
        /*
         * Tighter than Filament's 1.5rem. At three cards to a row the default
         * gap eats more width than the gain from sitting them side by side.
         */
        gap: 1rem;

        /*
         * The rail takes a share of the form rather than a fixed slab, so a
         * ~1000px form does not hand a sixth of itself to a progress ring. It
         * stops growing at 14rem, which is all the list needs.
         */
        grid-template-columns: minmax(0, 1fr) clamp(11.5rem, 16%, 14rem);
    }

    /*
     * The rail follows the page. It is a grid item, so the grid row is its
     * containing block and that is as tall as the form beside it.
     */
    .travel-basics > .fi-sc > :last-child {
        position: sticky;
        top: 5rem;
    }

    .travel-form-grid > .fi-sc,
    .travel-form-stack > .fi-sc {
        gap: 1rem;
    }

    /* Basics/booking/contacts, then the destination/pricing stack; anything
       after that (custom fields) keeps the full twelve. */
    .travel-form-grid > .fi-sc {
        grid-template-columns: repeat(12, minmax(0, 1fr));
    }

    .travel-form-grid > .fi-sc > :nth-child(1) {
        grid-column: span 7 / span 7;
    }

    .travel-form-grid > .fi-sc > :nth-child(2) {
        grid-column: span 5 / span 5;
    }

    .travel-form-grid > .fi-sc > :nth-child(n + 3) {
        grid-column: 1 / -1;
    }
}

/*
 * ============================================================================
 * Product media tab
 * ============================================================================
 *
 * Same two rails as the product-information tab: the work, then the score and
 * the upload rules.
 */
.travel-media {
    container-name: travel-media;
    container-type: inline-size;
}

.travel-media > .fi-sc {
    align-items: start;
}

@container travel-media (min-width: 60rem) {
    .travel-media > .fi-sc {
        gap: 1rem;
        grid-template-columns: minmax(0, 1fr) clamp(11.5rem, 16%, 14rem);
    }

    .travel-media > .fi-sc > :last-child {
        position: sticky;
        top: 5rem;
    }

    .travel-media-blocks > .fi-sc {
        gap: 1rem;
        grid-template-columns: repeat(12, minmax(0, 1fr));
    }

    .travel-media-blocks > .fi-sc > :nth-child(1) {
        grid-column: span 6 / span 6;
    }

    .travel-media-blocks > .fi-sc > :nth-child(2) {
        grid-column: span 6 / span 6;
    }
}

/* ---------------------------------------------------------- image library */

.travel-library {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* -------------------------------------------------------------- masthead */

.travel-masthead {
    align-items: baseline;
    display: flex;
    column-gap: 0.75rem;
    flex-wrap: wrap;
    row-gap: 0.25rem;
}

.travel-masthead-title {
    font-size: calc(1.125rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-masthead-summary {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    margin-inline-end: auto;
}

/*
 * Everything in this panel writes through, which is unusual on a page whose
 * other tabs wait for a save button. The chip is the acknowledgement; Alpine
 * takes it away again after a moment.
 */
.travel-saved {
    align-items: center;
    color: var(--geex-success-text, #15803d);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
}

.travel-saved .fi-icon {
    height: 1rem;
    width: 1rem;
}

/* ----------------------------------------------------------------- cards */

.travel-card {
    background-color: var(--geex-surface, #fdfdfd);
    border-radius: var(--geex-radius-card, 24px);
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 1.25rem;
}

.travel-card-head {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    justify-content: space-between;
}

/*
 * Tools that belong to the heading rather than to the card, kept beside the
 * words they act on. Across a card this wide, space-between put them a screen's
 * width from the thing they were labelled for.
 */
.travel-card-head-inline {
    justify-content: flex-start;
}

.travel-card-title {
    align-items: center;
    display: flex;
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
    gap: 0.5rem;
}

.travel-card-tools {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.travel-card-foot {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.travel-note {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-count {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    font-variant-numeric: tabular-nums;
    font-weight: 400;
}

/* Says the cover slot is empty, next to the heading that owns it. */
.travel-badge-todo {
    background-color: var(--geex-warning-soft, rgba(245, 158, 11, 0.22));
    border-radius: var(--geex-radius-chip, 12px);
    color: var(--geex-warning-text, #92400e);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    font-weight: 500;
    padding: 0.125rem 0.5rem;
}

/* -------------------------------------------------------------- toolbars */

.travel-search {
    align-items: center;
    background-color: var(--geex-canvas, #f3f2f7);
    border-radius: var(--geex-radius-control, 8px);
    color: var(--geex-text-muted, #a3a3a3);
    display: flex;
    gap: 0.375rem;
    padding-inline: 0.625rem;
}

.travel-search .fi-icon {
    flex: none;
    height: 1rem;
    width: 1rem;
}

.travel-search-input {
    background: none;
    border: 0;
    color: var(--geex-text, #464255);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    padding-block: 0.4375rem;
    width: 11rem;
}

.travel-search-input:focus {
    outline: none;
}

.travel-select {
    background-color: var(--geex-canvas, #f3f2f7);
    border: 0;
    border-radius: var(--geex-radius-control, 8px);
    color: var(--geex-text, #464255);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    padding: 0.4375rem 1.75rem 0.4375rem 0.625rem;
}

/*
 * The secondary ways in — pick from the library, add a link, clear the cover.
 *
 * Filament's `color('gray')` renders no colour utilities at all here, which
 * comes out looking unstyled rather than secondary. This gives them the same
 * flat grey as the search box and the sort control beside them, so the toolbar
 * reads as one row of quiet things and the filled upload button stays the one
 * obvious action.
 */
.travel-btn-quiet.fi-btn {
    background-color: var(--geex-canvas, #f3f2f7);
    box-shadow: none;
    color: var(--geex-text, #464255);
}

.travel-btn-quiet.fi-btn:hover {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    color: var(--geex-primary, #ab54db);
}

.travel-btn-quiet.fi-btn .fi-icon {
    color: inherit;
}

/*
 * The EN/中文 switch in the page header. Filled with the Geex "Quatinery"
 * cream rather than the gray outline Filament gives a secondary action, so it
 * reads as a language chip and not as another header button.
 */
.travel-locale-switch.fi-btn {
    background-color: var(--geex-quaternary, #f1e6b9);
    box-shadow: none;
    color: var(--geex-text, #464255);
    --tw-ring-color: transparent;
    --tw-ring-shadow: 0 0 #0000;
}

.travel-locale-switch.fi-btn:hover {
    background-color: color-mix(in oklab, var(--geex-quaternary, #f1e6b9) 82%, var(--geex-text, #464255));
    color: var(--geex-text, #464255);
}

.travel-locale-switch.fi-btn .fi-icon {
    color: inherit;
}

.travel-toggle {
    align-items: center;
    cursor: pointer;
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
    white-space: nowrap;
}

.travel-bulk {
    align-items: center;
    background-color: var(--geex-canvas, #f3f2f7);
    border-radius: var(--geex-radius-control, 8px);
    display: flex;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
}

.travel-bulk-count {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    margin-inline-end: auto;
}

/* ----------------------------------------------------------------- cover */

/*
 * A reference, not the subject.
 *
 * Left to grow, a 16:9 frame on a wide screen stood the better part of a
 * thousand pixels tall — one photograph filling the viewport on a page whose
 * job is to manage twenty of them.
 */
.travel-cover {
    align-items: stretch;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.travel-cover-frame {
    align-items: center;
    aspect-ratio: 16 / 9;
    background-color: var(--geex-canvas, #f3f2f7);
    border-radius: var(--geex-radius-control, 8px);
    display: flex;
    flex: 1 1 12rem;
    justify-content: center;
    margin: 0;
    max-width: 22rem;
    overflow: hidden;
}

.travel-cover-frame img {
    height: 100%;
    object-fit: cover;
    width: 100%;
}

.travel-cover-empty {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    padding: 0.5rem;
    text-align: center;
}

.travel-cover-spec {
    color: var(--geex-text-muted, #a3a3a3);
    flex-basis: 100%;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-cover-add {
    flex: 0 0 10.5rem;
    min-height: 0;
}

/* --------------------------------------------------------------- tile grid */

.travel-tiles {
    display: grid;
    gap: 0.75rem;
    grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
}

/*
 * A card, not a cropped photograph. The facts underneath — how big it is, how
 * many places show it — are what make a shared library usable; without them
 * every tile is an anonymous thumbnail and "is this safe to change?" has no
 * answer on the page.
 */
.travel-tile {
    background-color: var(--geex-surface, #fdfdfd);
    border: 1px solid var(--geex-line, #eceaf3);
    border-radius: var(--geex-radius-control, 8px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.travel-tile-selected {
    border-color: var(--geex-primary, #ab54db);
    box-shadow: 0 0 0 1px var(--geex-primary, #ab54db);
}

.travel-tile-media {
    aspect-ratio: 4 / 3;
    background-color: var(--geex-canvas, #f3f2f7);
    position: relative;
}

.travel-tile-image {
    height: 100%;
    object-fit: cover;
    width: 100%;
}

.travel-tile-placeholder {
    align-items: center;
    color: var(--geex-text-muted, #a3a3a3);
    display: flex;
    flex-direction: column;
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
    height: 100%;
    justify-content: center;
    padding: 0.5rem;
    text-align: center;
}

.travel-tile-placeholder .fi-icon {
    height: 1.25rem;
    width: 1.25rem;
}

/*
 * The controls float over the photograph. Each sits on its own translucent
 * plate, because a white glyph on a bright sky is no glyph at all.
 */
.travel-tile-check,
.travel-tile-handle {
    position: absolute;
    z-index: 1;
}

.travel-tile-check {
    inset-block-start: 0.5rem;
    inset-inline-start: 0.5rem;
}

.travel-tile-handle {
    align-items: center;
    background-color: rgba(255, 255, 255, 0.85);
    border-radius: 6px;
    color: var(--geex-text-muted, #a3a3a3);
    cursor: grab;
    display: flex;
    inset-block-start: 50%;
    inset-inline-start: 0.375rem;
    opacity: 0;
    padding: 0.25rem 0;
    transform: translateY(-50%);
    transition: opacity 150ms;
}

.travel-tile:hover .travel-tile-handle,
.travel-tile-handle:focus-visible {
    opacity: 1;
}

.travel-tile-handle .fi-icon {
    height: 1rem;
    margin-inline: -0.3125rem;
    width: 1rem;
}

.travel-tile-badge {
    background-color: rgba(255, 255, 255, 0.9);
    border-radius: 6px;
    bottom: 0.5rem;
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    inset-inline-start: 0.5rem;
    padding: 0.125rem 0.5rem;
    position: absolute;
}

/*
 * Which picture the website leads with. Top *right*: it used to share the
 * top-left corner with the selection box, and the two sat on top of each other
 * the moment bulk select was switched on.
 */
.travel-tile-cover {
    background-color: var(--geex-primary, #ab54db);
    border-radius: 6px;
    color: #fff;
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    inset-block-start: 0.5rem;
    inset-inline-end: 0.5rem;
    padding: 0.125rem 0.5rem;
    position: absolute;
}

/*
 * Sits over the picture while the transcoder is still working on it. The tile
 * shows the uploaded original in the meantime, so without this it looks
 * finished when it is not.
 */
.travel-tile-status {
    backdrop-filter: blur(2px);
    background-color: rgba(0, 0, 0, 0.55);
    border-radius: 6px;
    bottom: 0.5rem;
    color: #fff;
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    inset-inline-end: 0.5rem;
    padding: 0.125rem 0.5rem;
    position: absolute;
}

.travel-tile-meta {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    padding: 0.5rem 0.625rem 0.375rem;
}

.travel-tile-name {
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.travel-tile-facts {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    font-variant-numeric: tabular-nums;
}

.travel-tile-foot {
    align-items: center;
    display: flex;
    justify-content: space-between;
}

.travel-tile-used {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
}

/*
 * One dashed cell per way in, sitting in the same grid as the photographs so
 * "upload" and "pick from the library" are the same size and sit side by side.
 */
.travel-tile-add {
    align-items: center;
    border: 1px dashed var(--geex-line, #eceaf3);
    border-radius: var(--geex-radius-control, 8px);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    justify-content: center;
    min-height: 10rem;
    padding: 0.75rem;
    text-align: center;
}

.travel-tile-add:hover {
    border-color: var(--geex-primary, #ab54db);
}

/*
 * Both dashed cells also take a dropped file. The dashed edge is the usual sign
 * for it, but only to people who already expect one, so the cell says so — and
 * says it quietly, because the button beside it is the instruction that matters.
 */
.travel-drop-hint {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    line-height: 1.3;
}

.travel-tile-add-over {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    border-color: var(--geex-primary, #ab54db);
}

/* SortableJS marks the placeholder while a tile is in flight. */
.travel-tile.sortable-ghost {
    opacity: 0.4;
}

/* ------------------------------------------------------------------- chips */

.travel-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.travel-chip {
    align-items: center;
    background-color: var(--geex-canvas, #f3f2f7);
    border-radius: 999px;
    color: var(--geex-text, #464255);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
    line-height: 1.25rem;
    padding: 0.3125rem 0.75rem;
    transition: background-color 150ms, color 150ms;
    white-space: nowrap;
}

.travel-chip:hover {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
}

.travel-chip-active {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    color: var(--geex-primary, #ab54db);
    font-weight: 500;
}

.travel-chip-count {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    font-variant-numeric: tabular-nums;
}

.travel-chip-active .travel-chip-count {
    color: inherit;
}

/*
 * The media tab's own tabs, as an underline rather than the panel's pills.
 * Scoped to `.travel-media` on purpose: the same Tabs component is used all
 * over the application, and this is a decision about one page.
 */
.travel-media .fi-tabs {
    background: none;
    box-shadow: none;
    border-bottom: 1px solid var(--geex-line, #eceaf3);
    border-radius: 0;
    gap: 0.25rem;
    padding: 0;
}

.travel-media .fi-tabs-item {
    border-bottom: 2px solid transparent;
    border-radius: 0;
    background: none;
    padding-block: 0.625rem;
}

.travel-media .fi-tabs-item.fi-active {
    background: none;
    border-bottom-color: var(--geex-primary, #ab54db);
}

.travel-media .fi-tabs-item.fi-active .fi-tabs-item-label {
    color: var(--geex-primary, #ab54db);
    font-weight: 600;
}

/* --------------------------------------------------------------- spec card */

.travel-spec {
    background-color: var(--geex-surface, #fff);
    border-radius: 14px;
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1.25rem;
}

.travel-spec-title {
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-spec-list {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.travel-spec-item {
    display: flex;
    flex-direction: column;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.125rem;
    position: relative;
    padding-inline-start: 0.75rem;
}

.travel-spec-item::before {
    background-color: var(--geex-primary, #ab54db);
    border-radius: 999px;
    content: '';
    height: 0.3125rem;
    inset-block-start: 0.4375rem;
    inset-inline-start: 0;
    position: absolute;
    width: 0.3125rem;
}

.travel-spec-item-label {
    color: var(--geex-text, #464255);
}

.travel-spec-item-value {
    color: var(--geex-text-muted, #6b7280);
}

/* -------------------------------------------------------- content modules */

/*
 * A stack of collapsed cards inside a card. Filament gives a nested section the
 * same shadow and padding as a top-level one, which at this depth reads as a
 * pile of boxes rather than a list.
 */
.travel-modules .fi-sc-section .fi-section {
    box-shadow: none;
    --tw-ring-color: var(--geex-line, #eceaf3);
}

.travel-modules .fi-section-header {
    padding-block: 0.75rem;
}

/* --------------------------------------------------------------------- shape */

/*
 * The Geex theme rounds every card to 24px. Form controls sit at 8px panel-wide;
 * this form also pulls section corners down so the dense layout does not balloon.
 */
.travel-basics .fi-section,
.travel-basics .fi-sc-section,
.travel-media .fi-section,
.travel-media .fi-sc-section {
    border-radius: 14px;
}

.travel-basics .fi-input-wrp,
.travel-basics .fi-fo-file-upload-dropzone,
.travel-basics .fi-fo-toggle-buttons .fi-btn,
.travel-basics .fi-btn,
.travel-basics .fi-icon-btn,
.travel-basics .travel-coverage-step,
.travel-media .fi-input-wrp,
.travel-media .fi-fo-file-upload-dropzone,
.travel-media .fi-fo-toggle-buttons .fi-btn,
.travel-media .fi-btn,
.travel-media .fi-icon-btn,
.travel-completeness-item-action {
    border-radius: 8px;
}

.travel-pricing-model {
    gap: 0.5em;
}

/* --------------------------------------------------------- destinations read */

/*
 * The label and its "edit" link share a row, which no Filament layout does:
 * a grid child is one row per component. One row of two tracks, then.
 */
.travel-coverage-head > .fi-sc {
    align-items: center;
    grid-template-columns: minmax(0, 1fr) auto;
}

.travel-coverage-label {
    font-size: calc(0.875rem * var(--geex-type-scale, 1));
    font-weight: 500;
}

.travel-coverage-empty {
    color: var(--geex-text-faint, #9ca3af);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

.travel-coverage-paths {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.travel-coverage-path {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.travel-coverage-step {
    align-items: center;
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: var(--geex-radius-chip, 12px);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    padding: 0.25rem 0.625rem;
}

.travel-coverage-step + .travel-coverage-step::before {
    color: var(--geex-text-faint, #9ca3af);
    content: '›';
    margin-inline: -0.25rem 0.5rem;
}

/* ------------------------------------------------------------- dense bands */

/*
 * A band's heading and its explanation share a line. Filament stacks them, and
 * over a single row of controls that costs as much height as the row itself.
 */
.travel-dense .fi-section-header-text-ctn,
.travel-inline-heading .fi-section-header-text-ctn {
    align-items: baseline;
    column-gap: 0.75rem;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
}

.travel-inline-heading .fi-section-header-heading {
    flex: none;
    white-space: nowrap;
}

.travel-inline-heading .fi-section-header-description {
    flex: 1 1 12rem;
    margin: 0;
    min-width: 0;
}

#travel-product-pricing .fi-section-header-heading {
    align-items: center;
    display: inline-flex;
}

.travel-pricing-heading {
    align-items: center;
    display: inline-flex;
    gap: 0.375rem;
}

.travel-heading-hint {
    color: var(--geex-info-text, #2563eb);
    cursor: help;
    display: inline-flex;
}

.travel-heading-hint .fi-icon {
    block-size: 1rem;
    inline-size: 1rem;
}

.tippy-box[data-theme~='travel-hint'],
.tippy-box[data-theme~='travel-hint'] .tippy-content {
    font-size: 0.75rem;
    line-height: 1.55;
    max-width: 22rem;
}

/*
 * Nine counts across one band. Filament's default field gap is set for rows of
 * two, and at this density it opens more space between the figures than around
 * them.
 */
.travel-dense .fi-fo-field-label-content {
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    line-height: 1rem;
}

.travel-dense .fi-input-wrp {
    --fi-input-px: 0.625rem;
}

/* The lead row is labelled inline, so its label column is sized to the words. */
.travel-dense-lead .fi-fo-field.fi-fo-field-has-inline-label {
    column-gap: 0.5rem;
    grid-template-columns: auto minmax(0, 1fr);
}

.travel-dense-lead .fi-fo-field-label-col {
    align-items: center;
    justify-items: start;
}

/* ---------------------------------------------------------------- duration */

/*
 * "2 days × 1 night": one label over the pair, units set beside the boxes. The
 * nights box has no label of its own, so the row is bottom-aligned to bring it
 * level with the days box.
 */
.travel-duration > .fi-sc {
    align-items: end;
    column-gap: 0.375rem;
}

.travel-duration-unit {
    padding-block-end: 0.625rem;
    white-space: nowrap;
}

.travel-duration-times {
    text-align: center;
}

/* ------------------------------------------------------------- contact note */

.travel-contact-note {
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    line-height: 1rem;
}

/* --------------------------------------------------------- completeness rail */

.travel-completeness {
    background-color: var(--geex-surface, #fff);
    border-radius: var(--geex-radius-card, 24px);
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1.25rem;
}

.travel-completeness-title {
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-completeness-gauge {
    display: grid;
    justify-items: center;
    margin-block: 0.25rem;
    place-items: center;
}

.travel-completeness-gauge > * {
    grid-area: 1 / 1;
}

.travel-completeness-ring {
    height: 8.5rem;
    transform: rotate(-90deg);
    width: 8.5rem;
}

.travel-completeness-ring circle {
    fill: none;
    stroke-linecap: round;
    stroke-width: 9;
}

.travel-completeness-ring-track {
    stroke: var(--geex-line, #eceaf3);
}

.travel-completeness-ring-value {
    stroke: var(--geex-primary, #ab54db);
    transition: stroke-dashoffset 400ms ease;
}

.travel-completeness-figure {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.125rem;
}

.travel-completeness-percent {
    font-size: calc(1.75rem * var(--geex-type-scale, 1));
    font-weight: 600;
    line-height: 1;
}

.travel-completeness-percent small {
    font-size: calc(0.875rem * var(--geex-type-scale, 1));
    font-weight: 500;
    margin-inline-start: 0.0625rem;
}

.travel-completeness-caption,
.travel-completeness-lead,
.travel-completeness-done {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-completeness-list {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.travel-completeness-item {
    align-items: center;
    display: flex;
    gap: 0.5rem;
    justify-content: space-between;
}

.travel-completeness-item-label {
    align-items: center;
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.5rem;
    min-width: 0;
}

.travel-completeness-item-label::before {
    background-color: var(--geex-primary, #ab54db);
    border-radius: 999px;
    content: '';
    flex: none;
    height: 0.3125rem;
    width: 0.3125rem;
}

.travel-completeness-item-action {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    border-radius: var(--geex-radius-chip, 12px);
    color: var(--geex-primary, #ab54db);
    flex: none;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    padding: 0.1875rem 0.5rem;
}

.travel-completeness-toggle {
    align-items: center;
    border-top: 1px solid var(--geex-line, #eceaf3);
    color: var(--geex-text-muted, #6b7280);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
    justify-content: space-between;
    padding-block-start: 0.75rem;
    width: 100%;
}

.travel-completeness-toggle:hover {
    color: var(--geex-primary, #ab54db);
}

.travel-completeness-toggle-icon {
    height: 1rem;
    width: 1rem;
}

/*
 * Two-column form layout for the travel product form: the label sits in a
 * fixed, right-aligned column on the left and the control sits to its right,
 * matching the reference back office.
 *
 * Filament's own inline labels split the row 1/3 : 2/3, so labels of differing
 * length never line up between sections. A fixed track keeps every label in
 * the same column regardless of how wide its section is.
 *
 * Controls are capped rather than stretched. On a wide screen a section column
 * is ~800px, and an 800px-wide select reads as a page of banners rather than a
 * form; the reference back office sizes each control to what it holds.
 *
 * Only applies from the `sm` breakpoint up, where Filament turns inline labels
 * on; below that a field is stacked and these rules must not interfere.
 */
.travel-inline-form {
    --travel-label-col: 10rem;
    --travel-label-gap: 0.75rem;

    /*
     * Wide enough for two label-plus-control columns and no wider. Without it
     * an ultrawide window stretches the section's two columns to ~1150px each,
     * opening a dead band between a capped control and the next column's label.
     * The card still spans the page; only the fields inside are held together.
     */
    --travel-form-max: 96rem;

    /* Single-line text: names, codes, phone numbers. */
    --travel-control-max: 36rem;

    /* Multi-line text, which needs the room to show what was typed. */
    --travel-control-max-wide: 60rem;

    /* Pickers, where the option text sets the useful width. */
    --travel-control-max-narrow: 22rem;

    /* Counts and durations, a few digits at most. */
    --travel-control-max-tiny: 10rem;
}

.travel-inline-form .fi-section-content {
    max-width: var(--travel-form-max);
}

@media (min-width: 640px) {
    .travel-inline-form .fi-fo-field.fi-fo-field-has-inline-label {
        grid-template-columns: minmax(0, var(--travel-label-col)) minmax(0, 1fr);
        column-gap: var(--travel-label-gap);
    }

    .travel-inline-form
        .fi-fo-field.fi-fo-field-has-inline-label
        > .fi-fo-field-content-col {
        grid-column: span 1 / span 1;
        max-width: var(--travel-control-max);
    }

    .travel-inline-form
        .fi-fo-field.fi-fo-field-has-inline-label
        > .fi-fo-field-label-col {
        justify-items: end;
        padding-top: 0.375rem;
        text-align: end;
    }

    .travel-inline-form
        .fi-fo-textarea-wrp.fi-fo-field-has-inline-label
        > .fi-fo-field-content-col {
        max-width: var(--travel-control-max-wide);
    }

    .travel-inline-form
        .fi-fo-select-wrp.fi-fo-field-has-inline-label
        > .fi-fo-field-content-col {
        max-width: var(--travel-control-max-narrow);
    }

    .travel-inline-form
        .fi-fo-field.fi-fo-field-has-inline-label:has(
            > .fi-fo-field-content-col input[type='number']
        )
        > .fi-fo-field-content-col {
        max-width: var(--travel-control-max-tiny);
    }

    /*
     * Blocks that are not fields themselves but read as part of the field
     * above them, indented to line up with the control column.
     */
    .travel-inline-form .travel-inline-field-note {
        margin-inline-start: calc(
            var(--travel-label-col) + var(--travel-label-gap)
        );
    }
}

/*
 * ============================================================================
 * Itinerary tab
 * ============================================================================
 *
 * Three tracks: the days as a rail, the open day's timeline, and a preview of
 * what the website will show. Same reasoning as the other two tabs — the switch
 * is a container query, because the panel sidebar makes the viewport the wrong
 * number by about 320px.
 */
.travel-itinerary {
    container-name: travel-itinerary;
    container-type: inline-size;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.travel-itinerary-body {
    display: grid;
    gap: 1rem;
}

@container travel-itinerary (min-width: 62rem) {
    .travel-itinerary-body {
        align-items: start;
        /*
         * The rail is sized to "D12" and a city name, the preview to a line of
         * timeline text. Everything left over is the editor, which is the only
         * track whose contents grow.
         */
        grid-template-columns: 9.5rem minmax(0, 1fr) clamp(15rem, 22%, 19rem);
    }

    .travel-day-rail,
    .travel-preview {
        position: sticky;
        top: 5rem;
    }
}

/* ------------------------------------------------------------------ shape */

/*
 * The Geex theme rounds cards to 24px and controls to 18px. This screen is a
 * dense one and at that radius the corners start to crowd the text, so it steps
 * both down — matching the product information and media tabs.
 */
.travel-itinerary .fi-section,
.travel-itinerary .fi-sc-section {
    border-radius: 14px;
}

.travel-itinerary .fi-input-wrp,
.travel-itinerary .fi-fo-file-upload-dropzone,
.travel-itinerary .fi-fo-toggle-buttons .fi-btn,
.travel-itinerary .fi-btn,
.travel-itinerary .fi-icon-btn {
    border-radius: 8px;
}

/* Filament renders a dropdown item as a plain button; these want to be rows. */
.travel-itinerary .fi-dropdown-list .fi-btn {
    justify-content: flex-start;
    width: 100%;
}

/* ---------------------------------------------------------------- toolbar */

.travel-itinerary-toolbar {
    align-items: flex-start;
    background-color: var(--geex-surface, #fff);
    border-radius: 14px;
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem 1.25rem;
    padding: 0.875rem 1rem;
}

.travel-variants {
    align-items: flex-start;
    border-inline-end: 1px solid var(--geex-line, #eceaf3);
    display: flex;
    gap: 0.5rem;
    padding-inline-end: 1.25rem;
}

.travel-variant {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.travel-variant-name {
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 999px;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    font-weight: 500;
    padding: 0.3125rem 0.875rem;
    text-align: center;
}

.travel-variant-active .travel-variant-name {
    background-color: var(--geex-primary, #ab54db);
    color: var(--geex-on-primary, #fff);
}

.travel-variant-meta {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    text-align: center;
}

.travel-toolbar-group {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Day count and bulk settings sit at the far end, as on the reference form. */
.travel-toolbar-end {
    margin-inline-start: auto;
}

.travel-itinerary-notice {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

/* --------------------------------------------------------------- day rail */

.travel-day-rail {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.travel-day-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.travel-day-tab {
    align-items: center;
    background-color: var(--geex-surface, #fff);
    border: 1px solid var(--geex-line, #eceaf3);
    border-radius: 12px;
    display: flex;
    gap: 0.25rem;
    padding: 0.625rem 0.5rem;
    position: relative;
}

.travel-day-tab-active {
    border-color: var(--geex-primary, #ab54db);
    box-shadow: 0 0 0 1px var(--geex-primary, #ab54db);
}

.travel-day-tab-handle {
    color: var(--geex-text-faint, #9ca3af);
    cursor: grab;
    display: flex;
    flex: none;
}

.travel-day-tab-handle .fi-icon {
    height: 1rem;
    margin-inline: -0.3125rem;
    width: 1rem;
}

.travel-day-tab-body {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
    text-align: start;
}

.travel-day-tab-code {
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-day-tab-city {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.travel-day-dot {
    background-color: var(--geex-success, #22c55e);
    border-radius: 999px;
    flex: none;
    height: 0.4375rem;
    width: 0.4375rem;
}

.travel-day-dot-unsettled {
    background-color: var(--geex-warning, #f59e0b);
}

.travel-day-add {
    align-items: center;
    border: 1px dashed var(--geex-line, #d4d4d8);
    border-radius: 12px;
    color: var(--geex-text-muted, #6b7280);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
    justify-content: center;
    padding: 0.625rem;
}

.travel-day-add:hover {
    border-color: var(--geex-primary, #ab54db);
    color: var(--geex-primary, #ab54db);
}

.travel-day-add .fi-icon {
    height: 1rem;
    width: 1rem;
}

/* Below the breakpoint the rail lies down and scrolls sideways. */
@container travel-itinerary (max-width: 62rem) {
    .travel-day-rail {
        flex-direction: row;
    }

    .travel-day-list {
        flex-direction: row;
        overflow-x: auto;
        padding-block-end: 0.25rem;
    }

    .travel-day-tab {
        min-width: 8.5rem;
    }

    .travel-day-add {
        flex: none;
        padding-inline: 0.875rem;
    }
}

/* ------------------------------------------------------------- day editor */

.travel-day-stack {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    min-width: 0;
}

.travel-day {
    background-color: var(--geex-surface, #fff);
    border-radius: 14px;
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    padding: 1rem 1.25rem 1.25rem;
}

.travel-day-head {
    align-items: center;
    display: flex;
    gap: 0.625rem;
}

.travel-day-chip {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    border-radius: 8px;
    color: var(--geex-primary, #ab54db);
    flex: none;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    font-weight: 600;
    padding: 0.1875rem 0.5rem;
}

.travel-day-name {
    flex: 1 1 auto;
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.travel-day-head-actions {
    align-items: center;
    display: flex;
    flex: none;
    gap: 0.25rem;
}

/*
 * The day's name, on the header line beside its D-chip. Unlabelled: "D1" and a
 * box the width of the card is not a question anyone needs asked in words.
 */
.travel-day-name-input {
    flex: 1 1 16rem;
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 500;
    min-width: 0;
}

/*
 * The eight fields themselves are a Filament schema, so the grid, the labels
 * and the spacing are its. All this does is stop the panel's own section
 * chrome from drawing a second card inside the one already here.
 */
.travel-day-form > .fi-sc {
    gap: 1rem;
}

/*
 * ── The day as a run of steps ───────────────────────────────────────────────
 *
 * A day has an order to it — where it goes, how, what is seen, what is eaten,
 * where the night is spent — and eight equal grey labels hide that. This is the
 * node timeline's furniture put back over the form that replaced it: one rail,
 * a coloured dot per step, and the same tinted icon plate the clause board uses.
 *
 * The colours are `--tone` / `--tone-soft`, set by a `travel-tone-*` class on
 * each step. Same palette, same meanings, as when a day was thirteen nodes.
 *
 * Each step is a Filament section with `contained(false)`, which renders as
 * `div.travel-step.fi-sc-section > section.fi-section > header.fi-section-header`
 * with a bare `<svg class="fi-icon">` as the header's first child. Checked
 * against the rendered page rather than assumed.
 */
.travel-day-form {
    position: relative;
}

/*
 * The rail. Inset top and bottom so it starts and ends at the first and last
 * dot rather than floating past them.
 */
.travel-day-form::before {
    background-color: var(--geex-line, #eceaf3);
    content: '';
    inset-block: 1.5rem;
    inset-inline-start: 0.28125rem;
    position: absolute;
    width: 1px;
}

.travel-step {
    padding-inline-start: 1.75rem;
    position: relative;
}

/*
 * Geex paints every `.fi-sc-section` as a floating card. These steps already
 * sit inside one, so the extra radius, fill and shadow read as six boxes in
 * a box — and the header hairline cuts the fields off from the heading.
 */
html:not(.dark) .travel-day-form .travel-step.fi-sc-section,
html:not(.dark) .travel-day-form .travel-step > .fi-section {
    background-color: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
    --tw-ring-color: transparent;
    --tw-ring-shadow: 0 0 #0000;
}

html:not(.dark) .travel-day-form .travel-step .fi-section-header,
html:not(.dark) .travel-day-form .travel-step .fi-section-content-ctn {
    border: none;
    box-shadow: none;
}

/*
 * The dot, sat on the rail and lined up with the middle of the icon plate:
 * the header's 0.625rem of top padding plus half the plate's 1.75rem, less
 * half the dot. The ring is the card's own background, which breaks the rail
 * cleanly instead of drawing over it.
 */
.travel-step::before {
    background-color: var(--tone, #a1a1aa);
    border-radius: 999px;
    box-shadow: 0 0 0 3px var(--geex-surface, #fff);
    content: '';
    height: 0.625rem;
    inset-block-start: 1.1875rem;
    inset-inline-start: 0;
    position: absolute;
    width: 0.625rem;
}

/* The step's own indent replaces the section's, or the two would stack. */
.travel-step > .fi-section > .fi-section-header {
    padding-inline: 0;
}

/* The icon plate — the four lines that make .travel-terms-icon, on an <svg>. */
.travel-step > .fi-section > .fi-section-header > .fi-icon {
    background-color: var(--tone-soft, rgba(161, 161, 170, 0.15));
    border-radius: 999px;
    box-sizing: content-box;
    color: var(--tone, #a1a1aa);
    flex: none;
    height: 1rem;
    padding: 0.375rem;
    width: 1rem;
}

/* A step name, not a section title. */
.travel-step .fi-section-header-heading {
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    font-weight: 500;
}

.travel-day-actions {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
}

.travel-field {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    min-width: 0;
}

.travel-field-label {
    color: var(--geex-text, #464255);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    font-weight: 500;
}

.travel-input {
    background-color: var(--geex-surface, #fff);
    border: 1px solid var(--geex-line, #d4d4d8);
    border-radius: 8px;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    line-height: 1.25rem;
    padding: 0.4375rem 0.625rem;
    width: 100%;
}

.travel-input:focus {
    border-color: var(--geex-primary, #ab54db);
    outline: 2px solid transparent;
    outline-offset: 2px;
}

.travel-select {
    min-width: 9rem;
}

/*
 * Inline-flex rather than inline, because a folded day's chips carry a dot in
 * the colour of the step they come from — so the row and the card it folds down
 * from say green, amber and blue about the same things.
 */
.travel-stat {
    align-items: center;
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 6px;
    color: var(--geex-text-muted, #6b7280);
    display: inline-flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    font-variant-numeric: tabular-nums;
    gap: 0.3125rem;
    padding: 0.1875rem 0.5rem;
    white-space: nowrap;
}

/* Smaller than the standalone dot the colour picker uses: this one sits in text. */
.travel-stat .travel-tone-dot {
    block-size: 0.4375rem;
    inline-size: 0.4375rem;
}

/* "喀什市 → 吐鲁番市 · 飞机", on a folded day and in the preview alike. */
.travel-day-route {
    color: var(--geex-text-muted, #6b7280);
    flex: none;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    white-space: nowrap;
}

.travel-day-chips {
    display: flex;
    flex: none;
    flex-wrap: wrap;
    gap: 0.375rem;
}

/* Whether the day is finished, said in words as well as by the dot. */
.travel-day-state {
    align-items: center;
    color: var(--geex-success-text, #15803d);
    display: flex;
    flex: none;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
}

.travel-day-state-unsettled {
    color: var(--geex-warning-text, #92400e);
}

.travel-day-warning {
    align-items: center;
    background-color: var(--geex-warning-soft, rgba(245, 158, 11, 0.12));
    border-radius: 8px;
    color: var(--geex-warning-text, #92400e);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
    padding: 0.5rem 0.75rem;
}

.travel-day-warning .fi-icon {
    flex: none;
    height: 1rem;
    width: 1rem;
}

/* A folded day is one row: which day, what is on it, how long it runs. */
.travel-day-collapsed {
    align-items: center;
    background-color: var(--geex-surface, #fff);
    border-radius: 14px;
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    gap: 0.625rem;
    padding: 0.75rem 1.25rem;
    width: 100%;
}

.travel-day-collapsed-title {
    flex: 1 1 auto;
    font-size: calc(0.875rem * var(--geex-type-scale, 1));
    font-weight: 500;
    min-width: 0;
    overflow: hidden;
    text-align: start;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.travel-day-collapsed-chevron {
    color: var(--geex-text-faint, #9ca3af);
    flex: none;
    height: 1.125rem;
    width: 1.125rem;
}

/* ----------------------------------------------------------------- preview */

.travel-preview {
    background-color: var(--geex-surface, #fff);
    border-radius: 14px;
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1.25rem;
}

.travel-preview-head {
    align-items: center;
    display: flex;
    gap: 0.5rem;
    justify-content: space-between;
}

.travel-preview-title {
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-preview-tools {
    align-items: center;
    display: flex;
    gap: 0.375rem;
}

.travel-seg {
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 8px;
    display: flex;
    padding: 0.125rem;
}

.travel-seg-item {
    border-radius: 6px;
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    padding: 0.1875rem 0.5rem;
}

.travel-seg-item-active {
    background-color: var(--geex-surface, #fff);
    color: var(--geex-primary, #ab54db);
    font-weight: 500;
}

.travel-preview-count {
    font-size: calc(0.875rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-preview-empty {
    color: var(--geex-text-faint, #9ca3af);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-preview-day {
    border-top: 1px solid var(--geex-line, #eceaf3);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding-block-start: 0.75rem;
}

.travel-preview-day-head {
    align-items: center;
    display: flex;
    gap: 0.5rem;
}

.travel-preview-day-city {
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    font-weight: 500;
}

.travel-preview-day-route {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-preview-day-note {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    white-space: pre-line;
}

/*
 * "Brief" gives the overview two lines. Clamped rather than truncated server
 * side, so switching to "detail" is a re-render of the same string instead of a
 * second trip for the rest of it.
 */
.travel-preview-day-note-clamped {
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    display: -webkit-box;
    overflow: hidden;
}

.travel-preview-attractions {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.travel-preview-attractions li {
    align-items: center;
    color: var(--geex-text, #464255);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
}

.travel-preview-attractions .fi-icon {
    color: var(--geex-text-faint, #9ca3af);
    flex: none;
    height: 0.875rem;
    width: 0.875rem;
}

/* The outstanding list, at the foot of the preview where the eye ends up. */
.travel-preview-issues {
    background-color: var(--geex-warning-soft, rgba(245, 158, 11, 0.12));
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem;
}

.travel-preview-issues-lead {
    align-items: center;
    color: var(--geex-warning-text, #92400e);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    font-weight: 500;
    gap: 0.375rem;
}

.travel-preview-issues-lead .fi-icon {
    height: 1rem;
    width: 1rem;
}

.travel-preview-issue {
    align-items: center;
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.5rem;
    justify-content: space-between;
}

.travel-preview-issue button {
    color: var(--geex-primary, #ab54db);
    flex: none;
}

/* -------------------------------------------------------------------- tones */

/*
 * A colour and a wash of it, as a pair of custom properties, so that an icon
 * plate and the dot beside it are never two different greens. Read by the
 * clause board, the calendar's figures and the website preview's badge.
 */
.travel-tone-violet {
    --tone: #7c3aed;
    --tone-soft: rgba(124, 58, 237, 0.12);
}

.travel-tone-sky {
    --tone: #0ea5e9;
    --tone-soft: rgba(14, 165, 233, 0.12);
}

.travel-tone-green {
    --tone: #16a34a;
    --tone-soft: rgba(22, 163, 74, 0.12);
}

.travel-tone-amber {
    --tone: #f59e0b;
    --tone-soft: rgba(245, 158, 11, 0.14);
}

.travel-tone-blue {
    --tone: #2563eb;
    --tone-soft: rgba(37, 99, 235, 0.12);
}

.travel-tone-pink {
    --tone: #db2777;
    --tone-soft: rgba(219, 39, 119, 0.12);
}

.travel-tone-slate {
    --tone: #64748b;
    --tone-soft: rgba(100, 116, 139, 0.12);
}

/*
 * The create screen: the toolbar above looks perfectly usable, so the reason
 * there is nothing under it has to carry some weight of its own.
 */
.travel-itinerary-locked {
    align-items: center;
    border: 1px dashed var(--geex-line, #d4d4d8);
    border-radius: 14px;
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    padding: 3rem 1.5rem;
    text-align: center;
}

.travel-itinerary-locked .fi-icon {
    color: var(--geex-text-faint, #9ca3af);
    height: 2rem;
    margin-block-end: 0.25rem;
    width: 2rem;
}

.travel-itinerary-locked-title {
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-itinerary-locked-body {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    max-width: 26rem;
}

/*
 * ============================================================================
 * Price, stock & departures tab
 * ============================================================================
 *
 * The figures for the month and the calendar itself. The panel that edits one
 * day — or every ticked day — at a time is rendered by the same component and
 * teleported into the tab's right-hand rail, so it is styled here and placed
 * there.
 */
/*
 * The 综价 and what the website would charge for it, side by side above the
 * calendar.
 *
 * The right-hand track is the calendar's own day-panel track, repeated: the
 * two right-hand columns line up down the whole tab, and the reading half is
 * kept to what it needs so the typing half gets the rest. Measured off the form
 * rather than the window for the reason given above — the panel sidebar makes
 * the viewport the wrong number by about 320px.
 *
 * Stated here rather than as Filament column spans because the breakpoint has
 * to be the calendar's, to the rem; with no stylesheet the two cards simply
 * stack, which is the honest fallback.
 */
.travel-pricing-split {
    container-name: travel-pricing;
    container-type: inline-size;
}

/*
 * `.fi-sc` is carried for weight, not for meaning: this sheet is served before
 * Filament's own, and `.fi-grid:not(.fi-grid-direction-col)` sets the same
 * property at the same specificity — matched, the one loaded last would win,
 * and that is not this one.
 */
@container travel-pricing (min-width: 62rem) {
    .travel-pricing-split > .fi-grid.fi-sc {
        align-items: start;
        grid-template-columns: minmax(0, 1fr) clamp(15rem, 24%, 20rem);
    }

    /*
     * The right-hand card follows the page, as the completeness rail does on
     * the product-information tab: it is a grid item, so its row is as tall as
     * the calendar beside it, and a rail that scrolls away from a 31-day month
     * is a rail nobody reads.
     */
    .travel-pricing-split > .fi-grid.fi-sc > :last-child {
        position: sticky;
        top: 5rem;
    }

    /*
     * The rail carries the day being edited. Stuck to the top it can stand
     * taller than the window, which would put 「仅保存当天」 somewhere the
     * page cannot be scrolled to. It scrolls within itself instead.
     */
    .travel-pricing-rail {
        max-height: calc(100vh - 6rem);
        overflow-y: auto;
    }
}

.travel-calendar {
    container-name: travel-calendar;
    container-type: inline-size;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/*
 * The tab already names this block. A second heading and Geex's card padding
 * on a nested `.fi-sc-section` ate a strip the grid could have used.
 */
.travel-calendar-section > .fi-section > .fi-section-header,
.travel-calendar-section.fi-section > .fi-section-header {
    display: none;
}

html:not(.dark) .travel-calendar-section.fi-sc-section,
html:not(.dark) .travel-calendar-section > .fi-section,
html:not(.dark) .travel-calendar-section.fi-section {
    background-color: var(--geex-surface, #fff);
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
}

html:not(.dark) .travel-calendar-section > .fi-section > .fi-section-content-ctn,
html:not(.dark) .travel-calendar-section > .fi-section .fi-section-content,
html:not(.dark) .travel-calendar-section.fi-section .fi-section-content-ctn,
html:not(.dark) .travel-calendar-section.fi-section .fi-section-content {
    padding: 0.75rem 1rem 1rem;
}

/*
 * One track. The day panel used to be a second one here and now sits in the
 * tab's right-hand rail, which is the width this track was — see
 * `.travel-pricing-split` — so the calendar reads exactly as wide as before.
 */
.travel-calendar-body {
    display: grid;
    gap: 1rem;
}

/* Nothing of its own — it is a target for the teleport, and empty until a day
   is opened on a saved product. Hidden while empty so it does not open a gap
   above the completeness ring. */
#travel-day-panel-slot:empty {
    display: none;
}

.travel-calendar .fi-input-wrp,
.travel-calendar .fi-btn,
.travel-calendar .fi-icon-btn {
    border-radius: 8px;
}

.travel-calendar .fi-dropdown-list .fi-btn {
    justify-content: flex-start;
    width: 100%;
}

/* ---------------------------------------------------------------- toolbar */

.travel-calendar-toolbar {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.625rem;
}

/* One package for now, so this names it rather than pretending to choose. */
.travel-package {
    align-items: center;
    border: 1px solid var(--geex-line, #d4d4d8);
    border-radius: 8px;
    color: var(--geex-text, #464255);
    cursor: default;
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.5rem;
    padding: 0.4375rem 0.75rem;
}

.travel-package .fi-icon {
    color: var(--geex-text-faint, #9ca3af);
    height: 1rem;
    width: 1rem;
}

.travel-currency {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.12));
    border-radius: 8px;
    color: var(--geex-primary, #ab54db);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    padding: 0.375rem 0.75rem;
}

.travel-calendar-tools {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-inline-start: auto;
}

/* A rule the planner has to read before typing, rather than a caption under a
   heading. Wraps, unlike the calendar's one-liner below, so the icon sits on the
   first line instead of halfway down the paragraph. */
.travel-hint {
    align-items: flex-start;
    background-color: var(--geex-info-soft, rgba(59, 130, 246, 0.1));
    border-radius: 8px;
    color: var(--geex-info-text, #1d4ed8);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
    line-height: 1.7;
    padding: 0.5rem 0.75rem;
}

.travel-hint .fi-icon {
    flex: none;
    height: 1rem;
    margin-top: 0.1875rem;
    width: 1rem;
}

.travel-calendar-hint {
    align-items: center;
    background-color: var(--geex-info-soft, rgba(59, 130, 246, 0.1));
    border-radius: 8px;
    color: var(--geex-info-text, #1d4ed8);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
    padding: 0.5rem 0.75rem;
}

.travel-calendar-hint .fi-icon {
    flex: none;
    height: 1rem;
    width: 1rem;
}

/* ------------------------------------------------------ figures for the month */

.travel-figures {
    display: grid;
    gap: 0.75rem;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}

.travel-figure {
    align-items: center;
    background-color: var(--geex-surface, #fff);
    border-radius: 14px;
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    gap: 0.75rem;
    padding: 0.875rem 1rem;
}

.travel-figure-icon {
    align-items: center;
    background-color: var(--tone-soft, rgba(161, 161, 170, 0.15));
    border-radius: 10px;
    color: var(--tone, #a1a1aa);
    display: flex;
    flex: none;
    height: 2.25rem;
    justify-content: center;
    width: 2.25rem;
}

.travel-figure-icon .fi-icon {
    height: 1.25rem;
    width: 1.25rem;
}

.travel-figure-text {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
}

.travel-figure-text small {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-figure-text strong {
    font-size: calc(1.25rem * var(--geex-type-scale, 1));
    font-weight: 600;
    line-height: 1.2;
}

.travel-figure-note {
    color: var(--geex-text-faint, #9ca3af);
}

/* ------------------------------------------------------------- calendar nav */

.travel-calendar-main {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    min-width: 0;
}

.travel-calendar-nav {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.travel-calendar-month {
    font-size: calc(1rem * var(--geex-type-scale, 1));
    font-weight: 600;
    margin-inline-start: 0.25rem;
}

.travel-pill {
    border: 1px solid var(--geex-line, #d4d4d8);
    border-radius: 8px;
    color: var(--geex-text, #464255);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    padding: 0.3125rem 0.625rem;
}

.travel-pill:hover {
    border-color: var(--geex-primary, #ab54db);
    color: var(--geex-primary, #ab54db);
}

.travel-month-strip {
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 8px;
    display: flex;
    margin-inline-start: 0.75rem;
    padding: 0.125rem;
}

.travel-month-item {
    border-radius: 6px;
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    padding: 0.25rem 0.625rem;
}

.travel-month-item-active {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    color: var(--geex-primary, #ab54db);
    font-weight: 500;
}

.travel-calendar-filters {
    margin-inline-start: auto;
}

/* --------------------------------------------------------- selection bar */

.travel-selection-bar {
    align-items: center;
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.1));
    border-radius: 8px;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 0.5rem 0.75rem;
}

.travel-selection-count {
    align-items: center;
    cursor: pointer;
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    font-weight: 500;
    gap: 0.5rem;
}

.travel-selection-clear {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    margin-inline-start: auto;
}

.travel-selection-clear:hover {
    color: var(--geex-primary, #ab54db);
}

/* ------------------------------------------------------------------- grid */

.travel-grid {
    border: 1px solid var(--geex-line, #eceaf3);
    border-radius: 10px;
    overflow: hidden;
}

.travel-grid-head {
    background-color: var(--geex-canvas, #f9fafb);
    border-bottom: 1px solid var(--geex-line, #eceaf3);
    color: var(--geex-text-muted, #6b7280);
    display: grid;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    grid-template-columns: repeat(7, minmax(0, 1fr));
    text-align: center;
}

.travel-grid-head span {
    padding: 0.5rem 0;
}

.travel-grid-week {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
}

.travel-cell {
    border-block-end: 1px solid var(--geex-line, #f1f0f6);
    border-inline-end: 1px solid var(--geex-line, #f1f0f6);
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-height: 6.5rem;
    min-width: 0;
    padding: 0.375rem 0.5rem 0.5rem;
    position: relative;
}

.travel-grid-week:last-child .travel-cell {
    border-block-end: 0;
}

.travel-grid-week .travel-cell:last-child {
    border-inline-end: 0;
}

.travel-cell-outside {
    background-color: var(--geex-canvas, #fafafa);
}

.travel-cell-outside .travel-cell-day,
.travel-cell-outside .travel-cell-body {
    opacity: 0.35;
}

/* Filtered out rather than hidden: the month must keep its shape. */
.travel-cell-dimmed {
    opacity: 0.35;
}

.travel-cell-selected {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.08));
}

.travel-cell-focused {
    box-shadow: inset 0 0 0 2px var(--geex-primary, #ab54db);
}

.travel-cell-head {
    align-items: center;
    display: flex;
    justify-content: space-between;
}

.travel-cell-check {
    height: 0.875rem;
    width: 0.875rem;
}

.travel-cell-day {
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-cell-today .travel-cell-day {
    background-color: var(--geex-primary, #ab54db);
    border-radius: 6px;
    color: var(--geex-on-primary, #fff);
    padding-inline: 0.3125rem;
}

.travel-cell-body {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 0.0625rem;
    text-align: start;
}

.travel-cell-empty {
    color: var(--geex-text-faint, #c7c7cc);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    padding-block-start: 0.75rem;
}

.travel-cell-line {
    display: flex;
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
    line-height: 1.15rem;
    white-space: nowrap;
}

.travel-cell-line em {
    color: var(--geex-text-muted, #6b7280);
    font-style: normal;
    width: 1.75rem;
}

.travel-cell-line b {
    font-weight: 500;
}

/* The cost half of the pair, which the "show cost" switch hides. */
.travel-cell-line i {
    color: var(--geex-text-faint, #9ca3af);
    font-style: normal;
}

.travel-cell-status {
    align-items: center;
    display: flex;
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
}

.travel-dot {
    background-color: currentColor;
    border-radius: 999px;
    flex: none;
    height: 0.375rem;
    width: 0.375rem;
}

.travel-legend {
    color: var(--geex-text-muted, #6b7280);
    display: flex;
    flex-wrap: wrap;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 1rem;
}

.travel-legend-item {
    align-items: center;
    display: flex;
    gap: 0.375rem;
}

/*
 * Status colours the cell's own footer and the legend, not the whole cell: a
 * grid of seven coloured blocks per row is unreadable, and the figure the
 * planner is scanning for is the price.
 */
.travel-status-sellable .travel-cell-status,
.travel-legend-item.travel-status-sellable {
    color: #16a34a;
}

.travel-status-sold-out .travel-cell-status,
.travel-legend-item.travel-status-sold-out {
    color: #dc2626;
}

.travel-status-closed .travel-cell-status,
.travel-legend-item.travel-status-closed {
    color: #f59e0b;
}

.travel-status-unset .travel-cell-status,
.travel-legend-item.travel-status-unset {
    color: #9ca3af;
}

/* -------------------------------------------------------------- day panel */

.travel-day-panel {
    background-color: var(--geex-surface, #fff);
    border-radius: 14px;
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.travel-day-panel-header {
    border-bottom: 1px solid var(--geex-line, #eceaf3);
    padding: 1rem 1.5rem;
}

.travel-day-panel-title {
    font-size: var(--text-base, 1rem);
    font-weight: 600;
    line-height: 1.5rem;
    margin: 0;
}

.travel-day-panel-body {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    padding: 1.25rem 1.5rem 1.5rem;
}

.travel-day-panel-empty {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

.travel-day-panel-head {
    align-items: center;
    display: flex;
    gap: 0.5rem;
    justify-content: space-between;
}

.travel-day-panel-head h3 {
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-day-panel-row {
    align-items: center;
    display: flex;
    gap: 0.5rem;
    justify-content: space-between;
}

.travel-day-panel-grid {
    display: grid;
    gap: 0.75rem;
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* What an empty price box means, said under the boxes rather than left to be
   discovered. Smaller and fainter than the labels: it is read once. */
.travel-day-panel-note {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    margin-top: -0.375rem;
}

.travel-day-panel-stock {
    align-items: end;
    background-color: var(--geex-canvas, #f9fafb);
    border-radius: 10px;
    display: grid;
    gap: 0.75rem;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    padding: 0.75rem;
}

.travel-readout {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.travel-readout strong {
    font-size: calc(1rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

/* A currency sign inside the box, so the number starts where the eye does. */
.travel-input-money {
    display: flex;
    position: relative;
}

.travel-input-money em {
    color: var(--geex-text-muted, #6b7280);
    font-style: normal;
    inset-block-start: 50%;
    inset-inline-start: 0.625rem;
    position: absolute;
    transform: translateY(-50%);
}

.travel-input-money .travel-input {
    padding-inline-start: 1.625rem;
}

.travel-field-hint {
    color: var(--geex-text-faint, #9ca3af);
    cursor: help;
    display: inline-block;
    height: 0.875rem;
    vertical-align: -0.125rem;
    width: 0.875rem;
}

.travel-field-error {
    color: var(--geex-danger, #dc2626);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-margin {
    align-items: center;
    background-color: var(--geex-success-soft, rgba(22, 163, 74, 0.1));
    border-radius: 8px;
    color: var(--geex-success-text, #15803d);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    justify-content: space-between;
    padding: 0.625rem 0.75rem;
}

.travel-margin-negative {
    color: var(--geex-danger, #dc2626);
}

.travel-day-panel-apply,
.travel-day-panel-apply .fi-btn {
    justify-content: center;
    width: 100%;
}

/* ----------------------------------------------------------------- switch */

.travel-switch {
    align-items: center;
    cursor: pointer;
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
}

.travel-switch input {
    height: 0;
    opacity: 0;
    position: absolute;
    width: 0;
}

.travel-switch i {
    background-color: var(--geex-line, #d4d4d8);
    border-radius: 999px;
    display: block;
    flex: none;
    height: 1.125rem;
    position: relative;
    transition: background-color 150ms;
    width: 2rem;
}

.travel-switch i::after {
    background-color: #fff;
    border-radius: 999px;
    content: '';
    height: 0.875rem;
    inset-block-start: 0.125rem;
    inset-inline-start: 0.125rem;
    position: absolute;
    transition: transform 150ms;
    width: 0.875rem;
}

.travel-switch input:checked + i {
    background-color: var(--geex-primary, #ab54db);
}

.travel-switch input:checked + i::after {
    transform: translateX(0.875rem);
}

.travel-switch-labelled input:checked + i {
    background-color: var(--geex-success-text, #16a34a);
}

/*
 * ============================================================================
 * A tour's record pages
 * ============================================================================
 *
 * The edit screen is ten tabs of dense form, and Filament gives the View/Edit
 * switch a row of its own above them. It is rendered into the page header
 * instead — see ShowsRecordTabsInHeader. Folding the heading away is not done
 * here: geex-theme.css does that for every page in the panel.
 */

/*
 * Filament's tab strip carries the shape of a page-level navigation. Here it is
 * one control among the header's buttons, so it is drawn tighter and fully
 * round: a segmented switch, the same shape the clause board uses for its own
 * two-way choices.
 *
 * Only the shape. Where the strip sits, what it stands on and how the selected
 * tab is filled are the panel's business and are set in geex-theme.css for
 * every strip in the app.
 */
.travel-record-tabs {
    border-radius: 999px;
    padding: 0.1875rem;
}

.travel-record-tabs .fi-tabs-item {
    border-radius: 999px;
    padding-block: 0.3125rem;
}

/*
 * The switch sits in the middle of the header row, not at either end.
 *
 * It is neither a breadcrumb nor an action: it says which face of the record
 * you are looking at, so it is given the band of empty space between the two
 * rather than being filed with the buttons.
 *
 * Centred by auto margins rather than by taking it out of flow. Absolute
 * positioning would put it on the row's exact midpoint and, on a narrower
 * window, on top of the breadcrumbs it was meant to sit clear of. In flow the
 * margins simply give back whatever room they have, so the switch slides
 * towards the buttons as the window closes instead of colliding.
 *
 * Filament grows the actions block to fill the container, which would leave no
 * free space for those margins to claim, so here it is sized to its buttons.
 */
.fi-header-actions-ctn:has(.travel-record-tabs) {
    /* Filament sizes this block to its buttons; the band to centre in is the
       rest of the row, so it is claimed here and shared out below. */
    flex: 1;
}

.fi-header-actions-ctn:has(.travel-record-tabs) > .fi-ac {
    flex: 0 0 auto;
}

.fi-header .fi-header-actions-ctn > .travel-record-tabs {
    margin-inline: auto;
}

/*
 * ============================================================================
 * Clause maintenance tab
 * ============================================================================
 *
 * A card per group of clauses, the traveller's reading of them beside it, and
 * a footer that says when it last saved. Same two rails and the same container
 * query as the other tabs, at a wider threshold: a clause is a sentence, and
 * sentences need the width the itinerary's timeline does not.
 *
 * The sentence is the field here. A clause is drawn as its own words with the
 * blanks set into them, so the controls are sized to their content and sit on
 * the text baseline rather than in a column of labelled boxes.
 */
.travel-terms {
    container-name: travel-terms;
    container-type: inline-size;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.travel-terms-body {
    align-items: start;
    display: grid;
    gap: 1rem;
    grid-template-columns: minmax(0, 1fr);
}

@container travel-terms (min-width: 64rem) {
    .travel-terms-body {
        grid-template-columns: minmax(0, 1fr) clamp(15rem, 24%, 19rem);
    }

    .travel-terms-rail {
        position: sticky;
        top: 5rem;
    }
}

/* ------------------------------------------------------------------ shape */

/* Same step down from the Geex radii as the other dense screens. */
.travel-terms .fi-input-wrp,
.travel-terms .fi-btn,
.travel-terms .fi-icon-btn {
    border-radius: 8px;
}

/* Filament renders a dropdown item as a plain button; these want to be rows. */
.travel-terms .fi-dropdown-list .fi-btn {
    justify-content: flex-start;
    width: 100%;
}

/*
 * The clause picker lists whole sentences, blanks and all. Truncating them to
 * one line would cut exactly the part that tells two similar clauses apart —
 * "[适用人群][出发城市]至[到达城市]机票" against the same line ending in [席别].
 */
.travel-terms .fi-dropdown-list-item {
    align-items: flex-start;
}

.travel-terms .fi-dropdown-list-item-label {
    line-height: 1.5;
    white-space: normal;
}

/* ------------------------------------------------------- the four sections */

.travel-terms-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
}

.travel-terms-tab {
    border-radius: 999px;
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    padding: 0.3125rem 0.875rem;
}

.travel-terms-tab-active {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    color: var(--geex-primary, #ab54db);
    font-weight: 500;
}

/* ------------------------------------------------------------------ header */

.travel-terms-main {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    min-width: 0;
}

.travel-terms-head {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.travel-terms-heading {
    flex: 1 1 auto;
    min-width: 0;
}

.travel-terms-heading h3 {
    font-size: calc(1rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-terms-heading p {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

/* Says the tab does not have a save button, so nobody goes looking for one. */
.travel-terms-autosave {
    align-items: center;
    color: var(--geex-info-text, #1d4ed8);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
}

.travel-terms-autosave .fi-icon {
    height: 0.875rem;
    width: 0.875rem;
}

/* ------------------------------------------------------------- group cards */

.travel-terms-cards {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.travel-terms-card {
    background-color: var(--geex-surface, #fff);
    border-radius: 14px;
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
}

.travel-terms-card.sortable-ghost {
    opacity: 0.4;
}

.travel-terms-card-head {
    align-items: center;
    display: flex;
    gap: 0.625rem;
    padding: 0.75rem 1rem;
}

.travel-terms-handle {
    color: var(--geex-text-faint, #9ca3af);
    cursor: grab;
    display: flex;
    flex: none;
}

.travel-terms-handle .fi-icon {
    height: 1rem;
    margin-inline-end: -0.5rem;
    width: 1rem;
}

.travel-terms-icon {
    align-items: center;
    background-color: var(--tone-soft, rgba(161, 161, 170, 0.15));
    border-radius: 999px;
    color: var(--tone, #a1a1aa);
    display: flex;
    flex: none;
    height: 1.75rem;
    justify-content: center;
    width: 1.75rem;
}

.travel-terms-icon .fi-icon {
    height: 1rem;
    width: 1rem;
}

.travel-terms-name {
    flex: none;
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

/*
 * Folded, the card says what it holds. The chips take the room that is left and
 * stop at the end of it: this is a summary of a card that can be opened, not a
 * second place to read the clauses.
 */
.travel-terms-chips {
    display: flex;
    flex: 1 1 auto;
    gap: 0.375rem;
    min-width: 0;
    overflow: hidden;
}

.travel-terms-chip {
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 8px;
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    max-width: 16rem;
    overflow: hidden;
    padding: 0.1875rem 0.5rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.travel-terms-chip em {
    font-style: normal;
    font-weight: 500;
    margin-inline-end: 0.25rem;
}

.travel-terms-badge {
    border-radius: 999px;
    flex: none;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    padding: 0.1875rem 0.625rem;
}

.travel-terms-badge-success {
    background-color: var(--geex-success-soft, rgba(22, 163, 74, 0.12));
    color: var(--geex-success-text, #15803d);
}

.travel-terms-badge-warning {
    background-color: var(--geex-warning-soft, rgba(245, 158, 11, 0.12));
    color: var(--geex-warning-text, #92400e);
}

.travel-terms-badge-info {
    background-color: var(--geex-info-soft, rgba(59, 130, 246, 0.1));
    color: var(--geex-info-text, #1d4ed8);
}

.travel-terms-badge-gray {
    background-color: var(--geex-canvas, #f3f4f6);
    color: var(--geex-text-faint, #9ca3af);
}

.travel-terms-lock {
    color: var(--geex-text-faint, #9ca3af);
    display: flex;
    flex: none;
}

.travel-terms-lock .fi-icon {
    height: 1rem;
    width: 1rem;
}

/* ------------------------------------------------------------- card bodies */

.travel-terms-card-body {
    border-top: 1px solid var(--geex-line, #eceaf3);
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    padding: 0.875rem 1rem 1rem;
}

.travel-terms-clause {
    align-items: center;
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 10px;
    display: flex;
    gap: 0.5rem;
    justify-content: space-between;
    padding: 0.5rem 0.625rem;
}

.travel-terms-legend {
    color: var(--geex-warning-text, #92400e);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    font-weight: 500;
}

.travel-terms-note,
.travel-terms-issue {
    align-items: center;
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
}

.travel-terms-note {
    color: var(--geex-text-muted, #6b7280);
}

.travel-terms-issue {
    color: var(--geex-danger, #dc2626);
}

.travel-terms-note .fi-icon,
.travel-terms-issue .fi-icon {
    flex: none;
    height: 0.875rem;
    width: 0.875rem;
}

.travel-terms-empty {
    color: var(--geex-text-faint, #9ca3af);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-terms-add {
    align-items: center;
    align-self: flex-start;
    border: 1px dashed var(--geex-line, #d4d4d8);
    border-radius: 10px;
    color: var(--geex-text-muted, #6b7280);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
    padding: 0.375rem 0.75rem;
}

.travel-terms-add:hover {
    border-color: var(--geex-primary, #ab54db);
    color: var(--geex-primary, #ab54db);
}

.travel-terms-add .fi-icon {
    height: 1rem;
    width: 1rem;
}

.travel-terms-link {
    align-self: flex-start;
    color: var(--geex-primary, #ab54db);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

/* The meals card: what the itinerary adds up to, per traveller. */
.travel-terms-pairs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.travel-terms-pair {
    align-items: center;
    display: flex;
    gap: 0.375rem;
}

.travel-terms-pair em {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    border-radius: 8px;
    color: var(--geex-primary, #ab54db);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    font-style: normal;
    padding: 0.1875rem 0.5rem;
}

.travel-terms-pair b {
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 8px;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    font-weight: 500;
    padding: 0.1875rem 0.5rem;
}

/* ------------------------------------------------------ a required choice */

.travel-terms-choices {
    display: grid;
    gap: 0.5rem;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}

.travel-terms-choice {
    align-items: center;
    background-color: var(--geex-surface, #fff);
    border: 1px solid var(--geex-line, #d4d4d8);
    border-radius: 10px;
    display: flex;
    gap: 0.5rem;
    padding: 0.625rem 0.75rem;
    text-align: start;
}

.travel-terms-choice-active {
    border-color: var(--geex-primary, #ab54db);
    box-shadow: 0 0 0 1px var(--geex-primary, #ab54db);
}

.travel-terms-radio {
    border: 1px solid var(--geex-line, #d4d4d8);
    border-radius: 999px;
    flex: none;
    height: 1rem;
    position: relative;
    width: 1rem;
}

.travel-terms-choice-active .travel-terms-radio {
    border-color: var(--geex-primary, #ab54db);
}

.travel-terms-choice-active .travel-terms-radio::after {
    background-color: var(--geex-primary, #ab54db);
    border-radius: 999px;
    content: '';
    inset: 0.1875rem;
    position: absolute;
}

.travel-terms-choice-text {
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

/* ------------------------------------------------- a clause, as a sentence */

.travel-sentence {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
    line-height: 1.9;
    min-width: 0;
}

.travel-sentence-text {
    white-space: pre-wrap;
}

.travel-sentence-seg {
    background-color: var(--geex-surface, #fff);
}

.travel-sentence-select,
.travel-sentence-input {
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    height: 1.75rem;
    padding-block: 0;
    width: auto;
}

.travel-sentence-input {
    min-width: 6rem;
}

/*
 * A blank nobody has filled in yet. It is drawn as a gap in the sentence rather
 * than as an error: the clause is on its way to being finished, and the card's
 * own line at the bottom is what says how many are left.
 */
.travel-sentence-slot-empty {
    border-color: var(--geex-warning, #f59e0b);
    border-style: dashed;
}

/*
 * A blank that holds several words. The whole vocabulary of the clause is on
 * screen: what is in reads as a tag with a cross, what is out as a faint one
 * with a plus. Adding and removing are then the same gesture in the same place,
 * rather than a menu on one side and crosses on the other.
 */
.travel-tags {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}

.travel-tag {
    align-items: center;
    border: 1px solid var(--geex-line, #d4d4d8);
    border-radius: 8px;
    color: var(--geex-text-faint, #9ca3af);
    display: inline-flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.1875rem;
    padding: 0.125rem 0.375rem 0.125rem 0.5rem;
}

.travel-tag .fi-icon {
    height: 0.75rem;
    opacity: 0.6;
    width: 0.75rem;
}

.travel-tag:hover {
    border-color: var(--geex-primary, #ab54db);
    color: var(--geex-primary, #ab54db);
}

.travel-tag-on {
    background-color: var(--geex-surface, #fff);
    border-color: var(--geex-line, #d4d4d8);
    color: var(--geex-text, #464255);
}

/* Both ends of a journey as one field, with the arrow inside it. */
.travel-route {
    align-items: center;
    background-color: var(--geex-surface, #fff);
    border: 1px solid var(--geex-line, #d4d4d8);
    border-radius: 8px;
    display: inline-flex;
    gap: 0.25rem;
    padding: 0 0.375rem;
}

.travel-route-end {
    background-color: transparent;
    border: 0;
    color: inherit;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    height: 1.625rem;
    padding: 0;
}

.travel-route-end.travel-sentence-slot-empty {
    border: 0;
    color: var(--geex-warning-text, #92400e);
}

.travel-route-arrow {
    color: var(--geex-text-faint, #9ca3af);
    flex: none;
    height: 0.875rem;
    width: 0.875rem;
}

/* ---------------------------------------------------------- preview & foot */

.travel-terms-rail {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.travel-terms-preview-list {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    list-style: decimal;
    padding-inline-start: 1.25rem;
}

.travel-terms-preview-list li {
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

.travel-terms-preview-group {
    display: block;
    font-weight: 600;
}

.travel-terms-preview-line {
    color: var(--geex-text-muted, #6b7280);
    display: block;
}

.travel-terms-preview-foot {
    border-top: 1px solid var(--geex-line, #eceaf3);
    padding-block-start: 0.625rem;
}

.travel-terms-foot {
    align-items: center;
    border-top: 1px solid var(--geex-line, #eceaf3);
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    justify-content: space-between;
    padding-block-start: 0.75rem;
}

.travel-terms-saved {
    align-items: center;
    color: var(--geex-text-muted, #6b7280);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
}

.travel-terms-saved .fi-icon {
    color: var(--geex-success-text, #15803d);
    height: 0.875rem;
    width: 0.875rem;
}

/* The whole set of clauses in a modal, one section after another. */
.travel-term-sheet {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.travel-term-sheet-section h3 {
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
    margin-block-end: 0.375rem;
}

.travel-term-sheet-section ol {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    list-style: decimal;
    padding-inline-start: 1.25rem;
}

.travel-term-sheet-section li {
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

/*
 * ============================================================================
 * Dark mode
 * ============================================================================
 *
 * Everything built from a `--geex-*` token flips on its own — the dark values
 * are set once in geex-theme.css. What is left here is the colour that is not
 * a surface: the tones a node type is drawn in, the four calendar statuses, and
 * the handful of plates that float over a photograph.
 *
 * The accents move up the ramp rather than staying put. A 600-weight green on
 * a white card is the same distance from its background as a 400-weight green
 * on a dark one; keeping the light value would leave it muddy.
 */

/* Text is inherited from here down, so a card never depends on what Filament
   happens to have set on the element above it. */
.travel-basics,
.travel-media,
.travel-itinerary,
.travel-calendar,
.travel-library,
.travel-terms,
.travel-completeness,
.travel-spec {
    color: var(--geex-text);
}

.travel-figure-text strong,
.travel-readout strong,
.travel-preview-count,
.travel-calendar-month,
.travel-day-name,
.travel-day-tab-code {
    color: var(--geex-text);
}

/* A hand-rolled control has to say what colour its text is; a native input
   does not inherit one, and neither does an option list. */
.travel-input {
    color: var(--geex-text);
}

.travel-select option {
    background-color: var(--geex-surface);
    color: var(--geex-text);
}

html.dark {
    /*
     * Native controls — number spinners, the select chevron, date pickers —
     * are drawn by the browser from this, not from CSS.
     */
    color-scheme: dark;
}

html.dark .travel-input {
    /* A field the same grey as the card it sits on has no edge to speak of. */
    background-color: rgba(255, 255, 255, 0.05);
}

/* ------------------------------------------------------------- dark tones */

html.dark .travel-tone-violet {
    --tone: #a78bfa;
    --tone-soft: color-mix(in oklab, #a78bfa 18%, transparent);
}

html.dark .travel-tone-sky {
    --tone: #38bdf8;
    --tone-soft: color-mix(in oklab, #38bdf8 18%, transparent);
}

html.dark .travel-tone-green {
    --tone: #4ade80;
    --tone-soft: color-mix(in oklab, #4ade80 18%, transparent);
}

html.dark .travel-tone-amber {
    --tone: #fbbf24;
    --tone-soft: color-mix(in oklab, #fbbf24 18%, transparent);
}

html.dark .travel-tone-blue {
    --tone: #60a5fa;
    --tone-soft: color-mix(in oklab, #60a5fa 18%, transparent);
}

html.dark .travel-tone-pink {
    --tone: #f472b6;
    --tone-soft: color-mix(in oklab, #f472b6 18%, transparent);
}

html.dark .travel-tone-slate {
    --tone: #94a3b8;
    --tone-soft: color-mix(in oklab, #94a3b8 18%, transparent);
}

/* --------------------------------------------------------- dark statuses */

html.dark .travel-status-sellable .travel-cell-status,
html.dark .travel-legend-item.travel-status-sellable {
    color: #4ade80;
}

html.dark .travel-status-sold-out .travel-cell-status,
html.dark .travel-legend-item.travel-status-sold-out {
    color: #f87171;
}

html.dark .travel-status-closed .travel-cell-status,
html.dark .travel-legend-item.travel-status-closed {
    color: #fbbf24;
}

html.dark .travel-status-unset .travel-cell-status,
html.dark .travel-legend-item.travel-status-unset {
    color: #71717a;
}

/* ------------------------------------------------- plates over photographs */

/*
 * These sit on the image itself, so they take their contrast from the
 * photograph rather than from the page. A white plate stays readable over a
 * bright sky in light mode; in dark the surrounding chrome is dark and a white
 * chip reads as a hole punched in the tile.
 */
html.dark .travel-tile-handle,
html.dark .travel-tile-badge {
    background-color: rgba(0, 0, 0, 0.6);
    color: #fff;
}

html.dark .travel-tile-status {
    background-color: rgba(0, 0, 0, 0.75);
}

/* ------------------------------------------------------------ dark contrast */

/*
 * The completeness ring's track is a hairline in light mode; at dark-mode
 * opacity it disappears, and the ring loses the circle it is measured against.
 */
html.dark .travel-completeness-ring-track {
    stroke: rgba(255, 255, 255, 0.12);
}

/* An outside day is dimmer than the grid, not lighter than it. */
html.dark .travel-cell-outside {
    background-color: rgba(0, 0, 0, 0.2);
}

html.dark .travel-grid-head {
    background-color: rgba(255, 255, 255, 0.04);
}

/*
 * ============================================================================
 * The bulk price / stock dialog
 * ============================================================================
 *
 * A wide two-column dialog: the fields on the left, and down the right a rail
 * that keeps saying what pressing the button would do. The rail is the point
 * of the screen — one press here can rewrite a season — so it is styled as a
 * readout rather than as help text, and the figure that costs money (dates
 * already priced) carries the warning colour wherever it appears.
 */
.travel-bulk {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    /* The dialog's own breakpoint: it is far wider than the tab it opens over. */
    container-name: travel-bulk;
    container-type: inline-size;
}

.travel-bulk-head {
    align-items: start;
    display: flex;
    gap: 1rem;
    justify-content: space-between;
}

.travel-bulk-head h2 {
    color: var(--geex-text, #111827);
    font-size: calc(1.125rem * var(--geex-type-scale, 1));
    font-weight: 700;
}

.travel-bulk-head p {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    margin-block-start: 0.25rem;
}

/* ------------------------------------------------------------------- steps */

.travel-bulk-steps {
    align-items: center;
    display: flex;
    gap: 0.75rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.travel-bulk-step {
    align-items: center;
    color: var(--geex-text-faint, #9ca3af);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.5rem;
}

/* The rule between two steps: drawn by the step, so it stretches with the row. */
.travel-bulk-step:not(:last-child)::after {
    background-color: var(--geex-line, #eceaf3);
    block-size: 1px;
    content: '';
    flex: 1;
    margin-inline-start: 0.75rem;
    min-inline-size: 2rem;
}

.travel-bulk-step:not(:last-child) {
    flex: 1;
}

.travel-bulk-step-mark {
    align-items: center;
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 999px;
    block-size: 1.5rem;
    display: inline-flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    font-weight: 600;
    inline-size: 1.5rem;
    justify-content: center;
}

.travel-bulk-step-mark .fi-icon {
    block-size: 0.875rem;
    inline-size: 0.875rem;
}

.travel-bulk-step-done {
    color: var(--geex-primary, #ab54db);
}

.travel-bulk-step-done .travel-bulk-step-mark,
.travel-bulk-step-current .travel-bulk-step-mark {
    background-color: var(--geex-primary, #ab54db);
    color: var(--geex-on-primary, #fff);
}

.travel-bulk-step-current {
    color: var(--geex-primary, #ab54db);
    font-weight: 600;
}

/* -------------------------------------------------------------------- body */

.travel-bulk-body {
    display: grid;
    gap: 1rem;
}

@container travel-bulk (min-width: 58rem) {
    .travel-bulk-body {
        align-items: start;
        grid-template-columns: minmax(0, 1fr) clamp(16rem, 28%, 21rem);
    }
}

.travel-bulk-main {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    min-inline-size: 0;
}

.travel-bulk-card {
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 16px;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1rem;
}

.travel-bulk-card h3 {
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-bulk-card-head {
    align-items: center;
    display: flex;
    gap: 1rem;
    justify-content: space-between;
}

.travel-bulk-lead,
.travel-bulk-note,
.travel-bulk-help {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

/* ------------------------------------------------------ the choice of dates */

.travel-bulk-modes {
    display: grid;
    gap: 0.5rem;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}

.travel-bulk-modes-pair {
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}

.travel-bulk-mode {
    align-items: center;
    background-color: var(--geex-surface, #fff);
    border: 1px solid transparent;
    border-radius: 12px;
    display: flex;
    gap: 0.625rem;
    padding: 0.625rem 0.75rem;
    position: relative;
    text-align: start;
}

.travel-bulk-mode-active {
    border-color: var(--geex-primary, #ab54db);
    box-shadow: 0 0 0 1px var(--geex-primary, #ab54db);
}

.travel-bulk-mode-icon {
    align-items: center;
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    border-radius: 10px;
    color: var(--geex-primary, #ab54db);
    display: flex;
    flex: none;
    justify-content: center;
    padding: 0.375rem;
}

.travel-bulk-mode-icon .fi-icon {
    block-size: 1.125rem;
    inline-size: 1.125rem;
}

.travel-bulk-mode-text {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-inline-size: 0;
}

.travel-bulk-mode-text strong {
    font-size: calc(0.875rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-bulk-mode-text small {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
}

.travel-bulk-mode-check {
    block-size: 1.125rem;
    color: var(--geex-primary, #ab54db);
    inline-size: 1.125rem;
    inset-block-start: 0.625rem;
    inset-inline-end: 0.625rem;
    position: absolute;
}

.travel-bulk-range {
    align-items: end;
    display: flex;
    flex-wrap: wrap;
    gap: 0.625rem;
}

.travel-bulk-range .travel-field {
    min-inline-size: 9rem;
}

.travel-bulk-range-arrow {
    block-size: 1rem;
    color: var(--geex-text-faint, #9ca3af);
    inline-size: 1rem;
    margin-block-end: 0.625rem;
}

.travel-bulk-presets {
    margin-inline-start: auto;
}

.travel-bulk-weekdays {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.travel-bulk-weekday-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
}

.travel-bulk-weekday {
    background-color: var(--geex-surface, #fff);
    border-radius: 8px;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    min-inline-size: 2.25rem;
    padding: 0.3125rem 0.5rem;
}

.travel-bulk-weekday-on {
    background-color: var(--geex-primary, #ab54db);
    color: var(--geex-on-primary, #fff);
    font-weight: 600;
}

/* The running total of what the pattern matches, beside the pattern itself. */
.travel-bulk-match {
    background-color: var(--geex-success-soft, rgba(22, 163, 74, 0.12));
    border-radius: 8px;
    color: var(--geex-success-text, #15803d);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    margin-inline-start: auto;
    padding: 0.3125rem 0.625rem;
}

.travel-bulk-match-empty {
    background-color: var(--geex-warning-soft, rgba(245, 158, 11, 0.2));
    color: var(--geex-warning-text, #92400e);
}

/* ------------------------------------------------------------- what to write */

.travel-bulk-fields {
    display: grid;
    gap: 0.75rem;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}

@container travel-bulk (max-width: 46rem) {
    .travel-bulk-fields {
        grid-template-columns: minmax(0, 1fr);
    }
}

.travel-bulk-prices {
    display: grid;
    gap: 0.625rem;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}

.travel-bulk-stock {
    border-inline-start: 1px solid var(--geex-line, #eceaf3);
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    padding-inline-start: 0.75rem;
}

@container travel-bulk (max-width: 46rem) {
    .travel-bulk-stock {
        border-inline-start: 0;
        padding-inline-start: 0;
    }
}

.travel-bulk-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.travel-bulk-field-head {
    align-items: center;
    display: flex;
    gap: 0.5rem;
    justify-content: space-between;
}

/* "Leave as is" reads as an option on the field, not as a field of its own. */
.travel-bulk-keep {
    align-items: center;
    color: var(--geex-text-muted, #6b7280);
    cursor: pointer;
    display: flex;
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
}

.travel-bulk-keep .fi-checkbox-input {
    block-size: 0.875rem;
    inline-size: 0.875rem;
}

.travel-bulk-oversell {
    justify-content: start;
}

.travel-bulk-margins {
    background-color: var(--geex-success-soft, rgba(22, 163, 74, 0.12));
    border-radius: 10px;
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    padding: 0.5rem 0.75rem;
}

.travel-bulk-margin {
    color: var(--geex-success-text, #15803d);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-bulk-margin strong {
    font-weight: 600;
    margin-inline-start: 0.375rem;
}

/* A negative margin is not a green figure, whatever the strip around it says. */
.travel-bulk-margin-negative,
.travel-bulk-margin-negative strong {
    color: var(--geex-danger, #dc2626);
}

.travel-bulk-warning {
    align-items: center;
    background-color: var(--geex-warning-soft, rgba(245, 158, 11, 0.2));
    border-radius: 10px;
    color: var(--geex-warning-text, #92400e);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
    padding: 0.5rem 0.75rem;
}

.travel-bulk-warning .fi-icon {
    block-size: 1rem;
    flex: none;
    inline-size: 1rem;
}

/* -------------------------------------------------------------------- rail */

.travel-bulk-rail {
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 16px;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1rem;
}

.travel-bulk-rail h3 {
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-bulk-summary,
.travel-bulk-figures {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0;
}

.travel-bulk-summary > div,
.travel-bulk-figures > div {
    align-items: center;
    display: flex;
    gap: 0.75rem;
    justify-content: space-between;
}

.travel-bulk-summary dt,
.travel-bulk-figures dt {
    align-items: center;
    color: var(--geex-text-muted, #6b7280);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
}

.travel-bulk-summary dt .fi-icon {
    block-size: 0.875rem;
    color: var(--geex-primary, #ab54db);
    inline-size: 0.875rem;
}

.travel-bulk-summary dd,
.travel-bulk-figures dd {
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    font-weight: 600;
    margin: 0;
    text-align: end;
}

.travel-bulk-amber {
    color: var(--geex-warning-text, #92400e);
}

.travel-bulk-figures {
    background-color: var(--geex-surface, #fff);
    border-radius: 12px;
    padding: 0.75rem;
}

/* The week at a glance: which days this pattern lands on. */
.travel-bulk-dots {
    background-color: var(--geex-surface, #fff);
    border-radius: 12px;
    display: grid;
    gap: 0.25rem;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    padding: 0.625rem 0.5rem;
    text-align: center;
}

.travel-bulk-dots span {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.travel-bulk-dots em {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    font-style: normal;
}

.travel-bulk-dot-on {
    background-color: var(--geex-primary, #ab54db);
    block-size: 0.5rem;
    border-radius: 999px;
    inline-size: 0.5rem;
    margin-inline: auto;
}

.travel-bulk-dot-off {
    color: var(--geex-text-faint, #9ca3af);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    font-style: normal;
    line-height: 0.5rem;
}

.travel-bulk-estimate {
    align-items: center;
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    border-radius: 12px;
    color: var(--geex-primary, #ab54db);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    font-weight: 600;
    gap: 0.5rem;
    padding: 0.625rem 0.75rem;
}

.travel-bulk-estimate .fi-icon {
    block-size: 1rem;
    flex: none;
    inline-size: 1rem;
}

.travel-bulk-see {
    align-items: center;
    color: var(--geex-primary, #ab54db);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
    justify-content: space-between;
}

.travel-bulk-see .fi-icon {
    block-size: 1rem;
    inline-size: 1rem;
}

.travel-bulk-dates {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    max-block-size: 14rem;
    overflow-y: auto;
}

.travel-bulk-dates-rail {
    max-block-size: 9rem;
}

.travel-bulk-date {
    align-items: center;
    background-color: var(--geex-surface, #fff);
    border-radius: 8px;
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
    padding: 0.25rem 0.5rem;
}

.travel-bulk-date em {
    color: var(--geex-success-text, #15803d);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    font-style: normal;
}

.travel-bulk-date-existing em {
    color: var(--geex-warning-text, #92400e);
}

/* A date the "fill the gaps" mode will not touch is shown as read-only. */
.travel-bulk-date-skipped {
    opacity: 0.55;
}

.travel-bulk-date-skipped em {
    color: var(--geex-text-muted, #6b7280);
}

/* ------------------------------------------------------------------ footer */

.travel-bulk-footer {
    align-items: center;
    border-top: 1px solid var(--geex-line, #eceaf3);
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    justify-content: space-between;
    padding-block-start: 0.75rem;
}

.travel-bulk-notice {
    align-items: center;
    color: var(--geex-text-muted, #6b7280);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
}

.travel-bulk-notice .fi-icon {
    block-size: 1rem;
    inline-size: 1rem;
}

.travel-bulk-footer-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-inline-start: auto;
}

/* ---------------------------------------------------------- dark contrast */

/*
 * The dialog's cards sit on the modal's own surface rather than on the page,
 * so in dark mode `--geex-canvas` (an inset tint) is the right fill and the
 * white surfaces inside them have to step up rather than down.
 */
html.dark .travel-bulk-mode,
html.dark .travel-bulk-weekday,
html.dark .travel-bulk-figures,
html.dark .travel-bulk-dots,
html.dark .travel-bulk-date {
    background-color: rgba(255, 255, 255, 0.06);
}

html.dark .travel-bulk-weekday-on {
    background-color: var(--geex-primary, #c084fc);
    color: var(--geex-on-primary, #09090b);
}

/*
 * ============================================================================
 * Website & SEO tab
 * ============================================================================
 *
 * Five folding cards down the left and a rail down the right that draws the
 * card the website will draw. The rail is the point: none of these settings
 * are legible on their own — "Moderate" plus a line about walking two hours a
 * day is a chip and its subtitle — so the tab is only finished when the
 * preview beside it reads properly.
 *
 * Same container query as the other tabs: the rail folds under the cards when
 * the form is narrow.
 */
.travel-website,
.travel-advanced {
    --travel-website-rail: clamp(16rem, 26%, 21rem);
}

.travel-website {
    container-name: travel-website;
    container-type: inline-size;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.travel-website-head h2 {
    font-size: calc(1rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-website-head p {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

.travel-website-notice {
    align-items: center;
    background-color: var(--geex-info-soft, rgba(59, 130, 246, 0.1));
    border-radius: 12px;
    color: var(--geex-info-text, #1d4ed8);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.5rem;
    padding: 0.625rem 0.875rem;
}

.travel-website-notice .fi-icon {
    block-size: 1rem;
    flex: none;
    inline-size: 1rem;
}

.travel-website-body {
    display: grid;
    gap: 1rem;
}

@container travel-website (min-width: 64rem) {
    .travel-website-body {
        align-items: start;
        grid-template-columns: minmax(0, 1fr) var(--travel-website-rail);
    }

    .travel-website-rail {
        position: sticky;
        top: 5rem;
    }
}

/*
 * FAQs, add-ons and the rest are Filament sections under the board, not
 * cards inside it. Without this they span the rail as well as the cards.
 * Cap them to the board's main track so their right edge matches the SEO
 * card, leaving the rail's column empty beside them.
 */
.travel-advanced {
    container-name: travel-advanced;
    container-type: inline-size;
}

@container travel-advanced (min-width: 64rem) {
    .travel-advanced > .fi-sc > :not(:first-child) {
        max-width: calc(100% - var(--travel-website-rail) - 1rem);
    }
}

.travel-website-main {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    min-inline-size: 0;
}

/* ------------------------------------------------------------------- cards */

.travel-website-card {
    background-color: var(--geex-surface, #fff);
    border-radius: 16px;
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1rem;
}

.travel-website-card-head {
    align-items: center;
    display: flex;
    gap: 0.75rem;
    inline-size: 100%;
    text-align: start;
}

.travel-website-card-head > .fi-icon {
    block-size: 1rem;
    color: var(--geex-text-faint, #9ca3af);
    inline-size: 1rem;
}

.travel-website-card-title {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    margin-inline-end: auto;
    min-inline-size: 0;
}

.travel-website-card-title strong {
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-website-card-title small {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-website-badge {
    background-color: var(--geex-warning-soft, rgba(245, 158, 11, 0.2));
    border-radius: 999px;
    color: var(--geex-warning-text, #92400e);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    padding: 0.125rem 0.5rem;
}

.travel-website-badge-done {
    background-color: var(--geex-success-soft, rgba(22, 163, 74, 0.12));
    color: var(--geex-success-text, #15803d);
}

/* The tag beside a field saying who owns its value. */
.travel-website-source {
    background-color: var(--geex-info-soft, rgba(59, 130, 246, 0.1));
    border-radius: 6px;
    color: var(--geex-info-text, #1d4ed8);
    font-size: calc(0.625rem * var(--geex-type-scale, 1));
    font-style: normal;
    margin-inline-start: 0.375rem;
    padding: 0.0625rem 0.375rem;
}

/* ------------------------------------------------- the summary attributes */

.travel-website-attributes {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
}

/*
 * One attribute per row: what it is, the chips, the line under it, whether it
 * is shown, and the reset. The row wraps rather than scrolls, because a style
 * list is eight chips wide and a subtitle is a sentence.
 */
.travel-website-attribute {
    align-items: center;
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 12px;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.625rem 0.75rem;
}

.travel-website-attribute-label {
    color: var(--geex-text-muted, #6b7280);
    flex: none;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    inline-size: 7rem;
}

.travel-website-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
}

.travel-website-chip {
    align-items: center;
    background-color: var(--geex-surface, #fff);
    border: 1px solid transparent;
    border-radius: 10px;
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
    padding: 0.3125rem 0.625rem;
}

.travel-website-chip .fi-icon {
    block-size: 0.875rem;
    inline-size: 0.875rem;
}

.travel-website-chip-on {
    border-color: var(--geex-primary, #ab54db);
    color: var(--geex-primary, #ab54db);
    font-weight: 500;
}

.travel-website-sub {
    flex: 1 1 14rem;
    min-inline-size: 0;
}

.travel-website-show {
    flex: none;
}

/* ------------------------------------------------------ badge and figures */

.travel-website-marketing {
    display: grid;
    gap: 0.75rem;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
}

@container travel-website (max-width: 52rem) {
    .travel-website-marketing {
        grid-template-columns: minmax(0, 1fr);
    }
}

.travel-website-badge-editor,
.travel-website-proof {
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 12px;
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    padding: 0.75rem;
}

.travel-website-card-head-plain {
    justify-content: space-between;
}

.travel-website-colors {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
}

.travel-website-color {
    align-items: center;
    background-color: var(--geex-surface, #fff);
    border: 1px solid transparent;
    border-radius: 10px;
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
    padding: 0.3125rem 0.5rem;
}

.travel-website-color-on {
    border-color: var(--geex-primary, #ab54db);
}

.travel-tone-dot {
    background-color: var(--tone, #7c3aed);
    block-size: 0.625rem;
    border-radius: 999px;
    display: inline-block;
    inline-size: 0.625rem;
}

.travel-website-figures {
    display: grid;
    gap: 0.5rem;
    grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
}

.travel-website-figure {
    background-color: var(--geex-surface, #fff);
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: 0.5rem 0.625rem;
}

.travel-website-figure-input {
    font-size: calc(1.125rem * var(--geex-type-scale, 1));
    font-weight: 600;
    padding-inline: 0.375rem;
}

.travel-website-proof-foot {
    align-items: center;
    color: var(--geex-text-muted, #6b7280);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.75rem;
    justify-content: space-between;
}

/* A counter sitting inside the right-hand end of its own box. */
.travel-website-counted {
    display: flex;
    position: relative;
}

.travel-website-counted .travel-input {
    inline-size: 100%;
    padding-inline-end: 3.25rem;
}

.travel-website-counted i,
.travel-website-valid {
    color: var(--geex-text-faint, #9ca3af);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    font-style: normal;
    inset-block-start: 0.625rem;
    inset-inline-end: 0.625rem;
    position: absolute;
}

.travel-website-valid {
    block-size: 1rem;
    color: var(--geex-success-text, #15803d);
    inline-size: 1rem;
}

.travel-website-textarea {
    min-block-size: 4.5rem;
    resize: vertical;
}

/* --------------------------------------------------------------- taxonomy */

.travel-website-tags {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
}

.travel-website-tokens {
    align-items: center;
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 12px;
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    padding: 0.5rem;
}

.travel-website-token {
    align-items: center;
    background-color: var(--geex-surface, #fff);
    border-radius: 8px;
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
    padding: 0.25rem 0.5rem;
}

.travel-website-token .fi-icon {
    block-size: 0.875rem;
    color: var(--geex-text-faint, #9ca3af);
    inline-size: 0.875rem;
}

.travel-website-token-empty {
    color: var(--geex-text-faint, #9ca3af);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

.travel-website-token-add {
    flex: 1 1 10rem;
    min-inline-size: 0;
}

.travel-website-suggested {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
}

.travel-website-suggestion {
    align-items: center;
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    border-radius: 8px;
    color: var(--geex-primary, #ab54db);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
    padding: 0.25rem 0.5rem;
}

.travel-website-suggestion .fi-icon {
    block-size: 0.75rem;
    inline-size: 0.75rem;
}

/* --------------------------------------------------------------- operator */

.travel-website-operator {
    display: grid;
    gap: 0.625rem;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
}

.travel-website-operator-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

/* -------------------------------------------------------------------- seo */

.travel-website-seo {
    display: grid;
    gap: 0.75rem;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}

.travel-website-seo-tools {
    grid-column: 1 / -1;
}

/* ------------------------------------------------------------------- rail */

.travel-website-rail {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.travel-website-preview,
.travel-website-checks,
.travel-website-status {
    background-color: var(--geex-surface, #fff);
    border-radius: 16px;
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    padding: 0.875rem;
}

.travel-website-preview h3,
.travel-website-checks h3,
.travel-website-status h3 {
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-website-status h3 {
    align-items: center;
    display: flex;
    gap: 0.375rem;
}

.travel-website-status-hint {
    color: var(--geex-info-text, #2563eb);
    cursor: help;
    display: inline-flex;
}

.travel-website-status-hint .fi-icon {
    block-size: 1rem;
    inline-size: 1rem;
}

/* The frame switch is a control, not a strip across the rail. */
.travel-website-preview .travel-seg {
    align-self: flex-start;
}

.travel-website-preview-head {
    align-items: center;
    display: flex;
    gap: 0.5rem;
    justify-content: space-between;
}

/* The card the website draws, at the width it draws it. */
.travel-website-card-preview {
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 14px;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem;
}

.travel-website-card-preview-mobile {
    margin-inline: auto;
    max-inline-size: 15rem;
}

.travel-website-cover {
    align-items: center;
    aspect-ratio: 16 / 9;
    background-color: var(--geex-line, #eceaf3);
    border-radius: 10px;
    display: flex;
    justify-content: center;
    overflow: hidden;
    position: relative;
}

.travel-website-cover img {
    block-size: 100%;
    inline-size: 100%;
    object-fit: cover;
}

.travel-website-cover-empty {
    color: var(--geex-text-faint, #9ca3af);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-website-cover-badge {
    background-color: var(--tone, #7c3aed);
    border-radius: 999px;
    color: #fff;
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    inset-block-start: 0.5rem;
    inset-inline-end: 0.5rem;
    padding: 0.1875rem 0.5rem;
    position: absolute;
}

.travel-website-card-preview h4 {
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-website-preview-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}

.travel-website-preview-chips span {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    border-radius: 6px;
    color: var(--geex-primary, #ab54db);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    padding: 0.125rem 0.375rem;
}

.travel-website-preview-sub {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-website-preview-figures {
    align-items: center;
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
}

.travel-website-preview-figures .fi-icon {
    block-size: 0.875rem;
    color: var(--geex-warning-text, #f59e0b);
    inline-size: 0.875rem;
    margin-inline-end: 0.25rem;
}

.travel-website-checks ul {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.travel-website-checks li {
    align-items: center;
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.5rem;
    justify-content: space-between;
}

.travel-website-checks li span {
    align-items: center;
    color: var(--geex-text-muted, #6b7280);
    display: flex;
    gap: 0.375rem;
}

.travel-website-checks li .fi-icon {
    block-size: 1rem;
    color: var(--geex-success-text, #15803d);
    inline-size: 1rem;
}

.travel-website-checks li em {
    color: var(--geex-success-text, #15803d);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    font-style: normal;
}

.travel-website-check-pending {
    color: var(--geex-warning-text, #92400e);
}

.travel-website-checks li span:has(+ .travel-website-check-pending) .fi-icon {
    color: var(--geex-warning-text, #92400e);
}

/* The same checklist, opened out in a modal. */
.travel-website-check-sheet {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
}

.travel-website-check-sheet h4 {
    align-items: center;
    display: flex;
    font-size: calc(0.875rem * var(--geex-type-scale, 1));
    font-weight: 600;
    gap: 0.5rem;
    justify-content: space-between;
}

.travel-website-check-sheet h4 em {
    color: var(--geex-success-text, #15803d);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    font-style: normal;
}

.travel-website-check-sheet ul {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    list-style: none;
    margin: 0.375rem 0 0;
    padding: 0;
}

.travel-website-check-sheet li {
    align-items: center;
    color: var(--geex-text-muted, #6b7280);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
}

.travel-website-check-sheet li .fi-icon {
    block-size: 1rem;
    inline-size: 1rem;
}

/* ---------------------------------------------------------- dark contrast */

html.dark .travel-website-attribute,
html.dark .travel-website-badge-editor,
html.dark .travel-website-proof,
html.dark .travel-website-tokens,
html.dark .travel-website-card-preview {
    background-color: rgba(255, 255, 255, 0.04);
}

html.dark .travel-website-chip,
html.dark .travel-website-color,
html.dark .travel-website-figure,
html.dark .travel-website-token {
    background-color: rgba(255, 255, 255, 0.06);
}

/*
 * ============================================================================
 * Destination editor
 * ============================================================================
 *
 * Three rails: the sections down the left with the completeness card under
 * them, the section being edited in the middle, and the three questions asked
 * *about* the page — preview, publish checks, sync — down the right.
 *
 * The rail is Filament's own vertical tabs, which renders as one flex row of
 * nav-plus-panels. That is two of the three tracks and no home for the other
 * two, so the tabs container and its wrapper are dropped out of the layout with
 * `display: contents` and their children placed on the outer grid directly.
 * Nothing about the component changes — the tab state, the query string and the
 * jump-to-the-tab-with-the-error all still belong to Filament.
 *
 * Rows are `auto 1fr` on purpose. A grid item spanning two auto rows hands its
 * surplus height to both of them equally, which on a long section would push
 * the completeness card a screen below the rail it belongs to; giving row two
 * all the slack pins it directly under the last section.
 *
 * The switch is a container query, not a media query, for the same reason as
 * the product screens: the panel sidebar makes the viewport the wrong number by
 * about 320px, and measuring the form itself keeps working when it is
 * collapsed.
 */
.travel-destination {
    container-name: travel-destination;
    container-type: inline-size;
}

/* Narrow: the rail lies down above the form and the two cards stack under it. */
.travel-destination .fi-sc-tabs.fi-vertical {
    flex-direction: column;
}

.travel-destination .fi-tabs.fi-vertical {
    flex-direction: row;
    overflow-x: auto;
}

.travel-destination .fi-sc-tabs.fi-vertical .fi-sc-tabs-tab.fi-active {
    margin-block-start: 1rem;
    margin-inline-start: 0;
}

@container travel-destination (min-width: 68rem) {
    .travel-destination > .fi-sc {
        align-items: start;
        display: grid;
        gap: 1rem;
        grid-template-columns:
            clamp(11.5rem, 17%, 14.5rem)
            minmax(0, 1fr)
            clamp(15rem, 23%, 19.5rem);
        grid-template-rows: auto minmax(0, 1fr);
    }

    /*
     * Three boxes stand between the grid and the tabs' own children: the
     * column Filament wraps every schema component in, the component div
     * inside it, and the tabs container itself. All three are dropped so the
     * nav and the panels land on the outer grid.
     */
    .travel-destination > .fi-sc > :has(.fi-sc-tabs),
    .travel-destination > .fi-sc > :has(.fi-sc-tabs) > .fi-sc-component,
    .travel-destination .fi-sc-tabs.fi-vertical {
        display: contents;
    }

    .travel-destination .fi-tabs.fi-vertical {
        flex-direction: column;
        grid-area: 1 / 1;
        overflow: visible;
        position: sticky;
        top: 5rem;
    }

    .travel-destination .fi-sc-tabs-tab {
        grid-area: 1 / 2 / span 2 / span 1;
    }

    .travel-destination .fi-sc-tabs.fi-vertical .fi-sc-tabs-tab.fi-active {
        margin-block-start: 0;
    }

    /* The completeness card, directly under the last section on the rail. */
    .travel-destination > .fi-sc > :nth-child(2) {
        grid-area: 2 / 1;
    }

    /*
     * The three panels down the right. Placed on the wrapper Filament renders
     * around the component rather than on the card itself: the wrapper is the
     * grid item, and the card inside it is not.
     */
    .travel-destination > .fi-sc > :nth-child(3) {
        grid-area: 1 / 3 / span 2 / span 1;
        position: sticky;
        top: 5rem;
    }
}

/* --------------------------------------------------------------- the rail */

.travel-destination .fi-tabs.fi-vertical {
    border-radius: var(--geex-radius-card, 24px);
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    gap: 0.125rem;
    padding: 0.75rem;
}

.travel-destination .fi-tabs-item {
    justify-content: flex-start;
}

/* The badge is the section's score, so it sits at the far end of the row. */
.travel-destination .fi-tabs-item .fi-badge {
    margin-inline-start: auto;
}

.travel-destination .fi-tabs-item.fi-active {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.12));
}

.travel-destination .fi-sc-tabs-tab > .fi-sc {
    gap: 1rem;
}

/* ------------------------------------------------------------- completeness */

.travel-destination-progress {
    background-color: var(--geex-surface, #fff);
    border-radius: var(--geex-radius-card, 24px);
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    padding: 1.25rem;
}

.travel-destination-progress-title {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

.travel-destination-progress-percent {
    font-size: calc(1.75rem * var(--geex-type-scale, 1));
    font-weight: 600;
    line-height: 1.1;
}

.travel-destination-progress-percent small {
    font-size: calc(0.875rem * var(--geex-type-scale, 1));
    font-weight: 500;
    margin-inline-start: 0.0625rem;
}

.travel-destination-progress-bar {
    background-color: var(--geex-line, #eceaf3);
    border-radius: 999px;
    block-size: 0.375rem;
    overflow: hidden;
}

.travel-destination-progress-bar span {
    background-color: var(--geex-primary, #ab54db);
    border-radius: inherit;
    display: block;
    block-size: 100%;
    transition: inline-size 400ms ease;
}

.travel-destination-progress-count {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-destination-progress-complete,
.travel-destination-progress-warning {
    align-items: center;
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
}

.travel-destination-progress-complete {
    color: var(--geex-success-text, #15803d);
}

.travel-destination-progress-warning {
    color: var(--geex-warning-text, #92400e);
}

.travel-destination-progress-complete .fi-icon,
.travel-destination-progress-warning .fi-icon {
    block-size: 0.875rem;
    inline-size: 0.875rem;
}

/* ------------------------------------------------------------------- aside */

.travel-destination-aside > .fi-sc {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.travel-destination-panel {
    background-color: var(--geex-surface, #fff);
    border-radius: var(--geex-radius-card, 24px);
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1.25rem;
}

.travel-destination-panel-title {
    align-items: center;
    display: flex;
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
    gap: 0.375rem;
}

.travel-destination-panel-title .fi-icon {
    block-size: 1rem;
    color: var(--geex-text-muted, #6b7280);
    inline-size: 1rem;
}

.travel-destination-panel-action {
    color: var(--geex-primary, #ab54db);
    margin-inline-start: auto;
}

.travel-destination-panel-action .fi-icon {
    color: inherit;
}

/* --------------------------------------------------------------- preview */

.travel-destination-preview-card {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
}

.travel-destination-preview-card img {
    aspect-ratio: 16 / 9;
    border-radius: 12px;
    display: block;
    inline-size: 100%;
    object-fit: cover;
}

.travel-destination-preview-empty {
    align-items: center;
    aspect-ratio: 16 / 9;
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: 12px;
    color: var(--geex-text-faint, #9ca3af);
    display: flex;
    flex-direction: column;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
    justify-content: center;
}

.travel-destination-preview-empty .fi-icon {
    block-size: 1.5rem;
    inline-size: 1.5rem;
}

.travel-destination-preview-name {
    font-size: calc(1rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-destination-preview-name span {
    color: var(--geex-text-muted, #6b7280);
    font-weight: 500;
    margin-inline-start: 0.375rem;
}

.travel-destination-preview-tagline {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    margin-block-start: 0.125rem;
}

.travel-destination-preview-url {
    color: var(--geex-primary, #ab54db);
    display: block;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    margin-block-start: 0.375rem;
    overflow-wrap: anywhere;
}

.travel-destination-preview-inactive {
    align-items: center;
    color: var(--geex-warning-text, #92400e);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
}

.travel-destination-preview-inactive .fi-icon {
    block-size: 0.875rem;
    inline-size: 0.875rem;
}

/* ---------------------------------------------------------------- checks */

.travel-destination-check-list {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.travel-destination-check-list button {
    align-items: center;
    border-radius: 10px;
    display: flex;
    gap: 0.5rem;
    inline-size: 100%;
    justify-content: space-between;
    padding: 0.375rem 0.5rem;
    text-align: start;
}

.travel-destination-check-list button:hover {
    background-color: var(--geex-canvas, #f3f4f6);
}

.travel-destination-check-label {
    align-items: center;
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.5rem;
    min-width: 0;
}

.travel-destination-check-label .fi-icon {
    block-size: 1rem;
    color: var(--geex-text-muted, #6b7280);
    flex: none;
    inline-size: 1rem;
}

.travel-destination-check-state {
    align-items: center;
    display: flex;
    flex: none;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
}

.travel-destination-check-state .fi-icon {
    block-size: 0.875rem;
    inline-size: 0.875rem;
}

.travel-destination-done {
    color: var(--geex-success-text, #15803d);
}

.travel-destination-warning {
    color: var(--geex-warning-text, #92400e);
}

.travel-destination-pending {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    border-radius: var(--geex-radius-chip, 12px);
    color: var(--geex-primary, #ab54db);
    font-variant-numeric: tabular-nums;
    padding: 0.0625rem 0.375rem;
}

.travel-destination-check-toggle {
    align-items: center;
    border-top: 1px solid var(--geex-line, #eceaf3);
    color: var(--geex-text-muted, #6b7280);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
    justify-content: space-between;
    padding-block-start: 0.75rem;
    inline-size: 100%;
}

.travel-destination-check-toggle:hover {
    color: var(--geex-primary, #ab54db);
}

.travel-destination-check-toggle .fi-icon {
    block-size: 1rem;
    inline-size: 1rem;
    transition: transform 150ms ease;
}

.travel-destination-rotated {
    transform: rotate(90deg);
}

.travel-destination-outstanding {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.travel-destination-outstanding button {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    padding-inline-start: 0.5rem;
    text-align: start;
}

.travel-destination-outstanding button::before {
    background-color: var(--geex-primary, #ab54db);
    border-radius: 999px;
    content: '';
    display: inline-block;
    block-size: 0.3125rem;
    inline-size: 0.3125rem;
    margin-inline-end: 0.5rem;
    vertical-align: middle;
}

.travel-destination-outstanding button:hover {
    color: var(--geex-primary, #ab54db);
}

/* ------------------------------------------------------------------- sync */

.travel-destination-sync-rows {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.travel-destination-sync-rows > div {
    display: flex;
    gap: 0.5rem;
    justify-content: space-between;
}

.travel-destination-sync-rows dt {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

.travel-destination-sync-rows dd {
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    font-variant-numeric: tabular-nums;
}

.travel-destination-sync-state {
    align-items: center;
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
}

.travel-destination-sync-state .fi-icon {
    block-size: 1rem;
    inline-size: 1rem;
}

.travel-destination-sync-error {
    background-color: var(--geex-warning-soft, rgba(245, 158, 11, 0.12));
    border-radius: 10px;
    color: var(--geex-warning-text, #92400e);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    overflow-wrap: anywhere;
    padding: 0.5rem 0.625rem;
}

/* ---------------------------------------------------- the address, and the
   status line under the page title */

.travel-destination-url {
    align-items: center;
    background-color: var(--geex-canvas, #f3f4f6);
    border-radius: var(--geex-radius-control, 8px);
    color: var(--geex-text-muted, #6b7280);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
    overflow-wrap: anywhere;
    padding: 0.5rem 0.75rem;
}

.travel-destination-url .fi-icon {
    block-size: 1rem;
    color: var(--geex-success-text, #15803d);
    flex: none;
    inline-size: 1rem;
}

.travel-destination-url-empty .fi-icon {
    color: var(--geex-text-faint, #9ca3af);
}

.travel-destination-url a {
    color: inherit;
}

.travel-destination-url a:hover {
    color: var(--geex-primary, #ab54db);
}

.travel-destination-status {
    align-items: center;
    display: flex;
    gap: 0.625rem;
}

.travel-destination-status-badge {
    align-items: center;
    background-color: var(--geex-success-soft, rgba(21, 128, 61, 0.12));
    border-radius: var(--geex-radius-chip, 12px);
    color: var(--geex-success-text, #15803d);
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
    padding: 0.125rem 0.5rem;
}

.travel-destination-status-badge .fi-icon {
    block-size: 0.875rem;
    inline-size: 0.875rem;
}

.travel-destination-status-off {
    background-color: var(--geex-warning-soft, rgba(245, 158, 11, 0.12));
    color: var(--geex-warning-text, #92400e);
}

.travel-destination-status-saved {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

/* ---------------------------------------------------------- dark contrast */

html.dark .travel-destination-preview-empty,
html.dark .travel-destination-url {
    background-color: rgba(255, 255, 255, 0.06);
}

html.dark .travel-destination-check-list button:hover {
    background-color: rgba(255, 255, 255, 0.04);
}

.travel-destination .fi-fo-field-label-ctn > .fi-sc.fi-inline,
.travel-destination .fi-in-entry-label-ctn > .fi-sc.fi-inline {
    column-gap: 0.375rem;
}

/* ------------------------------------------------------- quote preview */

/*
 * No card chrome of its own: the preview is a section beside the pricing card
 * now, not a panel inset at the foot of it, and a bordered grey box inside a
 * white card reads as a box in a box.
 */
.travel-quote-preview {
    display: block;
}

.travel-quote-preview-from {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    font-weight: 400;
    margin: 0 0 0.625rem;
}

/*
 * The table does not fit a half-width card on a laptop, and its columns are all
 * load-bearing — dropping one to make it fit would be dropping a figure the
 * quote turns on. It scrolls instead.
 */
.travel-quote-preview-scroll {
    margin-inline: -0.25rem;
    overflow-x: auto;
    padding-inline: 0.25rem;
}

.travel-quote-preview-blocked,
.travel-quote-preview-notes {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    line-height: 1.5;
    margin: 0;
}

.travel-quote-preview-notes {
    list-style: none;
    margin-top: 0.625rem;
    padding: 0;
}

.travel-quote-preview-table {
    border-collapse: collapse;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    inline-size: 100%;
}

.travel-quote-preview-table th {
    color: var(--geex-text-muted, #6b7280);
    font-weight: 500;
    padding-block-end: 0.375rem;
    text-align: start;
}

.travel-quote-preview-table td {
    border-block-start: 1px solid var(--geex-border, rgba(15, 23, 42, 0.06));
    color: var(--geex-text, #111827);
    padding-block: 0.375rem;
    white-space: nowrap;
}

.travel-quote-preview-total {
    font-weight: 600;
}

.travel-quote-preview-pct {
    color: var(--geex-text-muted, #6b7280);
}

html.dark .travel-quote-preview {
    background-color: rgba(255, 255, 255, 0.04);
}

/* --------------------------------------------------------- add-row button */

/*
 * "Add a vehicle" wears the same tint as an option nobody has picked yet: it
 * offers a row rather than announcing one, so a solid brand fill would shout
 * over the rows it is meant to sit under. Paired with addActionAlignment(Start)
 * so it lines up with the first column of those rows instead of floating in
 * the middle of the section.
 *
 * Scoped through .travel-basics to outrank the gray-button rules Filament
 * gives a repeater's add action by default.
 */
.travel-basics .travel-add-pill .fi-fo-repeater-add .fi-btn,
.travel-resources .travel-add-pill .fi-fo-repeater-add .fi-btn {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--geex-primary, #ab54db) 24%, transparent);
    color: var(--geex-primary, #ab54db);
    font-weight: 500;
}

.travel-basics .travel-add-pill .fi-fo-repeater-add .fi-btn:hover,
.travel-resources .travel-add-pill .fi-fo-repeater-add .fi-btn:hover {
    background-color: color-mix(in oklab, var(--geex-primary, #ab54db) 26%, transparent);
    color: var(--geex-primary, #ab54db);
}

.travel-basics .travel-add-pill .fi-fo-repeater-add .fi-btn .fi-icon,
.travel-resources .travel-add-pill .fi-fo-repeater-add .fi-btn .fi-icon {
    color: inherit;
}

/* ============================================================================
 * Resources tab
 * ============================================================================
 *
 * The same three tracks as the destination editor: the two configurations down
 * the left, the one being edited in the middle, what it comes to down the
 * right. Measured off the form rather than the window — the panel sidebar makes
 * the viewport about 320px wider than this grid, so a viewport breakpoint
 * splits the page while the form itself still has no room.
 */
.travel-resources {
    container-name: travel-resources;
    container-type: inline-size;
}

.travel-resources > .fi-sc {
    align-items: start;
}

/* Narrow: the rail lies down above the panel and everything stacks. */
.travel-resources .fi-sc-tabs.fi-vertical {
    flex-direction: column;
}

.travel-resources .fi-tabs.fi-vertical {
    flex-direction: row;
    overflow-x: auto;
}

/*
 * An unpicked rail button is the same quiet chip as 「从素材库选」:
 * canvas grey, not a tint of the purple.
 */
.travel-resources .fi-tabs-item:not(.fi-active) {
    background-color: var(--geex-canvas, #f3f2f7);
    box-shadow: none;
}

.travel-resources .fi-tabs-item:not(.fi-active) .fi-tabs-item-label,
.travel-resources .fi-tabs-item:not(.fi-active) > .fi-icon {
    color: var(--geex-text, #464255);
}

.travel-resources .fi-tabs-item:not(.fi-active):hover {
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
}

.travel-resources .fi-tabs-item:not(.fi-active):hover .fi-tabs-item-label,
.travel-resources .fi-tabs-item:not(.fi-active):hover > .fi-icon {
    color: var(--geex-primary, #ab54db);
}

.travel-resources .fi-sc-tabs.fi-vertical .fi-sc-tabs-tab.fi-active {
    margin-block-start: 1rem;
    margin-inline-start: 0;
}

@container travel-resources (min-width: 68rem) {
    .travel-resources > .fi-sc {
        display: grid;
        gap: 1rem;
        grid-template-columns:
            clamp(11.5rem, 17%, 14.5rem)
            minmax(0, 1fr)
            clamp(15rem, 23%, 19.5rem);
        grid-template-rows: auto minmax(0, 1fr);
    }

    /*
     * Three boxes stand between the grid and the tabs' own children: the column
     * Filament wraps every schema component in, the component div inside it,
     * and the tabs container itself. All three are dropped so the nav and the
     * panels land on the outer grid.
     */
    .travel-resources > .fi-sc > :has(.fi-sc-tabs),
    .travel-resources > .fi-sc > :has(.fi-sc-tabs) > .fi-sc-component,
    .travel-resources .fi-sc-tabs.fi-vertical {
        display: contents;
    }

    .travel-resources .fi-tabs.fi-vertical {
        flex-direction: column;
        grid-area: 1 / 1;
        overflow: visible;
        position: sticky;
        top: 5rem;
    }

    .travel-resources .fi-sc-tabs-tab {
        grid-area: 1 / 2 / span 2 / span 1;
    }

    .travel-resources .fi-sc-tabs.fi-vertical .fi-sc-tabs-tab.fi-active {
        margin-block-start: 0;
    }

    /* The quoting rules, directly under the rail they explain. */
    .travel-resources > .fi-sc > :nth-child(2) {
        grid-area: 2 / 1;
    }

    /*
     * The aside. Placed on the wrapper Filament renders around the component
     * rather than on the cards themselves: the wrapper is the grid item.
     */
    .travel-resources > .fi-sc > :nth-child(3) {
        grid-area: 1 / 3 / span 2 / span 1;
        position: sticky;
        top: 5rem;
    }
}

.travel-resources-aside > .fi-sc {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* --------------------------------------------------------- overview rows */

.travel-resource-overview {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.travel-resource-overview-row {
    align-items: center;
    display: grid;
    gap: 0.5rem;
    grid-template-columns: auto minmax(0, 1fr) auto;
}

.travel-resource-overview-icon {
    align-items: center;
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    border-radius: 8px;
    color: var(--geex-primary, #ab54db);
    display: flex;
    height: 1.75rem;
    justify-content: center;
    width: 1.75rem;
}

.travel-resource-overview-icon .fi-icon {
    height: 1rem;
    width: 1rem;
}

.travel-resource-overview-label {
    display: flex;
    flex-direction: column;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

.travel-resource-overview-label small {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
}

.travel-resource-overview-value {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    grid-column: 2;
    grid-row: 2;
}

/* The chip spans both rows so a two-line label does not push it off centre. */
.travel-resource-chip {
    border-radius: 999px;
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    grid-column: 3;
    grid-row: 1 / span 2;
    padding: 0.125rem 0.5rem;
    white-space: nowrap;
}

.travel-resource-chip-done {
    background-color: var(--geex-success-soft, rgba(22, 163, 74, 0.1));
    color: var(--geex-success-text, #15803d);
}

.travel-resource-chip-warning {
    background-color: var(--geex-warning-soft, rgba(217, 119, 6, 0.12));
    color: var(--geex-warning-text, #b45309);
}

.travel-resource-chip-idle {
    background-color: var(--geex-canvas, #f3f4f6);
    color: var(--geex-text-muted, #6b7280);
}

/* --------------------------------------------------------- quote preview */

.travel-resource-preview-lines,
.travel-resource-preview-totals {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0;
}

.travel-resource-preview-lines > div,
.travel-resource-preview-totals > div {
    align-items: baseline;
    display: flex;
    gap: 0.5rem;
    justify-content: space-between;
}

.travel-resource-preview-lines dt,
.travel-resource-preview-totals dt {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

.travel-resource-preview-lines dt small {
    color: var(--geex-text-faint, #9ca3af);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    margin-inline-start: 0.25rem;
}

.travel-resource-preview-lines dd,
.travel-resource-preview-totals dd {
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    margin: 0;
}

.travel-resource-preview-totals {
    border-block-start: 1px solid var(--geex-border, rgba(15, 23, 42, 0.08));
    margin-block-start: 0.75rem;
    padding-block-start: 0.75rem;
}

.travel-resource-preview-headline dt,
.travel-resource-preview-headline dd {
    color: var(--geex-primary, #ab54db);
    font-weight: 600;
}

.travel-resource-preview-note,
.travel-resource-preview-blocked {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    line-height: 1.6;
    margin: 0.75rem 0 0;
}

/* --------------------------------------------------------- checks & rules */

.travel-resource-check-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.travel-resource-check {
    align-items: flex-start;
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
    line-height: 1.6;
    margin: 0;
}

.travel-resource-check .fi-icon {
    flex: none;
    height: 1rem;
    margin-top: 0.125rem;
    width: 1rem;
}

.travel-resource-check-ok {
    color: var(--geex-success-text, #15803d);
}

.travel-resource-check-warning {
    color: var(--geex-warning-text, #b45309);
}

.travel-resource-rules {
    color: var(--geex-text-muted, #6b7280);
    display: flex;
    flex-direction: column;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
    line-height: 1.6;
    margin: 0;
    padding-inline-start: 1rem;
}

/* --------------------------------------------------------- fee worked out */

.travel-resource-formula {
    align-items: center;
    background-color: var(--geex-canvas, #f9fafb);
    border-radius: 10px;
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
}

.travel-resource-formula-icon {
    align-items: center;
    background-color: var(--geex-primary-soft, rgba(171, 84, 219, 0.15));
    border-radius: 8px;
    color: var(--geex-primary, #ab54db);
    display: flex;
    height: 2rem;
    justify-content: center;
    width: 2rem;
}

.travel-resource-formula-icon .fi-icon {
    height: 1.125rem;
    width: 1.125rem;
}

.travel-resource-formula-text {
    display: flex;
    flex-direction: column;
}

.travel-resource-formula-text strong {
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-resource-formula-text small {
    color: var(--geex-text-muted, #6b7280);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
}

.travel-resource-formula-rows {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.25rem;
    list-style: none;
    margin: 0;
    margin-inline-start: auto;
    padding: 0;
}

.travel-resource-formula-rows li {
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
}

.travel-resource-formula-rows em {
    color: var(--geex-text-muted, #6b7280);
    font-style: normal;
}

/*
 * 「下单时可选」 is the middle of three answers. A solid fill reads as
 * committed — the same as 「已含于团费」 — and Filament's pale purple + dark
 * text on it is what made the label disappear. A dashed edge in the same
 * purple as the rail's "$15 / 团" chip says "this is a choice, not a given".
 *
 * Filament paints the picked label with `background-color: var(--bg)`, so
 * resetting `--bg` / `--text` is what actually shows through. `:has()` is
 * what finds the pair: extraAttributes land on the group, not the label.
 */
.travel-guide-supply .fi-fo-toggle-buttons-btn-ctn:has(> input[value="optional"]:checked) > label.fi-btn,
.travel-guide-supply .fi-fo-toggle-buttons-btn-ctn:has(> input[value="optional"]:checked) > label.fi-btn:hover {
    background-color: transparent;
    border: 1px dashed var(--geex-primary, #ab54db);
    box-shadow: none;
    color: var(--geex-primary, #ab54db);
    --bg: transparent;
    --hover-bg: transparent;
    --text: var(--geex-primary, #ab54db);
    --hover-text: var(--geex-primary, #ab54db);
    --tw-ring-color: transparent;
    --tw-ring-shadow: 0 0 #0000;
}

/*
 * ============================================================================
 * Media library board
 * ============================================================================
 *
 * The library's own screen: four counts, a tab strip, then three columns —
 * the ways a search is narrowed, the pictures, and what is outstanding.
 *
 * Three columns rather than two because the two rails answer opposite
 * questions. The left one is "show me less"; the right one is "what still
 * needs doing?" — and that second list is the reason somebody opens this page
 * without a picture in mind. Putting them on the same side would bury it.
 *
 * A container query, not a media query, for the same reason as .travel-basics:
 * the viewport is wrong by the width of the panel sidebar, which can be
 * collapsed. Measuring the board itself is exact.
 */

.travel-library-page .fi-page-content,
.travel-library-page .fi-main {
    max-width: none;
}

.travel-board {
    container-name: travel-board;
    container-type: inline-size;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* ------------------------------------------------------------ the numbers */

.travel-stats {
    display: grid;
    gap: 0.75rem;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}

.travel-stat {
    align-items: center;
    background-color: var(--geex-surface, #fdfdfd);
    border: 1px solid transparent;
    border-radius: var(--geex-radius-card, 24px);
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    gap: 0.75rem;
    padding: 1rem 1.25rem;
    text-align: start;
    width: 100%;
}

/* Three of the four are buttons: the number *is* the filter it stands for. */
button.travel-stat {
    cursor: pointer;
    transition: border-color 120ms ease, box-shadow 120ms ease;
}

button.travel-stat:hover {
    border-color: var(--geex-primary, #ab54db);
}

.travel-stat-active {
    border-color: var(--geex-primary, #ab54db);
    box-shadow: var(--geex-shadow-lg, 0 8px 24px rgba(0, 0, 0, 0.08));
}

.travel-stat-icon {
    align-items: center;
    border-radius: var(--geex-radius-control, 12px);
    display: flex;
    flex: none;
    height: 2.5rem;
    justify-content: center;
    width: 2.5rem;
}

.travel-stat-icon .fi-icon {
    height: 1.25rem;
    width: 1.25rem;
}

.travel-stat-icon-primary {
    background-color: var(--geex-primary-soft, #f3e8fb);
    color: var(--geex-primary, #ab54db);
}

.travel-stat-icon-warning {
    background-color: var(--geex-warning-soft, #fef3c7);
    color: var(--geex-warning-text, #b45309);
}

.travel-stat-icon-info {
    background-color: var(--geex-info-soft, #dbeafe);
    color: var(--geex-info-text, #1d4ed8);
}

.travel-stat-icon-success {
    background-color: var(--geex-success-soft, #dcfce7);
    color: var(--geex-success-text, #15803d);
}

.travel-stat-label {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

.travel-stat-value {
    font-size: calc(1.375rem * var(--geex-type-scale, 1));
    font-weight: 600;
    line-height: 1.2;
}

.travel-stat-note {
    color: var(--geex-text-faint, #c4c4c4);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
}

/* ----------------------------------------------------------------- tabs */

.travel-tabs {
    border-bottom: 1px solid var(--geex-line, #ececec);
    display: flex;
    gap: 0.25rem;
}

.travel-tab {
    align-items: center;
    border-bottom: 2px solid transparent;
    color: var(--geex-text-muted, #a3a3a3);
    display: flex;
    font-size: calc(0.875rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
    margin-bottom: -1px;
    padding: 0.625rem 0.875rem;
}

.travel-tab:hover {
    color: var(--geex-text, #262626);
}

.travel-tab-active {
    border-bottom-color: var(--geex-primary, #ab54db);
    color: var(--geex-primary, #ab54db);
    font-weight: 600;
}

/* A dot rather than a count: the number is already in the card above. */
.travel-tab-dot {
    background-color: var(--geex-info-text, #1d4ed8);
    border-radius: 999px;
    height: 0.375rem;
    width: 0.375rem;
}

.travel-tab-dot-danger {
    background-color: var(--geex-danger, #dc2626);
}

/*
 * The two stock libraries are planned, not present. They read faint and carry
 * the word on the tab itself, so the strip is honest at a glance rather than
 * only after a click.
 */
.travel-tab-pending {
    color: var(--geex-text-faint, #c4c4c4);
}

/* Faint until it is the one you are on: a greyed-out selected tab reads as
   disabled, and you did just click it. */
.travel-tab-pending.travel-tab-active {
    color: var(--geex-primary, #ab54db);
}

.travel-tab-badge {
    background-color: var(--geex-canvas, #f7f7f8);
    border-radius: var(--geex-radius-chip, 8px);
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.625rem * var(--geex-type-scale, 1));
    line-height: 1.4;
    padding: 0.0625rem 0.3125rem;
}

.travel-pending {
    align-items: center;
    background-color: var(--geex-surface, #fdfdfd);
    border-radius: var(--geex-radius-card, 24px);
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 3rem 1.5rem;
    text-align: center;
}

.travel-pending-icon {
    align-items: center;
    background-color: var(--geex-canvas, #f7f7f8);
    border-radius: var(--geex-radius-control, 12px);
    color: var(--geex-text-muted, #a3a3a3);
    display: flex;
    height: 3rem;
    justify-content: center;
    margin-bottom: 0.25rem;
    width: 3rem;
}

.travel-pending-icon .fi-icon {
    height: 1.5rem;
    width: 1.5rem;
}

.travel-pending-title {
    font-size: calc(1rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

.travel-pending-body {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    line-height: 1.6;
    max-width: 34rem;
}

.travel-pending-back {
    color: var(--geex-primary, #ab54db);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    margin-top: 0.5rem;
}

/* --------------------------------------------- somebody else's library */

/*
 * The stock tab borrows the library's toolbar and tiles wholesale — it is the
 * same act of looking through photographs, and giving it a second visual
 * language would only make the two harder to tell apart at the moment it
 * matters, which is when one of them is about to be imported into the other.
 * What is left here is the handful of parts the local grid has no use for.
 */
.travel-stock {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/*
 * The photographer, under every tile.
 *
 * Muted and small, but never hidden: Pexels asks for the credit wherever their
 * work is shown, and it doubles as the one thing on the tile that says this
 * photograph belongs to somebody outside the company.
 */
.travel-stock-credit {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.travel-stock-credit a:hover {
    color: var(--geex-primary, #ab54db);
    text-decoration: underline;
}

.travel-stock-error {
    color: var(--geex-danger, #dc2626);
}

.travel-stock-pager {
    align-items: center;
    display: flex;
    gap: 0.5rem;
    justify-content: center;
}

.travel-stock-foot {
    border-top: 1px solid var(--geex-line, #eceaf3);
    padding-top: 0.625rem;
    text-align: center;
}

.travel-stock-foot a {
    color: var(--geex-primary, #ab54db);
}

/* ------------------------------------------------------------ the columns */

.travel-board-body {
    display: grid;
    gap: 1rem;
    grid-template-columns: minmax(0, 1fr);
}

@container travel-board (min-width: 60rem) {
    .travel-board-body {
        align-items: start;
        grid-template-columns: 13.5rem minmax(0, 1fr);
    }
}

/*
 * Three columns, and the threshold is the whole point of the number.
 *
 * The board is the window less the panel sidebar, which is 16rem while
 * expanded — its default. A 1490px laptop leaves the board ~74.5rem with the
 * sidebar out and ~87rem with it collapsed, so a threshold of 82rem meant the
 * outstanding-work rail was only ever visible to somebody who had collapsed
 * the navigation. That is backwards: the rail is why this page is worth
 * opening without a picture in mind.
 *
 * 68rem is where the trade stops paying. Both rails run narrow through the
 * tight band so the width goes to the grid, which holds four tiles down to
 * about 74rem and three below that; at three the pictures are too sparse to
 * be worth a rail, and the fold below takes over.
 */
@container travel-board (min-width: 68rem) {
    .travel-board-body {
        gap: 0.75rem;
        grid-template-columns: 12rem minmax(0, 1fr) 14rem;
    }
}

@container travel-board (min-width: 86rem) {
    .travel-board-body {
        gap: 1rem;
        grid-template-columns: 13.5rem minmax(0, 1fr) 16rem;
    }
}

/* ------------------------------------------------------------- the rails */

.travel-rail {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    position: sticky;
    top: 1rem;
}

/*
 * Sticky needs a ceiling. The filter rail runs to eight groups, which is taller
 * than a laptop viewport, and a pinned element taller than the screen can never
 * be scrolled to the end of — the shape filter at the bottom was unreachable.
 *
 * The filter rail only. The cards on the right carry a shadow, and a scroll
 * container clips it flat against both edges.
 */
.travel-rail:not(.travel-rail-end) {
    max-height: calc(100dvh - 2rem);
    overflow-y: auto;
}

.travel-rail-group {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

.travel-rail-title {
    color: var(--geex-text-faint, #c4c4c4);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    font-weight: 600;
    letter-spacing: 0.04em;
    margin-bottom: 0.25rem;
    text-transform: uppercase;
}

.travel-rail-item {
    align-items: center;
    border-radius: var(--geex-radius-control, 12px);
    color: var(--geex-text, #262626);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.5rem;
    justify-content: space-between;
    padding: 0.375rem 0.625rem;
    width: 100%;
}

.travel-rail-item:hover {
    background-color: var(--geex-canvas, #f7f7f8);
}

.travel-rail-item-active {
    background-color: var(--geex-primary-soft, #f3e8fb);
    color: var(--geex-primary, #ab54db);
    font-weight: 600;
}

.travel-rail-label {
    align-items: center;
    display: flex;
    gap: 0.375rem;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/*
 * The glyph beside a rail option.
 *
 * Deliberately fainter than the word it sits next to: it is there to make a
 * column of eight rows scannable by shape, not to be read. It takes the row's
 * colour on the active one, so the chosen filter is one thing rather than a
 * purple word with a grey picture in front of it.
 */
.travel-rail-icon {
    color: var(--geex-text-faint, #c4c4c4);
    flex: none;
    height: 1rem;
    width: 1rem;
}

.travel-rail-item:hover .travel-rail-icon {
    color: var(--geex-text-muted, #a3a3a3);
}

.travel-rail-item-active .travel-rail-icon {
    color: currentColor;
}

.travel-rail-count {
    color: var(--geex-text-muted, #a3a3a3);
    flex: none;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    font-variant-numeric: tabular-nums;
}

.travel-rail-select {
    width: 100%;
}

.travel-rail-select + .travel-rail-select {
    margin-top: 0.375rem;
}

.travel-rail-clear {
    align-items: center;
    color: var(--geex-danger, #dc2626);
    display: flex;
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    gap: 0.375rem;
    padding: 0.375rem 0.625rem;
}

.travel-rail-clear .fi-icon {
    height: 0.875rem;
    width: 0.875rem;
}

.travel-rail-card {
    background-color: var(--geex-surface, #fdfdfd);
    border-radius: var(--geex-radius-card, 24px);
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    padding: 1rem;
}

/*
 * Below the three-column threshold the outstanding-work rail goes to the
 * bottom rather than squeezing the grid to three tiles. It is a list to check,
 * not something read while scrolling the pictures.
 *
 * It must come *after* .travel-rail, which it also matches. Container queries
 * add no specificity, so the previous version of this block sat above and lost
 * `flex-direction: row` to the plain `.travel-rail` rule below it — which
 * turned `flex-basis: 18rem` from a width into a height and left two mostly
 * empty cards four hundred pixels tall stacked across the page. Laid out with
 * grid rather than flex so the same collision cannot happen twice: .travel-rail
 * declares no `display: grid` to override it with.
 */
@container travel-board (max-width: 67.99rem) {
    .travel-rail-end {
        display: grid;
        gap: 1rem;
        grid-column: 1 / -1;
        grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
        /* Full-width and at the end of the page: nothing to stick to. */
        position: static;
    }
}

/* A status dot, shared by the rail's status list and the queue. */
.travel-dot {
    border-radius: 999px;
    flex: none;
    height: 0.4375rem;
    width: 0.4375rem;
}

.travel-dot-gray { background-color: var(--geex-text-faint, #c4c4c4); }
.travel-dot-info { background-color: var(--geex-info-text, #1d4ed8); }
.travel-dot-success { background-color: var(--geex-success-text, #15803d); }
.travel-dot-danger { background-color: var(--geex-danger, #dc2626); }

/* ------------------------------------------------------- the middle column */

.travel-board-main {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    min-width: 0;
}

.travel-board-tools {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.625rem;
    justify-content: space-between;
}

.travel-search-wide {
    flex: 1 1 18rem;
    max-width: 32rem;
}

.travel-board-tools-end {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.travel-layout-toggle {
    background-color: var(--geex-canvas, #f7f7f8);
    border-radius: var(--geex-radius-control, 12px);
    display: flex;
    padding: 0.125rem;
}

.travel-layout-button {
    border-radius: calc(var(--geex-radius-control, 12px) - 0.125rem);
    color: var(--geex-text-muted, #a3a3a3);
    padding: 0.3125rem 0.5rem;
}

.travel-layout-button-active {
    background-color: var(--geex-surface, #fdfdfd);
    box-shadow: var(--geex-shadow-md, 0 4px 8px rgba(0, 0, 0, 0.04));
    color: var(--geex-primary, #ab54db);
}

.travel-layout-button .fi-icon {
    height: 1rem;
    width: 1rem;
}

.travel-board-chips {
    align-items: center;
}

.travel-chip-removable {
    gap: 0.25rem;
}

.travel-chip-removable .fi-icon {
    height: 0.75rem;
    opacity: 0.6;
    width: 0.75rem;
}

.travel-chip-clear {
    color: var(--geex-primary, #ab54db);
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
}

.travel-board-bulk {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.625rem;
    min-height: 2rem;
}

.travel-board-tiles {
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
}

.travel-tile-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}

.travel-tile-tag {
    background-color: var(--geex-canvas, #f7f7f8);
    border-radius: var(--geex-radius-chip, 8px);
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    max-width: 100%;
    overflow: hidden;
    padding: 0.0625rem 0.375rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The place a picture is *of* earns the colour; a free-form term does not. */
.travel-tile-tag-place {
    background-color: var(--geex-primary-soft, #f3e8fb);
    color: var(--geex-primary, #ab54db);
}

.travel-tile-warn {
    color: var(--geex-warning-text, #b45309);
}

.travel-board-empty,
.travel-board-total {
    padding-block: 0.5rem;
}

.travel-board-pager {
    padding-top: 0.5rem;
}

/* ------------------------------------------------------------- list layout */

.travel-rows {
    display: flex;
    flex-direction: column;
}

.travel-row {
    align-items: center;
    border-bottom: 1px solid var(--geex-line, #ececec);
    display: grid;
    gap: 0.75rem;
    grid-template-columns: auto 3.5rem minmax(0, 2fr) minmax(0, 1fr) auto auto auto;
    padding: 0.5rem 0.25rem;
}

.travel-row-selected {
    background-color: var(--geex-primary-soft, #f3e8fb);
}

.travel-row-thumb {
    aspect-ratio: 4 / 3;
    border-radius: var(--geex-radius-chip, 8px);
    object-fit: cover;
    width: 3.5rem;
}

.travel-row-thumb-empty {
    align-items: center;
    background-color: var(--geex-canvas, #f7f7f8);
    color: var(--geex-text-faint, #c4c4c4);
    display: flex;
    justify-content: center;
}

.travel-row-body {
    min-width: 0;
}

.travel-row-name {
    font-size: calc(0.8125rem * var(--geex-type-scale, 1));
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.travel-row-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}

.travel-row-status {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

/* Below the three-column threshold the list sheds its middle columns rather
   than letting the name shrink to nothing. */
@container travel-board (max-width: 60rem) {
    .travel-row {
        grid-template-columns: auto 3.5rem minmax(0, 1fr) auto;
    }

    .travel-row-tags,
    .travel-row-status {
        display: none;
    }
}

/* ------------------------------------------------------------- the queue */

.travel-queue-row {
    align-items: center;
    display: flex;
    gap: 0.5rem;
}

.travel-queue-thumb {
    aspect-ratio: 1;
    border-radius: var(--geex-radius-chip, 8px);
    flex: none;
    object-fit: cover;
    width: 2rem;
}

.travel-queue-body {
    min-width: 0;
}

.travel-queue-name {
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.travel-queue-meta {
    align-items: center;
    color: var(--geex-text-muted, #a3a3a3);
    display: flex;
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    gap: 0.25rem;
}

/*
 * The row above a rail card's contents: a title on the left and the way into
 * the whole list on the right. Only the backlog card has one — the others have
 * nowhere further to go, and a "see all" that filtered to the same three rows
 * would be a lie about there being more.
 */
.travel-rail-head {
    align-items: baseline;
    display: flex;
    gap: 0.5rem;
    justify-content: space-between;
}

.travel-rail-head .travel-rail-title {
    margin-bottom: 0;
}

.travel-rail-more {
    align-items: center;
    color: var(--geex-primary, #ab54db);
    display: flex;
    flex: none;
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    gap: 0.125rem;
}

.travel-rail-more .fi-icon {
    height: 0.75rem;
    width: 0.75rem;
}

/*
 * Why a row is in the backlog, in the colour of how bad it is. Amber for work
 * outstanding, red for the one kind nothing can fix — an asset with no original
 * will never be encoded however many times somebody retries it.
 */
.travel-queue-flag {
    align-items: center;
    color: var(--geex-warning-text, #b45309);
    display: flex;
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    font-weight: 500;
    gap: 0.25rem;
}

.travel-queue-flag-danger {
    color: var(--geex-danger, #dc2626);
}

.travel-queue-flag .fi-icon {
    flex: none;
    height: 0.8125rem;
    width: 0.8125rem;
}

.travel-queue-meta .fi-icon {
    flex: none;
    height: 0.75rem;
    width: 0.75rem;
}

/* --------------------------------------------------------- storage health */

.travel-storage-headline {
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
}

.travel-storage-headline strong {
    font-size: calc(0.9375rem * var(--geex-type-scale, 1));
    font-weight: 600;
}

/*
 * One bar, four segments, drawn in the order the legend lists them. The widths
 * come from the filesystem rather than from a declared quota — see
 * AssetBoard::diskSpace() for why there is no number in this file to compare
 * against.
 */
.travel-storage-bar {
    align-items: center;
    background-color: var(--geex-canvas, #f3f2f7);
    border-radius: 999px;
    display: flex;
    height: 0.5rem;
    margin-block: 0.25rem 0.5rem;
    overflow: visible;
    position: relative;
}

.travel-storage-seg {
    height: 100%;
    /* So four adjacent segments read as one bar with joins, not as four bars. */
    min-width: 0;
}

.travel-storage-seg:first-child {
    border-end-start-radius: 999px;
    border-start-start-radius: 999px;
}

.travel-storage-seg-image { background-color: var(--geex-success-text, #15803d); }
.travel-storage-seg-video { background-color: var(--geex-info-text, #1d4ed8); }
.travel-storage-seg-variants { background-color: var(--geex-primary, #ab54db); }
.travel-storage-seg-other { background-color: var(--geex-text-faint, #c4c4c4); }

/*
 * The percentage sits at the end of the track rather than after the bar, which
 * is what keeps the card the same height whatever the disk is doing.
 */
.travel-storage-percent {
    color: var(--geex-text-muted, #a3a3a3);
    font-size: calc(0.6875rem * var(--geex-type-scale, 1));
    font-variant-numeric: tabular-nums;
    inset-inline-end: 0;
    position: absolute;
    top: -1.125rem;
}

.travel-dot-image { background-color: var(--geex-success-text, #15803d); }
.travel-dot-video { background-color: var(--geex-info-text, #1d4ed8); }
.travel-dot-variants { background-color: var(--geex-primary, #ab54db); }
.travel-dot-other { background-color: var(--geex-text-faint, #c4c4c4); }

.travel-storage {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.travel-storage > div {
    display: flex;
    font-size: calc(0.75rem * var(--geex-type-scale, 1));
    justify-content: space-between;
}

.travel-storage dt {
    align-items: center;
    color: var(--geex-text-muted, #a3a3a3);
    display: flex;
    gap: 0.375rem;
}

/* Outside the cards, in the margin — a standing fact rather than a reading. */
.travel-rail-footnote {
    align-items: center;
    display: flex;
    gap: 0.375rem;
    line-height: 1.5;
    padding-inline: 0.25rem;
}

.travel-rail-footnote .fi-icon {
    flex: none;
    height: 0.8125rem;
    width: 0.8125rem;
}

.travel-storage dd {
    font-variant-numeric: tabular-nums;
}
