/* ==========================================================================
   DropCatch — application stylesheet
   Vanilla CSS, no framework. Design system: light "studio" theme —
   indigo accent, white surfaces, Instrument Sans UI + JetBrains Mono data.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Fonts (self-hosted variable woff2, latin + latin-ext; CSP stays 'self')
   -------------------------------------------------------------------------- */

@font-face {
    font-family: 'Instrument Sans';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('../fonts/InstrumentSans-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Instrument Sans';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('../fonts/InstrumentSans-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'JetBrains Mono';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url('../fonts/JetBrainsMono-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'JetBrains Mono';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url('../fonts/JetBrainsMono-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --------------------------------------------------------------------------
   Design tokens
   -------------------------------------------------------------------------- */

:root {
    /* palette */
    --bg: #f6f7f9;
    --surface: #ffffff;
    --header-bg: rgba(255, 255, 255, .86);
    --field: #fbfbfd;
    --border: #e7e8ee;
    --border-strong: #d3d5df;
    --text: #151824;
    --muted: #5c6274;
    --faint: #8d92a3;
    --chip: #f2f3f7;
    --thead: #fafbfc;
    --track: #eceef3;
    --row-hover: #fafafd;

    --accent: #3f3ac4;
    --accent-strong: #2a2596;
    --accent-soft: rgba(63, 58, 196, .16);
    --accent-tint: #f4f4fd;
    --accent-line: #dedcfa;

    /* status */
    --ok-tint: #e8f5ee;
    --ok-text: #166b45;
    --ok-live: #1f9d6a;
    --info-tint: #eef1fb;
    --info-text: #3f3ac4;
    --warn-tint: #fdf0e0;
    --warn-text: #94601a;
    --warn-solid: #b8721a;
    --warn-banner-tint: #fdf5e8;
    --warn-banner-line: #f0dfbc;
    --danger-tint: #fdeee9;
    --danger-text: #b8391f;
    --danger-strong: #9c2f18;
    --neutral-tint: #f1f2f6;
    --neutral-text: #5c6274;

    /* vivid status (solid fills: badges, buttons, indicators) */
    --ok-bright: #12b377;      --ok-solid: #08945f;
    --danger-bright: #f0523c;  --danger-solid: #d63420;
    --warn-bright: #f59e0b;    --warn-vivid: #e07610;
    --violet-bright: #8b5cf6;  --violet-solid: #6b2bd9;
    --neutral-bright: #6b7a94; --neutral-solid: #4d596e;
    /* Two more status pills so every monitoring state reads distinctly:
       rose for a booking cancelled at the supplier, slate for one whose
       cancellation window simply closed. Both were grey before, which put
       "cancelled", "completed" and "deadline passed" in one colour. */
    --rose-bright: #ec4899;    --rose-solid: #be1d63;
    --slate-bright: #64748b;   --slate-solid: #3f4b5f;
    --accent-bright: #4f46e5;  --accent-violet: #7c3aed;
    --pill-ring: inset 0 0 0 1px rgba(255, 255, 255, .16);

    /* sidebar */
    --side: #ffffff;
    --side-border: #e7e8ee;
    --side-text: #151824;
    --side-faint: #8d92a3;
    --side-hover: #f4f4fa;
    --side-chip: #f2f3f7;
    --sidebar-width: 252px;
    --sidebar-rail: 76px;

    --avatar-bg: #eceafb;
    --avatar-text: #3f3ac4;

    /* shape + depth */
    --radius: 12px;
    --radius-sm: 9px;
    --shadow: 0 1px 2px rgba(16, 20, 35, .04);
    --shadow-lift: 0 10px 26px rgba(16, 20, 35, .09);
    --shadow-pop: 0 30px 70px rgba(12, 16, 28, .28);

    /* type */
    --font: 'Instrument Sans', system-ui, -apple-system, "Segoe UI", sans-serif;
    --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    --header-h: 58px;

    /* legacy alias kept for older inline styles */
    --c-warning: #b8721a;
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    font-family: var(--font);
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

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

::selection { background: #dcdafc; }

.icon { vertical-align: -0.18em; flex: none; }

.mono { font-family: var(--font-mono); font-size: 0.93em; }
.muted { color: var(--faint); }
.nowrap { white-space: nowrap; }

.sr-only {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@keyframes riseIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes toastIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes pulseDot { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.8); } }

/* --------------------------------------------------------------------------
   Layout shell
   -------------------------------------------------------------------------- */

.app { display: flex; min-height: 100vh; }

.app-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    margin-left: var(--sidebar-width);
}

.app-content {
    flex: 1;
    width: 100%;
    max-width: 1460px;
    padding: clamp(18px, 2.4vw, 28px) clamp(18px, 3vw, 34px) 56px;
    animation: riseIn .35s ease both;
}

/* --------------------------------------------------------------------------
   Sidebar
   -------------------------------------------------------------------------- */

.sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 40;
    width: var(--sidebar-width);
    display: flex;
    flex-direction: column;
    background: var(--side);
    border-right: 1px solid var(--side-border);
}

.sidebar-brand { padding: 18px 18px 12px; }

.brand-link {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--side-text);
    min-width: 0;
}
.brand-link:hover { color: var(--side-text); }

.brand-mark {
    width: 30px;
    height: 30px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 9px;
    background: var(--accent);
    color: #fff;
    font-weight: 700;
    font-size: 15px;
}

.brand-mark-lg { width: 40px; height: 40px; border-radius: 12px; font-size: 19px; }

.brand-name { min-width: 0; }
.brand-title {
    font-weight: 600;
    font-size: 14px;
    letter-spacing: -.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.brand-sub { font-size: 11.5px; color: var(--side-faint); }

.sidebar-nav {
    flex: 1;
    overflow-y: auto;
    padding: 2px 12px 12px;
}
.sidebar-nav::-webkit-scrollbar { width: 10px; }
.sidebar-nav::-webkit-scrollbar-thumb {
    background: rgba(15, 20, 35, .14);
    border-radius: 20px;
    border: 3px solid transparent;
    background-clip: content-box;
}

.sidebar-nav ul { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-direction: column; gap: 2px; }

.nav-group-label {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--side-faint);
    padding: 10px 10px 4px;
}

.nav-link {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 9px 10px;
    border-radius: var(--radius-sm);
    font-size: 13.5px;
    font-weight: 500;
    color: var(--side-text);
    transition: background .15s ease, color .15s ease;
}
.nav-link:hover { background: var(--side-hover); color: var(--side-text); }
.nav-link.is-active {
    background: var(--accent-tint);
    color: var(--accent);
    font-weight: 600;
    box-shadow: inset 0 0 0 1px var(--accent-line);
}
.nav-link .icon { color: var(--side-faint); }
.nav-link:hover .icon { color: var(--muted); }
.nav-link.is-active .icon { color: var(--accent); }
.nav-link span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.sidebar-footer {
    padding: 12px 14px 16px;
    border-top: 1px solid var(--side-border);
}

.sidebar-env {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    background: var(--side-chip);
    font-size: 11.5px;
    font-weight: 600;
    color: var(--side-text);
}
.env-meta {
    display: block;
    margin-top: 3px;
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 400;
    color: var(--side-faint);
}
.env-dot {
    width: 7px;
    height: 7px;
    flex: none;
    border-radius: 50%;
    align-self: flex-start;
    margin-top: 5px;
    animation: pulseDot 1.8s ease-in-out infinite;
}
.env-development { background: var(--warn-bright); }
.env-staging     { background: var(--violet-bright); }
.env-production  { background: var(--ok-bright); }

.sidebar-user {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 12px;
    color: var(--side-text);
    min-width: 0;
}
.sidebar-user:hover { color: var(--side-text); }
.sidebar-user:hover .sidebar-user-name { color: var(--accent); }
.sidebar-user-body { min-width: 0; flex: 1; }
.sidebar-user-name {
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sidebar-user-sub {
    font-size: 11.5px;
    color: var(--side-faint);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sidebar-overlay {
    position: fixed;
    inset: 0;
    z-index: 35;
    background: rgba(16, 20, 32, .42);
    backdrop-filter: blur(3px);
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.app-header {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 12px;
    height: var(--header-h);
    padding: 0 clamp(18px, 3vw, 34px);
    background: var(--header-bg);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--border);
}

.icon-btn.sidebar-toggle { display: none; }

.header-title { min-width: 0; }
.header-kicker {
    font-size: 11.5px;
    color: var(--faint);
    letter-spacing: .02em;
}
.header-page {
    font-size: 16px;
    font-weight: 600;
    letter-spacing: -.015em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.header-actions { margin-left: auto; display: flex; align-items: center; gap: 10px; }

.user-menu-btn {
    display: flex;
    align-items: center;
    gap: 9px;
    height: 40px;
    padding: 0 4px;
    border: none;
    background: transparent;
    border-radius: 999px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
    cursor: pointer;
}
.user-menu-btn:hover .avatar { box-shadow: 0 0 0 3px var(--accent-soft); }
.user-menu-btn .icon:last-child { color: var(--faint); }
.user-menu-name { max-width: 160px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.avatar {
    width: 34px;
    height: 34px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--avatar-bg);
    color: var(--avatar-text);
    font-size: 12.5px;
    font-weight: 600;
    transition: box-shadow .15s ease;
}
.avatar-sm { width: 30px; height: 30px; font-size: 11.5px; }
.avatar-lg { width: 48px; height: 48px; font-size: 17px; }

/* --------------------------------------------------------------------------
   Dropdown
   -------------------------------------------------------------------------- */

.dropdown { position: relative; }

.dropdown-menu {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 30;
    min-width: 220px;
    padding: 6px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lift);
    display: none;
    animation: riseIn .15s ease both;
}
.dropdown.is-open .dropdown-menu { display: block; }

.dropdown-header {
    padding: 8px 10px 10px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 6px;
}
.dropdown-header strong { display: block; font-size: 13px; font-weight: 600; }
.dropdown-header small { display: block; font-size: 11.5px; color: var(--faint); margin-top: 2px; }

.dropdown-item {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 8px 10px;
    border: none;
    background: none;
    border-radius: var(--radius-sm);
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
    text-align: left;
    cursor: pointer;
}
.dropdown-item:hover { background: var(--chip); color: var(--text); }
.dropdown-item .icon { color: var(--faint); }

/* --------------------------------------------------------------------------
   Breadcrumbs
   -------------------------------------------------------------------------- */

.breadcrumbs { margin: 0 0 14px; }
.breadcrumbs ol {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px;
    font-size: 12px;
    color: var(--faint);
}
.breadcrumbs li { display: flex; align-items: center; gap: 4px; }
.breadcrumbs li + li::before { content: "/"; color: var(--border-strong); }
.breadcrumbs a { color: var(--faint); }
.breadcrumbs a:hover { color: var(--accent); }
.breadcrumbs [aria-current] { color: var(--muted); font-weight: 500; }

/* --------------------------------------------------------------------------
   Page head
   -------------------------------------------------------------------------- */

.page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}

.page-title {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -.015em;
}
.page-sub { margin: 3px 0 0; font-size: 12.5px; color: var(--faint); }
.page-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    overflow: hidden;
}

.card + .card { margin-top: 14px; }

.card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 15px 18px;
    border-bottom: 1px solid var(--border);
}
.card-head h2 {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 14px;
    font-weight: 600;
}
.card-head h2 .icon { color: var(--faint); }
.card-head-link { font-size: 12.5px; font-weight: 500; white-space: nowrap; }
.card-head-note { font-size: 12px; font-weight: 500; color: var(--faint); white-space: nowrap; }

/* Note plus action button sharing the right side of a card head. */
.card-head-actions {
    display: flex;
    align-items: center;
    gap: 12px;
}

.card-form { padding: 20px; }
.card-form .card-head { margin: -20px -20px 20px; }
.card-form > .page-sub { margin: -8px 0 18px; }
.card-narrow { max-width: 720px; }

.empty-note { padding: 26px 18px; margin: 0; text-align: center; font-size: 13px; color: var(--faint); }

/* --------------------------------------------------------------------------
   Banners (inline notices above content)
   -------------------------------------------------------------------------- */

.banner {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    padding: 16px 18px;
    border-radius: var(--radius);
    margin-bottom: 14px;
}
.banner-warn { background: var(--warn-banner-tint); border: 1px solid var(--warn-banner-line); }

.banner-icon {
    width: 30px;
    height: 30px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 9px;
    color: #fff;
}
.banner-warn .banner-icon { background: var(--warn-solid); }

.banner-body { flex: 1; min-width: 0; }
.banner-title { font-size: 13.5px; font-weight: 600; margin-bottom: 3px; }
.banner-text { font-size: 13px; color: var(--muted); line-height: 1.55; }
.banner-text strong { color: var(--text); font-weight: 600; }

/* --------------------------------------------------------------------------
   Stat / KPI cards
   -------------------------------------------------------------------------- */

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(215px, 100%), 1fr));
    gap: 14px;
    margin-bottom: 14px;
}

