/* ==========================================================================
   TraveNexus design tokens
   ==========================================================================
   Values lifted from the agreed artboards in design/concepts. Two themes that
   are both designed: dark is not an inversion of light. Accents are lifted so
   they keep their meaning on a dark ground, and card depth switches from a
   shadow to a hairline, because a shadow does nothing in the dark.

   The theme is stamped on <html> server-side from a cookie, so there is no
   flash of the wrong theme on load.
   ========================================================================== */

:root,
[data-theme="light"] {
    /* Ground and chrome. The dark rail against a light stage is deliberate --
       it is what makes the working area read as a working area. */
    --stage:            #EEF1F5;
    --chrome:           #171C26;
    --chrome-text:      #F2F5FA;
    --chrome-text-dim:  #97A3B6;
    --chrome-fill:      rgba(255, 255, 255, .07);
    --chrome-fill-hi:   rgba(255, 255, 255, .14);
    --chrome-line:      rgba(255, 255, 255, .07);

    --surface:          #FFFFFF;
    --surface-sunken:   #FAFBFD;
    --surface-hover:    #F7F9FB;

    --text:             #131820;
    --text-2:           #5C6B80;
    --text-3:           #93A0B2;
    --text-4:           #B4BECB;

    --line:             #E4E8EE;
    --line-soft:        #EDF0F4;
    --line-row:         #F1F4F7;

    --fill:             #EFF2F6;
    --fill-hover:       #E7EBF1;

    --accent:           #3D6BE5;
    --accent-hover:     #2B51BC;
    --accent-soft:      #EAF0FE;
    --accent-on:        #FFFFFF;

    --good:             #18794E;
    --good-soft:        #E6F5EC;
    --warn:             #B7791F;
    --warn-soft:        #FDF3E2;
    --bad:              #CD2B31;
    --bad-soft:         #FDECEC;
    --bad-outline:      #F6CFCF;
    --row-attention:    #FFFBFB;

    /* Service families. Each product type keeps one hue everywhere it appears. */
    --svc-flight:       #0D7490;
    --svc-flight-soft:  #E6F4F9;
    --svc-stay:         #6E56CF;
    --svc-stay-soft:    #EDEBFB;
    --svc-transfer:     #B7791F;
    --svc-transfer-soft:#FDF3E2;
    --svc-package:      #3D6BE5;
    --svc-package-soft: #EAF0FE;
    --svc-activity:     #C2298A;
    --svc-activity-soft:#FCE9F3;
    --svc-off:          #93A0B2;
    --svc-off-soft:     #F1F4F8;

    --card-shadow:      0 1px 2px rgba(19, 24, 32, .05), 0 4px 14px -8px rgba(19, 24, 32, .14);
    --pop-shadow:       0 4px 6px -2px rgba(19, 24, 32, .08), 0 16px 32px -12px rgba(19, 24, 32, .22);
}

[data-theme="dark"] {
    --stage:            #12161D;
    --chrome:           #0C1017;
    --chrome-text:      #F2F5FA;
    --chrome-text-dim:  #7C8AA0;
    --chrome-fill:      rgba(255, 255, 255, .06);
    --chrome-fill-hi:   rgba(255, 255, 255, .14);
    --chrome-line:      rgba(255, 255, 255, .07);

    --surface:          #1A202A;
    --surface-sunken:   #1E2530;
    --surface-hover:    #212934;

    --text:             #E9EDF3;
    --text-2:           #9AA7BA;
    --text-3:           #6F7C8F;
    --text-4:           #5B6675;

    --line:             #2B333F;
    --line-soft:        #242C38;
    --line-row:         #232B36;

    --fill:             #242C38;
    --fill-hover:       #2C3542;

    --accent:           #7CA0FF;
    --accent-hover:     #A8C1FF;
    --accent-soft:      #1B2740;
    --accent-on:        #0C1017;

    --good:             #4ADE80;
    --good-soft:        #15301F;
    --warn:             #EEC15C;
    --warn-soft:        #332715;
    --bad:              #FF7070;
    --bad-soft:         #331A1C;
    --bad-outline:      #5A2C2E;
    --row-attention:    #241C1E;

    --svc-flight:       #5FC9E4;
    --svc-flight-soft:  #132A33;
    --svc-stay:         #A992F7;
    --svc-stay-soft:    #241F3B;
    --svc-transfer:     #EEC15C;
    --svc-transfer-soft:#332715;
    --svc-package:      #7CA0FF;
    --svc-package-soft: #1B2740;
    --svc-activity:     #F084C6;
    --svc-activity-soft:#33172A;
    --svc-off:          #6F7C8F;
    --svc-off-soft:     #242C38;

    /* Depth by hairline, not shadow. */
    --card-shadow:      0 0 0 1px #262E3A, 0 1px 2px rgba(0, 0, 0, .35);
    --pop-shadow:       0 0 0 1px #303A48, 0 16px 32px -12px rgba(0, 0, 0, .7);
}

/* ==========================================================================
   Base
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; }

body {
    margin: 0;
    background: var(--stage);
    color: var(--text);
    font-family: "Manrope", system-ui, -apple-system, "Segoe UI", sans-serif;
    font-size: 13px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -.02em; }

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); }

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 4px;
}

/* Except where nothing can tab to it.

   The router moves focus to each page's heading after navigating, so a screen
   reader announces where it has arrived. The browser then rings the heading as
   though somebody had tabbed to it, and a box round the word "Search" is the
   first thing on the page. Anything carrying tabindex="-1" is unreachable by
   keyboard, so a ring on it tells a keyboard user nothing -- the focus itself
   still does its job. */
[tabindex="-1"]:focus-visible { outline: none; }

/* Figures line up column to column, which is most of what makes a dense table
   readable. Every money and time value uses this. */
.tnx-num {
    font-family: "JetBrains Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.03em;
}

/* ==========================================================================
   Shell
   ========================================================================== */

.tnx-shell { display: flex; height: 100vh; overflow: hidden; }

.tnx-rail {
    width: 228px;
    flex: none;
    background: var(--chrome);
    display: flex;
    flex-direction: column;
}

.tnx-brand {
    height: 60px;
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 0 18px;
}

.tnx-brand-mark {
    width: 26px; height: 26px;
    border-radius: 7px;
    background: linear-gradient(140deg, #6E9BFF, #3D6BE5);
    display: flex; align-items: center; justify-content: center;
    flex: none;
}

.tnx-brand-name {
    font-size: 15px; font-weight: 700;
    color: var(--chrome-text);
    letter-spacing: -.02em;
}

.tnx-nav { padding: 6px 12px; display: flex; flex-direction: column; gap: 2px; flex: 1; }

.tnx-nav-group-label {
    padding: 14px 11px 6px;
    font-size: 10px; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--chrome-text-dim);
}

.tnx-nav-link {
    display: flex; align-items: center; gap: 11px;
    height: 34px; padding: 0 11px;
    border-radius: 7px;
    color: var(--chrome-text-dim);
    font-size: 13.5px; font-weight: 500;
    text-decoration: none;
    transition: background .12s, color .12s;
}
.tnx-nav-link:hover { background: var(--chrome-fill); color: #C7D0DD; }

.tnx-nav-link.active {
    background: var(--chrome-fill);
    color: var(--chrome-text);
    font-weight: 600;
    box-shadow: inset 2px 0 0 #6E9BFF;
}

.tnx-nav-count {
    margin-left: auto;
    font-size: 11px;
    background: rgba(255, 255, 255, .09);
    border-radius: 4px;
    padding: 1px 6px;
}

.tnx-nav-rule { height: 1px; background: var(--chrome-line); margin: 11px 4px; }

.tnx-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }

.tnx-topbar {
    height: 60px; flex: none;
    background: var(--chrome);
    display: flex; align-items: center; gap: 12px;
    padding: 0 22px 0 4px;
}

.tnx-content { flex: 1; overflow-y: auto; padding: 18px 22px 26px; }

/* ==========================================================================
   Chrome controls
   ========================================================================== */

.tnx-search {
    display: flex; align-items: center; gap: 9px;
    height: 33px; padding: 0 12px;
    border-radius: 8px;
    background: var(--chrome-fill);
    width: 320px;
    color: #8592A6;
    font-size: 13px;
    border: 0;
    cursor: text;
}

.tnx-kbd {
    margin-left: auto;
    font-size: 10px;
    background: rgba(255, 255, 255, .08);
    border-radius: 4px;
    padding: 1px 5px;
}

.tnx-chrome-btn {
    display: flex; align-items: center; justify-content: center;
    width: 33px; height: 33px;
    border: 0; border-radius: 8px;
    background: var(--chrome-fill);
    color: #C7D0DD;
    cursor: pointer;
    position: relative;
    transition: background .12s;
}
.tnx-chrome-btn:hover { background: rgba(255, 255, 255, .12); }

.tnx-chrome-dot {
    position: absolute; top: 6px; right: 7px;
    width: 6px; height: 6px; border-radius: 50%;
    background: #E5484D;
    box-shadow: 0 0 0 2px var(--chrome);
}

/* The privacy switch. Reads its own state so nobody has to guess whether
   figures are hidden. */
.tnx-privacy {
    display: flex; align-items: center; gap: 8px;
    height: 33px; padding: 0 11px;
    border: 0; border-radius: 8px;
    background: var(--chrome-fill);
    color: #C7D0DD;
    font-family: inherit; font-size: 12px; font-weight: 600;
    cursor: pointer;
    transition: background .12s;
}
.tnx-privacy:hover { background: rgba(255, 255, 255, .12); }