.stat-card { position: relative; padding: 18px 18px 16px; overflow: visible; }

.stat-label { font-size: 12.5px; font-weight: 600; color: var(--muted); }

.stat-value {
    display: block;
    margin-top: 10px;
    font-family: var(--font-mono);
    font-size: 27px;
    font-weight: 600;
    letter-spacing: -.03em;
    line-height: 1;
}

.stat-note { font-size: 11.5px; color: var(--faint); margin-top: 7px; }

.stat-link {
    position: absolute;
    top: 14px;
    right: 14px;
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border-radius: 8px;
    color: var(--faint);
}
.stat-link:hover { background: var(--accent-tint); color: var(--accent); }

/* --------------------------------------------------------------------------
   Dashboard columns + activity feed
   -------------------------------------------------------------------------- */

.dash-columns {
    display: grid;
    grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
    gap: 14px;
    align-items: start;
}
.dash-columns .card { margin: 0; }

.activity-list { list-style: none; margin: 0; padding: 6px 0; }

.activity-item {
    display: flex;
    gap: 12px;
    padding: 11px 18px;
    transition: background .15s ease;
}
.activity-item:hover { background: var(--row-hover); }
.activity-item + .activity-item { border-top: 1px solid var(--border); }

.activity-dot {
    width: 7px;
    height: 7px;
    flex: none;
    margin-top: 6px;
    border-radius: 50%;
}
.activity-dot-ok      { background: var(--ok-bright); box-shadow: 0 0 0 3px rgba(18, 179, 119, .16); }
.activity-dot-warning { background: var(--warn-bright); box-shadow: 0 0 0 3px rgba(245, 158, 11, .16); }
.activity-dot-danger  { background: var(--danger-bright); box-shadow: 0 0 0 3px rgba(240, 82, 60, .16); }

.activity-body { min-width: 0; }
.activity-desc { display: block; font-size: 13px; line-height: 1.5; }
.activity-meta {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin-top: 3px;
    font-size: 11.5px;
    color: var(--faint);
}

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

.table-toolbar {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    flex-wrap: wrap;
    padding: 14px;
    border-bottom: 1px solid var(--border);
}

/* A labelled control in the toolbar. Bare date inputs sitting in a row are
   unreadable — three identical boxes with no indication of which end of
   which range they are — so every control carries a caption. */
.filter-field {
    display: flex;
    flex-direction: column;
    gap: 5px;
    min-width: 0;
}
.filter-field > label {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .01em;
    color: var(--faint);
    white-space: nowrap;
}

/* One control skin for every toolbar input, select and date field. Without
   this, type="date" and type="search" fall back to the browser's own
   widget, which ignores the theme and does not line up with the selects. */
.table-toolbar select,
.table-toolbar input[type="date"],
.table-toolbar input[type="text"],
.table-toolbar input[type="search"] {
    height: 36px;
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text);
    transition: border-color .15s ease, box-shadow .15s ease;
}
.table-toolbar select { padding-right: 30px; cursor: pointer; }
.table-toolbar select:hover,
.table-toolbar input[type="date"]:hover { border-color: var(--border-strong); }

/* Date fields: normalise the intrinsic width Chrome gives them, and make the
   picker button read as part of the control rather than a browser artefact. */
.table-toolbar input[type="date"] {
    min-width: 142px;
    font-family: var(--font-mono);
    font-size: 12px;
}
.table-toolbar input[type="date"]::-webkit-calendar-picker-indicator {
    padding: 2px;
    border-radius: 4px;
    opacity: .55;
    cursor: pointer;
}
.table-toolbar input[type="date"]::-webkit-calendar-picker-indicator:hover {
    opacity: 1;
    background: var(--accent-tint);
}
/* Firefox keeps a spinner on date fields that clips the text. */
.table-toolbar input[type="date"]::-moz-calendar-picker-indicator { cursor: pointer; }

/* Two dates reading as a single range. */
.filter-range {
    display: flex;
    align-items: center;
    gap: 6px;
}
.range-sep { font-size: 12px; color: var(--faint); }

.filter-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
}

.search-box { position: relative; flex: 1 1 240px; min-width: 200px; max-width: 320px; }
.search-box .icon {
    position: absolute;
    left: 11px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--faint);
    pointer-events: none;
}
.search-box input[type="search"] {
    width: 100%;
    height: 36px;
    padding: 0 12px 0 34px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-family: inherit;
    font-size: 13px;
    font-weight: 400;
    color: var(--text);
}
/* Safari draws its own rounded search field and a decoration glyph. */
.search-box input[type="search"] { -webkit-appearance: none; appearance: none; }
.search-box input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
.search-box input[type="search"]::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
    width: 14px;
    height: 14px;
    background: var(--faint);
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18 6 6 18M6 6l12 12' stroke='black' stroke-width='2.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
    cursor: pointer;
}

/* Below the tablet breakpoint the toolbar becomes a two-column grid so the
   fields keep their labels instead of squeezing into an unreadable row. */
@media (max-width: 760px) {
    .table-toolbar { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: end; }
    .search-box { grid-column: 1 / -1; max-width: none; }
    .filter-field > select,
    .filter-field > input[type="date"] { width: 100%; min-width: 0; }
    /* Two date fields plus a separator do not fit half a phone width. */
    .filter-field-range { grid-column: 1 / -1; }
    .filter-range { flex-wrap: nowrap; }
    .filter-range input[type="date"] { flex: 1 1 0; min-width: 0; }
    .filter-actions { grid-column: 1 / -1; margin-left: 0; }
}