.tnx-switch {
    width: 26px; height: 15px;
    border-radius: 8px;
    background: rgba(255, 255, 255, .16);
    position: relative;
    transition: background .15s;
    flex: none;
}
.tnx-switch::after {
    content: "";
    position: absolute; top: 2px; left: 2px;
    width: 11px; height: 11px;
    border-radius: 50%;
    background: #8592A6;
    transition: transform .15s, background .15s;
}
.tnx-switch.on { background: var(--accent); }
.tnx-switch.on::after { transform: translateX(11px); background: #fff; }

.tnx-segment {
    display: flex; height: 33px; padding: 3px; gap: 2px;
    border-radius: 8px;
    background: var(--chrome-fill);
}
.tnx-segment button {
    display: flex; align-items: center; justify-content: center;
    width: 30px;
    border: 0; border-radius: 6px;
    background: transparent;
    color: #8592A6;
    cursor: pointer;
}
.tnx-segment button.on { background: var(--chrome-fill-hi); color: var(--chrome-text); }

.tnx-avatar {
    width: 30px; height: 30px; flex: none;
    border: 0; padding: 0; border-radius: 8px;
    background: linear-gradient(140deg, #6E9BFF, #3D6BE5);
    color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-size: 11px; font-weight: 700; font-family: inherit;
    cursor: pointer;
}
.tnx-avatar:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* Who is signed in, and the way out. */
.tnx-me { position: relative; }
.tnx-me-menu {
    position: absolute; top: calc(100% + 8px); right: 0; z-index: 40;
    min-width: 220px; padding: 6px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
    box-shadow: var(--pop-shadow);
    color: var(--text);
}
.tnx-me-who { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px 10px; border-bottom: 1px solid var(--line); margin-bottom: 6px; }
.tnx-me-who strong { font-size: 13px; font-weight: 600; }
.tnx-me-who span { font-size: 11.5px; color: var(--text-3); }
.tnx-me-menu form { margin: 0; }
.tnx-me-menu button {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 7px 10px; border: 0; border-radius: 6px;
    background: none; color: var(--text); font: inherit; font-size: 12.5px; text-align: left;
    cursor: pointer;
}
.tnx-me-menu button:hover { background: var(--accent-soft); }

/* ==========================================================================
   World clock
   ========================================================================== */

.tnx-clock {
    margin: 10px 12px 14px;
    padding: 13px 13px 11px;
    border-radius: 10px;
    background: rgba(255, 255, 255, .045);
}

.tnx-clock-title {
    display: flex; align-items: center; gap: 7px;
    margin-bottom: 11px;
    font-size: 10px; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--chrome-text-dim);
}

.tnx-clock-rows { display: flex; flex-direction: column; gap: 11px; }

.tnx-clock-head { display: flex; align-items: baseline; gap: 8px; }
.tnx-clock-city { font-size: 12.5px; font-weight: 600; color: #E3E9F1; }
.tnx-clock-note { font-size: 10px; color: #6E7C90; }
.tnx-clock-time { margin-left: auto; font-size: 13px; font-weight: 600; color: var(--chrome-text); }

/* A day as a 24-hour track: the lighter band is working hours there, the
   marker is now. Tells you whether a supplier's office is open. */
.tnx-clock-track {
    position: relative; height: 3px; margin-top: 6px;
    border-radius: 2px;
    background: rgba(255, 255, 255, .09);
    overflow: hidden;
}
.tnx-clock-day { position: absolute; height: 100%; background: rgba(233, 185, 73, .55); }
.tnx-clock-now { position: absolute; width: 3px; height: 100%; background: var(--chrome-text); }

.tnx-clock-row.closed .tnx-clock-city,
.tnx-clock-row.closed .tnx-clock-time { color: #98A5B8; }
.tnx-clock-row.closed .tnx-clock-day { background: rgba(233, 185, 73, .3); }
.tnx-clock-row.closed .tnx-clock-now { background: #7C8AA0; }

/* ==========================================================================
   Cards and page furniture
   ========================================================================== */

.tnx-card {
    background: var(--surface);
    border-radius: 11px;
    box-shadow: var(--card-shadow);
}

.tnx-card-pad { padding: 13px 16px; }

.tnx-card-head {
    display: flex; align-items: center; gap: 10px;
    padding: 13px 16px 12px;
}

.tnx-page-title { font-size: 20px; font-weight: 800; letter-spacing: -.03em; }
.tnx-page-sub { margin: 3px 0 0; font-size: 12.5px; color: var(--text-2); }

/* Title on the left, controls pushed to the right, wrapping on narrow screens
   rather than squashing the buttons. */
.tnx-page-head {
    display: flex; align-items: center; gap: 10px;
    flex-wrap: wrap;
}

.tnx-section-title { font-size: 13.5px; font-weight: 700; letter-spacing: -.015em; }

.tnx-grid-4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }

/* ==========================================================================
   Buttons
   ========================================================================== */

.tnx-btn {
    display: inline-flex; align-items: center; gap: 7px;
    height: 33px; padding: 0 15px;
    border: 0; border-radius: 8px;
    background: var(--accent); color: var(--accent-on);
    font-family: inherit; font-size: 13px; font-weight: 700;
    cursor: pointer;
    transition: background .12s;
}
.tnx-btn:hover { background: var(--accent-hover); }

.tnx-btn.quiet {
    background: var(--fill);
    color: var(--text);
    font-weight: 600;
}
.tnx-btn.quiet:hover { background: var(--fill-hover); }

.tnx-btn.sm { height: 28px; padding: 0 11px; font-size: 12px; }
.tnx-btn.quiet.danger { color: var(--bad); }
.tnx-btn.quiet.danger:hover { background: var(--bad-soft); }

/* Outlined: for the action that adds a line to a list, which should be easy
   to find and not the loudest thing on the card. */
.tnx-btn.line {
    background: var(--surface); color: var(--accent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent);
}
.tnx-btn.line:hover { background: var(--accent-soft); }

.tnx-btn:disabled { opacity: .45; cursor: default; }

/* ==========================================================================
   Status pills and service chips
   ========================================================================== */

.tnx-pill {
    display: inline-flex; align-items: center; gap: 5px;
    height: 20px; padding: 0 8px;
    border-radius: 5px;
    font-size: 11px; font-weight: 700; letter-spacing: -.01em;
    white-space: nowrap;
}
.tnx-pill.good    { background: var(--good-soft);   color: var(--good); }
.tnx-pill.warn    { background: var(--warn-soft);   color: var(--warn); }
.tnx-pill.bad     { background: var(--bad-soft);    color: var(--bad); }
.tnx-pill.info    { background: var(--accent-soft); color: var(--accent); }
.tnx-pill.violet  { background: var(--svc-stay-soft); color: var(--svc-stay); }
.tnx-pill.neutral { background: var(--fill);        color: var(--text-2); }
.tnx-pill.quiet   { background: var(--fill);        color: var(--text-3); }

.tnx-pill .dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }

/* Service chips: one hue per product family, a count badge when there is more
   than one, struck through when that service was cancelled. */
.tnx-chips { display: flex; gap: 3px; }

.tnx-chip {
    position: relative;
    display: inline-flex; align-items: center; justify-content: center;
    width: 21px; height: 21px;
    border-radius: 5px;
    flex: none;
}
.tnx-chip.flight   { background: var(--svc-flight-soft);   color: var(--svc-flight); }
.tnx-chip.stay     { background: var(--svc-stay-soft);     color: var(--svc-stay); }
.tnx-chip.transfer { background: var(--svc-transfer-soft); color: var(--svc-transfer); }
.tnx-chip.package  { background: var(--svc-package-soft);  color: var(--svc-package); }
.tnx-chip.activity { background: var(--svc-activity-soft); color: var(--svc-activity); }
.tnx-chip.off      { background: var(--svc-off-soft);      color: var(--svc-off); opacity: .55; }

.tnx-chip-count {
    position: absolute; bottom: -3px; right: -3px;
    background: currentColor;
    border-radius: 3px;
    padding: 0 2px;
    font-size: 8px; font-weight: 700; line-height: 1.4;
}
.tnx-chip-count span { color: var(--surface); }

/* ==========================================================================
   Filters
   ========================================================================== */

.tnx-filters {
    display: flex; gap: 3px; padding: 3px;
    border-radius: 8px;
    background: var(--fill);
}

.tnx-filter {
    display: flex; align-items: center;
    height: 24px; padding: 0 10px;
    border: 0; border-radius: 6px;
    background: transparent;
    color: var(--text-2);
    font-family: inherit; font-size: 12px; font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
}
.tnx-filter:hover { color: var(--text); }
.tnx-filter.on {
    background: var(--surface);
    color: var(--text);
    font-weight: 700;
    box-shadow: 0 1px 2px rgba(19, 24, 32, .08);
}
[data-theme="dark"] .tnx-filter.on { background: #333C4B; color: #F2F5FA; box-shadow: none; }

.tnx-inline-select {
    display: inline-flex; align-items: center; gap: 6px;
    height: 28px; padding: 0 10px;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: transparent;
    color: var(--text-2);
    font-family: inherit; font-size: 12px;
    cursor: pointer;
}
.tnx-inline-select:hover { border-color: var(--text-4); }

/* A search box that sits inside a card head. The icon is part of the frame so
   the whole thing focuses as one control. */
.tnx-search-field {
    display: inline-flex; align-items: center; gap: 7px;
    height: 28px; padding: 0 10px;
    border: 1px solid var(--line);
    border-radius: 7px;
    background: var(--surface);
    color: var(--text-3);
    min-width: 230px;
}
.tnx-search-field:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
    color: var(--accent);
}

.tnx-search-field input {
    flex: 1; min-width: 0;
    border: 0; background: transparent; padding: 0;
    color: var(--text);
    font-family: inherit; font-size: 12.5px;
}
.tnx-search-field input:focus { outline: 0; }
.tnx-search-field input::placeholder { color: var(--text-4); }

/* Says the list stops short, so nobody reads a capped table as the whole
   picture. */
.tnx-note {
    padding: 8px 16px;
    border-top: 1px solid var(--line-row);
    background: var(--surface-sunken);
    font-size: 11.5px; color: var(--text-2);
}

/* ==========================================================================
   Tables
   ========================================================================== */

.tnx-table { width: 100%; border-collapse: collapse; }

.tnx-table thead tr {
    background: var(--surface-sunken);
    border-top: 1px solid var(--line-soft);
    border-bottom: 1px solid var(--line-soft);
}

.tnx-table th {
    text-align: left;
    padding: 9px 12px;
    font-size: 10.5px; font-weight: 700;
    letter-spacing: .05em; text-transform: uppercase;
    color: var(--text-3);
    white-space: nowrap;
}

.tnx-table td {
    padding: 9px 12px;
    border-top: 1px solid var(--line-row);
    font-size: 12.5px;
    vertical-align: middle;
    white-space: nowrap;
}

.tnx-table tbody tr:first-child td { border-top: 0; }
.tnx-table tbody tr:hover { background: var(--surface-hover); }
.tnx-table tr.attention { background: var(--row-attention); }
.tnx-table .right { text-align: right; }
.tnx-table .pad-l { padding-left: 16px; }
.tnx-table .pad-r { padding-right: 16px; }

/* The dense variant used by Free cancellation and Agent position: hairlines
   only, no sunken header, tighter rhythm. */
.tnx-table.flush thead tr { background: transparent; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.tnx-table.flush th { padding: 6px 10px; }
.tnx-table.flush td { padding: 8px 10px; border-top: 0; border-bottom: 1px solid var(--line-row); }
.tnx-table.flush tbody tr:last-child td { border-bottom: 0; }
.tnx-table.flush tbody tr:hover { background: transparent; }

/* ==========================================================================
   Masked figures
   ==========================================================================
   Screen privacy for someone who is already allowed to see the number. What a
   role may not see is never sent to the browser at all -- that is permissions,
   and it is a different mechanism. */

.tnx-money { display: inline-flex; align-items: center; gap: 7px; }

.tnx-money-dots { letter-spacing: .12em; }

.tnx-eye {
    display: inline-flex; align-items: center; justify-content: center;
    width: 17px; height: 17px; flex: none;
    border: 0; border-radius: 4px;
    background: transparent;
    color: var(--text-4);
    cursor: pointer;
    padding: 0;
}
.tnx-eye:hover { background: var(--fill); color: var(--text-2); }

/* ==========================================================================
   Progress bars (wallet and credit as one figure)
   ========================================================================== */

.tnx-bar {
    display: flex; height: 4px;
    border-radius: 2px;
    overflow: hidden;
    background: var(--line-soft);
}
.tnx-bar .wallet { background: var(--accent); }
.tnx-bar .credit { background: color-mix(in srgb, var(--accent) 40%, var(--surface)); }
.tnx-bar .credit-warn { background: var(--warn); }

/* ==========================================================================
   Sign-in
   ========================================================================== */

.tnx-signin-page {
    min-height: 100vh;
    display: flex; align-items: center; justify-content: center;
    background: var(--stage);
    padding: 24px;
}

.tnx-signin {
    width: 100%; max-width: 25rem;
    background: var(--surface);
    border-radius: 14px;
    box-shadow: var(--pop-shadow);
    padding: 30px 32px 32px;
}

.tnx-signin h1 { font-size: 19px; margin-bottom: 4px; }
.tnx-signin .lead { font-size: 13px; color: var(--text-2); margin: 0 0 22px; }

.tnx-field { display: block; margin-bottom: 14px; }
.tnx-field span {
    display: block; margin-bottom: 5px;
    font-size: 12px; font-weight: 600; color: var(--text-2);
}
.tnx-field input {
    width: 100%; height: 38px;
    padding: 0 12px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--surface);
    color: var(--text);
    font-family: inherit; font-size: 14px;
}
.tnx-field input:focus {
    outline: 0;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.tnx-alert {
    padding: 10px 12px;
    border-radius: 8px;
    background: var(--bad-soft);
    color: var(--bad);
    font-size: 12.5px; font-weight: 600;
    margin-bottom: 18px;
}

/* ==========================================================================
   Empty states
   ========================================================================== */

.tnx-empty {
    display: flex; flex-direction: column; align-items: center;
    gap: 6px; padding: 42px 20px;
    text-align: center;
}
.tnx-empty-title { font-size: 13.5px; font-weight: 700; }
.tnx-empty-note { font-size: 12.5px; color: var(--text-2); max-width: 32ch; }

/* ==========================================================================
   Booking workspace
   ========================================================================== */

/* Which booking you are acting on, and what it costs, stay on screen while the
   services scroll. Cancelling the wrong service is expensive, so the reference
   never leaves view. */
.tnx-pinned {
    position: sticky; top: 0; z-index: 5;
    margin: -18px -22px 14px;
    padding: 15px 22px 12px;
    background: var(--stage);
    border-bottom: 1px solid var(--line);
}

.tnx-pinned-id { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* The money strip under the reference. Figures stay covered here like anywhere
   else -- this is the screen most likely to be open when somebody walks past. */
.tnx-pinned-money {
    display: flex; align-items: center; gap: 22px; flex-wrap: wrap;
    margin-top: 9px;
}

.tnx-pinned-money > div { display: flex; align-items: baseline; gap: 7px; }

.tnx-pinned-money dt {
    font-size: 10.5px; font-weight: 700;
    letter-spacing: .05em; text-transform: uppercase;
    color: var(--text-3);
}

/* Back to wherever this was opened from. Sized to its label rather than to a
   square: every use of it names the place it goes back to, and a fixed 28px box
   wrapped "My bookings" onto three lines. `align-self` because these nearly
   always sit in a flex column, where a stretched back button looks like a
   mistake. */
.tnx-back {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    align-self: flex-start;
    height: 28px; padding: 0 10px 0 8px; flex: none;
    white-space: nowrap;
    border: 1px solid var(--line); border-radius: 8px;
    background: var(--surface); color: var(--text-2);
    font-size: 12px; font-weight: 600;
}
.tnx-back:hover { border-color: var(--text-4); color: var(--text); }

/* A sentence that carries a figure, rather than an alert box shouting one. */
.tnx-callout {
    display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
    padding: 10px 14px;
    border-radius: 9px;
    background: var(--accent-soft);
    font-size: 12.5px; line-height: 1.6;
}
.tnx-callout > span { flex: 1 1 0; min-width: 200px; }
.tnx-callout.warn { background: var(--warn-soft); }
.tnx-callout.bad { background: var(--bad-soft); }

/* A quiet divider inside the services table, so a package reads as its parts
   rather than as one undifferentiated list. */
.tnx-table tr.group td {
    padding: 11px 16px 4px;
    border-top: 1px solid var(--line-row);
    background: transparent;
    font-size: 10px; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase;
    color: var(--text-3);
}
.tnx-table tbody tr.group:hover { background: transparent; }
.tnx-table tbody tr.group:first-child td { border-top: 0; }
.tnx-table tr.group + tr td { border-top: 0; }

/* A cancelled service stays on the booking as a record, but it is not part of
   what anyone owes -- the totals exclude it, so the row must not read at full
   strength as though it still counted. */
.tnx-table tr.struck td { color: var(--text-3); }
.tnx-table tr.struck .tnx-svc-name { text-decoration: line-through; }

.tnx-row-action {
    display: inline-flex; align-items: center; justify-content: center;
    width: 25px; height: 25px;
    border: 0; border-radius: 6px;
    background: transparent; color: var(--text-4);
    cursor: pointer; padding: 0;
}
.tnx-row-action:hover { background: var(--bad-soft); color: var(--bad); }
.tnx-row-action:disabled { opacity: .4; cursor: default; background: transparent; color: var(--text-4); }

/* Label and value on one line, for the small detail cards. */
.tnx-kv { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; padding: 6px 0; }
.tnx-kv + .tnx-kv { border-top: 1px solid var(--line-row); }
.tnx-kv dt { font-size: 12px; color: var(--text-2); }
.tnx-kv dd { margin: 0; font-size: 12.5px; font-weight: 600; text-align: right; }

/* ==========================================================================
   Booking folder
   ==========================================================================
   The structure from the agreed Option 2 artboards -- header strip, section
   rail, content card, action bar -- in our own tokens rather than the
   artboard's navy and teal. */

.bf { display: flex; flex-direction: column; gap: 12px; }

/* The six facts that identify a booking, each with its name above it. */
.bf-hdr { display: flex; flex-wrap: wrap; background: var(--surface); border-radius: 11px; box-shadow: var(--card-shadow); }
.bf-hdr > div { flex: 1 1 118px; padding: 10px 14px; position: relative; }
.bf-hdr dd .tnx-num { white-space: nowrap; }
.bf-hdr > div + div::before {
    content: ""; position: absolute; left: 0; top: 12px; bottom: 12px; width: 1px; background: var(--line);
}
.bf-hdr dt {
    font-size: 9px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--text-3); margin-bottom: 2px;
}
.bf-hdr dd { margin: 0; display: flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 700; letter-spacing: -.01em; }

.bf-body { display: grid; grid-template-columns: 176px minmax(0, 1fr); gap: 10px; align-items: start; }

/* Section rail */
.bf-nav { background: var(--surface); border-radius: 11px; box-shadow: var(--card-shadow); padding: 6px; }
.bf-nav-group {
    padding: 9px 10px 4px; font-size: 9px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase; color: var(--text-4);
}
/* justify-content is explicit because Chrome centres a display:flex button. */
.bf-nav-item {
    display: flex; align-items: center; justify-content: flex-start; gap: 9px; width: 100%;
    padding: 8px 11px; margin: 1px 0; border: 0; border-radius: 8px;
    background: transparent; color: var(--text-2);
    font-family: inherit; font-size: 12.5px; font-weight: 600; text-align: left;
    cursor: pointer;
}
.bf-nav-item:hover { background: var(--fill); color: var(--text); }
.bf-nav-item.on { background: var(--accent); color: var(--accent-on); font-weight: 700; }
.bf-nav-item .n {
    margin-left: auto; min-width: 18px; padding: 0 5px; border-radius: 4px;
    background: var(--fill); color: var(--text-3);
    font-size: 10px; font-weight: 700; text-align: center;
}
.bf-nav-item.on .n { background: rgba(255, 255, 255, .24); color: #fff; }
.bf-nav-item:disabled { opacity: .5; cursor: default; }
.bf-nav-item:disabled:hover { background: transparent; color: var(--text-2); }

/* Content card */
.bf-card { background: var(--surface); border-radius: 11px; box-shadow: var(--card-shadow); overflow: hidden; }

.bf-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 13px 15px 11px; }
.bf-head-icon {
    width: 34px; height: 34px; flex: none; border-radius: 9px;
    display: flex; align-items: center; justify-content: center;
    background: var(--accent-soft); color: var(--accent);
}
.bf-head h1 { font-size: 17px; font-weight: 800; letter-spacing: -.028em; margin: 0; }
.bf-head p { margin: 1px 0 0; font-size: 12px; color: var(--text-2); }
.bf-head .sp { flex: 1; }

/* "Operated by" strip */
.bf-ops {
    display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
    padding: 9px 17px; background: var(--surface-sunken);
    border-top: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft);
    font-size: 12px;
}
.bf-ops .sp { flex: 1; }
.bf-ops-kv { display: flex; align-items: baseline; gap: 6px; }
.bf-ops-kv dt { color: var(--text-3); font-weight: 600; }
.bf-ops-kv dd { margin: 0; font-weight: 700; }
.bf-avatar {
    width: 22px; height: 22px; border-radius: 50%; flex: none;
    display: flex; align-items: center; justify-content: center;
    background: var(--accent-soft); color: var(--accent);
    font-size: 9.5px; font-weight: 800;
}

/* Summary: itinerary beside the booking's own details */
.bf-split { display: grid; grid-template-columns: minmax(0, 1fr) 322px; gap: 0; }
.bf-split > :last-child { border-left: 1px solid var(--line-soft); }

@media (max-width: 1120px) {
    .bf-split { grid-template-columns: minmax(0, 1fr); }
    .bf-split > :last-child { border-left: 0; border-top: 1px solid var(--line-soft); }
}

/* ---- the itinerary ---- */
.bf-tl { padding: 6px 0 14px; }

.bf-day { display: flex; align-items: center; gap: 10px; padding: 11px 17px 6px; }
.bf-day-date {
    display: inline-flex; align-items: baseline; gap: 7px;
    font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
}
.bf-day-dow { color: var(--text-3); font-weight: 700; }
.bf-day-rule { flex: 1; height: 1px; background: var(--line-soft); }
.bf-day-sum { font-size: 10.5px; color: var(--text-3); font-weight: 600; white-space: nowrap; }

.bf-ev { display: grid; grid-template-columns: 62px 34px minmax(0, 1fr); align-items: start; }

.bf-ev-date {
    margin: 10px 0 0 17px; padding: 5px 0 6px;
    border: 1px solid var(--line); border-radius: 8px;
    text-align: center; background: var(--surface);
}
.bf-ev-date .d { display: block; font-size: 15px; font-weight: 800; letter-spacing: -.02em; line-height: 1.1; }
.bf-ev-date .m { display: block; font-size: 8.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--text-3); }

/* The rail runs the height of the row; the node sits on it. */
.bf-ev-rail { position: relative; align-self: stretch; display: flex; justify-content: center; }
.bf-ev-rail::before { content: ""; position: absolute; top: 0; bottom: 0; width: 2px; background: var(--line); }
.bf-ev:first-of-type .bf-ev-rail::before { top: 22px; }
.bf-ev.last .bf-ev-rail::before { bottom: calc(100% - 22px); }

.bf-node {
    position: relative; margin-top: 9px; width: 28px; height: 28px; border-radius: 9px;
    display: flex; align-items: center; justify-content: center; flex: none;
    box-shadow: 0 0 0 3px var(--surface);
}
.bf-node.flight { background: var(--svc-flight-soft); color: var(--svc-flight); }
.bf-node.stay { background: var(--svc-stay-soft); color: var(--svc-stay); }
.bf-node.transfer { background: var(--svc-transfer-soft); color: var(--svc-transfer); }
.bf-node.package { background: var(--svc-package-soft); color: var(--svc-package); }
.bf-node.activity { background: var(--svc-activity-soft); color: var(--svc-activity); }
.bf-node.off { background: var(--svc-off-soft); color: var(--svc-off); }

.bf-ev-body { padding: 10px 17px 12px 11px; min-width: 0; }
.bf-ev-kind { font-size: 9px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--text-3); }
.bf-ev-top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.bf-ev-name { font-size: 13px; font-weight: 700; letter-spacing: -.015em; overflow-wrap: anywhere; }
.bf-ev-price { margin-left: auto; white-space: nowrap; }
.bf-ev-state { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 7px; }
.bf-ev.off .bf-ev-name { text-decoration: line-through; color: var(--text-3); }

/* ---- booking details column ---- */
.bf-details { padding: 14px 17px; }
.bf-details h2 { font-size: 12.5px; font-weight: 700; letter-spacing: -.01em; margin: 0 0 4px; }
.bf-details dl { margin: 0; }
.bf-detail { padding: 9px 0; border-top: 1px solid var(--line-row); }
.bf-detail:first-of-type { border-top: 0; }
.bf-detail dt {
    font-size: 9px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--text-3); margin-bottom: 2px;
}
.bf-detail dd { margin: 0; font-size: 12.5px; font-weight: 600; overflow-wrap: anywhere; }