/* --------------------------------------------------------------------------
   Tables
   -------------------------------------------------------------------------- */

.table-wrap { overflow-x: auto; }
.table-wrap::-webkit-scrollbar { height: 10px; }
.table-wrap::-webkit-scrollbar-thumb {
    background: rgba(15, 20, 35, .14);
    border-radius: 20px;
    border: 3px solid transparent;
    background-clip: content-box;
}

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.table th,
.table td { padding: 11px 14px; text-align: left; vertical-align: middle; }

/* Without a floor the browser crushes the free-text columns until a hotel
   name wraps one word per line and every row grows to eight lines tall.
   Below this width the wrapper scrolls sideways instead, which keeps the
   rows readable. The value is set with the bookings list below, which is the
   widest table in the panel. */

/* Free-text cells get a floor and a ceiling, then clamp to two lines; the
   full value stays available as a tooltip. min-width matters as much as
   max-width here: in auto table layout a max alone does not reserve the
   column any space, so the hotel name was squeezed to a few characters. */
.cell-hotel { min-width: 196px; max-width: 250px; }
.cell-clamp {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------
   Bookings list
   --------------------------------------------------------------------------
   An eleven-column table that had to hold supplier data of unbounded length,
   and did it by growing: a long client reference or a resort with a
   twelve-word name pushed the table past its floor, and everything from
   Savings rightwards scrolled out of sight with nothing on screen to say so.
   Three rules keep it inside its budget. */

/* 1. The reference cell is fixed, not fluid. A client reference comes from
      whoever made the booking and can be any length at all, so it truncates
      to the column instead of setting it — the untruncated value is on the
      tooltip and, more usefully, on the copy button. */
.cell-ref { width: 180px; min-width: 180px; max-width: 180px; }

.ref-line { display: flex; align-items: center; gap: 4px; min-width: 0; }
.ref-line + .ref-line { margin-top: 1px; }

.ref-value {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ref-meta { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin-top: 5px; }

/* Visible on focus always, and on row hover — a copy affordance on every row
   at full strength turns the column into a wall of icons. */
.copy-btn {
    flex: none;
    display: inline-grid;
    place-items: center;
    width: 20px;
    height: 20px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--faint);
    cursor: pointer;
    opacity: 0;
    transition: opacity .15s ease, background .15s ease, color .15s ease;
}
.table tbody tr:hover .copy-btn,
.copy-btn:focus-visible { opacity: 1; }
.copy-btn:hover { background: var(--chip); color: var(--accent); }

/* Touch and reduced-motion users never get a hover, so the affordance has to
   be there from the start. */
@media (hover: none) {
    .copy-btn { opacity: 1; }
}

/* 2. With Supplier folded into the reference cell and the two widest columns
      (deadline, savings) stacked onto two lines, the table's natural width
      fits inside a 1440px window with nothing hidden. */
.table-wide { min-width: 1160px; }

/* 3. Header labels set the floor for the narrow columns — "Cancellation
      deadline" is wider than any date it sits above, and thead is nowrap
      globally. Letting just this table's headers wrap hands that width back
      to the data. */
.table.table-bookings thead th { white-space: normal; }

/* 4. Status stays pinned to the right edge, so the answer to "is this one
      still being watched?" survives any amount of sideways scrolling. The
      backgrounds are opaque on purpose — a sticky cell with a transparent
      background lets the columns underneath scroll through it. */
.table-bookings th:last-child,
.table-bookings td:last-child {
    position: sticky;
    right: 0;
    background: var(--surface);
    /* Reads as a pinned overlay that columns pass beneath, rather than as a
       column whose neighbour has been clipped. */
    box-shadow: -1px 0 0 var(--border), -10px 0 12px -10px rgba(15, 20, 35, .18);
}
.table-bookings thead th:last-child { background: var(--thead); }
.table-bookings tbody tr:hover td:last-child { background: var(--row-hover); }

/* The empty-state row is a single full-width cell, so it is also a
   :last-child — pinning it would park the message at the right edge. */
.table-bookings td.empty-note { position: static; box-shadow: none; }
.table th:first-child,
.table td:first-child { padding-left: 18px; }
.table th:last-child,
.table td:last-child { padding-right: 18px; }

.table thead th {
    background: var(--thead);
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--faint);
    white-space: nowrap;
}

.table tbody tr { border-top: 1px solid var(--border); transition: background .15s ease; }
.table tbody tr:hover { background: var(--row-hover); }

.table .num { text-align: right; font-family: var(--font-mono); font-size: 12.5px; }
.table thead .num { font-family: var(--font); font-size: 11.5px; }

.table-compact th,
.table-compact td { padding: 9px 12px; }

.actions-col { text-align: right; width: 1%; white-space: nowrap; }
.row-actions { display: inline-flex; align-items: center; gap: 4px; }
.inline-form { display: inline-flex; }

.cell-user { display: flex; align-items: center; gap: 10px; min-width: 0; }
.cell-user-lg { gap: 14px; }
.cell-title { display: block; font-weight: 500; color: var(--text); }
a.cell-title:hover { color: var(--accent); }
.cell-sub { display: block; font-size: 11.5px; color: var(--faint); margin-top: 2px; }

.currency-symbol {
    width: 32px;
    height: 32px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 9px;
    background: var(--chip);
    color: var(--text);
    font-family: var(--font-mono);
    font-size: 12px;
    font-weight: 600;
}

/* --------------------------------------------------------------------------
   Table footer + pagination
   -------------------------------------------------------------------------- */

.table-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding: 12px 18px;
    border-top: 1px solid var(--border);
}

.pagination-info { font-size: 12px; color: var(--faint); font-family: var(--font-mono); }

.pagination { display: flex; align-items: center; gap: 4px; }

.page-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    height: 30px;
    padding: 0 8px;
    border-radius: var(--radius-sm);
    font-size: 12.5px;
    font-weight: 500;
    font-family: var(--font-mono);
    color: var(--muted);
    transition: background .15s ease, color .15s ease;
}
a.page-link:hover { background: var(--chip); color: var(--text); }
.page-link.is-current { background: var(--accent); color: #fff; font-weight: 600; }
.page-link.is-disabled { color: var(--border-strong); }
.page-link.is-gap { color: var(--faint); }

/* --------------------------------------------------------------------------
   Badges (status pills)
   -------------------------------------------------------------------------- */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .01em;
    white-space: nowrap;
}
.badge-sm { padding: 1px 7px; font-size: 10.5px; }

/* Vivid solid pills: every status carries its own color, white label. */
.badge-success,
.badge-danger,
.badge-warning,
.badge-amber,
.badge-violet,
.badge-rose,
.badge-slate,
.badge-muted,
.badge-neutral {
    color: #fff;
    text-shadow: 0 1px 1px rgba(12, 16, 28, .18);
}
.badge-success {
    background: linear-gradient(135deg, var(--ok-bright), var(--ok-solid));
    box-shadow: 0 1px 3px rgba(8, 148, 95, .35), var(--pill-ring);
}
.badge-danger {
    background: linear-gradient(135deg, var(--danger-bright), var(--danger-solid));
    box-shadow: 0 1px 3px rgba(214, 52, 32, .35), var(--pill-ring);
}
.badge-warning,
.badge-amber {
    background: linear-gradient(135deg, var(--warn-bright), var(--warn-vivid));
    box-shadow: 0 1px 3px rgba(224, 118, 16, .35), var(--pill-ring);
}
.badge-violet {
    background: linear-gradient(135deg, var(--violet-bright), var(--violet-solid));
    box-shadow: 0 1px 3px rgba(107, 43, 217, .35), var(--pill-ring);
}
.badge-rose {
    background: linear-gradient(135deg, var(--rose-bright), var(--rose-solid));
    box-shadow: 0 1px 3px rgba(190, 29, 99, .35), var(--pill-ring);
}
.badge-slate {
    background: linear-gradient(135deg, var(--slate-bright), var(--slate-solid));
    box-shadow: 0 1px 3px rgba(63, 75, 95, .32), var(--pill-ring);
}
.badge-muted,
.badge-neutral {
    background: linear-gradient(135deg, var(--neutral-bright), var(--neutral-solid));
    box-shadow: 0 1px 3px rgba(77, 89, 110, .30), var(--pill-ring);
}
.badge-code {
    background: var(--accent-tint);
    color: var(--accent);
    border: 1px solid var(--accent-line);
    font-family: var(--font-mono);
    font-size: 11px;
    border-radius: 7px;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    height: 34px;
    padding: 0 14px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition: filter .15s ease, border-color .15s ease, background .15s ease, color .15s ease;
}

.btn-primary {
    background: linear-gradient(135deg, var(--accent-bright), var(--accent-violet));
    color: #fff;
    box-shadow: 0 1px 2px rgba(63, 58, 196, .30), 0 4px 12px rgba(124, 58, 237, .22);
}
.btn-primary:hover {
    filter: brightness(1.08);
    color: #fff;
    box-shadow: 0 2px 4px rgba(63, 58, 196, .32), 0 6px 16px rgba(124, 58, 237, .28);
}