/* ---- the add bar, kept out of the card so it reads as folder-level ---- */
.bf-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.bf-foot .sp { flex: 1; }
.bf-add {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 7px 12px; border: 1px solid var(--line); border-radius: 8px;
    background: var(--surface); color: var(--text);
    font-family: inherit; font-size: 12px; font-weight: 600;
    cursor: pointer;
}
.bf-add:hover { border-color: var(--accent); color: var(--accent); }
a.bf-add { text-decoration: none; }
/* The product being edited, so the eye knows which form is open below. */
.bf-add.on { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.bf-add.danger { color: var(--bad); border-color: var(--bad-soft); }
.bf-add.danger:hover { border-color: var(--bad); color: var(--bad); }

/* ---- one service, as a card: head, facts, its own lines, the supplier ----
   Sized to the card, not the window: a folder is read on ordinary office
   screens, so the columns fold as the card narrows rather than squeezing. */
.bf-svc-list { display: flex; flex-direction: column; gap: 10px; padding: 2px 10px 10px; }
.bf-svc { container-type: inline-size; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; background: var(--surface); }
.bf-svc-head {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 7px 10px 7px 12px; background: var(--fill); border-bottom: 1px solid var(--line);
}
.bf-svc-head h3 { margin: 0; font-size: 12.5px; font-weight: 700; letter-spacing: -.01em; }
.bf-svc-head .sp { flex: 1; }
.bf-svc-head .tnx-btn.sm { height: 26px; padding: 0 9px; font-size: 11.5px; }
.bf-svc-by {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 2px 7px; border-radius: 999px;
    background: var(--accent-soft); color: var(--accent);
    font-size: 10.5px; font-weight: 600;
}
.bf-svc.off .bf-svc-head h3, .bf-svc.off .bf-svc-who strong { text-decoration: line-through; color: var(--text-3); }

/* Three columns: who and where, then two lists of facts. */
.bf-svc-facts {
    display: grid; grid-template-columns: minmax(0, 1.3fr);
    grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
    gap: 8px 14px; padding: 10px 12px;
}
.bf-svc-facts > * + * { border-left: 1px solid var(--line-soft); padding-left: 14px; }
.bf-svc-who { display: flex; align-items: flex-start; gap: 9px; min-width: 0; }
.bf-svc-who > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.bf-svc-who strong { font-size: 13px; font-weight: 700; letter-spacing: -.015em; overflow-wrap: anywhere; }
.bf-svc-who span { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--text-2); overflow-wrap: anywhere; }
.bf-svc-who span svg { color: var(--text-3); flex: none; }
.bf-svc-who .tnx-chip { width: 28px; height: 28px; border-radius: 8px; flex: none; }

/* A list of facts: label, value, on one line each. */
.bf-kv { margin: 0; display: flex; flex-direction: column; gap: 4px; }
.bf-kv > div { display: grid; grid-template-columns: minmax(64px, max-content) minmax(0, 1fr); gap: 8px; align-items: baseline; }
.bf-kv dt { font-size: 10.5px; color: var(--text-3); font-weight: 600; white-space: nowrap; }
.bf-kv dd { margin: 0; font-size: 12px; font-weight: 600; overflow-wrap: anywhere; }
.bf-kv dd.tnx-num { white-space: nowrap; font-size: 11.5px; }
.bf-kv2 { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 14px; }

/* The two ends of a transfer, or of a tour, side by side. */
.bf-svc-ends { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 0 12px 10px; }
.bf-svc-end {
    display: flex; flex-direction: column; gap: 2px;
    padding: 8px 10px 9px; border-radius: 8px; background: var(--accent-soft);
    font-size: 11.5px; color: var(--text-2);
}
.bf-svc-end h4 { margin: 0 0 2px; display: flex; align-items: center; gap: 5px; font-size: 10.5px; font-weight: 700; color: var(--accent); }
.bf-svc-end h4 .kind { margin-left: auto; font-weight: 600; color: var(--text-3); text-transform: none; }
.bf-svc-end strong { font-size: 12px; color: var(--text); }
.bf-svc-end span { display: inline-flex; align-items: center; gap: 5px; }

/* A bordered grid -- the rooms of a hotel -- as the reference draws it:
   every cell ruled, the header on a sunken ground. */
.bf-grid-wrap { border-top: 1px solid var(--line); overflow-x: auto; }
.bf-grid { width: 100%; border-collapse: collapse; }
.bf-grid th, .bf-grid td { padding: 6px 10px; border: 1px solid var(--line); font-size: 12px; text-align: left; white-space: nowrap; }
.bf-grid th { background: var(--fill); font-weight: 700; color: var(--text); }
.bf-grid td { font-weight: 500; }
.bf-grid tbody tr:last-child td { border-bottom: 0; }
.bf-grid th:first-child, .bf-grid td:first-child { border-left: 0; }
.bf-grid th:last-child, .bf-grid td:last-child { border-right: 0; }

/* The supplier strip: their details on the left, the payments on the right. */
.bf-sup { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2.4fr); gap: 10px; padding: 10px 12px 12px; }
.bf-sup-panel { container-type: inline-size; min-width: 0; padding: 8px 12px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--fill); }

/* On a narrow screen the payment table scrolls sideways rather than losing
   its last columns without saying so. */
.bf-sup-panel.pay { overflow-x: auto; }
.bf-sup-panel h4 {
    margin: 0 0 7px; display: flex; align-items: center; gap: 7px 12px; flex-wrap: wrap;
    font-size: 12.5px; font-weight: 700; color: var(--accent);
}
.bf-sup-panel h4 .sp { flex: 1; }
.bf-sup-cost { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; font-weight: 700; color: var(--text-3); white-space: nowrap; }

/* What has actually gone out to the supplier: the figure somebody is looking
   for on this panel, so it is the one that carries the colour. */
.bf-sup-paid { color: var(--good); font-weight: 700; }

/* Label : value, in two columns. */
.bf-sup-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 18px; }
.bf-sup-list { border-collapse: collapse; }
.bf-sup-list th, .bf-sup-list td { padding: 3px 0; font-size: 11.5px; text-align: left; vertical-align: middle; }

/* Two columns of references need room. Where the panel has not got it, they
   go one under the other rather than cutting the values off. */
@container (max-width: 460px) {
    .bf-sup-cols { grid-template-columns: 1fr; gap: 0; }
}
.bf-sup-list th { width: 1%; padding-right: 8px; font-weight: 500; color: var(--text-2); white-space: nowrap; }
.bf-sup-list td:nth-child(2) { width: 1%; padding-right: 8px; color: var(--text-3); }
.bf-sup-list td:last-child { font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
.bf-sup-list td.tnx-num { white-space: nowrap; }

/* Payments: a ruled table on its own white ground, the header in the accent. */
.bf-sup-pay { width: 100%; border-collapse: separate; border-spacing: 0; border: 1px solid var(--line); border-radius: 7px; overflow: hidden; background: var(--surface); }
.bf-sup-pay th, .bf-sup-pay td { padding: 6px 8px; font-size: 12px; text-align: center; border-right: 1px solid var(--line); white-space: nowrap; }
.bf-sup-pay th:last-child, .bf-sup-pay td:last-child { border-right: 0; }
.bf-sup-pay th { background: var(--accent-soft); color: var(--accent); font-weight: 700; border-bottom: 1px solid var(--line);
    font-size: 10.5px; letter-spacing: .02em; padding-top: 5px; padding-bottom: 5px; }
.bf-sup-pay tbody tr + tr td { border-top: 1px solid var(--line-row); }
.bf-sup-pay td { font-weight: 500; }
.bf-sup-pay tfoot td { text-align: left; border-top: 1px solid var(--line); background: var(--surface-sunken); font-size: 11.5px; color: var(--text-2); }

/* The words for the paperwork. */
.bf-svc-words { display: flex; flex-direction: column; gap: 6px; padding: 0 12px 11px; }
.bf-svc-words > div { display: flex; flex-direction: column; gap: 1px; }
.bf-svc-words dt { font-size: 9.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--text-3); }
.bf-svc-words dd { margin: 0; font-size: 11.5px; line-height: 1.5; white-space: pre-wrap; }

/* An office screen at its normal zoom: the same layout as the reference,
   a size tighter -- three columns of facts, the two supplier panels side
   by side, the payments table with room for five columns. */
@container (max-width: 980px) {
    .bf-svc-facts { gap: 6px 10px; padding: 9px 10px; }
    .bf-svc-facts > * + * { padding-left: 10px; }
    .bf-svc-who { gap: 7px; }
    .bf-svc-who strong { font-size: 12.5px; }
    .bf-svc-who span { font-size: 11px; }
    .bf-kv { gap: 3px; }
    .bf-kv > div { gap: 6px; }
    .bf-kv dt { font-size: 10px; }
    .bf-kv dd { font-size: 11px; }
    .bf-kv dd.tnx-num { font-size: 10.5px; }
    .bf-grid th, .bf-grid td { padding: 5px 8px; font-size: 11px; }
    .bf-svc-ends { gap: 8px; padding: 0 10px 8px; }
    .bf-sup { grid-template-columns: minmax(0, 1fr) minmax(0, 2.4fr); gap: 8px; padding: 8px 10px 10px; }
    .bf-sup-panel { padding: 7px 9px 8px; }
    .bf-sup-panel h4 { font-size: 11.5px; margin-bottom: 5px; }
    .bf-sup-cost { font-size: 11.5px; }
    .bf-sup-cols { grid-template-columns: 1fr; gap: 0; }
    .bf-sup-list th, .bf-sup-list td { font-size: 11px; padding: 2px 0; }
    .bf-sup-pay th, .bf-sup-pay td { padding: 5px 5px; font-size: 11px; }
    .bf-sup-pay th { line-height: 1.2; font-size: 10px; }
    .bf-svc-words { padding: 0 10px 10px; }
}

/* Something small: one column of everything. */
@container (max-width: 640px) {
    .bf-svc-facts { grid-template-columns: 1fr; grid-auto-flow: row; }
    .bf-svc-facts > * + * { border-left: 0; padding-left: 0; border-top: 1px solid var(--line-soft); padding-top: 6px; }
    .bf-svc-ends, .bf-sup { grid-template-columns: 1fr; }
}

/* ---- the invoice tab, to the reference: details left, bands right, history below ---- */
.inv { container-type: inline-size; display: flex; flex-direction: column; gap: 8px; padding: 2px 12px 12px; }
.inv-top { display: flex; align-items: center; gap: 10px; font-size: 12px; font-weight: 600; }
.inv-top .sp { flex: 1; }
.inv-no { color: var(--accent); }
.inv-pro { color: var(--text-2); }
.inv-moved { color: var(--warn); font-weight: 600; }
.bf-inpkg { font-size: 11px; font-weight: 600; color: var(--text-3); white-space: nowrap; }

/* Booking notes: writing on the left, attaching on the right, history below. */
.bn-top { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; align-items: start; }
.bn-write .inv-row.col { align-items: stretch; }
.bn-lead { margin: 0 0 10px; font-size: 12px; font-weight: 600; color: var(--brand); }

/* The upload row wraps rather than pushing Add off the edge. */
.bn-pick { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.bn-kind { flex: 0 0 150px; width: 150px; }
.bn-doc-lbl { font-size: 11.5px; font-weight: 600; color: var(--text-2); white-space: nowrap; }
.bn-file { flex: 1 1 170px; min-width: 0; font-size: 11.5px; }
.bn-pick .tnx-btn { flex: 0 0 auto; }
.bn-count { display: flex; align-items: center; justify-content: flex-end; gap: 10px; padding: 0 2px 8px; }
/* A history is read across, not scanned down a column of figures: the
   words sit left and wrap, whatever the money tables do. */
.bn-table th, .bn-table td { text-align: left; }
.bn-table td:last-child { white-space: normal; line-height: 1.5; }
/* The card keeps its own rounded corners, so the table keeps its own too. */
.bn-table thead tr:first-child th:first-child { border-top-left-radius: 7px; }
.bn-table thead tr:first-child th:last-child { border-top-right-radius: 7px; }
.bn-table tbody tr:last-child td:first-child { border-bottom-left-radius: 7px; }
.bn-table tbody tr:last-child td:last-child { border-bottom-right-radius: 7px; }
.bn-table td { vertical-align: top; }
.bn-table tr.bn-note td:first-child { box-shadow: inset 3px 0 0 var(--brand); }
.bn-table tr.bn-act td:first-child { box-shadow: inset 3px 0 0 var(--line); }
.bn-tag { display: inline-block; padding: 1px 7px; border-radius: 999px; font-size: 10.5px; font-weight: 700; white-space: nowrap; }
.bn-tag.note { background: color-mix(in srgb, var(--brand) 14%, transparent); color: var(--brand); }
.bn-tag.act { background: var(--surface-2); color: var(--text-2); }
.bn-file-link { display: inline-flex; align-items: center; gap: 4px; margin-left: 8px; font-size: 11.5px; font-weight: 600; color: var(--brand); }

@media (max-width: 1100px) { .bn-top { grid-template-columns: 1fr; } }

/* Vouchers: the addresses and the counts side by side, then the list. */
.vch-body { grid-template-columns: minmax(0, 1fr) 260px; }
.vch-counts table { width: 100%; }
.vch-counts td:first-child { color: var(--text-2); }
.vch-type { color: var(--brand); font-weight: 600; }
.vch-holds { margin-left: 8px; font-size: 10.5px; font-weight: 600; color: var(--text-3); text-transform: lowercase; }
.vch-table td { vertical-align: middle; }
.vch-table .inv-dot.down { display: inline-flex; gap: 5px; align-items: center; width: auto; height: auto; padding: 0;
    background: none; color: var(--brand); font-size: 11.5px; font-weight: 600; border-radius: 0; }
.vch-table .inv-dot.down svg { color: var(--bad); }

/* The accounts panel: where the money comes from at the top, what each
   part cost on the left, the summary on the right. */
.acc-bar { display: flex; align-items: baseline; gap: 14px; padding: 2px 2px 6px; }
.acc-where { font-size: 14px; font-weight: 800; letter-spacing: -.02em; }
.acc-bar .sp { flex: 1; }
.acc-no { font-size: 11.5px; color: var(--text-2); }
.acc-no b { color: var(--text-1); font-weight: 700; }

.acc-set { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; }
.acc-fields { display: grid; grid-auto-flow: column; grid-auto-columns: max-content;
    grid-template-rows: auto auto auto; align-items: center; gap: 4px 16px; }
.acc-fld { display: contents; }
.acc-lbl { font-size: 9.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); white-space: nowrap; }
.acc-note { font-size: 10.5px; color: var(--text-3); white-space: nowrap; }
.acc-money { display: flex; align-items: center; gap: 6px; }
.acc-money .tnx-inp { width: 116px; }
.acc-ccy { font-size: 10.5px; font-weight: 700; color: var(--text-3); }
.acc-update { grid-row: 2; }
.acc-set .sp { flex: 1; }
.acc-lock { display: flex; align-items: center; gap: 12px; font-size: 12px; }
.acc-frozen { display: flex; align-items: center; gap: 7px; padding: 7px 10px; border-radius: 8px;
    background: color-mix(in srgb, var(--warn) 12%, transparent); color: var(--warn); font-size: 11.5px; font-weight: 600; }