.btn-secondary {
    background: var(--accent-tint);
    border-color: var(--accent-line);
    color: var(--accent);
    font-weight: 600;
}
.btn-secondary:hover { background: #eae8fc; border-color: var(--accent); color: var(--accent-strong); }

.btn-danger {
    background: linear-gradient(135deg, var(--danger-bright), var(--danger-solid));
    color: #fff;
    box-shadow: 0 1px 2px rgba(214, 52, 32, .28), 0 4px 12px rgba(214, 52, 32, .18);
}
.btn-danger:hover { filter: brightness(1.07); color: #fff; }

.btn-success {
    background: linear-gradient(135deg, var(--ok-bright), var(--ok-solid));
    color: #fff;
    box-shadow: 0 1px 2px rgba(8, 148, 95, .28), 0 4px 12px rgba(8, 148, 95, .18);
}
.btn-success:hover { filter: brightness(1.07); color: #fff; }

.btn-warning {
    background: linear-gradient(135deg, var(--warn-bright), var(--warn-vivid));
    color: #fff;
    box-shadow: 0 1px 2px rgba(224, 118, 16, .28), 0 4px 12px rgba(224, 118, 16, .18);
}
.btn-warning:hover { filter: brightness(1.07); color: #fff; }

.btn-info {
    background: linear-gradient(135deg, var(--violet-bright), var(--violet-solid));
    color: #fff;
    box-shadow: 0 1px 2px rgba(107, 43, 217, .28), 0 4px 12px rgba(107, 43, 217, .18);
}
.btn-info:hover { filter: brightness(1.07); color: #fff; }

.btn-ghost { background: transparent; color: var(--accent); font-weight: 600; }
.btn-ghost:hover { background: var(--accent-tint); color: var(--accent-strong); }

.btn-block { display: flex; width: 100%; height: 40px; font-size: 14px; }

.btn-link {
    display: inline;
    height: auto;
    padding: 0;
    border: none;
    background: none;
    font-family: inherit;
    font-size: inherit;
    font-weight: 500;
    color: var(--accent);
    cursor: pointer;
}
.btn-link:hover { color: var(--accent-strong); }

.icon-btn {
    display: inline-grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border: none;
    background: transparent;
    border-radius: 8px;
    color: var(--faint);
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}
.icon-btn:hover { background: var(--accent-tint); color: var(--accent); }
.icon-btn-danger:hover { background: var(--danger-tint); color: var(--danger-text); }

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */

.form-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
}

.form-group { margin-bottom: 16px; }
.form-grid .form-group { margin-bottom: 0; }
.form-group-wide { grid-column: 1 / -1; }

.form-group label {
    display: block;
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    margin-bottom: 6px;
}
.req { color: var(--danger-text); }

.form-group input:not([type="checkbox"]):not([type="radio"]),
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 10px 13px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--field);
    font-family: inherit;
    font-size: 13.5px;
    color: var(--text);
    transition: border-color .15s ease, box-shadow .15s ease;
}
.form-group textarea { resize: vertical; min-height: 90px; }
.form-group select { cursor: pointer; }

input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

input.is-invalid,
select.is-invalid,
textarea.is-invalid { border-color: var(--danger-text); }
input.is-invalid:focus-visible,
select.is-invalid:focus-visible,
textarea.is-invalid:focus-visible { box-shadow: 0 0 0 3px rgba(184, 57, 31, .16); }

input[disabled], select[disabled], textarea[disabled] {
    background: var(--chip);
    color: var(--faint);
    cursor: not-allowed;
}
input[readonly] { background: var(--chip); }

input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); }

.field-error { margin: 6px 0 0; font-size: 12px; font-weight: 500; color: var(--danger-text); }
.field-hint { margin: 6px 0 0; font-size: 12px; color: var(--faint); line-height: 1.5; }

.form-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}

.form-fieldset {
    margin: 20px 0 0;
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.form-fieldset legend {
    padding: 0 8px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--faint);
}

.checkbox-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 8px;
}

.checkbox-item {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 9px 11px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-size: 12.5px;
    font-weight: 500;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease;
}
.checkbox-item:hover { border-color: var(--accent-line); background: var(--row-hover); }
.checkbox-item:has(input:checked) {
    border-color: var(--accent-line);
    background: var(--accent-tint);
}
.checkbox-item input { margin-top: 2px; }
.checkbox-item small { display: block; font-weight: 400; font-size: 11.5px; color: var(--faint); margin-top: 2px; }

.checkbox-label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
}

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

.perm-module {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.perm-module-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 14px;
    background: var(--thead);
    border-bottom: 1px solid var(--border);
}
.perm-module-name {
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted);
}
.perm-module .checkbox-grid { padding: 12px 14px; }

.input-affix { position: relative; }
.input-affix input { padding-right: 42px; }
.affix-btn {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border: none;
    background: transparent;
    border-radius: 7px;
    color: var(--faint);
    cursor: pointer;
}
.affix-btn:hover { background: var(--accent-tint); color: var(--accent); }

/* --------------------------------------------------------------------------
   Notes + detail lists
   -------------------------------------------------------------------------- */

.note {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 12px 14px;
    border-radius: var(--radius-sm);
    font-size: 12.5px;
    line-height: 1.55;
}
.note .icon { margin-top: 1px; }
.note-info { background: var(--info-tint); color: var(--info-text); }

.detail-list { margin: 0; }
.detail-list > div {
    display: grid;
    grid-template-columns: 170px minmax(0, 1fr);
    gap: 14px;
    padding: 10px 18px;
    min-height: 48px;
    align-items: center;
}
.detail-list > div + div { border-top: 1px solid var(--border); }
.detail-list dt { font-size: 12.5px; font-weight: 600; color: var(--muted); }
.detail-list dd { margin: 0; font-size: 13px; }

/* Split rows — 2 or 3 label/value pairs sharing one .detail-list row.
   dt/dd stay direct children of the row div so the markup remains a valid
   `dl > div > dt,dd` group. Column flow over two explicit rows lays each
   pair out label-over-value, so the 170px label gutter isn't needed per
   pair. Selectors are `.detail-list > …` because the base `.detail-list >
   div` rule (0,1,1) would otherwise outrank a bare `.detail-split` (0,1,0).
   Row 2 is 1fr and items stretch: when equal-height cards grow a row, the
   dd band absorbs the surplus and the column rule stays full height. */
.detail-list > .detail-split {
    grid-auto-flow: column;
    grid-template-rows: auto 1fr;
    align-items: stretch;
    gap: 0;
    padding: 0;
}
.detail-list > .detail-split-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.detail-list > .detail-split-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.detail-list > .detail-split > dt,
.detail-list > .detail-split > dd { min-width: 0; overflow-wrap: anywhere; }
.detail-list > .detail-split > dt { padding: 12px 18px 0; }
.detail-list > .detail-split > dd { padding: 5px 18px 12px; }

/* Rule between columns, drawn on both bands so the line runs unbroken.
   Column-starting items are dt 3,5,7… and dd 4,6,8… in source order. */
.detail-list > .detail-split > dt:nth-child(2n + 3),
.detail-list > .detail-split > dd:nth-child(2n + 4) { border-left: 1px solid var(--border); }

/* Collapse is driven by card width, not viewport: the same viewport gives a
   ~340px card or a full-width one depending on whether .grid-2 is 2-up or
   1-up and whether the sidebar is a rail, so a media query cannot get this
   right. Collapsed rows fall back to the stacked look of a normal row.
   Without @container support the rows simply stay side by side. */
.detail-list { container-type: inline-size; }

/* Thresholds are measured, not guessed: a bold "Mon, 17 Aug 2026" date at
   13px Instrument Sans needs ~107px, so a 3-up row starts wrapping just
   under a 450px container — collapse there, with the margin covering the
   widest weekday/month the format can produce. The 2-up pairs carry short
   codes and only run out of room near 280px. The column rule is reset
   through the same :nth-child selectors that set it: a plain `> dd` reset
   is (0,2,2) and would lose to the (0,3,2) border rule above. */
@container (max-width: 450px) {
    .detail-list > .detail-split-3 {
        grid-auto-flow: row;
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: none;
    }
    .detail-list > .detail-split-3 > dt { padding: 10px 18px 0; }
    .detail-list > .detail-split-3 > dd { padding: 3px 18px 10px; }
    .detail-list > .detail-split-3 > dt:nth-child(2n + 3),
    .detail-list > .detail-split-3 > dd:nth-child(2n + 4) { border-left: 0; }
    .detail-list > .detail-split-3 > dt:nth-child(2n + 3) { border-top: 1px solid var(--border); }
}

@container (max-width: 280px) {
    .detail-list > .detail-split-2 {
        grid-auto-flow: row;
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: none;
    }
    .detail-list > .detail-split-2 > dt { padding: 10px 18px 0; }
    .detail-list > .detail-split-2 > dd { padding: 3px 18px 10px; }
    .detail-list > .detail-split-2 > dt:nth-child(2n + 3),
    .detail-list > .detail-split-2 > dd:nth-child(2n + 4) { border-left: 0; }
    .detail-list > .detail-split-2 > dt:nth-child(2n + 3) { border-top: 1px solid var(--border); }
}

/* --------------------------------------------------------------------------
   Tabs — sectioned page content
   -------------------------------------------------------------------------- */