.acc-body { display: grid; grid-template-columns: minmax(0, 1fr) 286px; gap: 8px; align-items: start; }
.acc-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 10px; padding: 4px 2px; }
.acc-net { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 6px; }
.acc-net.gap { visibility: hidden; }
.acc-net-lbl { min-width: 0; font-size: 10.5px; font-weight: 600; letter-spacing: -.005em; color: var(--text-2); text-wrap: balance; }
.acc-net-lbl i { display: block; font-size: 10px; font-style: normal; font-weight: 500; color: var(--text-3); }
.acc-net-val { width: 72px; padding: 5px 6px; border-radius: 6px; background: var(--surface-sunken);
    font-size: 12px; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
.acc-summary table th, .acc-summary table td { padding: 6px 7px; }
.acc-summary table td { text-align: left; }
.acc-summary table td.tnx-num { text-align: right; font-weight: 700; }
.acc-summary table td.acc-ccy { width: 44px; text-align: right; }
.acc-summary .due { color: var(--warn); }
.acc-summary .owed { color: var(--bad); }
.acc-vat { display: flex; gap: 16px; padding: 9px 2px 2px; font-size: 11.5px; color: var(--text-2); }
.acc-vat label { display: flex; align-items: center; gap: 6px; }

@media (max-width: 1100px) { .acc-body { grid-template-columns: 1fr; } }

/* On a narrow folder the figures read down one column rather than
   squeezing their names onto two lines. */
@container (max-width: 780px) { .acc-grid { grid-template-columns: 1fr; } }

/* The accounts tab: the four figures, then the button. */
.acc-facts { display: flex; align-items: flex-end; gap: 22px; flex-wrap: wrap; padding: 4px 2px 2px; }
.acc-facts > div { display: flex; flex-direction: column; gap: 2px; }
.acc-facts dt { font-size: 9.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--text-3); }
.acc-facts dd { margin: 0; font-size: 15px; font-weight: 800; letter-spacing: -.02em; }
.acc-facts > div.due dd { color: var(--warn); }
.acc-facts .sp { flex: 1; }
.inv-no b, .inv-cur b { font-weight: 800; }
.inv-cur { color: var(--good); }
/* The bands need no more than their columns; the details take the rest. */
.inv-body { display: grid; grid-template-columns: minmax(0, 1fr) 292px; gap: 8px; align-items: start; }
.inv-panel { border: 1px solid var(--line); border-radius: 8px; background: var(--fill); padding: 7px 10px 10px; min-width: 0; }
.inv-panel h4 { margin: 0 0 7px; font-size: 12px; font-weight: 700; }
.inv-panel .tnx-inp, .inv-panel .tnx-sel { height: 28px; font-size: 12px; }
.inv-row { display: flex; align-items: center; gap: 7px; margin-bottom: 7px; min-width: 0; }
.inv-row.col { flex-direction: column; align-items: stretch; }
.inv-lbl { flex: 0 0 58px; font-size: 11.5px; color: var(--text-2); }
.inv-row.col .inv-lbl { flex: none; }
.inv-addr { flex: 1 1 auto; max-width: 320px; min-width: 0; }
.inv-ccy { font-size: 11.5px; font-weight: 700; color: var(--text-2); }
.inv-row .tnx-sel { width: 100%; }
.inv-subj { flex: 1 1 auto; max-width: 480px; min-width: 0; }
.inv-rate { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--text-2); white-space: nowrap; }
.inv-check { display: flex; align-items: center; gap: 7px; margin: 2px 0 7px 65px; font-size: 11.5px; cursor: pointer; }
.inv-check input { accent-color: var(--accent); width: 14px; height: 14px; margin: 0; }
.inv-panel .tnx-area[readonly] { background: var(--surface-sunken); color: var(--text-2); }
.inv-legend { display: flex; align-items: center; justify-content: flex-end; gap: 6px 8px; margin-top: 8px; font-size: 11px; color: var(--text-2); }
.inv-legend i { font-style: italic; }
.inv-dot {
    display: inline-flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; border-radius: 50%; color: #fff; flex: none;
}
.inv-dot.down { background: var(--bad); }
.inv-dot.mail { background: var(--good); }
a.inv-dot { text-decoration: none; }
a.inv-dot:hover { filter: brightness(1.1); }
.inv-acts { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.inv-send { display: flex; justify-content: center; padding: 2px 0 4px; }
.inv-send .tnx-btn { padding: 0 22px; }

/* Only something small stacks the bands under the details; the Charges
   row may then wrap its rate to a second line. */
@container (max-width: 640px) {
    .inv-body { grid-template-columns: 1fr; }
    .inv-row { flex-wrap: wrap; }
}

/* A section whose data the database does not hold yet. Says so plainly rather
   than drawing a screen full of dashes. */
.bf-pending { display: flex; flex-direction: column; align-items: center; gap: 7px; padding: 46px 24px; text-align: center; }
.bf-pending-title { font-size: 13.5px; font-weight: 700; }
.bf-pending-note { font-size: 12.5px; color: var(--text-2); max-width: 46ch; line-height: 1.6; }

/* ==========================================================================
   Forms
   ==========================================================================
   The offline booking form is long by nature -- a flight alone has a PNR,
   segments, baggage and a supplier block. So the field itself is compact and
   the grid does the work of grouping. */

.tnx-steps { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.tnx-step {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 7px 13px 7px 8px; border-radius: 9px;
    background: var(--surface); color: var(--text-3);
    font-size: 12.5px; font-weight: 600;
    border: 0; font-family: inherit; cursor: pointer;
}
.tnx-step .n {
    width: 20px; height: 20px; flex: none; border-radius: 6px;
    display: flex; align-items: center; justify-content: center;
    background: var(--fill); color: var(--text-3);
    font-size: 10.5px; font-weight: 800;
}
.tnx-step.on { color: var(--text); box-shadow: inset 0 0 0 1px var(--accent); }
.tnx-step.on .n { background: var(--accent); color: var(--accent-on); }
.tnx-step.done { color: var(--text-2); }
.tnx-step.done .n { background: var(--good-soft); color: var(--good); }
.tnx-step:disabled { cursor: default; opacity: .55; }
.tnx-step-rule { width: 14px; height: 1px; background: var(--line); flex: none; }

/* A field grid: twelve columns, and a field says how many it wants. Rows sit
   close: a form that fits on one screen is read as one thing. */
.tnx-form { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 9px 12px; }

.tnx-fld { grid-column: span 3; display: flex; flex-direction: column; gap: 3px; min-width: 0; }

/* A form grid placed inside another one takes the full row, rather than
   arriving as a single cell and squashing everything it holds into it. */
.tnx-form.nested { grid-column: 1 / -1; }
.tnx-fld.w1 { grid-column: span 1; }
.tnx-fld.w2 { grid-column: span 2; }
.tnx-fld.w4 { grid-column: span 4; }
.tnx-fld.w5 { grid-column: span 5; }
.tnx-fld.w6 { grid-column: span 6; }
.tnx-fld.w7 { grid-column: span 7; }
.tnx-fld.w8 { grid-column: span 8; }
.tnx-fld.w12 { grid-column: span 12; }

@media (max-width: 900px) {
    .tnx-fld, .tnx-fld.w1, .tnx-fld.w2, .tnx-fld.w4, .tnx-fld.w5, .tnx-fld.w6, .tnx-fld.w7, .tnx-fld.w8 { grid-column: span 6; }
}
@media (max-width: 560px) {
    .tnx-fld, .tnx-fld.w1, .tnx-fld.w2, .tnx-fld.w4, .tnx-fld.w5, .tnx-fld.w6, .tnx-fld.w7, .tnx-fld.w8 { grid-column: span 12; }
}

/* Only the label. Sentence case, because these are read a hundred times a
   day and capitals slow that down; a shade darker than a table heading for
   the same reason. A hint is also a span in here, and is styled below. */
.tnx-fld > span:first-child {
    font-size: 11px; font-weight: 600; letter-spacing: 0; line-height: 1.2;
    color: var(--text-2);
}
.tnx-fld > span .req { color: var(--bad); margin-left: 2px; }

.tnx-inp, .tnx-sel, .tnx-area {
    width: 100%; min-width: 0;
    padding: 0 9px; height: 30px;
    border: 1px solid var(--line); border-radius: 7px;
    background: var(--surface); color: var(--text);
    font-family: inherit; font-size: 12.5px;
}
.tnx-area { height: auto; padding: 6px 9px; line-height: 1.5; resize: vertical; }
.tnx-inp:focus, .tnx-sel:focus, .tnx-area:focus {
    outline: 0; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.tnx-inp::placeholder, .tnx-area::placeholder { color: var(--text-4); }
.tnx-inp:disabled, .tnx-sel:disabled { background: var(--fill); color: var(--text-3); }

/* Every box is typed in the one face, whatever it holds: a date, a PNR and
   a name side by side should not look like three different forms. Digits
   still line up, which is all the data face was really for. */
.tnx-inp[type="date"], .tnx-inp[type="time"], .tnx-inp[type="datetime-local"],
.tnx-inp[type="number"], .tnx-inp.num {
    font-variant-numeric: tabular-nums;
}

/* An empty date control still shows dd/mm/yyyy, and the browser paints that in
   the field's own colour -- so without this it reads as heavily as a real date
   and pulls the eye to the one thing nobody has filled in. */
.tnx-inp[type="date"], .tnx-inp[type="time"], .tnx-inp[type="datetime-local"] {
    color: var(--text-4);
}
.tnx-inp[type="date"].filled, .tnx-inp[type="time"].filled,
.tnx-inp[type="datetime-local"].filled,
.tnx-inp[type="date"]:focus, .tnx-inp[type="time"]:focus,
.tnx-inp[type="datetime-local"]:focus {
    color: var(--text);
}

/* A control with a leading icon that is part of its frame, so the icon reads as
   belonging to the field rather than floating beside it. */
.tnx-control {
    display: flex; align-items: stretch;
    border: 1px solid var(--line); border-radius: 7px;
    background: var(--surface); overflow: hidden;
}
.tnx-control:focus-within {
    border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.tnx-control .ico {
    display: flex; align-items: center; justify-content: center;
    width: 29px; flex: none;
    border-right: 1px solid var(--line);
    background: var(--surface-sunken); color: var(--text-3);
}
.tnx-control input, .tnx-control select {
    flex: 1; min-width: 0; height: 28px; padding: 0 8px;
    border: 0; border-radius: 0; background: transparent;
    color: var(--text); font-family: inherit; font-size: 12.5px;
}
.tnx-control input:focus, .tnx-control select:focus { outline: 0; box-shadow: none; }
.tnx-control input[type="date"], .tnx-control input[type="time"] {
    font-variant-numeric: tabular-nums;
    color: var(--text-4);
}
.tnx-control input.filled, .tnx-control input:focus { color: var(--text); }

/* A unit chosen inside the box -- the currency a cost is billed in sits
   against the figure, in the place the prefix would be, rather than taking a
   field of its own. */
.tnx-control select.unit {
    flex: none; width: auto; height: auto; padding: 0 4px 0 7px;
    border-right: 1px solid var(--line);
    background: var(--surface-sunken); color: var(--text-3);
    font-size: 10.5px; font-weight: 700; cursor: pointer;
}

/* A field that cannot be used yet stays where it is, greyed. Hiding it would
   move everything else on the row and lose the reader's place. */
.tnx-control.off { background: var(--fill); }
.tnx-control.off input, .tnx-control.off select { color: var(--text-4); cursor: not-allowed; }

/* What a field is for, said under it rather than in a tooltip nobody opens.
   Wins over the label rule whatever position it sits in: a hint is a sentence
   wherever it appears, and a sentence in capitals is a shout. */
.tnx-hint, .tnx-fld > span.tnx-hint {
    font-size: 10.5px; font-weight: 500; letter-spacing: 0; text-transform: none;
    color: var(--text-3); line-height: 1.35;
}

/* Fields that belong together, set apart by a tint rather than a hard rule. */
.tnx-panel {
    grid-column: span 12;
    border-radius: 9px; background: var(--accent-soft);
    padding: 10px 12px 12px;
}
.tnx-panel-head { display: flex; align-items: flex-start; gap: 9px; margin-bottom: 8px; }
.tnx-panel-head .ico {
    width: 24px; height: 24px; flex: none; border-radius: 6px;
    display: flex; align-items: center; justify-content: center;
    background: var(--surface); color: var(--accent);
}
.tnx-panel-head h3 { margin: 0; font-size: 12.5px; font-weight: 700; color: var(--accent); }
.tnx-panel-head p { margin: 1px 0 0; font-size: 11px; color: var(--text-2); }
.tnx-panel .tnx-inp, .tnx-panel .tnx-control { background: var(--surface); }

/* Passengers, as a table rather than a card each. Four travellers is four rows,
   not four screens of scrolling. */
.tnx-ptable { width: 100%; border-collapse: collapse; }
.tnx-ptable th {
    text-align: left; padding: 0 5px 4px;
    font-size: 10px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--text-3); white-space: nowrap;
}
.tnx-ptable td { padding: 3px 5px; vertical-align: middle; }
.tnx-ptable td:first-child, .tnx-ptable th:first-child { padding-left: 0; }
.tnx-ptable td:last-child, .tnx-ptable th:last-child { padding-right: 0; text-align: center; }
.tnx-ptable .no { font-size: 11.5px; color: var(--text-3); text-align: center; }
.tnx-ptable .lead { text-align: center; }
.tnx-ptable input[type="radio"] { accent-color: var(--accent); width: 15px; height: 15px; }

/* One line per thing: a flight leg, a room. The legs table adds a two-row
   header that groups the airport pair, the departure and the arrival, so
   thirteen columns read as four things. */
.tnx-segs, .tnx-lines { width: 100%; border-collapse: collapse; }
.tnx-segs { min-width: 928px; table-layout: fixed; }
.tnx-lines { min-width: 860px; }
.tnx-segs th.grp {
    padding: 4px 4px 3px; text-align: center;
    font-size: 10.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
    color: var(--text-2); background: var(--fill);
    border-bottom: 1px solid var(--line);
}
.tnx-segs th.grp:empty { background: transparent; border-bottom-color: transparent; }
.tnx-segs thead tr:last-child th, .tnx-lines thead th {
    padding: 4px 3px 3px; text-align: left;
    font-size: 9px; font-weight: 500; letter-spacing: .03em; text-transform: uppercase;
    overflow: hidden; text-overflow: ellipsis;
    color: var(--text-3); white-space: nowrap;
    border-bottom: 1px solid var(--line-soft);
}
.tnx-segs td, .tnx-lines td { padding: 2px 2px; vertical-align: middle; }
.tnx-segs td:first-child, .tnx-lines td:first-child { padding-left: 0; }
.tnx-segs td:last-child, .tnx-lines td:last-child { padding-right: 0; text-align: center; }
.tnx-lines td:last-child { width: 34px; }
.tnx-segs .tnx-inp, .tnx-lines .tnx-inp, .tnx-lines .tnx-sel { height: 28px; padding: 0 6px; font-size: 12px; }
.tnx-segs .tnx-inp { font-size: 11.5px; padding: 0 5px; }
.tnx-segs .tnx-inp[type="date"], .tnx-segs .tnx-inp[type="time"] { padding: 0 2px 0 5px; }
.tnx-segs .tnx-inp::-webkit-calendar-picker-indicator { margin-left: 0; padding: 2px; }
.tnx-segs .tnx-row-action { width: 22px; height: 22px; }
.tnx-segs tfoot td:last-child, .tnx-lines tfoot td:last-child { padding: 8px 0 0; text-align: right; }

/* On a tinted card the group strip takes a slightly deeper tint, and the
   column rule fades to match. */
.tnx-panel .tnx-segs th.grp { background: color-mix(in srgb, var(--accent) 8%, transparent); border-bottom-color: transparent; }

/* One band across the whole row, rounded at the ends, with a hairline gap in
   the card's own colour between groups: a break without a line. */
.tnx-segs th.grp + th.grp { border-left: 2px solid var(--surface); }
.tnx-panel .tnx-segs th.grp + th.grp { border-left-color: var(--accent-soft); }
.tnx-segs th.grp:first-child { border-radius: 5px 0 0 5px; }
.tnx-segs th.grp:last-child { border-radius: 0 5px 5px 0; }
.tnx-panel .tnx-segs thead tr:last-child th, .tnx-panel .tnx-lines thead th { border-bottom: 0; }
.tnx-panel-foot { display: flex; justify-content: flex-end; margin-top: 8px; }

/* A box that offers names as they are typed, the offers in a list beneath. */
.tnx-lookup { position: relative; }
.tnx-lookup-list {
    position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 30;
    display: flex; flex-direction: column; gap: 1px; padding: 4px;
    min-width: 280px; max-height: 264px; overflow-y: auto;
    background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
    box-shadow: var(--pop-shadow);
}
.tnx-lookup-item {
    display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
    width: 100%; padding: 6px 9px; border: 0; border-radius: 6px;
    background: none; font-family: inherit; text-align: left; cursor: pointer;
}
.tnx-lookup-item:hover, .tnx-lookup-item.on { background: var(--accent-soft); }
.tnx-lookup-item .name { font-size: 12.5px; font-weight: 600; color: var(--text); }
.tnx-lookup-item .where { font-size: 11px; color: var(--text-3); }

/* The paste box for a GDS itinerary, open only when asked for. */
.tnx-paste { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.tnx-paste-foot { display: flex; align-items: center; gap: 8px; }
.tnx-panel .tnx-area { background: var(--surface); }

/* Two things sharing one column: a name beside a select, a box beside its
   remove button. The box takes what the label or button leaves. */
.tnx-pair { display: flex; align-items: center; gap: 8px; min-width: 0; }
.tnx-pair .who { flex: none; width: 54px; font-size: 12px; font-weight: 600; color: var(--text-3); }
.tnx-pair .tnx-sel, .tnx-pair .tnx-inp { flex: 1; min-width: 0; }
.tnx-pair .tnx-row-action { flex: none; }
.tnx-pair .tnx-sel.gender { flex: 0 0 58px; padding: 0 0 0 8px; }

/* Fields on one line with a hairline between them, as a ledger has columns.
   Only the fields marked, so a second row is not ruled at its left edge. */
.tnx-form.divided > .tnx-fld.sep {
    border-left: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
    padding-left: 12px;
}
.tnx-panel .tnx-control select, .tnx-panel .tnx-control input { background: transparent; }
.tnx-panel .tnx-sel { background: var(--surface); }
.tnx-lines td.no, .tnx-lines th:first-child { width: 22px; font-size: 11.5px; color: var(--text-3); text-align: center; }
.tnx-lines td:nth-child(4), .tnx-lines td:nth-child(5) { width: 76px; }

/* A name typed that could not be made into anybody. */
.tnx-inp.bad { border-color: var(--warn); }

/* A few choices in a row -- what kind of place a transfer starts from. */
.tnx-radios { display: flex; flex-wrap: wrap; gap: 4px 16px; padding: 2px 0; }
.tnx-radio {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12px; font-weight: 600; color: var(--text-2); cursor: pointer;
}
.tnx-radio input { accent-color: var(--accent); width: 14px; height: 14px; margin: 0; cursor: pointer; }
.tnx-radio:has(input:checked) { color: var(--text); }

/* A line that opens the part of a form nobody needs most days. */
.tnx-fold {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 0; border: 0; background: none;
    font-family: inherit; font-size: 11px; font-weight: 700; letter-spacing: .04em;
    color: var(--text-3); cursor: pointer;
}
.tnx-fold:hover { color: var(--text-2); }
.tnx-fold svg { transition: transform .12s; }
.tnx-fold.open svg { transform: rotate(90deg); }

.tnx-legend {
    grid-column: span 12;
    display: flex; align-items: center; gap: 9px;
    margin-top: 3px; margin-bottom: -2px;
    font-size: 10px; font-weight: 700; letter-spacing: .07em;
    text-transform: uppercase; color: var(--text-3);
}
.tnx-legend::after { content: ""; flex: 1; height: 1px; background: var(--line-soft); }
.tnx-legend:first-child { margin-top: 0; }

/* Picking which passengers are on a service. */
.tnx-picks { display: flex; flex-wrap: wrap; gap: 6px; }
.tnx-pick {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 5px 11px; border-radius: 999px;
    border: 1px solid var(--line); background: var(--surface); color: var(--text-2);
    font-family: inherit; font-size: 12px; font-weight: 600;
    cursor: pointer;
}
.tnx-pick:hover { border-color: var(--text-4); }
.tnx-pick.on {
    background: var(--accent-soft); border-color: var(--accent); color: var(--accent);
}
.tnx-pick .tick { width: 13px; height: 13px; flex: none; }
.tnx-pick .type {
    font-size: 9.5px; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; color: var(--text-4);
}
.tnx-pick.on .type { color: var(--accent); }

/* The list of services built so far. */
.tnx-basket { display: flex; flex-direction: column; }
.tnx-basket-row {
    display: flex; align-items: center; gap: 11px;
    padding: 8px 15px; border-top: 1px solid var(--line-row);
}
.tnx-basket-row:first-child { border-top: 0; }
.tnx-basket-row .body { min-width: 0; flex: 1; }
.tnx-basket-row .name { font-size: 12.5px; font-weight: 600; }
.tnx-basket-row .meta { font-size: 11px; color: var(--text-3); margin-top: 1px; }
.tnx-basket-row.closed .name, .tnx-basket-row.closed .meta { color: var(--text-4); text-decoration: line-through; }

/* A service past changing says so where the Edit button would be. */
.tnx-status.off {
    font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--text-3); padding: 3px 8px; border-radius: 999px; background: var(--fill);
}

.tnx-error {
    grid-column: span 12;
    padding: 9px 12px; border-radius: 8px;
    background: var(--bad-soft); color: var(--bad);
    font-size: 12px; font-weight: 600;
}

/* ==========================================================================
   MudBlazor: keep dialogs, snackbars and pickers, dress them in our tokens
   ========================================================================== */

.mud-dialog { background: var(--surface) !important; color: var(--text) !important; border-radius: 12px !important; }
.mud-dialog-title { font-family: inherit !important; font-weight: 700 !important; letter-spacing: -.02em; }
.mud-input-label, .mud-input, .mud-select { font-family: inherit !important; }
.mud-snackbar { font-family: inherit !important; }

@media (prefers-reduced-motion: reduce) {
    * { transition: none !important; animation: none !important; }
}


/* ---------------------------------------------------------------------------
   A grid that sorts and filters from its own headings: the words sort, the
   funnel opens the values that column holds. Shared by the bookings table
   and the booking notes.
--------------------------------------------------------------------------- */
.gf { position: relative; display: inline-flex; }
.gf-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.gf-head.end { justify-content: flex-end; }
.gf-sort { cursor: pointer; user-select: none; white-space: nowrap; }
.gf-sort:hover { color: var(--brand); }
.gf-funnel { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; padding: 0;
    border: 0; border-radius: 5px; background: transparent; color: var(--text-3); cursor: pointer; }
.gf-funnel:hover { background: var(--surface-2); color: var(--brand); }
.gf-funnel.on { background: var(--brand); color: #fff; }

.gf-away { position: fixed; inset: 0; z-index: 20; }
.gf-pop { position: fixed; top: 0; left: 0; z-index: 25; visibility: hidden; width: 244px; padding: 8px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 9px;
    box-shadow: 0 12px 28px rgba(16, 24, 40, .16); text-align: left; font-weight: 400; text-transform: none; letter-spacing: 0; }
.gf-pop.dates { display: flex; flex-direction: column; gap: 8px; width: 210px; }
.gf-pop.dates label { display: flex; flex-direction: column; gap: 3px; }
.gf-pop.dates label span { font-size: 9.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); }
.gf-search { display: flex; align-items: center; gap: 6px; padding: 0 8px; margin-bottom: 6px;
    border: 1px solid var(--line); border-radius: 7px; color: var(--text-3); }
.gf-search .tnx-inp { border: 0; height: 30px; padding: 0; font-size: 12px; background: transparent; }
.gf-list { display: flex; flex-direction: column; gap: 1px; max-height: 232px; overflow-y: auto; }
.gf-list label { display: flex; align-items: center; gap: 7px; padding: 4px 6px; border-radius: 6px;
    font-size: 12px; font-weight: 500; color: var(--text-1); cursor: pointer; }
.gf-list label:hover { background: var(--surface-2); }
.gf-list label.gf-all { font-weight: 700; }
.gf-list input { accent-color: var(--brand); }
.gf-none { padding: 6px; font-size: 11.5px; color: var(--text-3); }


/* ---------------------------------------------------------------------------
   Find booking: the panel above the list. Folded, it says what it is
   searching for, so nobody wonders why the list is short.
--------------------------------------------------------------------------- */
.fb-head {
    display: flex; align-items: center; gap: 10px; width: 100%;
    padding: 11px 16px; border: 0; background: transparent;
    font-family: inherit; text-align: left; cursor: pointer;
}
.fb-title { display: inline-flex; align-items: center; gap: 7px;
    font-size: 12.5px; font-weight: 700; color: var(--text); white-space: nowrap; }
.fb-asked { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: 11.5px; color: var(--text-3); }
/* Pointing down while folded, up while open: the panel says which way it goes. */
.fb-chevron { display: inline-flex; color: var(--text-3); transform: rotate(90deg); transition: transform .15s ease; }
.fb-chevron.open { transform: rotate(-90deg); }
.fb-head:hover .fb-chevron { color: var(--text-2); }

.fb-body { padding: 0 16px 14px; border-top: 1px solid var(--line-soft); padding-top: 13px; }

/* A date range is one idea, so it is one field with two ends. */
.fb-range { display: flex; align-items: center; gap: 5px; }
.fb-range > span { color: var(--text-4); }

.fb-actions { display: flex; align-items: center; gap: 8px; margin-top: 13px; }


/* Where a supplier stands on one service, beside the heading that says so. */
.bf-pay-state { display: inline-block; margin-left: 8px; padding: 1px 7px; border-radius: 999px;
    font-size: 10px; font-weight: 700; letter-spacing: .02em; white-space: nowrap; }
.bf-pay-state.good { background: var(--good-soft); color: var(--good); }
.bf-pay-state.warn { background: var(--warn-soft); color: var(--warn); }
.bf-pay-state.bad { background: var(--bad-soft); color: var(--bad); }
.bf-pay-state.violet { background: color-mix(in srgb, var(--brand) 14%, transparent); color: var(--brand); }
.bf-pay-state.quiet { background: var(--surface-2); color: var(--text-3); }
.bf-pay-state.under { display: block; margin: 2px auto 0; width: fit-content; }


/* A cancelled payment is still part of the history, so it stays on the table
   -- greyed, struck through where the figures are, and labelled. Removing it
   would hide that it ever happened. */
.bf-pay-off > td { background: var(--fill); color: var(--text-3); }
.bf-pay-off > td:first-child .tnx-money { text-decoration: line-through; }

/* What cancelling actually does, said before it is done. */
.cp-note { display: flex; gap: 9px; padding: 10px 11px; border-radius: 9px;
    background: var(--warn-soft); color: var(--text-1); font-size: 12px; line-height: 1.5; }
.cp-note > span:first-child { color: var(--warn); flex: none; margin-top: 1px; }


/* Cancelling one payment is a small, rare act on a crowded row, so it is an
   icon with its words on hover rather than a sentence in every line. */
.bf-pay-undo { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px;
    padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--text-3); cursor: pointer; }
.bf-pay-undo:hover { background: var(--bad-soft); color: var(--bad); }
.bf-pay-undo:disabled { opacity: .4; cursor: default; }


/* The bookings grid's own weights. These are what it looked like before the
   calm block below, and what it goes back to if that block is removed. */
.tnx-table .bk-ref { font-weight: 600; }

/* The id is the door into the booking, so it says so when the pointer is on
   it -- and being a real link, it can be opened in its own tab. */
.tnx-table .bk-ref a { color: inherit; text-decoration: none; }
.tnx-table .bk-ref a:hover { color: var(--accent); text-decoration: underline; }
.tnx-table .bk-amount .tnx-num { font-weight: 600; }
.tnx-table .bk-action { color: var(--accent); font-weight: 600; }

/* ===========================================================================
   Calm reading on the bookings grid                          added 2026-09-19
   ---------------------------------------------------------------------------
   The grid is worked in all day, and every row was shouting at once: two
   filled pills, four tinted chips, three columns in bold and a coloured
   action, with nothing else on the page to compete against. Read down it for
   an hour and the eye has nowhere to rest.

   So colour is spent only where it changes what somebody does -- money still
   owed, a refund to issue, a booking not yet confirmed. Everything ordinary
   is told in words with a dot of colour beside it, which is still never
   colour alone.

   TO ROLL BACK: delete this block and take "calm" out of the table's class in
   Components/Shared/BookingTable.razor. Nothing else uses either.
   =========================================================================== */

/* Air between the rows, and a lighter hand on the rules. */
.tnx-table.calm td { padding: 11px 12px; border-top-color: var(--line-soft); }
.tnx-table.calm th { padding: 8px 12px; font-weight: 600; letter-spacing: .035em; color: var(--text-4); }

/* A reference and an amount are facts to read, not headlines to announce. */
.tnx-table.calm .bk-ref { font-weight: 500; color: var(--text-2); }
.tnx-table.calm .bk-amount .tnx-num { font-weight: 500; }

/* Ordinary news -- confirmed, paid -- loses its block of colour and keeps a
   dot of it, so the row reads as a sentence rather than a set of labels. */
.tnx-table.calm .tnx-pill {
    height: auto; padding: 0; gap: 6px;
    background: transparent; color: var(--text-1);
    font-size: 11.5px; font-weight: 500; letter-spacing: 0;
}
.tnx-table.calm .tnx-pill::before {
    content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--text-4);
}
.tnx-table.calm .tnx-pill.good::before    { background: var(--good); }
.tnx-table.calm .tnx-pill.info::before    { background: var(--accent); }
.tnx-table.calm .tnx-pill .dot            { display: none; }

/* Anything still waiting on somebody keeps the fill it had: these are the
   rows a person is looking for. */
.tnx-table.calm .tnx-pill.warn,
.tnx-table.calm .tnx-pill.bad,
.tnx-table.calm .tnx-pill.violet {
    height: 20px; padding: 0 8px; font-weight: 600;
}
.tnx-table.calm .tnx-pill.warn   { background: var(--warn-soft);     color: var(--warn); }
.tnx-table.calm .tnx-pill.bad    { background: var(--bad-soft);      color: var(--bad); }
.tnx-table.calm .tnx-pill.violet { background: var(--svc-stay-soft); color: var(--svc-stay); }
.tnx-table.calm .tnx-pill.warn::before,
.tnx-table.calm .tnx-pill.bad::before,
.tnx-table.calm .tnx-pill.violet::before { display: none; }

/* The chips keep their hues, which are how a product is recognised, and give
   up the tinted tiles behind them. */
.tnx-table.calm .tnx-chips { gap: 4px; }
.tnx-table.calm .tnx-chip { width: 18px; height: 18px; background: transparent; }
.tnx-table.calm .tnx-chip-count { bottom: -4px; right: -5px; background: var(--surface); border-radius: 4px; }
.tnx-table.calm .tnx-chip-count span { color: var(--text-3); }

/* What to do next is the one thing on the row worth following, so it stays
   blue -- at the weight of everything else around it. */
.tnx-table.calm .bk-action { color: var(--accent); font-weight: 500; }

/* ===========================================================================
   Deciding what goes back                                    added 2026-09-19
   ---------------------------------------------------------------------------
   Cancelling and refunding are two decisions and need not happen on the same
   day (D-124), so the cancel dialog asks a third question and the folder
   carries the answer until somebody gives one.
   =========================================================================== */

.bf-refund {
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px solid var(--line-soft);
}

.bf-refund-head {
    font-size: 11px; font-weight: 600; letter-spacing: .04em;
    text-transform: uppercase; color: var(--text-4);
    margin-bottom: 8px;
}

/* The amount belongs to the option above it, so it is indented to the radio's
   label rather than starting a new column of its own. The width cap goes on
   the field inside, not on the flex item: capping the item lets it sit beside
   the radio instead of under it. */
.bf-refund-amount { margin: 2px 0 10px 32px; }
.bf-refund-amount .mud-input-control { max-width: 260px; }

.bf-refund-note { color: var(--text-3); }

/* On the folder, an open refund sits between the facts and the itinerary:
   past the header somebody skims, ahead of the detail they came for. */
.bf-refund-open { margin: 0 0 16px; }
.bf-refund-open .tnx-btn { margin-left: auto; }

/* MudBlazor lays radios out in a wrapping row, which turns three sentences
   into a paragraph. One choice per line: each child of the group takes the
   full width, so the row wraps after every one. */
.bf-refund .mud-radio-group > * { flex: 0 0 100%; }

/* Its indent sits outside the flex basis, so trim the basis by the same
   amount or the group overflows by exactly one indent. */
.bf-refund .mud-radio-group > .bf-refund-amount { flex-basis: calc(100% - 32px); }
.bf-refund .mud-radio { align-items: flex-start; }

/* ===========================================================================
   Administration                                              added 2026-09-19
   ---------------------------------------------------------------------------
   Users and roles under Settings, an agency's own page, and the agency portal.
   =========================================================================== */

/* A card's heading row: title, a quiet subtitle, then the buttons. */
.tnx-list-head {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 12px 14px 10px;
}
.tnx-list-title { font-size: 13.5px; font-weight: 700; color: var(--text); }
.tnx-list-sub { font-size: 12px; color: var(--text-3); }
.tnx-row-actions { display: inline-flex; gap: 6px; }
.tnx-list-head .sp, .ag-head .sp { flex: 1; }
.tnx-table tr.muted td { color: var(--text-3); }

/* Label / value pairs inside dialogs. */
.tnx-kv { display: flex; flex-direction: column; gap: 2px; }
.tnx-kv-k { font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--text-4); }
.tnx-kv-v { font-size: 13.5px; color: var(--text); }
.tnx-kv-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.tnx-field-label { font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--text-4); margin: 6px 0 8px; }

/* A set of things to tick. Each is a row the whole width of which is the
   target, with a note beside the name. */
.tnx-checks { display: flex; flex-direction: column; gap: 4px; }
.tnx-check {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 10px; border-radius: 8px;
    border: 1px solid var(--line-soft);
    cursor: pointer; font-size: 13px;
}
.tnx-check:hover { background: var(--fill-hover); }
.tnx-check.on { border-color: var(--accent); background: var(--accent-soft); }
.tnx-check.locked { cursor: default; opacity: .6; }
.tnx-check.locked:hover { background: transparent; }
.tnx-check input { accent-color: var(--accent); width: 15px; height: 15px; flex: none; }
.tnx-check-name { font-weight: 500; }
.tnx-check-note { margin-left: auto; font-size: 11.5px; color: var(--text-4); }
.tnx-check-flag {
    font-size: 10px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
    padding: 1px 6px; border-radius: 4px; background: var(--warn-soft); color: var(--warn);
}

/* Roles: the list down the left, the permissions on the right. */
.tnx-roles { display: grid; grid-template-columns: minmax(220px, 300px) minmax(0, 1fr); gap: 16px; align-items: start; }
.tnx-roles-list { display: flex; flex-direction: column; padding-bottom: 8px; }
.tnx-role {
    display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
    margin: 0 8px; padding: 9px 10px; border-radius: 8px; border: 0;
    background: transparent; text-align: left; cursor: pointer; font: inherit; color: var(--text);
}
.tnx-role:hover { background: var(--fill-hover); }
.tnx-role.on { background: var(--accent-soft); }
.tnx-role-name { font-weight: 600; font-size: 13px; }
.tnx-role-meta { font-size: 11.5px; color: var(--text-3); }
.tnx-role-tag { font-size: 10.5px; color: var(--warn); font-weight: 600; margin-top: 2px; }
.tnx-perm-group { padding: 4px 14px 12px; }
.tnx-perm-cat { font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--text-4); margin: 6px 0 8px; }
.tnx-perm-group .tnx-check { margin-bottom: 4px; }
@media (max-width: 900px) { .tnx-roles { grid-template-columns: 1fr; } }

/* The history list: a dot, a sentence, who and when. */
.tnx-trail { list-style: none; margin: 0; padding: 4px 14px 14px; display: flex; flex-direction: column; gap: 2px; }
.tnx-trail-row { display: flex; gap: 12px; padding: 8px 0; border-top: 1px solid var(--line-soft); }
.tnx-trail-row:first-child { border-top: 0; }
.tnx-trail-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--text-4); margin-top: 7px; }
.tnx-trail-dot.good { background: var(--good); }
.tnx-trail-dot.warn { background: var(--warn); }
.tnx-trail-dot.bad { background: var(--bad); }
.tnx-trail-text { font-size: 13px; line-height: 1.5; color: var(--text); }
.tnx-trail-meta { display: flex; gap: 8px; font-size: 11.5px; color: var(--text-3); margin-top: 2px; }
.tnx-trail-self { color: var(--accent); }

/* The agency page. */
.ag { display: flex; flex-direction: column; gap: 16px; }
.ag-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.ag-who { display: flex; align-items: center; gap: 12px; }
.ag-who .bf-avatar { width: 40px; height: 40px; font-size: 14px; }
.ag-name { margin: 0; font-size: 20px; font-weight: 700; letter-spacing: -.01em; }
.ag-sub { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 12px; color: var(--text-3); margin-top: 2px; }
.ag-sub a { color: var(--accent); text-decoration: none; }
.ag-status { display: flex; gap: 6px; }
.ag-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; align-items: start; }
@media (max-width: 900px) { .ag-grid { grid-template-columns: 1fr; } }
.ag-money { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; padding: 4px 14px 16px; }
.ag-fig dt { font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--text-4); }
.ag-fig dd { margin: 3px 0 0; font-size: 14px; font-weight: 500; }
.ag-fig-lead dd { font-size: 18px; font-weight: 700; }
.ag-fig dd.bad { color: var(--bad); }
.ag-products { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 6px; padding: 4px 14px 14px; }
.ag-products .tnx-check { padding: 7px 9px; }

/* The portal rail says what is not here yet, rather than being oddly short. */
.tnx-rail-note { margin: auto 12px 14px; font-size: 11px; line-height: 1.5; color: var(--text-4); }