.tab-list {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    padding: 6px;
    margin-bottom: 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.tab {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 11px;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: none;
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    line-height: 1.2;
    color: var(--muted);
    white-space: nowrap;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.tab .icon { color: var(--faint); transition: color .15s ease; }
.tab:hover { background: var(--accent-tint); color: var(--text); }
.tab:hover .icon { color: var(--muted); }
.tab[aria-selected="true"] {
    background: var(--accent-tint);
    border-color: var(--accent-line);
    font-weight: 600;
    color: var(--accent);
}
.tab[aria-selected="true"] .icon { color: var(--accent); }

.tab-panel:focus { outline: none; }
.tab-panel:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: var(--radius); }

/* Narrow screens: 11 labels wrap into a strip taller than the content it
   introduces, so scroll sideways instead. JS keeps the active tab in view. */
@media (max-width: 760px) {
    .tab-list {
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
    }
    .tab-list::-webkit-scrollbar { display: none; }
}

/* Printing a booking should produce the whole record, not one section. */
@media print {
    .tab-list { display: none; }
    .tab-panel[hidden] { display: block; }
}

/* --------------------------------------------------------------------------
   Hotel profile — supplier content gallery, facility chips
   -------------------------------------------------------------------------- */

.hotel-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr));
    gap: 8px;
    padding: 18px 18px 0;
}
.hotel-shot {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    background: var(--surface-2, #f6f7f9);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}

.hotel-facilities { padding: 0 18px 16px; }
.hotel-facilities > summary { cursor: pointer; font-size: 12.5px; }

/* One booked room's content: heading, its own photographs, occupancy and
   facilities. Several stack inside a single card, so each is separated by a
   rule rather than being its own card — the tab already has one. */
.room-profile + .room-profile { border-top: 1px solid var(--border); }
.room-profile-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    padding: 14px 18px 0;
}
.room-profile-title {
    margin: 0;
    font-size: 14px;
    font-weight: 650;
    color: var(--text);
}
.room-gallery { padding-top: 12px; }
.room-chips { padding: 0 18px 16px; margin-top: 0; }

.chip-list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 10px;
}
.chip {
    padding: 4px 9px;
    background: var(--accent-tint);
    border: 1px solid var(--accent-line);
    border-radius: var(--radius-sm);
    font-size: 12px;
    color: var(--muted);
}

/* Action row pinned under a card's own content (not the page header). */
.card-foot {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 14px 18px;
    border-top: 1px solid var(--border);
}
.card-foot:first-child { border-top: 0; }

/* --------------------------------------------------------------------------
   Charts — server-rendered SVG (no chart library; CSP is script-src 'self')
   -------------------------------------------------------------------------- */

.chart-wrap { padding: 16px 18px 4px; }

/* Inline activity indicator for work the page started by itself. */
@keyframes spin { to { transform: rotate(360deg); } }
.icon.spin {
    animation: spin 1s linear infinite;
    vertical-align: -2px;
}
@media (prefers-reduced-motion: reduce) {
    .icon.spin { animation: none; opacity: .6; }
}

.chart {
    display: block;
    width: 100%;
    /* Height follows the viewBox aspect so nothing is distorted; the SVG is
       laid out in its own units and scales uniformly. */
    height: auto;
    overflow: visible;
}

.chart-grid { stroke: var(--border); stroke-width: 1; }
.chart-axis {
    fill: var(--faint);
    font-family: var(--font-mono);
    font-size: 10.5px;
}

.chart-area { fill: var(--accent-tint); stroke: none; }
.chart-line {
    fill: none;
    stroke: var(--accent);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
    /* preserveAspectRatio="none" stretches the viewBox, which would also
       stretch stroke width; this keeps the line an even weight. */
    vector-effect: non-scaling-stroke;
}

.chart-point {
    fill: var(--surface);
    stroke: var(--accent);
    stroke-width: 2;
    vector-effect: non-scaling-stroke;
}
/* A check that came in under the booked rate — the thing being watched for. */
.chart-point.is-below { fill: var(--ok-bright, #16a34a); stroke: var(--ok-bright, #16a34a); }

.chart-ref {
    stroke: var(--faint);
    stroke-width: 1;
    stroke-dasharray: 4 4;
    vector-effect: non-scaling-stroke;
}
.chart-ref-label {
    fill: var(--faint);
    font-size: 10.5px;
    font-weight: 600;
}

.chart-caption {
    margin: 0;
    padding: 0 18px 16px;
    font-size: 12px;
    color: var(--faint);
}

/* --------------------------------------------------------------------------
   Settings hub — one tile per configurable area
   -------------------------------------------------------------------------- */

.settings-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
    gap: 14px;
}

.settings-tile {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 18px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    color: inherit;
    text-decoration: none;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.settings-tile:hover {
    border-color: var(--accent-line);
    box-shadow: var(--shadow-lift);
    transform: translateY(-1px);
    color: inherit;
}
.settings-tile:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.settings-tile-icon {
    display: grid;
    place-items: center;
    flex: none;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-sm);
    background: var(--accent-tint);
    color: var(--accent);
}

.settings-tile-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.settings-tile-title { font-size: 14px; font-weight: 650; color: var(--text); }
.settings-tile-text { font-size: 12.5px; line-height: 1.5; color: var(--muted); }

/* Pinned right and nudged on hover, so the tile reads as a destination. */
.settings-tile-go {
    margin-left: auto;
    align-self: center;
    color: var(--faint);
    transition: transform .15s ease, color .15s ease;
}
.settings-tile:hover .settings-tile-go { transform: translateX(2px); color: var(--accent); }

/* The destructive tile reads as destructive before it is clicked, not only
   once the confirmation page has loaded. */
.settings-tile.is-danger .settings-tile-icon {
    background: var(--danger-tint, #fdf0ec);
    color: var(--danger-text);
}
.settings-tile.is-danger:hover {
    border-color: var(--danger-text);
    box-shadow: 0 10px 26px rgba(184, 57, 31, .14);
}
.settings-tile.is-danger:hover .settings-tile-go { color: var(--danger-text); }

@media (prefers-reduced-motion: reduce) {
    .settings-tile,
    .settings-tile-go { transition: none; }
    .settings-tile:hover { transform: none; }
}

/* Explanatory paragraph inside a card, aligned to the card's own padding. */
.card-note {
    margin: 0;
    padding: 14px 18px;
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--muted);
}

/* Checkbox list — a set of togglable options inside a form group. */
.check-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-height: 220px;
    overflow-y: auto;
    padding: 6px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
}
.check-list .check-item {
    /* Scoped to .check-list so it outranks `.form-group label`, which is
       display:block and would otherwise stack the box above its text. */
    display: flex;
    margin-bottom: 0;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
}
.check-list .check-item:hover { background: var(--accent-tint); }
.check-list .check-item input { flex: none; width: auto; margin: 0; }
.check-list .check-item > span { display: flex; font-weight: 500; color: var(--text); align-items: center; gap: 7px; flex-wrap: wrap; min-width: 0; }

/* --------------------------------------------------------------------------
   Toasts
   -------------------------------------------------------------------------- */

.toast-stack {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 70;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    width: max-content;
    max-width: min(560px, calc(100vw - 32px));
}

.toast {
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: 100%;
    padding: 11px 14px 11px 18px;
    border-radius: 999px;
    background: var(--text);
    color: #fff;
    font-size: 13px;
    font-weight: 500;
    box-shadow: 0 12px 32px rgba(12, 16, 28, .28);
    animation: toastIn .22s ease both;
    transition: opacity .2s ease, transform .2s ease;
}
.toast.is-hiding { opacity: 0; transform: translateY(8px); }