/* The portal's own door: the same form, marked as the agency's. */
.tnx-signin-tag {
    margin-left: auto; font-size: 10.5px; font-weight: 600; letter-spacing: .05em;
    text-transform: uppercase; color: var(--accent);
    background: var(--accent-soft); padding: 2px 8px; border-radius: 999px;
}
.tnx-signin-foot { margin: 18px 0 0; font-size: 12.5px; color: var(--text-3); text-align: center; }
.tnx-signin-foot a { color: var(--accent); }

/* The services being excused from the non-refundable rule, in the dialog that
   asks why (D-133). */
.nr-list { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.nr-list li { display: flex; align-items: center; gap: 8px; font-size: 13px; }

/* ==========================================================================
   The online portal
   ==========================================================================
   An agency's search results. Deliberately not the back office's table: these
   are things being chosen between, not records being worked through, so each
   one is a block with its price set apart on the right where the eye goes
   last. Nothing here carries a supplier's name or a cost -- see
   TraveNexus.Web.Portal.IPortalPricing and D-125. */

.pt-results { display: flex; flex-direction: column; }

.pt-result {
    display: flex; align-items: stretch; gap: 16px;
    padding: 13px 16px;
    border-top: 1px solid var(--line-row);
}
.pt-result:first-child { border-top: 0; }
.pt-result:hover { background: var(--surface-sunken); }

/* Still readable, still priced, just not buyable by this account. Hiding it
   would leave an agency wondering what it is missing; greying the whole row
   would make the terms hard to read, and the terms are the reason. */
.pt-result.blocked .pt-result-name,
.pt-result.blocked .pt-result-buy { opacity: .6; }

.pt-result-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }

.pt-result-name { font-size: 13.5px; font-weight: 700; letter-spacing: -.015em; }

.pt-result-sub {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    font-size: 11.5px; color: var(--text-2);
}
.pt-result-sub > * + *::before {
    content: "·"; margin-right: 8px; color: var(--text-4);
}

.pt-stars { color: var(--warn); letter-spacing: .5px; }

.pt-includes { display: flex; flex-wrap: wrap; gap: 4px; }

.pt-include {
    padding: 1px 7px;
    border-radius: 4px;
    background: var(--fill);
    font-size: 10.5px; font-weight: 600; color: var(--text-2);
}

.pt-terms { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }

.pt-terms-note { font-size: 11px; color: var(--text-3); }

/* The one refusal an agency reads most often, so it says what to do about it
   rather than only that the answer is no (D-133). */
.pt-refused {
    margin-top: 2px; padding: 6px 9px;
    border-radius: 6px;
    background: var(--bad-soft);
    font-size: 11.5px; font-weight: 600; color: var(--bad);
}

.pt-result-buy {
    flex: none; width: 150px;
    display: flex; flex-direction: column; align-items: flex-end; justify-content: center; gap: 4px;
    padding-left: 16px;
    border-left: 1px solid var(--line-row);
    text-align: right;
}

.pt-result-basis { font-size: 10.5px; color: var(--text-3); }

/* On a narrow screen the price sits under what it is for, rather than in a
   column squeezed to nothing. */
@media (max-width: 720px) {
    .pt-result { flex-direction: column; gap: 10px; }
    .pt-result-buy {
        width: auto;
        flex-direction: row; align-items: center; justify-content: space-between;
        padding-left: 0; padding-top: 10px;
        border-left: 0; border-top: 1px solid var(--line-row);
    }
}

/* Checkout. Narrower than the results list on purpose: this is one thing being
   read carefully, not many being compared. */

.pt-checkout {
    display: flex; flex-direction: column; gap: 12px;
    max-width: 1180px;
}

.pt-summary { display: flex; align-items: flex-start; gap: 16px; }
.pt-summary-main { flex: 1; min-width: 0; }
.pt-summary-price { flex: none; text-align: right; }

/* Something moved between searching and here. Loud enough not to be scrolled
   past, because agreeing to a price nobody read is the whole thing this
   prevents. */
.pt-changed {
    display: flex; align-items: flex-start; gap: 9px;
    padding: 10px 13px;
    border-radius: 9px;
    background: var(--warn-soft);
    color: var(--warn);
    font-size: 12.5px; line-height: 1.5;
}
.pt-changed strong { font-weight: 700; }
.pt-changed .tnx-money { color: inherit; }

.pt-checkout-foot {
    display: flex; align-items: center; gap: 10px;
    padding: 13px 16px;
    border-radius: 11px;
    background: var(--surface);
    box-shadow: var(--card-shadow);
    position: sticky; bottom: 12px;
}

.pt-smallprint { margin: 0; font-size: 11px; color: var(--text-3); line-height: 1.5; }

/* Confirmed. The one screen in the portal allowed to breathe. */
.pt-done { text-align: center; padding: 28px 24px; }

.pt-done-mark {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; margin-bottom: 12px;
    border-radius: 50%;
    background: var(--good-soft); color: var(--good);
}

.pt-done-facts { max-width: 340px; margin: 16px auto 0; text-align: left; }

.pt-done-actions { display: flex; justify-content: center; gap: 8px; margin-top: 18px; }

@media (max-width: 560px) {
    .pt-summary { flex-direction: column; }
    .pt-summary-price { text-align: left; }
    .pt-checkout-foot { flex-wrap: wrap; position: static; }
}

/* ==========================================================================
   The portal's search panel
   ==========================================================================
   Where, when, who, go -- on one line, at the size of something typed a hundred
   times a day rather than the compact scale of the back office. Everything
   optional lives underneath, folded, so the line stays the line. */

.pt-panel { padding: 13px 14px 12px; }

.pt-hunt { display: flex; align-items: stretch; gap: 8px; flex-wrap: wrap; }

/* A labelled box. The label sits inside it rather than above, so the row reads
   as one control per field instead of two rows of things. */
.pt-box {
    position: relative;
    display: flex; flex-direction: column; justify-content: center; gap: 1px;
    min-width: 150px; min-height: 52px;
    padding: 7px 11px;
    border: 1px solid var(--line); border-radius: 9px;
    background: var(--surface);
}
.pt-box.grow { flex: 1 1 240px; }
.pt-box:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

.pt-box > span:first-child {
    font-size: 10.5px; font-weight: 600; color: var(--text-3); letter-spacing: 0;
}

.pt-inp {
    width: 100%; min-width: 0;
    border: 0; padding: 0; background: transparent;
    color: var(--text); font-family: inherit; font-size: 14px; font-weight: 600;
}
.pt-inp:focus { outline: 0; }
.pt-inp::placeholder { color: var(--text-4); font-weight: 500; }
.pt-inp[type="date"] { font-variant-numeric: tabular-nums; }

.pt-go { height: auto; min-height: 52px; padding: 0 26px; font-size: 14px; }

/* Who is going: read as a sentence, changed in a panel. */
.pt-who { min-width: 175px; }

.pt-who-button {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    width: 100%; padding: 0; border: 0; background: transparent;
    color: var(--text); font-family: inherit; font-size: 14px; font-weight: 600;
    cursor: pointer;
}
.pt-who.open { border-color: var(--accent); }
.pt-who.open .pt-who-button svg { transform: rotate(180deg); }
.pt-who-button svg { color: var(--text-3); transition: transform .15s; }

.pt-who-panel {
    position: absolute; z-index: 30; top: calc(100% + 6px); right: 0;
    width: 290px; padding: 12px;
    border: 1px solid var(--line); border-radius: 11px;
    background: var(--surface);
    box-shadow: 0 12px 28px rgba(16, 24, 40, .16);
    display: flex; flex-direction: column; gap: 10px;
    cursor: default;
}

.pt-who-room { display: flex; flex-direction: column; gap: 7px; }
.pt-who-room + .pt-who-room { padding-top: 10px; border-top: 1px solid var(--line-row); }

.pt-who-room-head { display: flex; align-items: center; gap: 8px; font-size: 12px; }

.pt-who-drop {
    margin-left: auto; border: 0; padding: 0; background: transparent;
    color: var(--bad); font-family: inherit; font-size: 11px; font-weight: 600;
    cursor: pointer;
}

.pt-who-line {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    font-size: 13px;
}

/* Minus, the figure, plus. Faster than typing and impossible to type nonsense
   into, which a number box is not. */
.pt-step { display: flex; align-items: center; gap: 2px; }
.pt-step button {
    width: 26px; height: 26px;
    border: 1px solid var(--line); border-radius: 7px;
    background: var(--surface); color: var(--text);
    font-family: inherit; font-size: 14px; line-height: 1;
    cursor: pointer;
}
.pt-step button:hover:not(:disabled) { background: var(--fill); }
.pt-step button:disabled { color: var(--text-4); cursor: default; }
.pt-step b { min-width: 24px; text-align: center; font-size: 13px; font-weight: 700; }

.pt-who-ages { display: flex; flex-wrap: wrap; gap: 6px; }
.pt-who-ages label { display: flex; flex-direction: column; gap: 2px; }
.pt-who-ages span { font-size: 10px; color: var(--text-3); }
.pt-who-ages select { width: 84px; }

.pt-who-foot { display: flex; align-items: center; gap: 8px; padding-top: 4px; }

/* Additional parameters: a disclosure, not a second form. */
.pt-more {
    display: inline-flex; align-items: center; gap: 7px;
    margin-top: 11px; padding: 0; border: 0; background: transparent;
    color: var(--text-2); font-family: inherit; font-size: 12px; font-weight: 600;
    cursor: pointer;
}
.pt-more:hover { color: var(--text); }
.pt-more svg { transition: transform .15s; }
.pt-more.open svg { transform: rotate(180deg); }

.pt-more-panel {
    display: flex; align-items: flex-end; flex-wrap: wrap; gap: 14px;
    margin-top: 10px; padding-top: 12px;
    border-top: 1px solid var(--line-row);
}

.pt-more-group { display: flex; flex-direction: column; gap: 5px; }
.pt-more-group > span {
    font-size: 10.5px; font-weight: 600; color: var(--text-3);
}

/* A field with a cross to empty it, for the one that is sometimes required and
   sometimes wrong. */
.pt-clearable { display: flex; align-items: center; gap: 6px; }
.pt-clearable button {
    border: 0; padding: 0; background: transparent;
    color: var(--text-4); font-size: 13px; line-height: 1; cursor: pointer;
}
.pt-clearable button:hover { color: var(--bad); }

.pt-check {
    display: inline-flex; align-items: center; gap: 7px;
    height: 30px;
    font-size: 12.5px; color: var(--text-2); cursor: pointer;
}
.pt-check input { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }

@media (max-width: 720px) {
    .pt-box, .pt-box.grow { flex: 1 1 100%; min-width: 0; }
    .pt-go { flex: 1 1 100%; }
    .pt-who-panel { right: auto; left: 0; width: 100%; }
}

/* The house chevron points right. A disclosure wants it pointing down when
   shut and up when open, so both are turned rather than a second icon added. */
.pt-who-button svg, .pt-more svg { transform: rotate(90deg); }
.pt-who.open .pt-who-button svg, .pt-more.open svg { transform: rotate(-90deg); }

/* Saying it in words. Sits under the form it fills, not above it: the form is
   what gets searched, and this is one way of getting there. */

.pt-smart { display: flex; align-items: stretch; gap: 8px; margin-top: 10px; }

.pt-smart .pt-box { border-style: dashed; }
.pt-smart .pt-box:focus-within { border-style: solid; }

.pt-read { height: auto; min-height: 52px; padding: 0 16px; white-space: nowrap; }

/* What it made of it, and what it could not. Quiet: these are notes, not
   errors -- the form above already shows what was understood. */
.pt-smart-said {
    display: flex; flex-direction: column; gap: 3px;
    margin-top: 8px; padding: 9px 12px;
    border-radius: 8px;
    background: var(--fill);
    font-size: 11.5px; line-height: 1.5; color: var(--text-2);
}

@media (max-width: 720px) {
    .pt-smart { flex-direction: column; }
    .pt-read { min-height: 40px; }
}

/* ------------------------------------------------------------------
   Flights

   A journey, then the fares it is sold on. Deliberately plain: the
   design pass on this portal comes once every product is present.
   ------------------------------------------------------------------ */
.pt-fl-row { margin-bottom: 8px; }

.pt-swap {
    align-self: center;
    width: 26px; height: 26px; flex: 0 0 26px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--line); border-radius: 50%;
    background: var(--surface); color: var(--text-2);
    font-size: 13px; cursor: pointer;
}
.pt-swap:hover { border-color: var(--accent); color: var(--accent); }

.pt-fl {
    display: flex; flex-direction: column;
    border-top: 1px solid var(--line-row);
    padding: 12px 14px;
}
.pt-fl:first-child { border-top: 0; }

.pt-fl-main { display: flex; flex-direction: column; gap: 8px; }

.pt-fl-air {
    display: flex; align-items: baseline; gap: 8px;
    font-size: 13px; letter-spacing: -.01em;
}
.pt-fl-air span { font-size: 11px; color: var(--text-3); }

.pt-fl-leg {
    display: flex; align-items: center; gap: 14px;
    padding: 6px 0;
}

.pt-fl-at { display: flex; flex-direction: column; min-width: 54px; }
.pt-fl-at b { font-size: 15px; font-weight: 700; line-height: 1.2; }
.pt-fl-at span { font-size: 10.5px; color: var(--text-3); }

.pt-fl-next { font-size: 10px; font-weight: 600; color: var(--warn, var(--text-3)); }

.pt-fl-mid {
    flex: 1 1 auto; min-width: 90px;
    display: flex; flex-direction: column; align-items: center; gap: 3px;
}
.pt-fl-line {
    width: 100%; height: 1px;
    background: var(--line);
}
.pt-fl-dur, .pt-fl-stops { font-size: 10.5px; color: var(--text-3); }

.pt-fl-fares {
    display: flex; flex-wrap: wrap; gap: 8px;
    margin-top: 10px;
}

.pt-fl-fare {
    flex: 1 1 180px; min-width: 0;
    display: flex; flex-direction: column; gap: 6px;
    padding: 10px 11px;
    border: 1px solid var(--line); border-radius: 8px;
    background: var(--surface-sunken);
}
.pt-fl-fare.blocked { opacity: .6; }

.pt-fl-fare-name { font-size: 12px; font-weight: 700; }

.pt-fl-fare-has {
    display: flex; flex-direction: column; gap: 2px;
    font-size: 10.5px; color: var(--text-2);
}

.pt-fl-fare-buy {
    display: flex; flex-direction: column; gap: 5px;
    margin-top: auto;
    align-items: flex-start;
}

@media (max-width: 720px) {
    .pt-fl-leg { gap: 8px; }
    .pt-fl-fare { flex: 1 1 100%; }
}

/* ------------------------------------------------------------------
   Who is travelling

   A block a person, headed by who they are. One row of fields: five
   where something is ticketed, three where it is not, and the passport
   folded away underneath because most of what is sold never asks for
   it.
   ------------------------------------------------------------------ */
.pt-pax { display: flex; flex-direction: column; gap: 6px; }
.pt-pax + .pt-pax { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line-row); }

/* Who the block is for. Derived from the party that was priced, so it is
   stated rather than given a column somebody would try to change. */
.pt-pax-who {
    font-size: 12.5px; font-weight: 700; letter-spacing: -.01em;
    color: var(--text);
}

.pt-pax-row { display: grid; gap: 8px; align-items: end; }
.pt-pax-row.plain { grid-template-columns: 96px minmax(0, 1fr) minmax(0, 1fr); }
.pt-pax-row.ticketed {
    grid-template-columns:
        82px minmax(0, 1fr) minmax(0, 1fr) 118px 148px;
}

.pt-pax-fld { display: flex; flex-direction: column; gap: 3px; min-width: 0; }