.toast-icon { display: grid; place-items: center; flex: none; }
.toast-success .toast-icon { color: #7ee0ab; }
.toast-error   .toast-icon { color: #ff9d8a; }
.toast-warning .toast-icon { color: #f5c97b; }
.toast-info    .toast-icon { color: #a9b4ff; }

.toast-text { min-width: 0; }

.toast-close {
    display: grid;
    place-items: center;
    width: 24px;
    height: 24px;
    flex: none;
    border: none;
    background: transparent;
    border-radius: 50%;
    color: rgba(255, 255, 255, .55);
    cursor: pointer;
}
.toast-close:hover { background: rgba(255, 255, 255, .12); color: #fff; }

/* --------------------------------------------------------------------------
   Modals
   -------------------------------------------------------------------------- */

.modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 12vh 16px 16px;
    background: rgba(16, 20, 32, .42);
    backdrop-filter: blur(3px);
    overflow-y: auto;
}
.modal-backdrop[hidden] { display: none; }

.modal {
    width: min(440px, 100%);
    height: fit-content;
    padding: 22px 24px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    box-shadow: var(--shadow-pop);
    animation: riseIn .18s ease both;
}

.modal-icon {
    width: 40px;
    height: 40px;
    display: grid;
    place-items: center;
    margin-bottom: 14px;
    border-radius: 12px;
    background: var(--warn-banner-tint);
    color: var(--warn-solid);
}

.modal-title { margin: 0 0 6px; font-size: 16px; font-weight: 600; letter-spacing: -.01em; }
.modal-text { margin: 0 0 18px; font-size: 13px; color: var(--muted); line-height: 1.55; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }
.modal .form-group:last-of-type { margin-bottom: 0; }
.modal .modal-actions { margin-top: 18px; }

/* --------------------------------------------------------------------------
   Auth (login)
   -------------------------------------------------------------------------- */

.auth-body { background: var(--surface); }

.auth-shell {
    min-height: 100vh;
    display: grid;
    grid-template-columns: 1.05fr .95fr;
}

.auth-pane {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 40px;
    padding: 56px clamp(32px, 6vw, 96px);
    background: var(--surface);
}

.auth-brand { display: flex; align-items: center; gap: 10px; }
.auth-brand-name { font-weight: 600; font-size: 14.5px; letter-spacing: -.01em; }

.auth-form-wrap { max-width: 380px; width: 100%; }
.auth-title {
    margin: 0 0 8px;
    font-size: 40px;
    font-weight: 600;
    letter-spacing: -.025em;
    line-height: 1.08;
}
.auth-lead { margin: 0 0 28px; color: var(--muted); font-size: 14px; line-height: 1.6; }

.auth-foot { margin: 0; font-size: 12px; color: var(--faint); }

.auth-art {
    display: flex;
    align-items: flex-end;
    padding: 56px;
    background: linear-gradient(160deg, #eceafb 0%, #f6f7f9 60%, #e6f0f5 100%);
}

.auth-art-card {
    max-width: 360px;
    padding: 22px 24px;
    background: rgba(255, 255, 255, .9);
    backdrop-filter: blur(6px);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}
.auth-art-kicker {
    margin-bottom: 10px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--accent);
}
.auth-art-title {
    font-size: 20px;
    font-weight: 600;
    letter-spacing: -.015em;
    line-height: 1.25;
    color: var(--text);
}
.auth-art-text { margin-top: 6px; font-size: 13px; color: var(--muted); line-height: 1.6; }

/* --------------------------------------------------------------------------
   Focus + motion
   -------------------------------------------------------------------------- */

.btn:focus-visible,
a:focus-visible,
.icon-btn:focus-visible,
.affix-btn:focus-visible,
.toast-close:focus-visible,
.dropdown-item:focus-visible,
.user-menu-btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--accent-soft);
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

/* Tablet: collapse sidebar to an icon rail */
@media (max-width: 1180px) and (min-width: 761px) {
    .app-main { margin-left: var(--sidebar-rail); }
    .sidebar { width: var(--sidebar-rail); }
    .sidebar-brand { padding-left: 14px; padding-right: 14px; }
    .brand-name,
    .nav-group-label,
    .nav-link span,
    .sidebar-env,
    .sidebar-user { display: none; }
    .sidebar-nav { padding-left: 10px; padding-right: 10px; }
    .nav-link { justify-content: center; padding: 10px; }
    .sidebar-footer { display: flex; justify-content: center; padding: 12px 8px 16px; }
    .sidebar-footer::before {
        content: "";
        width: 7px;
        height: 7px;
        border-radius: 50%;
        animation: pulseDot 1.8s ease-in-out infinite;
    }
    .sidebar-footer.env-is-development::before { background: var(--warn-bright); }
    .sidebar-footer.env-is-staging::before     { background: var(--violet-bright); }
    .sidebar-footer.env-is-production::before  { background: var(--ok-bright); }
}

@media (max-width: 1024px) {
    .dash-columns { grid-template-columns: 1fr; }
}

/* Mobile: off-canvas drawer (toggled by .sidebar-open on body) */
@media (max-width: 760px) {
    .app-main { margin-left: 0; }

    .sidebar {
        transform: translateX(-100%);
        transition: transform .22s ease;
        box-shadow: none;
    }
    body.sidebar-open .sidebar {
        transform: translateX(0);
        box-shadow: var(--shadow-lift);
    }

    .icon-btn.sidebar-toggle { display: inline-grid; }

    .header-kicker { display: none; }
    .user-menu-name { display: none; }
    .user-menu-btn .icon:last-child { display: none; }

    .form-grid { grid-template-columns: 1fr; }
    .detail-list > div { grid-template-columns: 1fr; gap: 3px; }

    .auth-shell { grid-template-columns: 1fr; }
    .auth-art { display: none; }
    .auth-pane { padding: 36px 24px; }
    .auth-title { font-size: 32px; }

    .toast-stack { bottom: 16px; }
}

/* ---------------------------------------------------------------------------
   Hotel booking monitoring
--------------------------------------------------------------------------- */
.grid-2 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
    gap: 14px;
    align-items: stretch;
}

/* Vertical rhythm between section blocks — `.card + .card` alone does not
   cover grid wrappers, which left sections touching with zero margin. */
.grid-2 + .grid-2,
.grid-2 + .card,
.card + .grid-2 { margin-top: 14px; }

/* Cards that are grid items must not inherit the `.card + .card` flow
   margin — it pushed every card after the first 14px down inside its grid
   cell, making sibling cards in the same row start lower and end shorter. */
.stat-grid > .card,
.grid-2 > .card { margin-top: 0; }

/* Paired cards render as equal-height boxes; the detail rows share the
   surplus height so the shorter card never ends in dead whitespace. */
.grid-2 > .card { display: flex; flex-direction: column; min-width: 0; }
.grid-2 > .card > .card-head { flex: none; }
.grid-2 > .card > .detail-list {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
}
.grid-2 > .card > .detail-list > div { flex: 1 0 auto; }

.code-block {
    background: var(--surface-2, #f6f7f9);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 12px 14px;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 12px;
    line-height: 1.55;
    white-space: pre-wrap;
    word-break: break-word;
}

.btn-sm {
    padding: 4px 10px;
    font-size: 12.5px;
}

.row-actions form { display: inline-block; margin: 0; }
.page-actions form { display: inline-block; margin: 0; }
.page-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

.text-success { color: var(--ok-text, #166b45); }
.text-danger  { color: var(--danger-text, #b8391f); }

/* =====================================================================
   API Log viewer + shared loading/skeleton primitives
   ===================================================================== */

.text-warning { color: var(--warn-text, #a16a12); }

/* Label with a trailing action, e.g. "Password  …  Forgot password?" */
.label-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}
.label-row label { margin-bottom: 0; }
.label-link {
    font-size: 12.5px;
    color: var(--muted, #6b6a76);
    text-decoration: none;
}
.label-link:hover { color: var(--accent, #3f3ac4); text-decoration: underline; }

/* Totals row on the database table inventory. */
.table tfoot td {
    border-top: 2px solid var(--line, #e6e5ee);
    background: var(--canvas, #f6f5fa);
    font-size: 12.5px;
}
.grow { flex: 1 1 auto; min-width: 0; }
.w-90 { width: 90px; }

.stat-grid-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.stat-unit { font-size: 13px; font-weight: 500; color: var(--faint); margin-left: 3px; }

/* Filters --------------------------------------------------------------- */
.log-filters {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 16px 18px;
    border-bottom: 1px solid var(--border);
}
.log-filters-row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.log-filters input,
.log-filters select {
    height: 36px;
    padding: 0 11px;
    font: inherit;
    font-size: 13px;
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
}
.log-filters input:focus,
.log-filters select:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.filter-label {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 12.5px;
    color: var(--muted);
    white-space: nowrap;
}

/* Skeletons ------------------------------------------------------------- */
.skeleton {
    display: inline-block;
    height: 12px;
    border-radius: 6px;
    background: linear-gradient(90deg, var(--chip) 25%, var(--border) 50%, var(--chip) 75%);
    background-size: 200% 100%;
    animation: skeleton-shimmer 1.1s ease-in-out infinite;
}
.skeleton.w-30 { width: 30px; }
.skeleton.w-40 { width: 40px; }
.skeleton.w-50 { width: 50px; }
.skeleton.w-60 { width: 60px; }
.skeleton.w-70 { width: 70px; }
.skeleton.w-full { width: 100%; max-width: 260px; }
@keyframes skeleton-shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
    .skeleton { animation: none; }
}

/* Table ----------------------------------------------------------------- */
.log-table td { vertical-align: middle; }
.log-row { cursor: pointer; }
.log-row:hover td { background: var(--chip); }
.log-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.log-call { max-width: 340px; }
.log-endpoint {
    display: block;
    font-size: 11.5px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.log-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 18px;
    border-top: 1px solid var(--border);
    font-size: 12.5px;
}
.log-pager { display: flex; gap: 8px; }

/* Detail page ----------------------------------------------------------- */
.kv-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 14px 22px;
    padding: 18px;
    margin: 0;
}
.kv dt {
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--faint);
    margin-bottom: 3px;
}
.kv dd { margin: 0; font-size: 13.5px; word-break: break-word; }
.kv-copy { display: flex; align-items: center; gap: 6px; }
.kv-wrap { word-break: break-all; }

.card-danger { border-color: var(--danger-tint); }
.card-danger .card-title { color: var(--danger-text); }

.log-section { border-top: 1px solid var(--border); }
.log-section summary {
    padding: 12px 18px;
    font-size: 13px;
    font-weight: 600;
    color: var(--muted);
    cursor: pointer;
    user-select: none;
}
.log-section summary:hover { color: var(--text); }
.log-section .code-block,
.log-section .table-wrap { margin: 0 18px 16px; }
.log-section .code-block {
    max-height: 480px;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
}

/* Timeline -------------------------------------------------------------- */
.log-timeline { list-style: none; margin: 0; padding: 6px 18px 18px; }
.log-step {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 12px 10px 12px 4px;
    border-radius: var(--radius-sm);
}
.log-step + .log-step::before {
    content: "";
    position: absolute;
    left: 9px;
    top: -12px;
    height: 16px;
    border-left: 2px solid var(--border);
}
.log-step.is-current { background: var(--accent-tint); }
.log-step-dot {
    flex: none;
    width: 12px;
    height: 12px;
    margin-top: 5px;
    border-radius: 50%;
    border: 2px solid var(--surface);
    box-shadow: 0 0 0 1px var(--border-strong);
}
.dot-success    { background: var(--ok-bright); }
.dot-failed     { background: var(--danger-bright); }
.dot-timeout    { background: var(--warn-bright); }
.dot-pending,
.dot-processing { background: var(--violet-bright); }
.dot-cancelled  { background: var(--neutral-bright); }
.log-step-body { min-width: 0; flex: 1 1 auto; }
.log-step-top { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; font-size: 13px; }
.log-step-meta { margin-top: 3px; font-size: 11.5px; overflow-wrap: anywhere; }

@media (max-width: 1180px) {
    .stat-grid-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
    .stat-grid-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .log-filters-row { flex-direction: column; align-items: stretch; }
    .filter-label { justify-content: space-between; }
    .log-call { max-width: none; }
}

/* =====================================================================
   Confirmation modal v2 + busy/spinner states
   ===================================================================== */

.modal-subject {
    margin: -6px 0 4px;
    font-family: var(--font-mono);
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    background: var(--chip);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 6px 10px;
    display: inline-block;
    max-width: 100%;
    overflow-wrap: anywhere;
}

.modal-warning {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    margin: 2px 0 6px;
    padding: 8px 12px;
    font-size: 12.5px;
    color: var(--danger-text);
    background: var(--danger-tint);
    border-radius: var(--radius-sm);
}
.modal-warning .icon { flex: none; }

/* Buttons in flight: spinner replaces the label, clicks are inert. */
.btn.is-loading,
.icon-btn.is-loading {
    position: relative;
    pointer-events: none;
    color: transparent !important;
}
.btn.is-loading > .icon,
.icon-btn.is-loading > .icon { visibility: hidden; }
.btn.is-loading::after,
.icon-btn.is-loading::after {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    border: 2px solid rgba(21, 24, 36, 0.2);
    border-top-color: rgba(21, 24, 36, 0.75);
    animation: btn-spin 0.7s linear infinite;
}
.btn-primary.is-loading::after,
.btn-danger.is-loading::after,
.btn-success.is-loading::after,
.btn-warning.is-loading::after,
.btn-info.is-loading::after {
    border-color: rgba(255, 255, 255, 0.35);
    border-top-color: #fff;
}
@keyframes btn-spin {
    to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
    .btn.is-loading::after,
    .icon-btn.is-loading::after { animation-duration: 1.6s; }
}

/* Supplier connection-test verdict cell */
.conn-cell { white-space: nowrap; }
.conn-cell .cell-sub { display: block; font-size: 11px; color: var(--faint); margin-top: 3px; }
.conn-cell a.cell-sub { color: var(--accent); }

/* Banner variants for System Health */
.banner-ok     { background: var(--ok-tint); border: 1px solid #c8e6d5; }
.banner-ok .banner-icon { background: var(--ok-text); }
.banner-danger { background: var(--danger-tint); border: 1px solid #f5cfc2; }
.banner-danger .banner-icon { background: var(--danger-text); }

/* Supplier credential setup: schema-driven fields */
.cred-env-group { max-width: 320px; margin-bottom: 18px; }
.cred-key {
    display: inline-block;
    padding: 1px 7px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg);
    font-size: 11.5px;
    color: var(--muted);
}
.cred-status {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 4px 0 6px;
    font-size: 12.5px;
}
.cred-status .icon { flex-shrink: 0; }
.cred-status-ok    { color: var(--ok-solid); }
.cred-status-warn  { color: var(--warn-vivid); }
.cred-status-muted { color: var(--neutral-bright); }

.cred-advanced summary {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 20px;
    font-size: 13px;
    font-weight: 600;
    color: var(--muted);
    cursor: pointer;
    user-select: none;
}
.cred-advanced summary:hover { color: var(--text); }
.cred-advanced summary .icon { color: inherit; }
.cred-advanced-body { padding: 0 20px 20px; }
.cred-advanced-body > .page-sub { margin: 0 0 18px; }

/* ==========================================================================
   Hotel Booking Details — summary strip, sync logs & change tracking
   ========================================================================== */

.booking-summary {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    margin-bottom: 14px;
}

/* Each summary card is a fixed 3-band column — label / value / note — with a
   shared value-band height and a bottom-pinned note, so all four cards align
   on the same horizontal lines no matter what type of content they carry. */
.booking-summary .stat-card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}
.booking-summary .stat-label { line-height: 1.35; }
.booking-summary .stat-value,
.booking-summary .summary-badges {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    min-height: 32px;
    margin-top: 8px;
}
.booking-summary .stat-value { font-size: 22px; }
.booking-summary .stat-value-sm { font-size: 17px; line-height: 1.3; letter-spacing: -.01em; }
.booking-summary .stat-note { margin-top: auto; padding-top: 8px; }
.summary-urgent { border-color: var(--danger-tint); box-shadow: inset 3px 0 0 var(--danger-bright); }

/* Highlighted reference values (supplier confirmation, internal ref) */
.ref-highlight {
    display: inline-block;
    max-width: 100%;
    padding: 2px 8px;
    background: var(--accent-tint);
    border: 1px solid var(--accent-line);
    border-radius: var(--radius-sm);
    font-weight: 600;
    color: var(--accent);
    overflow-wrap: anywhere;
}

/* Sync timeline entries */
.sync-timeline .log-step { align-items: flex-start; }
.sync-timeline .log-step + .log-step { border-top: 1px solid var(--border); }
.sync-timeline .log-step + .log-step::before { display: none; }

.sync-note {
    margin-top: 7px;
    font-size: 12.5px;
    color: var(--faint);
    font-style: italic;
}
.sync-error {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 7px;
    padding: 5px 10px;
    font-size: 12.5px;
    color: var(--danger-text);
    background: var(--danger-tint);
    border-radius: var(--radius-sm);
}
.sync-error .icon { flex: none; }

/* Before → After field changes */
.chg-list {
    margin-top: 8px;
    display: grid;
    gap: 5px;
}
.chg-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
}
.chg-label {
    min-width: 150px;
    font-weight: 600;
    color: var(--muted);
}
.chg-old,
.chg-new {
    padding: 1px 8px;
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 12px;
    overflow-wrap: anywhere;
}
.chg-old {
    background: var(--danger-tint);
    color: var(--danger-text);
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}
.chg-new {
    background: var(--ok-tint);
    color: var(--ok-text);
    font-weight: 600;
}
.chg-arrow { color: var(--faint); }

/* Raw before/after snapshots inside a sync log entry */
.sync-raw { margin-top: 8px; }
.sync-raw > summary { cursor: pointer; font-size: 12px; }
.sync-raw-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
    gap: 10px;
    margin-top: 8px;
}
.sync-raw-grid .code-block { max-height: 260px; overflow: auto; margin: 0; }
.sync-raw-title {
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--faint);
    margin-bottom: 4px;
}

/* Summary strip: 4 → 2 → 1 columns. Forced column counts (instead of
   auto-fit) prevent the lopsided 3+1 wrap at intermediate widths. */
@media (max-width: 1220px) {
    .booking-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
    .chg-label { min-width: 100%; }
}
@media (max-width: 560px) {
    .booking-summary { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Table row actions — visible chip buttons (replaces ghosted faint icons)
   ========================================================================== */

.row-actions { gap: 6px; }

.row-actions .icon-btn {
    width: 32px;
    height: 32px;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--muted);
    box-shadow: 0 1px 2px rgba(21, 24, 36, .05);
    transition: background .15s ease, color .15s ease,
                border-color .15s ease, box-shadow .15s ease,
                transform .12s ease;
}
.row-actions .icon-btn:hover {
    background: var(--accent-tint);
    border-color: var(--accent-line);
    color: var(--accent);
    transform: translateY(-1px);
    box-shadow: 0 3px 8px rgba(63, 58, 196, .14);
}
.row-actions .icon-btn:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(21, 24, 36, .05); }

/* Semantic hover identities */
.row-actions .icon-btn-ok:hover {
    background: var(--ok-tint);
    border-color: var(--ok-live);
    color: var(--ok-text);
    box-shadow: 0 3px 8px rgba(18, 179, 119, .16);
}
.row-actions .icon-btn-warn:hover {
    background: var(--warn-tint);
    border-color: var(--warn-solid);
    color: var(--warn-text);
    box-shadow: 0 3px 8px rgba(184, 114, 26, .16);
}
.row-actions .icon-btn-danger:hover {
    background: var(--danger-tint);
    border-color: var(--danger-bright);
    color: var(--danger-text);
    box-shadow: 0 3px 8px rgba(240, 82, 60, .16);
}

/* ==========================================================================
   Connection test modal (supplier credentials page)
   ========================================================================== */

.modal-wide { width: min(760px, 100%); padding: 20px 22px; }

.tc-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}
.tc-title {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 15.5px;
    text-align: left;
}
.tc-title .icon { color: var(--faint); }

.tc-loading {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 22px 4px;
    font-size: 13px;
    color: var(--muted);
}
.tc-spinner {
    flex: none;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 2px solid var(--track);
    border-top-color: var(--accent);
    animation: btn-spin .7s linear infinite;
}

.tc-verdict {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 9px;
    font-size: 13.5px;
    font-weight: 600;
}
.tc-detail { margin: 6px 0 0; font-size: 12.5px; }

.tc-meta { display: grid; gap: 4px; margin: 12px 0 0; }
.tc-meta > div {
    display: grid;
    grid-template-columns: 110px 1fr;
    gap: 10px;
    font-size: 12.5px;
}
.tc-meta dt { font-weight: 600; color: var(--muted); }
.tc-meta dd { margin: 0; overflow-wrap: anywhere; }

.tc-logs { margin-top: 16px; border-top: 1px solid var(--border); padding-top: 12px; }
.tc-logs-title {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 0 0 8px;
    font-size: 13px;
    font-weight: 600;
}
.tc-logs-title .icon { color: var(--faint); }
.tc-logs-note { font-size: 12.5px; margin: 8px 0 0; }

.tc-log {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--field);
}
.tc-log + .tc-log { margin-top: 8px; }
.tc-log-summary {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    padding: 9px 12px;
    cursor: pointer;
    font-size: 12.5px;
    list-style: none;
}
.tc-log-summary::-webkit-details-marker { display: none; }
.tc-log[open] .tc-log-summary { border-bottom: 1px solid var(--border); }
.tc-log-op { font-weight: 600; overflow-wrap: anywhere; }
.tc-log-body { padding: 10px 12px 12px; }
.tc-log-body .tc-meta { margin: 0 0 8px; }
.tc-log-body .code-block { max-height: 240px; overflow: auto; margin: 0; }

.tc-payload-title {
    margin: 10px 0 4px;
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--faint);
}

.tc-actions { margin-top: 16px; }

@media (max-width: 640px) {
    .tc-meta > div { grid-template-columns: 1fr; gap: 2px; }
}

/* ==========================================================================
   Clickable table rows (tr[data-href])
   ========================================================================== */

.table-rowlink tbody tr[data-href] { cursor: pointer; }
.table-rowlink tbody tr[data-href]:hover { background: var(--row-hover); }
.table-rowlink tbody tr[data-href]:hover .rowlink-chevron { color: var(--accent); transform: translateX(2px); }

.rowlink-col { width: 34px; text-align: right; }
.rowlink-chevron { color: var(--faint); transition: color .15s ease, transform .15s ease; vertical-align: middle; }

.cell-link { color: inherit; }
.cell-link:hover { color: var(--accent); }

/* Credential modals (supplier details page) */
.cred-modal-sub { margin: 0 0 14px; text-align: left; }
.modal-scroll { max-height: 62vh; overflow-y: auto; padding-right: 4px; }
.modal-scroll .form-group + .form-group { margin-top: 14px; }

/* Danger banner (blocking configuration problems) */
.banner-danger { background: var(--danger-tint); border: 1px solid var(--danger-bright); }
.banner-danger .banner-icon { background: var(--danger-solid); }
.banner-danger .banner-title { color: var(--danger-strong); }
.banner-list { margin: 6px 0 0; padding-left: 18px; }
.banner-list li { margin: 2px 0; }
.banner-actions { margin-top: 10px; display: flex; gap: 8px; flex-wrap: wrap; }

/* Button that renders as a card-head link (modal openers) */
.linklike { background: none; border: none; padding: 0; cursor: pointer; font: inherit; color: var(--accent); display: inline-flex; align-items: center; gap: 5px; }
.linklike:hover { text-decoration: underline; }

/* Stored-keys table inside credential modals */
.cred-stored { margin-bottom: 14px; }
.table-compact td { padding: 7px 10px; font-size: 12.5px; }
.cred-stored .table-wrap { border: 1px solid var(--border); border-radius: var(--radius-sm); }

/* Body scroll lock while any modal is open (no background scroll,
   no double scrollbar; gutter kept to avoid layout shift). */
body.modal-open { overflow: hidden; }
html { scrollbar-gutter: stable; }

/* Supplier info modal context chips + URL rows with inline edit */
.info-context { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.url-row { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.url-row .icon-btn { width: 26px; height: 26px; }

/* ============================================================ Mapping tab */
.mapping-intro { margin: -6px 0 14px; font-size: 13px; max-width: 860px; }
.mapping-banner { margin-bottom: 14px; }
.mapping-booked {
    margin: 0 0 14px; padding: 12px 14px;
    background: var(--chip);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}
.mapping-booked-label {
    font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--faint); margin-bottom: 7px;
}
.mapping-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.mapping-status { font-size: 12.5px; margin: 0 0 10px; min-height: 18px; }
.mapping-table td { vertical-align: top; }
.mapping-sub { font-size: 11.5px; }
.mapping-room + .mapping-room { margin-top: 8px; }
.mapping-room-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.mapping-error { max-width: 320px; }
.mapping-best { margin-left: 6px; }
.mapping-spinner {
    width: 12px; height: 12px; border-width: 2px;
    margin-right: 7px; vertical-align: -1px;
}
.mapping-actions-cell { white-space: nowrap; }
.mapping-actions-cell .btn + .btn { margin-left: 6px; }

/* Details modal */
.mapping-attrs td, .mapping-attrs th { font-size: 12.5px; }
.mapping-stage {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px;
    padding: 8px 0; border-bottom: 1px dashed var(--border);
}
.mapping-stage:last-child { border-bottom: 0; }
.mapping-stage-name { font-size: 12.5px; }
.mapping-endpoint { max-width: 100%; overflow-wrap: anywhere; }
.mapping-detail {
    flex-basis: 100%; margin: 4px 0 0; padding: 8px 10px;
    background: #14142b; color: #e6e6f0;
    border-radius: var(--radius-sm);
    font-family: var(--font-mono); font-size: 11px; line-height: 1.5;
    max-height: 240px; overflow: auto; white-space: pre;
}
.mapping-stages, .mapping-apilogs { margin-bottom: 14px; }

/* --------------------------------------------------------------------------
   Sync bookings — live progress

   Replaces the form inside the dialog once a run starts. Every figure here
   comes from the server's own run counters, so the bar tracks real work:
   the fill is bookings processed out of bookings found, and it stays
   indeterminate only while the supplier's list call is still out and there
   is genuinely no total to divide by yet.
   -------------------------------------------------------------------------- */

.sync-progress-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 8px;
}
.sync-progress-label { font-size: 13px; font-weight: 600; color: var(--text); }
.sync-progress-elapsed { font-size: 11.5px; color: var(--faint); }

.progress-track {
    position: relative;
    height: 6px;
    border-radius: 999px;
    background: var(--track);
    overflow: hidden;
}
.progress-fill {
    height: 100%;
    width: 0;
    border-radius: 999px;
    background: var(--accent);
    transition: width .25s ease;
}
/* No total yet: a travelling band rather than a fake percentage. */
.progress-track.is-indeterminate .progress-fill {
    width: 35%;
    animation: progressSlide 1.15s ease-in-out infinite;
}
@keyframes progressSlide {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(320%); }
}
@media (prefers-reduced-motion: reduce) {
    .progress-track.is-indeterminate .progress-fill { animation: none; width: 100%; opacity: .45; }
    .progress-fill { transition: none; }
}

.sync-rows { list-style: none; margin: 14px 0 0; padding: 0; }
.sync-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: 13px;
}
.sync-row + .sync-row { margin-top: 8px; }
.sync-row.is-running { border-color: var(--accent-line); background: var(--accent-tint); }
.sync-row.is-failed  { border-color: var(--danger-bright); background: var(--danger-tint); }

.sync-row-dot {
    flex: none;
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--border-strong);
}
.sync-row.is-running .sync-row-dot { background: var(--accent); animation: pulseDot 1.1s ease-in-out infinite; }
.sync-row.is-done    .sync-row-dot { background: var(--ok-bright); }
.sync-row.is-partial .sync-row-dot { background: var(--warn-bright); }
.sync-row.is-failed  .sync-row-dot { background: var(--danger-bright); }

.sync-row-main { min-width: 0; flex: 1; }
.sync-row-name { font-weight: 600; }
.sync-row-note {
    display: block;
    margin-top: 2px;
    font-size: 11.5px;
    color: var(--muted);
    overflow-wrap: anywhere;
}
.sync-row-counts { flex: none; font-size: 11.5px; color: var(--muted); white-space: nowrap; }

.sync-progress .modal-actions { margin-top: 16px; }

/* --------------------------------------------------------------------------
   Settings → Cron Jobs
   -------------------------------------------------------------------------- */

.cron-interval-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
    gap: 16px;
}

.setup-steps { margin: 0; padding-left: 22px; }
.setup-steps > li { margin: 0 0 18px; font-size: 13px; line-height: 1.6; }
.setup-steps > li:last-child { margin-bottom: 4px; }
.setup-steps > li > strong { display: inline-block; margin-bottom: 2px; }
.setup-steps p { margin: 4px 0; }
.setup-steps .code-block { margin: 8px 0; }
.setup-copy { float: right; }