.pt-pax-fld > span:first-child {
    font-size: 10.5px; font-weight: 600; letter-spacing: .02em;
    color: var(--text-3);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pt-pax-fld > span .req { color: var(--bad); margin-left: 2px; }

.pt-doc-open {
    align-self: flex-start;
    display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 9px;
    border: 1px solid var(--line); border-radius: 7px;
    background: var(--surface);
    font-size: 11.5px; font-weight: 600; color: var(--text-2);
    cursor: pointer;
}
.pt-doc-open:hover { border-color: var(--accent); color: var(--text); }
.pt-doc-open svg:last-of-type {
    color: var(--text-3); transition: transform .15s;
    transform: rotate(90deg);
}
.pt-doc-open.open svg:last-of-type { transform: rotate(-90deg); }

.pt-doc {
    display: grid; gap: 8px;
    grid-template-columns: minmax(0, 1.4fr) 90px 90px 148px;
    padding: 10px 11px;
    border: 1px solid var(--line); border-radius: 8px;
    background: var(--surface-sunken);
}

/* Three abreast rather than five, and every column the same width: a
   gender select under an 82px title column would be unusable. */
@media (max-width: 920px) {
    .pt-pax-row.ticketed { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 680px) {
    .pt-pax-row.plain,
    .pt-pax-row.ticketed,
    .pt-doc { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* ==========================================================================
   The portal's results

   A rail that narrows what is in hand, a strip that answers "which one",
   and a card a journey. The agent lives here all day, so density beats
   decoration: nothing is bigger than the job it does, and the three things
   they actually read -- the time, the price, and whether it can be given
   back -- are the three things that carry weight.
   ========================================================================== */
.pt-page { display: flex; flex-direction: column; gap: 12px; }

/* What was asked, once the form has folded away. */
.pt-asked {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 9px 12px;
    border: 1px solid var(--line); border-radius: 11px;
    background: var(--surface);
    box-shadow: var(--card-shadow);
}

.pt-asked-chips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.pt-chip {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 9px;
    border-radius: 999px;
    background: var(--fill);
    font-size: 11.5px; font-weight: 600; color: var(--text-2);
    white-space: nowrap;
}
.pt-chip.strong { background: var(--accent-soft); color: var(--accent); }
.pt-chip svg { opacity: .85; }

.pt-results-layout {
    display: grid;
    grid-template-columns: 232px minmax(0, 1fr);
    gap: 12px;
    align-items: start;
}

/* ---------------------------------------------------------------- the rail */
.pt-rail {
    position: sticky; top: 12px;
    border: 1px solid var(--line); border-radius: 11px;
    background: var(--surface);
    box-shadow: var(--card-shadow);
    overflow: hidden;
}

.pt-rail-head {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 12px;
    background: var(--chrome); color: var(--chrome-text);
    font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}
.pt-rail-head > span:first-child { flex: 1; }

.pt-rail-reset {
    padding: 3px 8px;
    border: 0; border-radius: 999px;
    background: var(--chrome-fill-hi); color: var(--chrome-text);
    font: inherit; font-size: 10px; letter-spacing: .04em;
    cursor: pointer;
}
.pt-rail-reset:hover { background: var(--accent); }

.pt-rail-body {
    display: flex; flex-direction: column;
    max-height: calc(100vh - 150px);
    overflow-y: auto;
}

.pt-rail-group { padding: 11px 12px; border-top: 1px solid var(--line-row); }
.pt-rail-group:first-child { border-top: 0; }

.pt-rail-title {
    margin-bottom: 7px;
    font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    color: var(--text-3);
}

.pt-rail-range { display: flex; align-items: baseline; gap: 6px; font-size: 11.5px; color: var(--text-2); }
.pt-rail-range strong { font-size: 13px; font-weight: 700; color: var(--text); }

.pt-rail-ends {
    display: flex; justify-content: space-between;
    font-size: 10px; color: var(--text-3);
}

.pt-slider { width: 100%; margin: 7px 0 3px; accent-color: var(--accent); }

/* One narrowing: what it is on the left, how many it would leave on the
   right. A count of nought is shown and disabled rather than hidden, so the
   list does not move under somebody as they tick things. */
.pt-tick {
    display: flex; align-items: center; gap: 8px;
    padding: 3.5px 0;
    font-size: 11.5px; color: var(--text-2);
    cursor: pointer;
}
.pt-tick:hover { color: var(--text); }
.pt-tick > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pt-tick > b { font-size: 10.5px; font-weight: 600; color: var(--text-4); }
.pt-tick input { accent-color: var(--accent); margin: 0; }
.pt-tick.empty { opacity: .45; cursor: default; }

/* ------------------------------------------------------------- the answers */
.pt-found { display: flex; flex-direction: column; gap: 10px; min-width: 0; }

.pt-sorts {
    display: flex; align-items: stretch; gap: 8px; flex-wrap: wrap;
    padding: 8px;
    border: 1px solid var(--line); border-radius: 11px;
    background: var(--surface);
    box-shadow: var(--card-shadow);
}

.pt-sort {
    flex: 1 1 150px; min-width: 0; max-width: 240px;
    display: flex; align-items: center; gap: 9px;
    padding: 8px 11px;
    border: 1px solid var(--line); border-radius: 9px;
    background: var(--surface);
    text-align: left; cursor: pointer;
    transition: border-color .12s, background .12s;
}
.pt-sort:hover { border-color: var(--accent); }
.pt-sort.on { border-color: var(--accent); background: var(--accent-soft); }

.pt-sort-mark {
    display: flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; flex: 0 0 28px;
    border-radius: 8px;
    background: var(--fill); color: var(--text-3);
}
.pt-sort.on .pt-sort-mark { background: var(--accent); color: var(--accent-on); }

.pt-sort-said { display: flex; flex-direction: column; gap: 1px; min-width: 0; }

.pt-sort-name {
    font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    color: var(--text-3);
}
.pt-sort.on .pt-sort-name { color: var(--accent); }
.pt-sort-value { font-size: 15px; font-weight: 800; color: var(--text); }
.pt-sort-note { font-size: 10.5px; color: var(--text-3); }

.pt-found-count {
    display: flex; align-items: center; gap: 4px;
    padding: 0 6px;
    font-size: 11.5px; color: var(--text-3);
}
.pt-found-count strong { font-size: 13px; color: var(--text); }

/* --------------------------------------------------------------- a journey */
.pt-trip { overflow: hidden; }

.pt-trip-head {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 11px 14px;
    border-bottom: 1px solid var(--line-row);
}

/* The airline's two letters, in the product family's hue. A real logo would
   mean fetching one per carrier from somewhere; two letters are what an agent
   says out loud anyway. */
.pt-mark {
    display: flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; flex: 0 0 34px;
    border-radius: 9px;
    background: color-mix(in srgb, var(--mark) 12%, transparent);
    color: var(--mark);
    font-size: 12px; font-weight: 800; letter-spacing: .02em;
}

.pt-trip-named { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.pt-trip-airline { font-size: 13.5px; font-weight: 700; letter-spacing: -.015em; }
.pt-trip-numbers { font-size: 10.5px; color: var(--text-3); }

.pt-trip-from { display: flex; align-items: baseline; gap: 5px; }
.pt-trip-from > span { font-size: 10.5px; color: var(--text-3); }

.pt-trip-legs { display: flex; flex-direction: column; }

.pt-leg {
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr) 96px;
    align-items: center; gap: 14px;
    padding: 11px 14px;
}
.pt-leg + .pt-leg { border-top: 1px dashed var(--line); }

.pt-leg-end { display: flex; flex-direction: column; gap: 1px; }
.pt-leg-end.right { text-align: right; }
.pt-leg-end b { font-size: 17px; font-weight: 700; line-height: 1.15; letter-spacing: -.02em; }
.pt-leg-port { font-size: 11.5px; font-weight: 600; color: var(--text-2); }
.pt-leg-day { font-size: 10px; color: var(--text-4); }
.pt-leg-next { font-size: 10px; font-weight: 700; color: var(--warn); vertical-align: super; }

.pt-leg-path { display: flex; flex-direction: column; align-items: center; gap: 3px; width: 100%; }
.pt-leg-took { font-size: 11px; font-weight: 600; color: var(--text-2); }

.pt-leg-line {
    position: relative;
    display: flex; align-items: center; justify-content: space-between;
    width: 100%; height: 1px;
    background: var(--line);
}
.pt-leg-dot, .pt-leg-stop { width: 5px; height: 5px; border-radius: 50%; background: var(--text-4); }
.pt-leg-stop { background: var(--warn); }
.pt-leg-plane {
    display: flex; align-items: center;
    padding-left: 3px;
    background: var(--surface);
    color: var(--svc-flight);
}

.pt-leg-stops { font-size: 10.5px; color: var(--warn); }
.pt-leg-stops.direct { color: var(--good); }

/* ------------------------------------------------------------------- fares */
.pt-fares { background: var(--surface-sunken); border-top: 1px solid var(--line-row); }

.pt-fares-head {
    padding: 7px 14px;
    font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    color: var(--text-3);
}

.pt-fare {
    display: grid;
    grid-template-columns: 190px minmax(0, 1fr) 120px 86px;
    align-items: center; gap: 12px;
    padding: 9px 14px;
    border-top: 1px solid var(--line-row);
}
.pt-fare:hover { background: var(--surface-hover); }
.pt-fare.blocked { opacity: .62; }

.pt-fare-named { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.pt-fare-name { font-size: 12.5px; font-weight: 700; }

.pt-fare-has { display: flex; flex-wrap: wrap; gap: 4px; }

/* What is in the fare and what is not, said the same way. A list of only the
   good news makes the cheap fare look like the dear one. */
.pt-has {
    position: relative;
    display: inline-flex; align-items: center; justify-content: center; gap: 3px;
    min-width: 27px; height: 24px; padding: 0 6px;
    border: 1px solid transparent; border-radius: 6px;
    font-size: 10px; font-weight: 700;
    background: var(--fill); color: var(--text-3);
    cursor: default;
}
.pt-has b { font-weight: 700; letter-spacing: -.01em; }
.pt-has.yes { background: var(--good-soft); color: var(--good); border-color: color-mix(in srgb, var(--good) 18%, transparent); }

/* Not in this fare, and drawn as struck through rather than merely faint.
   Faint reads as unimportant, and a missing checked bag is the opposite of
   unimportant -- it is the whole reason the cheap fare is cheap. */
.pt-has.no {
    background: var(--surface);
    border-color: var(--line);
    color: var(--text-3);
}
.pt-has.no::after {
    content: ''; position: absolute; left: 3px; right: 3px; top: 50%;
    height: 1.5px; border-radius: 1px;
    background: var(--bad); opacity: .55;
    transform: rotate(-20deg);
}

/* The wording is on hover and for a screen reader, never only in a shape. */
.tnx-sr {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap; border: 0;
}

.pt-fare-buy { display: flex; flex-direction: column; align-items: flex-end; gap: 1px; }
.pt-fare-basis { font-size: 10px; color: var(--text-3); }

.pt-fare > .tnx-btn { justify-self: end; }
.pt-fare > .pt-refused { grid-column: 1 / -1; }

/* ----------------------------------------------- a bed, a transfer, a tour */
.pt-rows { display: flex; flex-direction: column; overflow: hidden; }

.pt-row {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 12px 14px;
    border-top: 1px solid var(--line-row);
}
.pt-row:first-child { border-top: 0; }
.pt-row:hover { background: var(--surface-hover); }
.pt-row.blocked .pt-row-name, .pt-row.blocked .pt-row-buy { opacity: .62; }

.pt-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.pt-row-name { font-size: 13.5px; font-weight: 700; letter-spacing: -.015em; }

.pt-row-sub {
    display: flex; flex-wrap: wrap; gap: 8px;
    font-size: 11.5px; color: var(--text-2);
}
.pt-row-sub > * + *::before { content: '\00b7'; margin-right: 8px; color: var(--text-4); }

.pt-row-buy {
    display: flex; flex-direction: column; align-items: flex-end; gap: 5px;
    min-width: 120px;
}

.tnx-link {
    padding: 0; border: 0; background: none;
    font: inherit; color: var(--accent); text-decoration: underline;
    cursor: pointer;
}

@media (max-width: 1100px) {
    .pt-results-layout { grid-template-columns: minmax(0, 1fr); }
    .pt-rail { position: static; }
    .pt-rail-body { max-height: none; flex-direction: row; flex-wrap: wrap; }
    .pt-rail-group { flex: 1 1 200px; border-top: 0; border-left: 1px solid var(--line-row); }
    .pt-rail-group:first-child { border-left: 0; }
}

@media (max-width: 760px) {
    .pt-fare { grid-template-columns: minmax(0, 1fr) auto; }
    .pt-fare-has { grid-column: 1 / -1; }
    .pt-leg { grid-template-columns: 76px minmax(0, 1fr) 76px; gap: 8px; }
    .pt-row { flex-wrap: wrap; }
    .pt-row-buy { flex-direction: row; align-items: center; width: 100%; justify-content: space-between; }
}

.pt-ask-head { display: flex; align-items: center; gap: 12px; }
.pt-ask-head h1 { flex: 1; margin: 0; }

/* The one refusal that applies to every blocked fare on a card, said once. */
.pt-fares-note {
    display: flex; align-items: center; gap: 7px;
    padding: 8px 14px;
    border-top: 1px solid var(--line-row);
    background: var(--bad-soft);
    font-size: 11.5px; color: var(--bad);
}
.pt-fares-note svg { flex: 0 0 auto; opacity: .8; }

/* ==========================================================================
   Checking out

   Two columns: what is being bought on the left, what is being agreed to on
   the right. The summary follows the page down, because the thing somebody
   is committing to and the button that commits should never be a scroll
   apart.
   ========================================================================== */
.pt-book {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 290px;
    gap: 12px;
    align-items: start;
}

.pt-book-main { display: flex; flex-direction: column; gap: 12px; min-width: 0; }

.pt-trip-terms {
    padding: 11px 14px;
    font-size: 11.5px; color: var(--text-2);
}

/* The flight numbers under the path, where the route is already drawn. */
.pt-leg-which { font-size: 10px; color: var(--text-4); text-align: center; }

/* ------------------------------------------------------- what the fare is */
.pt-fare-detail {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0;
    overflow: hidden;
}

.pt-detail {
    display: flex; flex-direction: column; gap: 5px;
    padding: 12px 14px;
    border-left: 1px solid var(--line-row);
}
.pt-detail:first-child { border-left: 0; }

.pt-detail-head {
    display: flex; align-items: center; gap: 6px;
    margin-bottom: 2px;
    font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    color: var(--text-3);
}

.pt-detail-line {
    display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
    font-size: 11.5px;
}
.pt-detail-line > span { color: var(--text-3); }
.pt-detail-line > b { font-weight: 600; color: var(--text); text-align: right; }

/* What is not in the fare reads as not in the fare, rather than as a value. */
.pt-detail-line > b.none { color: var(--text-4); font-weight: 500; }

.pt-detail-note {
    margin-top: 2px;
    font-size: 10.5px; line-height: 1.45; color: var(--text-3);
}

/* ------------------------------------------------------------- the summary */
.pt-book-rail { position: sticky; top: 12px; }

.pt-rail-card { display: flex; flex-direction: column; padding: 14px; gap: 11px; }

.pt-rail-top { display: flex; flex-direction: column; gap: 2px; }
.pt-rail-name { font-size: 15px; font-weight: 800; letter-spacing: -.02em; }
.pt-rail-rate { font-size: 11.5px; color: var(--text-2); }

.pt-rail-trip {
    display: flex; flex-direction: column; gap: 6px;
    padding: 10px 11px;
    border-radius: 9px;
    background: var(--surface-sunken);
}

.pt-rail-hop { display: flex; flex-direction: column; gap: 1px; }
.pt-rail-ports { font-size: 12.5px; font-weight: 700; letter-spacing: -.01em; }
.pt-rail-when { font-size: 10.5px; color: var(--text-3); }

.pt-rail-facts { display: flex; flex-direction: column; gap: 6px; margin: 0; }
.pt-rail-facts > div {
    display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
}
.pt-rail-facts dt { font-size: 11.5px; color: var(--text-3); }
.pt-rail-facts dd {
    margin: 0;
    font-size: 11.5px; font-weight: 600; color: var(--text); text-align: right;
}
.pt-rail-facts dd.yes { color: var(--good); }
.pt-rail-facts dd.no { color: var(--bad); }

.pt-rail-total {
    display: flex; flex-direction: column; gap: 1px;
    padding-top: 10px;
    border-top: 1px solid var(--line-row);
}
.pt-rail-total > span { font-size: 10.5px; color: var(--text-3); }

/* What is still missing, said before the button rather than after it. */
.pt-rail-missing {
    padding: 8px 10px;
    border-radius: 8px;
    background: var(--warn-soft);
    font-size: 11px; line-height: 1.45; color: var(--warn);
}

.pt-rail-go { width: 100%; justify-content: center; }
.pt-rail-again { width: 100%; justify-content: center; }

.pt-rail-card .pt-smallprint { margin: 0; font-size: 10.5px; line-height: 1.5; }

@media (max-width: 1000px) {
    .pt-book { grid-template-columns: minmax(0, 1fr); }
    .pt-book-rail { position: static; }
    .pt-fare-detail { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .pt-detail:nth-child(3) { border-left: 0; }
    .pt-detail:nth-child(n + 3) { border-top: 1px solid var(--line-row); }
}

@media (max-width: 620px) {
    .pt-fare-detail { grid-template-columns: minmax(0, 1fr); }
    .pt-detail { border-left: 0; border-top: 1px solid var(--line-row); }
    .pt-detail:first-child { border-top: 0; }
}

/* ==========================================================================
   The portal's search panel

   Four questions along the top, then one row of fields that each say three
   things: what they are for, what is in them, and what that works out to.
   A date box reads back as digits, and digits do not say whether a flight
   lands on a Saturday.
   ========================================================================== */
/* Not 'overflow: hidden'. The card's rounded top is the tab strip's job,
   because the travellers popover hangs out of the bottom of this card and a
   card that clips it swallows half the control. */
.pt-panel { padding: 0; }

.pt-panel-body { padding: 14px; display: flex; flex-direction: column; }

/* ---------------------------------------------------------------- the tabs */
.pt-tabs {
    display: flex; align-items: stretch; gap: 2px;
    padding: 0 6px;
    border-radius: 11px 11px 0 0;
    background: var(--surface-sunken);
    border-bottom: 1px solid var(--line);
    overflow-x: auto;
}

.pt-tab {
    position: relative;
    display: inline-flex; align-items: center; gap: 7px;
    padding: 12px 14px 11px;
    border: 0; background: none;
    font: inherit; font-size: 12.5px; font-weight: 600;
    color: var(--text-2); white-space: nowrap;
    cursor: pointer;
}
.pt-tab svg { color: var(--text-3); }
.pt-tab:hover { color: var(--text); }
.pt-tab:hover svg { color: var(--text-2); }

.pt-tab.on { color: var(--accent); font-weight: 700; background: var(--surface); }
.pt-tab.on svg { color: var(--accent); }
.pt-tab.on::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: -1px;
    height: 2px; background: var(--accent);
}

/* ------------------------------------------------------- the trip segments */
.pt-seg {
    display: inline-flex; align-self: flex-start; gap: 2px;
    margin-bottom: 10px; padding: 3px;
    border-radius: 9px;
    background: var(--fill);
}

.pt-seg-item {
    padding: 6px 15px;
    border: 0; border-radius: 7px;
    background: none;
    font: inherit; font-size: 12px; font-weight: 600;
    color: var(--text-2);
    cursor: pointer;
}
.pt-seg-item:hover { color: var(--text); }
.pt-seg-item.on {
    background: var(--surface); color: var(--accent); font-weight: 700;
    box-shadow: 0 1px 2px rgba(19, 24, 32, .08);
}

/* ------------------------------------------------------------- the fields */
.pt-fields { display: flex; align-items: stretch; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.pt-fields:last-of-type { margin-bottom: 0; }

.pt-field {
    position: relative;
    display: flex; align-items: center; gap: 10px;
    min-height: 46px; padding: 5px 11px;
    border: 1px solid var(--line); border-radius: 10px;
    background: var(--surface);
    cursor: text;
}
.pt-field.grow { flex: 1 1 190px; min-width: 0; }
.pt-field.dated { flex: 0 0 auto; }
.pt-field:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.pt-field > svg:first-child { flex: 0 0 auto; color: var(--text-3); }

.pt-field-said { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }

.pt-field-label {
    font-size: 10.5px; font-weight: 600; letter-spacing: .01em;
    color: var(--text-3);
    white-space: nowrap;
}

.pt-field-value {
    width: 100%; min-width: 0; padding: 0; border: 0; background: none;
    font: inherit; font-size: 13.5px; font-weight: 700; letter-spacing: -.01em;
    color: var(--text);
}
.pt-field-value:focus { outline: none; }
.pt-field-value::placeholder { font-weight: 500; color: var(--text-4); }

/* What the date works out to. Never the control itself -- somebody who
   changes the day of the week has to change the date. */
.pt-field-sub {
    font-size: 10px; color: var(--text-3);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.pt-field-clear {
    display: flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; flex: 0 0 20px;
    border: 0; border-radius: 50%;
    background: var(--fill); color: var(--text-3);
    cursor: pointer;
}
.pt-field-clear:hover { background: var(--bad-soft); color: var(--bad); }

/* A native select laid over the whole card, so the card is the control and
   the browser still draws the list it knows how to draw. */
.pt-field.picked { cursor: pointer; }
.pt-field-pick {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    opacity: 0; cursor: pointer;
}

.pt-swap {
    align-self: center;
    display: flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; flex: 0 0 34px;
    border: 1px solid var(--line); border-radius: 50%;
    background: var(--surface); color: var(--accent);
    cursor: pointer;
    transition: background .12s, border-color .12s;
}
.pt-swap:hover { background: var(--accent-soft); border-color: var(--accent); }

.pt-go {
    min-height: 46px; padding: 0 20px;
    gap: 8px;
    font-size: 13.5px; font-weight: 700;
}

/* The party control, which is a field that opens rather than one that types. */
.pt-field.pt-who { padding: 0; cursor: pointer; min-width: 190px; }
.pt-field.pt-who > svg:first-child { margin-left: 11px; }

.pt-who-button {
    display: flex; align-items: center; gap: 10px;
    flex: 1; min-width: 0;
    padding: 5px 11px 5px 10px;
    border: 0; background: none;
    font: inherit; text-align: left;
    cursor: pointer;
}
.pt-who-button .pt-field-said { flex: 1; }

@media (max-width: 900px) {
    .pt-field.dated { flex: 1 1 160px; }
    .pt-go { flex: 1 1 100%; justify-content: center; }
}

@media (max-width: 620px) {
    .pt-field, .pt-field.grow, .pt-field.dated { flex: 1 1 100%; }
    .pt-swap { align-self: flex-end; }
}

/* The house chevron points right; a thing that opens downward wants it down. */
.pt-field.picked > svg:last-of-type { transform: rotate(90deg); color: var(--text-3); }

/* Sits under the form it belongs to, at the edge somebody reads from. */
.pt-panel-body > .pt-more { align-self: flex-start; }

/* The three-line date field sets the height of its whole row, so its lines
   are measured rather than left to the browser's defaults -- a native date
   input is half a centimetre taller than the text beside it otherwise. */
.pt-field { padding: 4px 11px; min-height: 44px; }
.pt-field-label { line-height: 1.25; }
.pt-field-value { line-height: 1.35; }
.pt-field-sub { line-height: 1.2; }
.pt-field input[type="date"].pt-field-value { height: 19px; }

/* ------------------------------------------------- city or airport, as typed

   A city and an airport are not the same thing and must not look it. LON is
   every London airport and LHR is one of them, and the mistake that matters
   is picking the first while meaning the second. */
.pt-find {
    position: absolute; z-index: 40; top: calc(100% + 5px); left: 0;
    min-width: 100%; max-width: 420px;
    max-height: 310px; overflow-y: auto;
    padding: 4px;
    border: 1px solid var(--line); border-radius: 10px;
    background: var(--surface);
    box-shadow: var(--pop-shadow);
    cursor: default;
}

.pt-find-item {
    display: flex; align-items: center; gap: 10px; width: 100%;
    padding: 7px 8px;
    border: 0; border-radius: 7px;
    background: none;
    font: inherit; text-align: left;
    cursor: pointer;
}
.pt-find-item:hover, .pt-find-item.on { background: var(--accent-soft); }

.pt-find-code {
    display: flex; align-items: center; justify-content: center;
    width: 40px; height: 26px; flex: 0 0 40px;
    border-radius: 6px;
    background: var(--fill); color: var(--text-2);
    font-size: 11px; font-weight: 800; letter-spacing: .02em;
}

/* A whole city wears the accent, so it is never mistaken for one airport. */
.pt-find-code.city { background: var(--accent); color: var(--accent-on); }

.pt-find-said { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.pt-find-name { font-size: 12.5px; font-weight: 600; color: var(--text); }

.pt-find-where {
    display: flex; gap: 6px;
    font-size: 10.5px; color: var(--text-3);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pt-find-where b { color: var(--accent); font-weight: 700; }

/* Setting overflow-x alone leaves overflow-y computed as auto, and the tab
   strip overshoots its own height by the one pixel of the active underline --
   which was enough to put a scrollbar down the side of it. */
.pt-tabs { overflow-y: hidden; }

/* Two lines a field now that nothing carries a third, so the row loses the
   height the weekday under a date was taking. */
.pt-field { min-height: 44px; padding: 5px 11px; }
.pt-field-value { font-size: 13px; }
.pt-field .pt-field-value[type="date"] { height: 18px; }
.pt-go { min-height: 44px; }
.pt-who-button { padding: 5px 11px 5px 10px; }

/* ==========================================================================
   Supplier connections

   One row a connection, and under it — only when asked — what it is allowed
   to sell. The choosing lives beside the row it changes rather than in a
   dialog, because it is the one setting staff touch often and the only one
   that needs no credentials typing.
   ========================================================================== */

/* A sentence above a table, where a note under it would be read too late. */
.tnx-told {
    display: flex; align-items: flex-start; gap: 9px;
    padding: 10px 13px;
    border: 1px solid var(--accent-soft); border-radius: 10px;
    background: var(--accent-soft);
    font-size: 12px; line-height: 1.55; color: var(--text-2);
}
.tnx-told svg { flex: 0 0 auto; margin-top: 2px; color: var(--accent); }

.sc-table td { vertical-align: middle; }

.sc-named { display: flex; align-items: center; gap: 10px; }

/* The three letters this company gave it. Two Amadeus contracts look
   identical in a list until something tells them apart. */
.sc-mark {
    display: flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; flex: 0 0 38px;
    border-radius: 9px;
    background: var(--fill); color: var(--text-2);
    font-size: 11.5px; font-weight: 800; letter-spacing: .03em;
}
.sc-mark.live { background: var(--accent-soft); color: var(--accent); }

.sc-named-said { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.sc-name { font-weight: 600; }

.sc-under {
    display: flex; align-items: center; gap: 6px;
    font-size: 11px; color: var(--text-3);
}

.sc-type { font-size: 12px; color: var(--text-2); }
.sc-when { font-size: 11px; color: var(--text-3); margin-top: 3px; }

.sc-hint { color: var(--text-4); vertical-align: middle; margin-left: 3px; cursor: help; }

/* ------------------------------------------------------- what it may sell */
.sc-services { display: inline-flex; align-items: center; gap: 5px; }

.sc-service {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px;
    border: 1px solid transparent; border-radius: 8px;
    background: var(--fill); color: var(--text-4);
}
.sc-service.on {
    background: var(--good-soft); color: var(--good);
    border-color: color-mix(in srgb, var(--good) 20%, transparent);
}

/* Switched off, as against never offered. The first is a choice somebody
   made and the second is not theirs to make. */
.sc-service.off { background: var(--fill); color: var(--text-3); }
.sc-service.cannot { background: transparent; border-color: var(--line-soft); color: var(--text-4); opacity: .5; }

.sc-more { padding: 0 7px; }
.sc-more svg { transform: rotate(90deg); transition: transform .15s; }
.sc-more.open svg { transform: rotate(-90deg); }

/* ------------------------------------------------------------- the panel */
.sc-panel-row > .sc-panel-cell { padding: 0; background: var(--surface-sunken); }

.sc-panel {
    display: flex; flex-direction: column;
    border-top: 1px solid var(--line);
}

.sc-panel-head { padding: 13px 16px 0; }
.sc-panel-sub { margin-top: 2px; font-size: 11.5px; color: var(--text-3); }

.sc-panel-body {
    display: grid; grid-template-columns: minmax(0, 1fr) 240px; gap: 16px;
    padding: 12px 16px 14px;
}

.sc-choices {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 8px;
    align-content: start;
}

.sc-choice {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 11px;
    border: 1px solid var(--line); border-radius: 10px;
    background: var(--surface);
}
.sc-choice.cannot { opacity: .55; background: var(--surface-sunken); }

.sc-choice-mark {
    display: flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; flex: 0 0 32px;
    border-radius: 8px;
    background: var(--fill); color: var(--text-3);
}
.sc-choice-mark.on { background: var(--good-soft); color: var(--good); }

.sc-choice-said { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.sc-choice-name { font-size: 12.5px; font-weight: 600; }
.sc-choice-note { font-size: 10.5px; color: var(--text-3); }

.sc-facts {
    display: flex; flex-direction: column; gap: 8px; margin: 0;
    padding: 12px 13px;
    border: 1px solid var(--line); border-radius: 10px;
    background: var(--surface);
}
.sc-facts > div { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.sc-facts dt { font-size: 11.5px; color: var(--text-3); }
.sc-facts dd { margin: 0; font-size: 11.5px; font-weight: 600; color: var(--text); text-align: right; }

.sc-panel-foot {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 11px 16px;
    border-top: 1px solid var(--line-row);
    background: var(--surface);
}

.sc-panel-note {
    display: flex; align-items: center; gap: 7px;
    font-size: 11px; color: var(--text-3);
}
.sc-panel-note svg { flex: 0 0 auto; }

/* The switch was drawn for the dark rail, where an off state of white at 16%
   reads. On a white row it is invisible, which on a column headed "in use"
   is the one thing it must never be. */
.tnx-table .tnx-switch, .sc-choice .tnx-switch {
    width: 34px; height: 19px;
    background: var(--fill-hover);
    cursor: pointer;
}
.tnx-table .tnx-switch::after, .sc-choice .tnx-switch::after { width: 15px; height: 15px; }
.tnx-table .tnx-switch.on, .sc-choice .tnx-switch.on { background: var(--accent); }
.tnx-table .tnx-switch.on::after, .sc-choice .tnx-switch.on::after { transform: translateX(15px); }

/* A service the supplier does not offer is not a choice anybody has. */
.tnx-switch:disabled { opacity: .45; cursor: not-allowed; }

@media (max-width: 1000px) {
    .sc-panel-body { grid-template-columns: minmax(0, 1fr); }
}

/* The table needs about a thousand pixels before anything is squeezed. In a
   narrower window it scrolls sideways rather than being clipped by the card:
   a Test button hidden behind a rounded corner is still a Test button somebody
   is looking for. */
.sc-scroll { overflow-x: auto; overflow-y: visible; }
.sc-scroll::-webkit-scrollbar { height: 8px; }
.sc-scroll::-webkit-scrollbar-track { background: var(--surface-sunken); }
.sc-scroll::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }
.sc-scroll::-webkit-scrollbar-thumb:hover { background: var(--text-4); }

/* And a little less of it to need. Ten pixels over on a 1280 window is a
   scrollbar that reads as a fault rather than an offer, so the marks, the
   gaps between the buttons and the room inside each cell each give up a
   little and the table fits a laptop whole. */
.sc-service { width: 26px; height: 26px; }
.sc-services { gap: 4px; }
.sc-mark { width: 34px; height: 34px; flex-basis: 34px; }
.sc-table th, .sc-table td { padding-right: 10px; }
.sc-table .tnx-row-actions { gap: 5px; }

/* ---------------------------------------------------------- fare rules

   The supplier's own terms, which run to paragraphs of booking-system
   shorthand. They used to be printed down the "If plans change" column,
   where they buried the four plain answers above them. A link instead,
   and the whole of what the airline said opens in a dialog. */
.pt-detail-rules {
    display: inline-flex; align-items: center; gap: 5px;
    margin-top: 6px; padding: 0;
    border: 0; background: none;
    font: inherit; font-size: 11px; font-weight: 600;
    color: var(--accent); cursor: pointer;
    text-decoration: underline; text-underline-offset: 2px;
}
.pt-detail-rules:hover { color: var(--accent-strong, var(--accent)); }

/* The same offer inside a notice, where the surrounding text is the warning
   colour and a blue link would read as something else entirely. */
.pt-changed-link {
    display: inline; margin-left: 4px; padding: 0;
    border: 0; background: none;
    font: inherit; font-weight: 700; color: inherit; cursor: pointer;
    text-decoration: underline; text-underline-offset: 2px;
}

.fr-head { margin-bottom: 10px; }
.fr-what { font-size: 14px; font-weight: 700; }
.fr-fare { margin-top: 1px; font-size: 12px; color: var(--text-3); }

/* Scrolls on its own so the Close button stays put. Fare rules can run long
   and a dialog that grows past the screen hides the way out of itself. */
.fr-body {
    max-height: 46vh; overflow-y: auto;
    padding: 12px 13px;
    border: 1px solid var(--line); border-radius: 9px;
    background: var(--surface-sunken);
}

/* The airline's capitals, given line height and a measure to be read at.
   Left as sent: these are the terms somebody is agreeing to. */
.fr-para {
    margin: 0 0 9px;
    font-size: 11.5px; line-height: 1.65; letter-spacing: .01em;
    color: var(--text-2);
}
.fr-para:last-child { margin-bottom: 0; }

.fr-said {
    display: flex; align-items: flex-start; gap: 7px;
    margin-top: 10px;
    font-size: 11px; line-height: 1.5; color: var(--text-3);
}
.fr-said svg { flex: 0 0 auto; margin-top: 2px; }

/* ==========================================================================
   Ticketing

   Seats an airline is holding that nobody has paid for. The deadline leads
   every row because it is the only thing here that runs out: a permission can
   be granted and a wallet topped up, but an airline that has taken the seats
   back cannot be argued with.
   ========================================================================== */
.tk-page { display: flex; flex-direction: column; gap: 12px; }

.tk-row { display: flex; flex-direction: column; padding: 0; overflow: hidden; }
.tk-row.gone { opacity: .72; }

.tk-head {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding: 13px 16px;
}

.tk-named { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.tk-what { font-size: 13.5px; font-weight: 650; }

.tk-refs {
    display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
    font-size: 11.5px; color: var(--text-3);
}
.tk-sep { color: var(--text-4); }

/* The clock. Quiet while there is time, loud in the last day, spent after. */
.tk-when {
    display: flex; flex-direction: column; align-items: flex-end; gap: 1px;
    padding: 6px 11px;
    border-radius: 9px;
    background: var(--fill);
}
.tk-when.soon { background: var(--warn-soft); color: var(--warn); }
.tk-when.gone { background: var(--bad-soft); color: var(--bad); }

.tk-when-label { font-size: 9.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; opacity: .8; }
.tk-when-value { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }
.tk-when-left { font-size: 10.5px; opacity: .85; }

.tk-price { display: flex; flex-direction: column; align-items: flex-end; gap: 1px; }
.tk-price .tnx-money { font-size: 16px; font-weight: 800; }
.tk-price-note { font-size: 10px; color: var(--text-3); }

/* ------------------------------------------------------ what was asked */
.tk-checks {
    display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
    padding: 0 16px 12px;
}

.tnx-check {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 9px;
    border-radius: 7px;
    font-size: 11px; font-weight: 550;
    background: var(--fill); color: var(--text-3);
}
.tnx-check svg { flex: 0 0 auto; }
.tnx-check.yes { background: var(--good-soft); color: var(--good); }
.tnx-check.no { background: var(--bad-soft); color: var(--bad); }

/* Neither a pass nor a failure: something nobody could ask. A tick against
   something we did not check is worse than no tick at all. */
.tnx-check.warn { background: var(--warn-soft); color: var(--warn); }

.tk-stop {
    display: flex; align-items: flex-start; gap: 9px;
    margin: 0 16px 12px;
    padding: 10px 13px;
    border-radius: 9px;
    background: var(--bad-soft); color: var(--bad);
    font-size: 12px; line-height: 1.5;
}
.tk-stop svg { flex: 0 0 auto; margin-top: 2px; }

.tk-foot {
    display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
    padding: 11px 16px;
    border-top: 1px solid var(--line-row);
    background: var(--surface-sunken);
}
.tk-foot-note { font-size: 11px; color: var(--text-3); }

.tnx-empty {
    display: flex; align-items: center; gap: 12px;
    font-size: 12.5px; color: var(--text-3);
}
.tnx-empty svg { flex: 0 0 auto; color: var(--text-4); }
.tnx-empty strong { color: var(--text); }
