/* ==========================================================================
   OXFORD PARTNER — agent panel design system
   agents/assets/css/agents.css

   This file is owned by /agents/ and loaded by nothing outside it. It is the
   only place component styling lives; page stylesheets add layout, never
   colour.

   EVERY TOKEN IS --ag- PREFIXED ON PURPOSE.
   The shared Oxford chrome declares :root blocks of its own (includes/
   footer_user.php redefines --card-bg to 3% white, which is what made
   "solid" cards go see-through elsewhere in this codebase). Nothing here may
   be renamed to a generic token, even though this panel ships its own
   chrome — a future include is one import away from the same collision.

   Colour lives in exactly two places:
     :root here          — the neutral scale and the semantic scale
     themes.css          — the eight brand ramps, swapped on [data-ag-theme]
   A component that hard-codes a brand hex is a bug; it will not follow the
   agent's chosen theme.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
    /* --- brand ramp ---------------------------------------------------
       Defined here so the panel renders correctly even if themes.css
       fails to load, and overridden wholesale per theme. These values are
       the Oxford Blue house ramp. */
    --ag-brand:        #12397f;
    --ag-brand-deep:   #0c2757;
    --ag-brand-2:      #1a4da3;
    --ag-brand-3:      #2f6fd0;
    --ag-accent:       #1f6feb;
    --ag-accent-hover: #1a5ed1;
    --ag-accent-soft:  #dbe7fb;
    --ag-accent-wash:  #eff4fd;
    --ag-accent-line:  rgba(31, 111, 235, .32);
    --ag-on-brand:     #ffffff;

    /* The sidebar and every brand-filled surface. One gradient, so a theme
       change moves the whole chrome at once. */
    --ag-brand-grad:   linear-gradient(168deg, #163f8b 0%, #12397f 38%, #0c2757 100%);
    --ag-accent-grad:  linear-gradient(135deg, #2f6fd0 0%, #1f6feb 100%);

    /* --- ground & surfaces ------------------------------------------- */
    --ag-ground:       #f4f6fb;
    --ag-surface:      #ffffff;
    --ag-surface-2:    #f8fafd;
    --ag-surface-3:    #eef2f9;
    --ag-overlay:      rgba(10, 22, 46, .52);

    /* --- ink ---------------------------------------------------------- */
    --ag-ink:          #111a2e;
    --ag-ink-2:        #42506b;
    --ag-ink-3:        #6b7790;
    --ag-ink-4:        #95a0b5;

    /* --- lines & shadow ---------------------------------------------- */
    --ag-line:         #dde3ee;
    --ag-line-soft:    #eaeef6;
    --ag-line-strong:  #c6cfe0;
    --ag-shadow-xs:    0 1px 2px rgba(17, 26, 46, .05);
    --ag-shadow-sm:    0 1px 3px rgba(17, 26, 46, .06), 0 4px 12px -6px rgba(17, 26, 46, .10);
    --ag-shadow:       0 2px 6px rgba(17, 26, 46, .05), 0 14px 32px -20px rgba(12, 39, 87, .32);
    --ag-shadow-lg:    0 4px 12px rgba(17, 26, 46, .06), 0 30px 60px -32px rgba(12, 39, 87, .40);
    --ag-ring:         0 0 0 3px var(--ag-accent-soft);

    /* --- semantic ----------------------------------------------------
       Independent of the brand ramp: "paid" must stay green in the Crimson
       theme, or the status colours stop meaning anything. */
    --ag-ok:           #0f7a4f;
    --ag-ok-bg:        #e4f4ec;
    --ag-ok-line:      #b7e0cb;
    --ag-warn:         #8a5a06;
    --ag-warn-bg:      #fdf1dc;
    --ag-warn-line:    #f0d6a4;
    --ag-danger:       #a8242f;
    --ag-danger-bg:    #fbe8e9;
    --ag-danger-line:  #f1c2c6;
    --ag-info:         #0d5f9e;
    --ag-info-bg:      #e4f0fa;
    --ag-info-line:    #b9d8ef;

    /* --- type -------------------------------------------------------- */
    --ag-font:      "Inter", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
    --ag-font-head: "Plus Jakarta Sans", "Inter", "Segoe UI", system-ui, sans-serif;
    --ag-font-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;

    /* --- metrics ----------------------------------------------------- */
    --ag-rail:      266px;   /* sidebar, expanded */
    --ag-rail-slim: 76px;    /* sidebar, collapsed */
    --ag-topbar:    64px;
    /* The content column. Narrower than the old 1560 so a page reads as a
       document rather than a wall, matching the reference front end. */
    --ag-shell:     1320px;
    /* 90% of the available width, capped at the shell: the content keeps a
       margin either side on every screen, and never grows past the shell on a
       very wide monitor. A page can override this token alone. */
    --ag-col:       min(var(--ag-shell), 90%);
    --ag-radius:    14px;
    --ag-radius-sm: 9px;
    --ag-radius-lg: 20px;
    --ag-gap:       18px;

    /* One duration for everything that moves, so the panel feels like one
       piece of software. */
    --ag-ease:      200ms cubic-bezier(.4, 0, .2, 1);
}

/* --------------------------------------------------------------------------
   2. Reset
   -------------------------------------------------------------------------- */

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

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

body.ag-body {
    margin: 0;
    font-family: var(--ag-font);
    font-size: 14.5px;
    line-height: 1.55;
    color: var(--ag-ink);
    background: var(--ag-ground);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* EVERY ELEMENT DEFAULT BELOW IS WRAPPED IN :where(), WHICH HAS ZERO SPECIFICITY.
   They were written as `.ag-body a`, `.ag-body h2` — class + element, which
   BEATS a single component class like `.ag-nav-link` or `.ag-btn-primary`. So
   every link-shaped component inherited the accent colour: sidebar entries and
   filled buttons went accent-on-accent and their text vanished, and
   `.ag-dash-h` rendered as a full-size h2 instead of a small label. Zero
   specificity means these are true defaults: any component class wins, while
   they still beat the browser's own stylesheet. */

:where(.ag-body img, .ag-body svg) { max-width: 100%; }
:where(.ag-body img) { height: auto; }

[hidden] { display: none !important; }

:where(.ag-body h1, .ag-body h2, .ag-body h3,
       .ag-body h4, .ag-body h5, .ag-body h6) {
    margin: 0 0 .5em;
    font-family: var(--ag-font-head);
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -.01em;
    color: var(--ag-ink);
}

:where(.ag-body h1) { font-size: 1.6rem; }
:where(.ag-body h2) { font-size: 1.3rem; }
:where(.ag-body h3) { font-size: 1.08rem; }
:where(.ag-body h4) { font-size: .98rem; }

:where(.ag-body p) { margin: 0 0 1em; }
:where(.ag-body p:last-child) { margin-bottom: 0; }

:where(.ag-body a) {
    color: var(--ag-accent);
    text-decoration: none;
    transition: color var(--ag-ease);
}
:where(.ag-body a:hover) { color: var(--ag-accent-hover); text-decoration: underline; }

:where(.ag-body hr) {
    height: 1px;
    margin: var(--ag-gap) 0;
    border: 0;
    background: var(--ag-line);
}

/* Visible focus on every interactive thing, always. Agents work this panel
   all day and many of them keyboard through the booking forms. */
.ag-body :is(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--ag-accent);
    outline-offset: 2px;
    border-radius: 4px;
}

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

/* --------------------------------------------------------------------------
   3. Shell — sidebar rail, topbar, content
   -------------------------------------------------------------------------- */

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

/* --- sidebar ------------------------------------------------------------ */

.ag-rail {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 60;
    width: var(--ag-rail);
    display: flex;
    flex-direction: column;
    background: var(--ag-brand-grad);
    color: #fff;
    transition: width var(--ag-ease), transform var(--ag-ease);
}

/* The hairline that separates rail from content, drawn inside the rail so it
   scrolls with nothing and never doubles up with a card border. */
.ag-rail::after {
    content: "";
    position: absolute;
    inset: 0 0 0 auto;
    width: 1px;
    background: rgba(255, 255, 255, .10);
}

.ag-rail-head {
    display: flex;
    align-items: center;
    gap: 11px;
    height: var(--ag-topbar);
    padding: 0 18px;
    flex: 0 0 auto;
    border-bottom: 1px solid rgba(255, 255, 255, .10);
}

.ag-rail-logo {
    display: grid;
    place-items: center;
    width: 38px; height: 38px;
    flex: 0 0 38px;
    border-radius: 11px;
    background: rgba(255, 255, 255, .14);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .16);
    overflow: hidden;
}
.ag-rail-logo img { width: 100%; height: 100%; object-fit: contain; padding: 4px; }

.ag-rail-name {
    min-width: 0;
    font-family: var(--ag-font-head);
    font-weight: 700;
    font-size: .98rem;
    letter-spacing: -.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ag-rail-name small {
    display: block;
    font-family: var(--ag-font);
    font-weight: 500;
    font-size: .68rem;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .58);
}

.ag-rail-scroll {
    flex: 1 1 auto;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 14px 12px 18px;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, .22) transparent;
}
.ag-rail-scroll::-webkit-scrollbar { width: 7px; }
.ag-rail-scroll::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, .20);
    border-radius: 99px;
}

.ag-rail-group {
    margin: 16px 0 7px;
    padding: 0 10px;
    font-size: .66rem;
    font-weight: 700;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .42);
}
.ag-rail-group:first-child { margin-top: 2px; }

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

.ag-nav-link {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9.5px 12px;
    border-radius: 10px;
    font-size: .9rem;
    font-weight: 500;
    color: rgba(255, 255, 255, .80);
    white-space: nowrap;
    transition: background var(--ag-ease), color var(--ag-ease);
}
.ag-body .ag-nav-link:hover {
    background: rgba(255, 255, 255, .10);
    color: #fff;
    text-decoration: none;
}

.ag-nav-link.is-active {
    background: rgba(255, 255, 255, .16);
    color: #fff;
    font-weight: 600;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12);
}
/* The current-page marker. On the rail edge so it reads as a tab into the
   content area rather than a decoration on the pill. */
.ag-nav-link.is-active::before {
    content: "";
    position: absolute;
    left: -12px; top: 50%;
    width: 3px; height: 22px;
    transform: translateY(-50%);
    border-radius: 0 3px 3px 0;
    background: #fff;
}

/* Line art in the row's own colour. The colour-coded solid glyphs live in the
   header module bar; the rail stays quiet so the labels lead. */
.ag-nav-ico {
    flex: 0 0 20px;
    width: 20px; height: 20px;
    stroke: currentColor;
    stroke-width: 1.7;
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: .92;
}

.ag-nav-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

.ag-nav-tag {
    margin-left: auto;
    padding: 1px 7px;
    border-radius: 99px;
    font-size: .66rem;
    font-weight: 700;
    background: rgba(255, 255, 255, .20);
    color: #fff;
}
.ag-nav-tag.is-alert { background: #e0566a; }

.ag-nav-link.is-danger { color: #ffc3c9; }
.ag-body .ag-nav-link.is-danger:hover { background: rgba(224, 86, 106, .22); color: #fff; }

/* --- the collapsed rail ------------------------------------------------
   A single [data-ag-rail="slim"] on the shell drives both the rail and the
   content offset, so the two can never disagree mid-transition. */
.ag-shell[data-ag-rail="slim"] .ag-rail { width: var(--ag-rail-slim); }
.ag-shell[data-ag-rail="slim"] .ag-main { margin-left: var(--ag-rail-slim); }
.ag-shell[data-ag-rail="slim"] .ag-rail-name,
.ag-shell[data-ag-rail="slim"] .ag-nav-label,
.ag-shell[data-ag-rail="slim"] .ag-nav-tag,
.ag-shell[data-ag-rail="slim"] .ag-rail-group,
.ag-shell[data-ag-rail="slim"] .ag-rail-foot { display: none; }
.ag-shell[data-ag-rail="slim"] .ag-rail-head { justify-content: center; padding: 0; }
.ag-shell[data-ag-rail="slim"] .ag-nav-link { justify-content: center; padding: 11px 0; }

.ag-rail-foot {
    flex: 0 0 auto;
    padding: 13px 16px;
    border-top: 1px solid rgba(255, 255, 255, .10);
    font-size: .72rem;
    color: rgba(255, 255, 255, .52);
}

/* --- main column -------------------------------------------------------- */

.ag-main {
    flex: 1 1 auto;
    min-width: 0;
    margin-left: var(--ag-rail);
    display: flex;
    flex-direction: column;
    transition: margin var(--ag-ease);
}

/* --- patterned ground ----------------------------------------------------
   An eight-point girih star tile, the same geometry the Zaereen front end
   uses. It is drawn in black and used as a MASK rather than as a coloured
   background image: a data URI cannot read a CSS variable, so tinting it any
   other way would mean eight near-identical copies of this blob, one per
   theme, and a ninth every time a theme is added. Masked, the fill is just
   var(--ag-accent) and it follows the agent's chosen colour for free.
   Every page in the panel carries it, so moving between them does not change
   the ground under the cards. */

:root {
    --ag-pattern: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cg fill='none' stroke='%23000' stroke-width='1.05'%3E%3Cpath d=%22M0.00 -14.14 L2.26 -5.45 L10.00 -10.00 L5.45 -2.26 L14.14 0.00 L5.45 2.26 L10.00 10.00 L2.26 5.45 L0.00 14.14 L-2.26 5.45 L-10.00 10.00 L-5.45 2.26 L-14.14 0.00 L-5.45 -2.26 L-10.00 -10.00 L-2.26 -5.45 Z%22/%3E%3Cpath d=%22M40.00 -14.14 L42.26 -5.45 L50.00 -10.00 L45.45 -2.26 L54.14 0.00 L45.45 2.26 L50.00 10.00 L42.26 5.45 L40.00 14.14 L37.74 5.45 L30.00 10.00 L34.55 2.26 L25.86 0.00 L34.55 -2.26 L30.00 -10.00 L37.74 -5.45 Z%22/%3E%3Cpath d=%22M0.00 25.86 L2.26 34.55 L10.00 30.00 L5.45 37.74 L14.14 40.00 L5.45 42.26 L10.00 50.00 L2.26 45.45 L0.00 54.14 L-2.26 45.45 L-10.00 50.00 L-5.45 42.26 L-14.14 40.00 L-5.45 37.74 L-10.00 30.00 L-2.26 34.55 Z%22/%3E%3Cpath d=%22M40.00 25.86 L42.26 34.55 L50.00 30.00 L45.45 37.74 L54.14 40.00 L45.45 42.26 L50.00 50.00 L42.26 45.45 L40.00 54.14 L37.74 45.45 L30.00 50.00 L34.55 42.26 L25.86 40.00 L34.55 37.74 L30.00 30.00 L37.74 34.55 Z%22/%3E%3Cpath d=%22M20.00 5.86 L22.26 14.55 L30.00 10.00 L25.45 17.74 L34.14 20.00 L25.45 22.26 L30.00 30.00 L22.26 25.45 L20.00 34.14 L17.74 25.45 L10.00 30.00 L14.55 22.26 L5.86 20.00 L14.55 17.74 L10.00 10.00 L17.74 14.55 Z%22/%3E%3C/g%3E%3Cg fill='%23000'%3E%3Cpath d=%22M20.00 -3.40 L23.40 0.00 L20.00 3.40 L16.60 0.00 Z%22/%3E%3Cpath d=%22M0.00 16.60 L3.40 20.00 L0.00 23.40 L-3.40 20.00 Z%22/%3E%3Cpath d=%22M40.00 16.60 L43.40 20.00 L40.00 23.40 L36.60 20.00 Z%22/%3E%3Cpath d=%22M20.00 36.60 L23.40 40.00 L20.00 43.40 L16.60 40.00 Z%22/%3E%3C/g%3E%3C/svg%3E");
    /* The stepped merlon fringe used where a dark band meets the content —
       the search bar and the package hero both draw it. Black, for use as a
       mask, so it takes the theme colour. */
    --ag-crest: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='16' viewBox='0 0 24 18'%3E%3Cpath d='M0,18 L0,13 L4,13 L4,8 L8,8 L8,3 L12,0 L16,3 L16,8 L20,8 L20,13 L24,13 L24,18 Z' fill='%23000'/%3E%3C/svg%3E");
}

.ag-main {
    position: relative;
    background-color: var(--ag-accent-wash);
}
.ag-main::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-color: var(--ag-accent);
    opacity: .11;
    -webkit-mask-image: var(--ag-pattern);
            mask-image: var(--ag-pattern);
    /* Small on purpose: at tile size this reads as a fine damask behind the
       cards, which is what the Zaereen front end does. Larger and the stars
       start competing with the content. */
    -webkit-mask-size: 26px 26px;
            mask-size: 26px 26px;
}
/* The tile is absolutely positioned, so it paints over the text of any
   sibling that is not itself positioned. The topbar is already sticky. */
.ag-content {
    position: relative;
    z-index: 1;
}

/* The header carries the rail's colour, so the two read as one frame around
   the content rather than as a white strip sitting on a coloured sidebar.
   Flat --ag-brand, not the rail's gradient: 64px of a 168deg gradient is a
   slice that never lines up with the rail's own stop at any window height. */
.ag-topbar {
    position: sticky;
    top: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    gap: 12px;
    height: var(--ag-topbar);
    padding: 0 20px;
    background: var(--ag-brand);
    border-bottom: 1px solid rgba(255, 255, 255, .10);
}

/* --- the bar's contents, now on a dark ground ---------------------------- */

.ag-topbar .ag-icon-btn { color: rgba(255, 255, 255, .82); }
.ag-topbar .ag-icon-btn:hover { background: rgba(255, 255, 255, .14); color: #fff; }
.ag-topbar .ag-icon-btn .ag-dot { box-shadow: 0 0 0 2px var(--ag-brand); }

.ag-topbar .ag-balance {
    background: rgba(255, 255, 255, .12);
    border-color: rgba(255, 255, 255, .18);
    box-shadow: none;
}
.ag-body .ag-topbar .ag-balance:hover { border-color: rgba(255, 255, 255, .38); }
.ag-topbar .ag-balance-k { color: rgba(255, 255, 255, .66); }
.ag-topbar .ag-balance-v { color: #fff; }
/* --ag-danger is tuned for white and goes muddy here. */
.ag-topbar .ag-balance-v.is-low { color: #ffb1b1; }

.ag-topbar .ag-who:hover { background: rgba(255, 255, 255, .12); }
.ag-topbar .ag-who-name { color: #fff; }
.ag-topbar .ag-who-role { color: rgba(255, 255, 255, .6); }
.ag-topbar .ag-who > svg { color: rgba(255, 255, 255, .7); }

/* --- module bar ----------------------------------------------------------
   The icon row /b2b/ carries in its navbar, in this panel's own icon set.
   Each tile's identity colour arrives as --tile from ui/topbar.php. */

.ag-modbar {
    display: flex;
    align-items: stretch;
    /* Room between the nine marks, as /b2b/'s bar has it: at 8px the glyphs ran
       together into one band of colour and the row read as a single control
       rather than nine destinations. */
    gap: 18px;
    min-width: 0;
}

.ag-modbar-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    padding: 6px 10px;
    border-radius: 11px;
    line-height: 1;
    transition: background var(--ag-ease);
}
.ag-body .ag-modbar-item:hover { background: rgba(255, 255, 255, .13); text-decoration: none; }
.ag-modbar-item.is-on { background: rgba(255, 255, 255, .17); }

/* No tile behind the glyph, as in /b2b/: on the dark bar the solid colour is
   the marker, and a tinted plate only dulls it. */
.ag-modbar-ico {
    display: grid;
    place-items: center;
    color: var(--tile);
}
.ag-modbar-ico svg {
    /* Bigger than the rail's 20px, as /b2b/ draws them: this bar is a row of
       marks read at a glance, not a list read down the side, and the icon is
       what is actually aimed at — the label under it is a caption. */
    width: 26px; height: 26px;
    fill: currentColor;
    stroke: none;
}

.ag-modbar-label {
    font-size: .68rem;
    font-weight: 600;
    white-space: nowrap;
    color: rgba(255, 255, 255, .76);
}
.ag-modbar-item.is-on .ag-modbar-label { color: #fff; }

.ag-icon-btn {
    display: grid;
    place-items: center;
    width: 38px; height: 38px;
    flex: 0 0 38px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: 10px;
    background: transparent;
    color: var(--ag-ink-2);
    cursor: pointer;
    transition: background var(--ag-ease), color var(--ag-ease), border-color var(--ag-ease);
}
.ag-icon-btn:hover { background: var(--ag-surface-3); color: var(--ag-ink); }
.ag-icon-btn svg {
    width: 19px; height: 19px;
    stroke: currentColor; stroke-width: 1.8; fill: none;
    stroke-linecap: round; stroke-linejoin: round;
}
.ag-icon-btn .ag-dot {
    position: absolute;
    top: 8px; right: 9px;
    width: 7px; height: 7px;
    border-radius: 50%;
    background: #e0566a;
    box-shadow: 0 0 0 2px var(--ag-surface);
}
.ag-icon-btn { position: relative; }

.ag-topbar-title {
    min-width: 0;
    font-family: var(--ag-font-head);
    font-weight: 700;
    font-size: 1.02rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ag-topbar-spacer { flex: 1 1 auto; }

/* The balance chip. Two figures in this business disagree by design — the
   ledger balance and the bookings total come from different tables — so the
   chip shows ONE labelled number and links to the report for the rest. */
.ag-balance {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 6px 13px;
    border: 1px solid var(--ag-line);
    border-radius: 99px;
    background: var(--ag-surface);
    box-shadow: var(--ag-shadow-xs);
    font-size: .82rem;
    white-space: nowrap;
}
.ag-body .ag-balance:hover { border-color: var(--ag-accent-line); text-decoration: none; }
.ag-balance-k {
    font-size: .66rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ag-ink-3);
}
.ag-balance-v { font-weight: 700; color: var(--ag-ink); font-variant-numeric: tabular-nums; }
.ag-balance-v.is-low { color: var(--ag-danger); }

.ag-content {
    flex: 1 1 auto;
    width: 100%;
    /* --ag-col, not the expression inline: the hero band and the facts strip
       are measured against the SAME column, so a page that widens one has to
       widen all three or the band and the content stop lining up. Setting the
       token once is what keeps them together — see $ag_col in ui/shell_open. */
    max-width: var(--ag-col);
    margin: 0 auto;
    padding: 22px 20px 48px;
}

/* --- key/value rows --------------------------------------------------------
   A label beside its value: a booking's facts, a hotel's details, a lead's
   record. Moved out of bookings.css when the hotel page started using it —
   that page does not load bookings.css, so its Contact tab rendered as an
   unstyled definition list with the values indented under the labels.
   -------------------------------------------------------------------------- */
.ag-kv {
    display: grid;
    grid-template-columns: minmax(120px, auto) 1fr;
    gap: 9px 16px;
    margin: 0;
    font-size: .875rem;
}
.ag-kv dt {
    color: var(--ag-ink-3);
    font-size: .8rem;
}
.ag-kv dd {
    margin: 0;
    color: var(--ag-ink);
    font-weight: 500;
    min-width: 0;
    overflow-wrap: break-word;
}

/* On a phone the label sits above its value — two columns of 160px each is
   narrower than most of the values they hold. */
@media (max-width: 720px) {
    .ag-kv { grid-template-columns: minmax(0, 1fr); gap: 2px 0; }
    .ag-kv dt { margin-top: 8px; }
}

/* --- the booking panels ------------------------------------------------------
   The chrome behind BOTH the package page's "Plan your journey" and the hotel
   page's "Book your stay": a dark head over a light body, the labelled fields,
   the party steppers and the two buttons. It lives here rather than in
   package.css because the hotel page does not load that sheet — its panel
   rendered as unstyled black blocks until this moved.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   THE ACCENT SET for the whole booking flow — quote panel, enquiry dialog,
   reservation page — declared once.

   All three run on TWO tones, as the reference front end does: a dark band
   over a light ground. Both now come from the THEME the agent picked in
   Appearance, so the flow wears the panel's own colours instead of a champagne
   gold that belonged to no theme and clashed with eight of the nine.

   Every value is derived from the accent ramp themes.css already ships, so a
   new theme needs nothing added here:

     --gold       ink, icons and hairline text on a light ground   (accent)
     --gold-soft  the same on a DARK band — accent lifted towards white,
                  because the sober accents sit darker than white and read as
                  greyed-out when set straight onto the brand-deep band
     --gold-wash  the tint behind a tile or a total                (accent-wash)
     --gold-line  hairlines and field borders                      (accent-soft)
     --gold-grad  the primary button                               (accent-grad)

   The names are kept: they are load-bearing across three stylesheets, and
   renaming them buys nothing a comment cannot say.

   This lives on .ag-body rather than on .ag-pk-plan, where it started: a modal
   is a child of <body>, not of the panel, so every rule outside the panel was
   resolving to its fallback — which is why the enquiry button once rendered as
   a white outline instead of the filled slab it is written to be.
   -------------------------------------------------------------------------- */
.ag-body {
    --gold:      var(--ag-accent);
    /* Plain fallback first, for a browser without color-mix. */
    --gold-soft: #cbd8e8;
    --gold-soft: color-mix(in srgb, var(--ag-accent) 42%, #fff);
    --gold-wash: var(--ag-accent-wash);
    --gold-line: var(--ag-accent-soft);
    --gold-grad: var(--ag-accent-grad);
    /* The ground a field or an inner tile sits on: a hair lighter than the
       wash it sits inside, so the two are distinguishable in every theme. */
    --gold-card: #fff;
    --gold-card: color-mix(in srgb, var(--ag-accent-wash) 35%, #fff);
    /* What reads on top of --gold-grad. The accent ramps are dark, so this is
       white in every shipped theme. */
    --gold-on:   #fff;

    /* A DARKER rule for a table grid. --gold-line is an accent at ~18% and is
       right for a field border sitting on a tinted panel; ruling a table with
       it left lines that were there but could not be seen. This is the same
       hue at roughly half strength. */
    --gold-rule: #b9c6d8;
    --gold-rule: color-mix(in srgb, var(--ag-accent) 45%, #fff);

    /* The party steppers' own two marks. Deliberately NOT themed — see
       .ag-pk-field label. The -ink pair is a step darker so the small caps
       label clears AA on the panel's white ground, which the button fills
       (set behind white glyphs at 32px) do not have to. */
    --ag-pk-green:     #22a05b;
    --ag-pk-green-ink: #1a7d47;
    --ag-pk-amber:     #e79a1f;
    --ag-pk-amber-ink: #a96c09;
}

/* ==========================================================================

/* --- quote panel ---------------------------------------------------------- */

/* --------------------------------------------------------------------------
   The quote panel runs on TWO colours, as the reference does: the theme's own
   dark brand, and gold. The gold is deliberately NOT themed — it is the one
   warm accent in a panel of sober ramps, and the same champagne the hero title
   uses, so the two read as one design rather than two.
   -------------------------------------------------------------------------- */

.ag-pk-plan { overflow: hidden; }

.ag-pk-plan-head {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 11px;
    padding: 15px 13px;
    background: var(--ag-brand-deep);
    font-family: var(--ag-font-head);
    font-size: .96rem;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--gold-soft);
}
.ag-pk-plan-head svg { color: var(--gold-soft); }
.ag-pk-plan-head svg {
    width: 17px; height: 17px;
    stroke: currentColor; stroke-width: 1.8; fill: none;
}

.ag-pk-plan-row {
    display: grid;
    grid-template-columns: 1.4fr 1fr 1fr;
    gap: 10px;
    margin-bottom: 16px;
}
.ag-pk-field label {
    display: flex;
    align-items: center;
    /* Centred over the control it names, so the three read as one row of
       three columns rather than as three left-ragged blocks. */
    justify-content: center;
    gap: 5px;
    margin-bottom: 5px;
    font-size: .62rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--ag-ink-3);
}
.ag-pk-field label svg {
    width: 12px; height: 12px;
    color: currentColor;
    stroke: currentColor; stroke-width: 1.9; fill: none;
}
/* The three controls are colour-coded as /b2b/'s booking card codes them —
   date amber, adults green, children amber — and the label takes the same
   colour as the buttons under it, so the eye pairs them without reading.
   These three stay FIXED across themes on purpose: they are a semantic code
   (who is travelling), not decoration, and re-tinting them per theme would
   make adults green in one panel and claret in the next. */
.ag-pk-field.is-date label     { color: var(--ag-pk-amber-ink); }
.ag-pk-field.is-adults label   { color: var(--ag-pk-green-ink); }
.ag-pk-field.is-children label { color: var(--ag-pk-amber-ink); }

.ag-pk-step {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 44px;
    padding: 0 5px;
    border: 1px solid var(--ag-line);
    border-radius: 10px;
    background: var(--ag-surface-2);
}
/* Smaller than the pill they sit in, not filling it: at 32px the two buttons
   crowded the count between them and the control read as three slabs. The pill
   keeps its 44px so the date, adults and children fields stay on one line. */
.ag-pk-step button {
    width: 26px; height: 26px;
    padding: 0;
    border: 0;
    border-radius: 7px;
    background: var(--ag-pk-green);
    font-size: .95rem;
    line-height: 1;
    color: #fff;
    cursor: pointer;
    transition: filter var(--ag-ease);
}
.ag-pk-step button:hover:not(:disabled) { filter: brightness(1.1); }
.ag-pk-step button:disabled { opacity: .3; cursor: not-allowed; }
/* Adults green, children amber — the reference's pairing. */
.ag-pk-step.is-alt button { background: var(--ag-pk-amber); }
.ag-pk-step span {
    font-size: 1rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--ag-ink);
}

/* Two outline actions and one gold, as the reference has them. */
.ag-pk-btn2,
.ag-pk-btn-go {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    height: 42px;
    padding: 0 14px;
    border-radius: 10px;
    font-family: var(--ag-font);
    font-size: .88rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
}
.ag-pk-btn2 {
    flex: 0 1 auto;
    border: 1px solid var(--gold-line);
    background: var(--ag-surface);
    color: var(--ag-ink-2);
}
.ag-body .ag-pk-btn2:hover { border-color: var(--gold); color: var(--ag-ink); text-decoration: none; }
.ag-pk-btn2 svg { width: 15px; height: 15px; color: var(--gold); stroke: currentColor; stroke-width: 1.9; fill: none; }

.ag-pk-btn-go {
    flex: 1 1 auto;
    border: 1px solid var(--ag-accent);
    background: var(--gold-grad);
    color: var(--gold-on);
}
.ag-body .ag-pk-btn-go:hover { filter: brightness(1.06); text-decoration: none; color: var(--gold-on); }
.ag-pk-btn-go svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 2.2; fill: none; }
/* The heart sits inline here, not floated over an image. */
.ag-pk-cta .ag-wish {
    position: static;
    flex: 0 0 40px;
    width: 40px; height: 40px;
    border: 1px solid var(--ag-line);
    background: var(--ag-surface-2);
    box-shadow: none;
}

.ag-pk-note {
    margin: 11px 0 0;
    font-size: .73rem;
    line-height: 1.5;
    color: var(--ag-ink-3);
}

/* --- a filter rail beside a list ---------------------------------------------
   Hotels, visas, activities and bookings all put a narrowing rail to the left
   of their results. It lives here rather than in hotels.css, where it started,
   because three of those four pages do not load that sheet — and each time one
   of them adopted the rail it rendered full width, stacked above the list it
   was meant to filter.
   -------------------------------------------------------------------------- */

.ag-hsplit {
    display: grid;
    grid-template-columns: 280px minmax(0, 1fr);
    gap: var(--ag-gap);
    align-items: start;
}
.ag-hmain { min-width: 0; }

@media (max-width: 1080px) {
    /* Above the list rather than beside it, and never pinned: a rail stuck to
       the top of a one-column page covers the results it filters. */
    .ag-hsplit { grid-template-columns: minmax(0, 1fr); }
}

/* --- content beside a rail --------------------------------------------------
   Shared by the package page and the hotel page: a content column with a fixed
   400px panel beside it. Moved here from package.css for the same reason the
   tabs were — the hotel page does not load that sheet, and without these three
   rules its "Book your stay" panel rendered underneath the room list instead of
   beside it.

   The panel is a FIXED column, not a share of the page: widen the window and
   the extra goes to the content, which can use it, rather than stretching a
   panel whose controls are already the size they want to be.
   -------------------------------------------------------------------------- */
.ag-pk-split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 400px;
    gap: var(--ag-gap);
    align-items: start;
}
.ag-pk-main { min-width: 0; }
.ag-pk-aside { min-width: 0; position: sticky; top: calc(var(--ag-topbar) + 14px); }

@media (max-width: 1080px) {
    .ag-pk-split { grid-template-columns: minmax(0, 1fr); }
    .ag-pk-aside { position: static; }
}

/* --- tabs ------------------------------------------------------------------
   Shared: the package page and the hotel page wear the same strip. It lives
   here rather than in package.css because agents.css is the one sheet every
   page loads, and the hotel page does not load package.css.
   -------------------------------------------------------------------------- */

.ag-pk-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 3px;
    margin-bottom: -1px;        /* the open tab joins the card below */
    padding: 0 10px;
}
.ag-pk-tab {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 9px 16px 10px;
    /* A closed tab has to be a shade DARKER than the page it sits on, or it
       disappears into it — surface-2 is all but the page's own colour here. */
    border: 1px solid var(--ag-line);
    border-color: color-mix(in srgb, var(--ag-accent) 28%, var(--ag-line));
    border-bottom-color: transparent;
    border-radius: 10px 10px 0 0;
    background: var(--ag-surface-3);
    background: color-mix(in srgb, var(--ag-accent) 10%, var(--ag-surface));
    font-family: var(--ag-font);
    font-size: .86rem;
    font-weight: 600;
    /* On-brand rather than grey: a closed tab still has to read as a tab. */
    color: var(--ag-brand-2);
    cursor: pointer;
    transition: background var(--ag-ease), color var(--ag-ease), border-color var(--ag-ease);
}
/* Each tab keeps its own colour on the icon, so the row is read by colour the
   way the header module bar is; the label stays neutral for legibility. */
.ag-pk-tab svg {
    flex: none;
    width: 15px; height: 15px;
    color: var(--tile, currentColor);
    stroke: currentColor; stroke-width: 1.9; fill: none;
    stroke-linecap: round; stroke-linejoin: round;
}
.ag-pk-tab:hover {
    background: color-mix(in srgb, var(--ag-accent) 18%, var(--ag-surface));
    color: var(--ag-ink);
}
/* The open tab is SOLID, as the reference's is. It was white on a white card,
   which is exactly the "not visible" — a tab cannot be marked by a background
   its own panel already has. */
.ag-pk-tab.is-on {
    position: relative;
    z-index: 1;
    background: var(--ag-brand);
    border-color: var(--ag-brand);
    color: #fff;
    font-weight: 700;
}
.ag-pk-tab.is-on svg { color: #fff; }
.ag-pk-pane[hidden] { display: none; }

/* --- page head ---------------------------------------------------------- */

.ag-page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 14px;
    margin-bottom: 20px;
}
.ag-page-head > div:first-child { flex: 1 1 320px; min-width: 0; }
.ag-page-head h1 { margin: 0 0 3px; }
.ag-page-sub { margin: 0; color: var(--ag-ink-3); font-size: .89rem; }
.ag-page-actions { display: flex; flex-wrap: wrap; gap: 9px; }

.ag-crumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin: 0 0 9px;
    padding: 0;
    list-style: none;
    font-size: .78rem;
    color: var(--ag-ink-3);
}
.ag-crumbs li { display: flex; align-items: center; gap: 6px; }
.ag-crumbs li + li::before { content: "/"; color: var(--ag-ink-4); }
.ag-crumbs a { color: var(--ag-ink-3); }
.ag-crumbs a:hover { color: var(--ag-accent); }
.ag-crumbs [aria-current] { color: var(--ag-ink); font-weight: 600; }

/* --------------------------------------------------------------------------
   4. Cards & panels
   -------------------------------------------------------------------------- */

/* Cards are outlined in the agent's own theme rather than in neutral grey, so
   the choice reaches the body of the page and not just the rail and buttons.
   A QUARTER of the accent, not the accent itself: at full strength every card
   on a dense page shouted, and the ruled tables inside them stopped reading as
   quieter than their container. The plain line is declared first, so a browser
   without color-mix() keeps the old grey rather than losing the border. */
.ag-card {
    background: var(--ag-surface);
    border: 1px solid var(--ag-line);
    border: 1px solid color-mix(in srgb, var(--ag-accent) 25%, var(--ag-line));
    border-radius: var(--ag-radius);
    box-shadow: var(--ag-shadow-sm);
}
.ag-card + .ag-card { margin-top: var(--ag-gap); }

.ag-card-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--ag-line-soft);
}
.ag-card-head h2, .ag-card-head h3 { margin: 0; font-size: 1rem; }
.ag-card-head .ag-spacer { flex: 1 1 auto; }
.ag-card-body { padding: 18px; }
.ag-card-body.is-flush { padding: 0; }
.ag-card-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 13px 18px;
    border-top: 1px solid var(--ag-line-soft);
    background: var(--ag-surface-2);
    border-radius: 0 0 var(--ag-radius) var(--ag-radius);
}

/* --- stat tiles --------------------------------------------------------
   The dashboard's top row. auto-fit so the row reflows instead of needing a
   breakpoint per count. */
.ag-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(198px, 1fr));
    gap: 14px;
    margin-bottom: var(--ag-gap);
}

.ag-stat {
    position: relative;
    padding: 16px 17px;
    background: var(--ag-surface);
    border: 1px solid var(--ag-line);
    border: 1px solid color-mix(in srgb, var(--ag-accent) 25%, var(--ag-line));
    border-radius: var(--ag-radius);
    box-shadow: var(--ag-shadow-sm);
    overflow: hidden;
}
.ag-body a.ag-stat:hover {
    border-color: var(--ag-accent-line);
    box-shadow: var(--ag-shadow);
    text-decoration: none;
}
.ag-stat-k {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 9px;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--ag-ink-3);
}
.ag-stat-ico {
    display: grid;
    place-items: center;
    width: 30px; height: 30px;
    border-radius: 9px;
    background: var(--ag-accent-wash);
    color: var(--ag-accent);
}
.ag-stat-ico svg {
    width: 16px; height: 16px;
    stroke: currentColor; stroke-width: 1.8; fill: none;
    stroke-linecap: round; stroke-linejoin: round;
}
.ag-stat-v {
    font-family: var(--ag-font-head);
    font-size: 1.58rem;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -.02em;
    color: var(--ag-ink);
    font-variant-numeric: tabular-nums;
}
.ag-stat-note { margin-top: 5px; font-size: .78rem; color: var(--ag-ink-3); }
.ag-stat-note.is-up { color: var(--ag-ok); }
.ag-stat-note.is-down { color: var(--ag-danger); }

/* Tinted variants. The tint is the semantic scale, never the brand ramp, so
   these keep meaning when the agent switches theme. */
.ag-stat.is-ok .ag-stat-ico     { background: var(--ag-ok-bg);     color: var(--ag-ok); }
.ag-stat.is-warn .ag-stat-ico   { background: var(--ag-warn-bg);   color: var(--ag-warn); }
.ag-stat.is-danger .ag-stat-ico { background: var(--ag-danger-bg); color: var(--ag-danger); }
.ag-stat.is-info .ag-stat-ico   { background: var(--ag-info-bg);   color: var(--ag-info); }

/* --------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */

.ag-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 9px 17px;
    border: 1px solid transparent;
    border-radius: 10px;
    font-family: var(--ag-font);
    font-size: .875rem;
    font-weight: 600;
    line-height: 1.25;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--ag-ease), border-color var(--ag-ease),
                color var(--ag-ease), box-shadow var(--ag-ease), transform var(--ag-ease);
}
.ag-body .ag-btn:hover { text-decoration: none; }
.ag-btn:active { transform: translateY(1px); }
.ag-btn:disabled, .ag-btn.is-disabled {
    opacity: .55;
    pointer-events: none;
}
.ag-btn svg {
    width: 16px; height: 16px;
    stroke: currentColor; stroke-width: 1.8; fill: none;
    stroke-linecap: round; stroke-linejoin: round;
}

.ag-btn-primary {
    background: var(--ag-accent-grad);
    border-color: transparent;
    color: var(--ag-on-brand);
    box-shadow: 0 1px 2px rgba(17, 26, 46, .10), 0 8px 18px -10px var(--ag-accent-line);
}
.ag-body .ag-btn-primary:hover { background: var(--ag-accent-hover); color: #fff; }

.ag-btn-ghost {
    background: var(--ag-surface);
    border-color: var(--ag-line);
    color: var(--ag-ink);
}
.ag-body .ag-btn-ghost:hover {
    background: var(--ag-surface-2);
    border-color: var(--ag-line-strong);
    color: var(--ag-ink);
}

.ag-btn-soft {
    background: var(--ag-accent-wash);
    border-color: var(--ag-accent-soft);
    color: var(--ag-brand-2);
}
.ag-body .ag-btn-soft:hover { background: var(--ag-accent-soft); color: var(--ag-brand-deep); }

.ag-btn-plain {
    background: transparent;
    border-color: transparent;
    color: var(--ag-ink-2);
    padding-inline: 10px;
}
.ag-body .ag-btn-plain:hover { background: var(--ag-surface-3); color: var(--ag-ink); }

.ag-btn-danger {
    background: var(--ag-danger);
    border-color: transparent;
    color: #fff;
}
.ag-body .ag-btn-danger:hover { background: #8e1d27; color: #fff; }

.ag-btn-danger-soft {
    background: var(--ag-danger-bg);
    border-color: var(--ag-danger-line);
    color: var(--ag-danger);
}
.ag-body .ag-btn-danger-soft:hover { background: #f6d9db; color: #8e1d27; }

.ag-btn-sm { padding: 6px 12px; font-size: .8rem; border-radius: 8px; }
.ag-btn-sm svg { width: 14px; height: 14px; }
.ag-btn-lg { padding: 12px 24px; font-size: .95rem; border-radius: 12px; }
.ag-btn-block { width: 100%; }

.ag-btn-row { display: flex; flex-wrap: wrap; gap: 9px; }

/* --------------------------------------------------------------------------
   6. Forms
   -------------------------------------------------------------------------- */

.ag-field { margin-bottom: 15px; }

.ag-label {
    display: block;
    margin-bottom: 6px;
    font-size: .8rem;
    font-weight: 600;
    color: var(--ag-ink-2);
}
.ag-label .ag-req { color: var(--ag-danger); }

.ag-input,
.ag-select,
.ag-textarea {
    display: block;
    width: 100%;
    padding: 9.5px 12px;
    font-family: var(--ag-font);
    font-size: .9rem;
    line-height: 1.45;
    color: var(--ag-ink);
    background: var(--ag-surface);
    border: 1px solid var(--ag-line-strong);
    border-radius: 10px;
    transition: border-color var(--ag-ease), box-shadow var(--ag-ease);
    appearance: none;
}
.ag-input::placeholder, .ag-textarea::placeholder { color: var(--ag-ink-4); }

.ag-input:focus,
.ag-select:focus,
.ag-textarea:focus {
    outline: none;
    border-color: var(--ag-accent);
    box-shadow: var(--ag-ring);
}

.ag-input:disabled, .ag-select:disabled, .ag-textarea:disabled,
.ag-input[readonly] {
    background: var(--ag-surface-3);
    color: var(--ag-ink-3);
    cursor: not-allowed;
}

.ag-textarea { min-height: 96px; resize: vertical; }

/* The chevron is a background image so the control keeps one box model and
   no wrapper element is needed to position an icon. */
.ag-select {
    padding-right: 36px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%236b7790' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 7.5l5 5 5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 11px center;
    background-size: 17px;
}

.ag-hint { margin-top: 5px; font-size: .76rem; color: var(--ag-ink-3); }
/* AN ICON IN A HINT HAD NO SIZE, AND THAT IS A SPECTACULAR FAILURE.
   An inline <svg> with a viewBox but no width/height stretches to its
   container, and SVG's default fill is BLACK — so ag_icon('info'), which is a
   single <circle r="9.2">, rendered as a black disc the width of the page and
   swallowed the whole view. The only thing holding it back was the global
   `max-width: 100%`, which caps the width and nothing else.
   Sized and stroked here, beside .ag-hint itself, because the gap is in the
   hint — not in the pages that put an icon in one. */
.ag-hint svg {
    width: 14px; height: 14px;
    vertical-align: -2px;
    stroke: currentColor; stroke-width: 2; fill: none;
    stroke-linecap: round; stroke-linejoin: round;
}
.ag-error { margin-top: 5px; font-size: .76rem; color: var(--ag-danger); font-weight: 500; }

.ag-input.is-invalid, .ag-select.is-invalid, .ag-textarea.is-invalid {
    border-color: var(--ag-danger);
}
.ag-input.is-invalid:focus { box-shadow: 0 0 0 3px var(--ag-danger-bg); }

/* An input with a leading icon or a trailing button. */
.ag-input-wrap { position: relative; display: flex; align-items: center; }
.ag-input-wrap .ag-input { padding-left: 38px; }
.ag-input-ico {
    position: absolute;
    left: 12px;
    display: grid; place-items: center;
    width: 17px; height: 17px;
    color: var(--ag-ink-4);
    pointer-events: none;
}
.ag-input-ico svg {
    width: 17px; height: 17px;
    stroke: currentColor; stroke-width: 1.8; fill: none;
    stroke-linecap: round; stroke-linejoin: round;
}
.ag-input-btn {
    position: absolute;
    right: 6px;
    display: grid; place-items: center;
    width: 30px; height: 30px;
    padding: 0;
    border: 0; border-radius: 8px;
    background: transparent;
    color: var(--ag-ink-3);
    cursor: pointer;
}
.ag-input-btn:hover { background: var(--ag-surface-3); color: var(--ag-ink); }
.ag-input-btn svg {
    width: 17px; height: 17px;
    stroke: currentColor; stroke-width: 1.8; fill: none;
    stroke-linecap: round; stroke-linejoin: round;
}
.ag-input-wrap:has(.ag-input-btn) .ag-input { padding-right: 42px; }

/* Grid for form layout. --ag-col is the span; default full width. */
.ag-form-grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 0 14px;
}
.ag-form-grid > * { grid-column: span 12; }
/* The WHOLE ladder, 1 to 12. It used to carry only the widths that happened to
   be in use, and a field asking for one of the gaps (ag-col-5) matched nothing
   and silently fell back to the full-width default above — a row of four
   fields became four rows, with no error anywhere to say why. */
.ag-col-1  { grid-column: span 1  !important; }
.ag-col-2  { grid-column: span 2  !important; }
.ag-col-3  { grid-column: span 3  !important; }
.ag-col-4  { grid-column: span 4  !important; }
.ag-col-5  { grid-column: span 5  !important; }
.ag-col-6  { grid-column: span 6  !important; }
.ag-col-7  { grid-column: span 7  !important; }
.ag-col-8  { grid-column: span 8  !important; }
.ag-col-9  { grid-column: span 9  !important; }
.ag-col-10 { grid-column: span 10 !important; }
.ag-col-11 { grid-column: span 11 !important; }
.ag-col-12 { grid-column: span 12 !important; }

/* Checkbox / radio */
.ag-check {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    font-size: .875rem;
    color: var(--ag-ink-2);
    cursor: pointer;
}
.ag-check input[type="checkbox"],
.ag-check input[type="radio"] {
    flex: 0 0 17px;
    width: 17px; height: 17px;
    margin: 2px 0 0;
    accent-color: var(--ag-accent);
    cursor: pointer;
}

/* A row of choices that look like cards — used for payment mode, room type. */
.ag-choices { display: flex; flex-wrap: wrap; gap: 10px; }
.ag-choice {
    position: relative;
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 10px 15px;
    border: 1px solid var(--ag-line-strong);
    border-radius: 11px;
    background: var(--ag-surface);
    font-size: .875rem;
    font-weight: 500;
    cursor: pointer;
    transition: border-color var(--ag-ease), background var(--ag-ease), box-shadow var(--ag-ease);
}
.ag-choice input { position: absolute; opacity: 0; pointer-events: none; }
.ag-choice:has(input:checked) {
    border-color: var(--ag-accent);
    background: var(--ag-accent-wash);
    color: var(--ag-brand-2);
    box-shadow: var(--ag-ring);
}

/* --------------------------------------------------------------------------
   7. Tables
   -------------------------------------------------------------------------- */

/* Always inside this wrapper: a booking table is wider than a phone and the
   page body must never scroll sideways. */
.ag-table-wrap {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.ag-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: .875rem;
}

.ag-table th {
    padding: 11px 14px;
    text-align: left;
    font-size: .71rem;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--ag-ink-3);
    background: var(--ag-surface-2);
    border-bottom: 1px solid var(--ag-line);
    white-space: nowrap;
}
.ag-table td {
    padding: 12px 14px;
    border-bottom: 1px solid var(--ag-line-soft);
    vertical-align: middle;
    color: var(--ag-ink-2);
}
.ag-table tbody tr:last-child td { border-bottom: 0; }
.ag-table tbody tr:hover td { background: var(--ag-surface-2); }

.ag-table .ag-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ag-table .ag-strong { color: var(--ag-ink); font-weight: 600; }

/* A sticky first column, for the wide booking grids. */
.ag-table.is-pinned td:first-child,
.ag-table.is-pinned th:first-child {
    position: sticky;
    left: 0;
    background: var(--ag-surface);
    box-shadow: 1px 0 0 var(--ag-line-soft);
}
.ag-table.is-pinned th:first-child { background: var(--ag-surface-2); }

/* --------------------------------------------------------------------------
   8. Badges, chips, pills
   -------------------------------------------------------------------------- */

.ag-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 9px;
    border: 1px solid transparent;
    border-radius: 99px;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .01em;
    white-space: nowrap;
}
.ag-badge-ok     { background: var(--ag-ok-bg);     color: var(--ag-ok);     border-color: var(--ag-ok-line); }
.ag-badge-warn   { background: var(--ag-warn-bg);   color: var(--ag-warn);   border-color: var(--ag-warn-line); }
.ag-badge-danger { background: var(--ag-danger-bg); color: var(--ag-danger); border-color: var(--ag-danger-line); }
.ag-badge-info   { background: var(--ag-info-bg);   color: var(--ag-info);   border-color: var(--ag-info-line); }
.ag-badge-mute   { background: var(--ag-surface-3); color: var(--ag-ink-3);  border-color: var(--ag-line); }

.ag-badge::before {
    content: "";
    width: 6px; height: 6px;
    border-radius: 50%;
    background: currentColor;
}
.ag-badge.is-plain::before { display: none; }

.ag-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 11px;
    border: 1px solid var(--ag-line);
    border-radius: 99px;
    background: var(--ag-surface-2);
    font-size: .78rem;
    color: var(--ag-ink-2);
}
/* Buttons size their own icons; a chip did not, so an inline SVG fell back to
   its default box and swamped the pill as a black blob. */
.ag-chip svg {
    flex: 0 0 auto;
    width: 13px;
    height: 13px;
}
.ag-chip-xs svg { width: 11px; height: 11px; }

/* --------------------------------------------------------------------------
   9. Alerts & empty states
   -------------------------------------------------------------------------- */

.ag-alert {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    padding: 13px 15px;
    margin-bottom: var(--ag-gap);
    border: 1px solid;
    border-radius: var(--ag-radius-sm);
    font-size: .875rem;
}
.ag-alert svg {
    flex: 0 0 18px;
    width: 18px; height: 18px;
    margin-top: 1px;
    stroke: currentColor; stroke-width: 1.8; fill: none;
    stroke-linecap: round; stroke-linejoin: round;
}
.ag-alert strong { display: block; margin-bottom: 2px; }
.ag-alert-ok     { background: var(--ag-ok-bg);     border-color: var(--ag-ok-line);     color: #0a5c3b; }
.ag-alert-warn   { background: var(--ag-warn-bg);   border-color: var(--ag-warn-line);   color: #74490a; }
.ag-alert-danger { background: var(--ag-danger-bg); border-color: var(--ag-danger-line); color: #8e1d27; }
.ag-alert-info   { background: var(--ag-info-bg);   border-color: var(--ag-info-line);   color: #0b4f84; }

.ag-empty {
    padding: 54px 24px;
    text-align: center;
    color: var(--ag-ink-3);
}
.ag-empty-ico {
    display: grid;
    place-items: center;
    width: 62px; height: 62px;
    margin: 0 auto 15px;
    border-radius: 50%;
    background: var(--ag-surface-3);
    color: var(--ag-ink-4);
}
.ag-empty-ico svg {
    width: 27px; height: 27px;
    stroke: currentColor; stroke-width: 1.6; fill: none;
    stroke-linecap: round; stroke-linejoin: round;
}
.ag-empty h3 { margin: 0 0 5px; font-size: 1.02rem; color: var(--ag-ink); }
.ag-empty p { max-width: 46ch; margin: 0 auto 16px; font-size: .88rem; }

/* --------------------------------------------------------------------------
   10. Tabs & pagination
   -------------------------------------------------------------------------- */

.ag-tabs {
    display: flex;
    gap: 2px;
    margin: 0 0 var(--ag-gap);
    padding: 0;
    list-style: none;
    border-bottom: 1px solid var(--ag-line);
    overflow-x: auto;
    scrollbar-width: none;
}
.ag-tabs::-webkit-scrollbar { display: none; }

.ag-tab {
    padding: 10px 15px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: transparent;
    font-family: var(--ag-font);
    font-size: .875rem;
    font-weight: 600;
    color: var(--ag-ink-3);
    white-space: nowrap;
    cursor: pointer;
    transition: color var(--ag-ease), border-color var(--ag-ease);
}
.ag-body .ag-tab:hover { color: var(--ag-ink); text-decoration: none; }
.ag-tab.is-active { color: var(--ag-accent); border-bottom-color: var(--ag-accent); }
.ag-tab .ag-count {
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 99px;
    font-size: .7rem;
    background: var(--ag-surface-3);
    color: var(--ag-ink-3);
}
.ag-tab.is-active .ag-count { background: var(--ag-accent-soft); color: var(--ag-brand-2); }

.ag-pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: var(--ag-gap);
}
.ag-pager-info { margin-right: auto; font-size: .82rem; color: var(--ag-ink-3); }
.ag-pager-link {
    display: grid;
    place-items: center;
    min-width: 34px; height: 34px;
    padding: 0 9px;
    border: 1px solid var(--ag-line);
    border-radius: 9px;
    background: var(--ag-surface);
    font-size: .84rem;
    font-weight: 600;
    color: var(--ag-ink-2);
}
.ag-body .ag-pager-link:hover {
    border-color: var(--ag-accent-line);
    color: var(--ag-accent);
    text-decoration: none;
}
.ag-pager-link.is-active {
    background: var(--ag-accent);
    border-color: var(--ag-accent);
    color: #fff;
}
.ag-pager-link.is-disabled { opacity: .45; pointer-events: none; }

/* --------------------------------------------------------------------------
   11. Dropdown menus
   -------------------------------------------------------------------------- */

.ag-pop { position: relative; }

.ag-pop-panel {
    position: absolute;
    top: calc(100% + 7px);
    right: 0;
    z-index: 70;
    min-width: 230px;
    padding: 7px;
    background: var(--ag-surface);
    border: 1px solid var(--ag-line);
    border-radius: var(--ag-radius);
    box-shadow: var(--ag-shadow-lg);
    /* Animated out, not display:none, so the open state is one attribute and
       the transition works in both directions. */
    opacity: 0;
    transform: translateY(-5px);
    visibility: hidden;
    transition: opacity var(--ag-ease), transform var(--ag-ease), visibility var(--ag-ease);
}
.ag-pop[data-open="true"] .ag-pop-panel {
    opacity: 1;
    transform: none;
    visibility: visible;
}
.ag-pop-panel.is-left { right: auto; left: 0; }

/* --- Holidays mega menu --------------------------------------------------
   A wide destination panel under the Holidays tile, as in /b2b/. It is far
   wider than its trigger, so it is centred on the tile and then clamped to the
   viewport — anchored to the tile's right edge it ran off-screen on the left.
   -------------------------------------------------------------------------- */

/* position: static on purpose, overriding .ag-pop. The panel is far wider than
   its trigger, so it must be centred on the BAR, not on the tile — and an
   absolutely positioned panel is placed against its nearest positioned
   ancestor. Left relative, the panel centred on a ~70px tile sitting near the
   left of the window and ran off under the rail. Static hands the job to the
   sticky .ag-topbar, which spans the content area. (/b2b/ hit this too and
   fixed it the same way.) */
.ag-mega-wrap {
    display: flex;
    position: static;
}

/* THE PANEL SIZES TO ITS COLUMNS, as Zaereen's does: each column as wide as its
   longest name and no wider, with 32px between them. A fixed 1060px of evenly
   stretched columns padded every column out to the widest name in the menu. */
.ag-pop-panel.ag-mega {
    right: auto;
    left: 50%;
    transform: translateX(-50%) translateY(-5px);
    width: max-content;
    max-width: calc(100vw - 32px);
    padding: 20px 24px 14px;
}
.ag-pop[data-open="true"] .ag-pop-panel.ag-mega { transform: translateX(-50%); }

.ag-mega-grid {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    align-items: start;
    gap: 0 32px;
    max-height: min(70vh, 620px);
    overflow-y: auto;
}
/* A window too narrow for six columns side by side rewraps them in threes. */
@media (max-width: 1180px) {
    .ag-mega-grid {
        grid-auto-flow: row;
        grid-template-columns: repeat(3, max-content);
        gap: 4px 28px;
    }
}

/* The region: a small uppercase label with its own mark. */
.ag-mega-col h6 {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 7px;
    font-size: .6rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--ag-accent);
}
.ag-mega-rico {
    flex: none;
    width: 13px; height: 13px;
    fill: none;
    stroke: currentColor; stroke-width: 1.6;
    stroke-linecap: round; stroke-linejoin: round;
}
.ag-mega-col ul { margin: 0 0 14px; padding: 0; list-style: none; }

/* A destination: its mark, the name taking the room, the count pinned right. */
.ag-mega-col a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 5px 8px;
    border-radius: 7px;
    font-size: .845rem;
    color: var(--ag-ink);
    white-space: nowrap;
    transition: color var(--ag-ease), background-color var(--ag-ease);
}
/* Each destination carries its own colour, at full strength: the mark is the
   point of the row, not a watermark behind it. */
.ag-mega-ico {
    flex: none;
    width: 15px; height: 15px;
    fill: none;
    stroke: var(--tile, var(--ag-accent)); stroke-width: 1.6;
    stroke-linecap: round; stroke-linejoin: round;
}
.ag-mega-col a em {
    flex: 1 1 auto;
    min-width: 0;
    font-style: normal;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ag-mega-col a span {
    flex: none;
    font-size: .69rem;
    color: var(--ag-ink-3);
    font-variant-numeric: tabular-nums;
}
.ag-body .ag-mega-col a:hover {
    color: var(--tile, var(--ag-accent));
    background: color-mix(in srgb, var(--tile, var(--ag-accent)) 10%, transparent);
    text-decoration: none;
}
.ag-mega-col a:hover span { color: inherit; }

.ag-mega-all {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    margin-top: 4px;
    padding: 12px 0 2px;
    border-top: 1px solid var(--ag-line);
    font-size: .8125rem;
    font-weight: 600;
    color: var(--ag-accent);
}
.ag-mega-all svg {
    width: 15px; height: 15px;
    fill: none;
    stroke: currentColor; stroke-width: 1.6;
    stroke-linecap: round; stroke-linejoin: round;
}
.ag-body .ag-mega-all:hover { text-decoration: none; color: var(--ag-brand-2); }

.ag-pop-head {
    padding: 9px 11px 10px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--ag-line-soft);
}
.ag-pop-head strong { display: block; font-size: .89rem; }
.ag-pop-head span { font-size: .76rem; color: var(--ag-ink-3); }

.ag-pop-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 11px;
    border: 0;
    border-radius: 9px;
    background: transparent;
    font-family: var(--ag-font);
    font-size: .86rem;
    font-weight: 500;
    color: var(--ag-ink-2);
    text-align: left;
    cursor: pointer;
}
.ag-body .ag-pop-item:hover {
    background: var(--ag-surface-2);
    color: var(--ag-ink);
    text-decoration: none;
}
.ag-pop-item svg {
    flex: 0 0 17px;
    width: 17px; height: 17px;
    stroke: currentColor; stroke-width: 1.8; fill: none;
    stroke-linecap: round; stroke-linejoin: round;
    color: var(--ag-ink-3);
}
.ag-pop-item.is-danger { color: var(--ag-danger); }
.ag-body .ag-pop-item.is-danger:hover { background: var(--ag-danger-bg); color: var(--ag-danger); }
.ag-pop-sep { height: 1px; margin: 5px 0; background: var(--ag-line-soft); }

/* --------------------------------------------------------------------------
   12. Avatar
   -------------------------------------------------------------------------- */

.ag-avatar {
    display: grid;
    place-items: center;
    width: 36px; height: 36px;
    flex: 0 0 36px;
    border-radius: 50%;
    background: var(--ag-accent-grad);
    color: #fff;
    font-family: var(--ag-font-head);
    font-size: .86rem;
    font-weight: 700;
    letter-spacing: .01em;
    overflow: hidden;
    text-transform: uppercase;
}
.ag-avatar img { width: 100%; height: 100%; object-fit: cover; }
.ag-avatar-lg { width: 56px; height: 56px; flex-basis: 56px; font-size: 1.2rem; }
.ag-avatar-sm { width: 28px; height: 28px; flex-basis: 28px; font-size: .7rem; }

.ag-who {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 5px 11px 5px 5px;
    border: 1px solid transparent;
    border-radius: 99px;
    background: transparent;
    cursor: pointer;
    transition: background var(--ag-ease), border-color var(--ag-ease);
}
.ag-who:hover { background: var(--ag-surface-3); }
.ag-who-text { min-width: 0; text-align: left; line-height: 1.25; }
.ag-who-name {
    display: block;
    font-size: .83rem;
    font-weight: 600;
    color: var(--ag-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 150px;
}
.ag-who-role {
    display: block;
    font-size: .71rem;
    color: var(--ag-ink-3);
    white-space: nowrap;
}

/* --------------------------------------------------------------------------
   13. Theme picker
   -------------------------------------------------------------------------- */

.ag-theme-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
    gap: 10px;
}

.ag-theme-opt {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--ag-line);
    border-radius: 11px;
    background: var(--ag-surface);
    cursor: pointer;
    text-align: left;
    transition: border-color var(--ag-ease), box-shadow var(--ag-ease), background var(--ag-ease);
}
.ag-theme-opt:hover { border-color: var(--ag-line-strong); background: var(--ag-surface-2); }
.ag-theme-opt input { position: absolute; opacity: 0; pointer-events: none; }
.ag-theme-opt:has(input:checked) {
    border-color: var(--ag-accent);
    box-shadow: var(--ag-ring);
}

/* The swatch paints the same gradient the rail wears, so the preview cannot
   drift from the result. */
.ag-theme-dot {
    flex: 0 0 26px;
    width: 26px; height: 26px;
    border-radius: 8px;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .12);
}
.ag-theme-name { font-size: .85rem; font-weight: 600; color: var(--ag-ink); }
.ag-theme-hint { display: block; font-size: .72rem; font-weight: 400; color: var(--ag-ink-3); }

/* The swatch row inside the topbar popover. */
.ag-theme-row { display: flex; flex-wrap: wrap; gap: 7px; padding: 4px 7px 8px; }
.ag-theme-swatch {
    width: 28px; height: 28px;
    padding: 0;
    border: 2px solid transparent;
    border-radius: 9px;
    cursor: pointer;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .14);
    transition: transform var(--ag-ease), border-color var(--ag-ease);
}
.ag-theme-swatch:hover { transform: scale(1.08); }
.ag-theme-swatch[aria-pressed="true"] {
    border-color: var(--ag-ink);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .7);
}

/* --------------------------------------------------------------------------
   14. Modal
   -------------------------------------------------------------------------- */

.ag-modal {
    position: fixed;
    inset: 0;
    z-index: 120;
    display: grid;
    place-items: center;
    padding: 20px;
    background: var(--ag-overlay);
    backdrop-filter: blur(3px);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--ag-ease), visibility var(--ag-ease);
}
.ag-modal[data-open="true"] { opacity: 1; visibility: visible; }

.ag-modal-box {
    width: 100%;
    max-width: 520px;
    max-height: calc(100vh - 40px);
    display: flex;
    flex-direction: column;
    background: var(--ag-surface);
    border-radius: var(--ag-radius-lg);
    box-shadow: var(--ag-shadow-lg);
    transform: translateY(10px) scale(.99);
    transition: transform var(--ag-ease);
}
.ag-modal[data-open="true"] .ag-modal-box { transform: none; }
.ag-modal-box.is-wide { max-width: 860px; }

.ag-modal-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--ag-line-soft);
}
.ag-modal-head h2 { margin: 0; font-size: 1.05rem; flex: 1 1 auto; }
.ag-modal-body { padding: 20px; overflow-y: auto; }
.ag-modal-foot {
    display: flex;
    justify-content: flex-end;
    gap: 9px;
    padding: 14px 20px;
    border-top: 1px solid var(--ag-line-soft);
    background: var(--ag-surface-2);
    border-radius: 0 0 var(--ag-radius-lg) var(--ag-radius-lg);
}

/* --------------------------------------------------------------------------
   15. Skeleton / loading
   -------------------------------------------------------------------------- */

.ag-skel {
    background: linear-gradient(90deg, var(--ag-surface-3) 25%, var(--ag-line-soft) 37%, var(--ag-surface-3) 63%);
    background-size: 400% 100%;
    border-radius: 6px;
    animation: ag-shimmer 1.3s ease-in-out infinite;
}
@keyframes ag-shimmer {
    0%   { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

.ag-spin {
    display: inline-block;
    width: 16px; height: 16px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: ag-spin .7s linear infinite;
}
@keyframes ag-spin { to { transform: rotate(360deg); } }

/* --------------------------------------------------------------------------
   16. Utilities — the handful that actually earn their keep
   -------------------------------------------------------------------------- */

.ag-row   { display: flex; flex-wrap: wrap; gap: var(--ag-gap); }
.ag-stack { display: flex; flex-direction: column; gap: 10px; }
.ag-between { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ag-spacer { flex: 1 1 auto; }

.ag-grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--ag-gap); }
.ag-grid-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: var(--ag-gap); }

.ag-mute   { color: var(--ag-ink-3); }
.ag-small  { font-size: .8rem; }
.ag-tiny   { font-size: .72rem; }
.ag-bold   { font-weight: 700; }
.ag-num-f  { font-variant-numeric: tabular-nums; }
.ag-right  { text-align: right; }
.ag-center { text-align: center; }
.ag-nowrap { white-space: nowrap; }
.ag-truncate { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.ag-mt-0 { margin-top: 0 !important; }
.ag-mb-0 { margin-bottom: 0 !important; }
.ag-mt   { margin-top: var(--ag-gap); }
.ag-mb   { margin-bottom: var(--ag-gap); }

/* --------------------------------------------------------------------------
   17. Responsive
   -------------------------------------------------------------------------- */

/* The rail becomes a drawer. One attribute on the shell again, so the
   backdrop, the rail and the body scroll-lock stay in step. */
.ag-rail-scrim {
    position: fixed;
    inset: 0;
    z-index: 55;
    background: var(--ag-overlay);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--ag-ease), visibility var(--ag-ease);
}

@media (max-width: 1024px) {
    .ag-rail {
        transform: translateX(-100%);
        box-shadow: var(--ag-shadow-lg);
    }
    .ag-main { margin-left: 0; }

    /* The slim variant is meaningless on a drawer: below this width the rail
       is either off-screen or fully open. */
    .ag-shell[data-ag-rail="slim"] .ag-rail { width: var(--ag-rail); }
    .ag-shell[data-ag-rail="slim"] .ag-main { margin-left: 0; }
    .ag-shell[data-ag-rail="slim"] .ag-rail-name,
    .ag-shell[data-ag-rail="slim"] .ag-nav-label,
    .ag-shell[data-ag-rail="slim"] .ag-nav-tag,
    .ag-shell[data-ag-rail="slim"] .ag-rail-group,
    .ag-shell[data-ag-rail="slim"] .ag-rail-foot { display: revert; }
    .ag-shell[data-ag-rail="slim"] .ag-rail-head { justify-content: flex-start; padding: 0 18px; }
    .ag-shell[data-ag-rail="slim"] .ag-nav-link { justify-content: flex-start; padding: 9.5px 12px; }

    .ag-shell[data-ag-drawer="open"] .ag-rail { transform: none; }
    .ag-shell[data-ag-drawer="open"] .ag-rail-scrim { opacity: 1; visibility: visible; }
}

@media (min-width: 1025px) {
    /* The drawer toggle is a phone affordance; on desktop the same button
       collapses the rail instead. */
    .ag-rail-scrim { display: none; }

    /* The module bar takes this space, and the page's own h1 and breadcrumbs
       already name the page — two labels for it in one screen is one too many. */
    .ag-topbar-title { display: none; }
}

/* Between these widths the bar keeps its icons but drops the labels, rather
   than pushing the balance chip and account menu off the bar. The spacing
   tightens with them — nine icons alone need far less room than nine labelled
   tiles, and the gap is what buys that room back. */
/* Raised from 1480 when the icons grew to 26px and the gap to 18: the labelled
   bar is wider than it was, so it has to shed its labels sooner or it starts
   pushing the balance chip off the end. */
@media (max-width: 1560px) {
    .ag-modbar-label { display: none; }
    .ag-modbar { gap: 8px; }
    .ag-modbar-item { padding: 5px 8px; }
}

@media (max-width: 1024px) {
    /* The rail drawer is the navigation here. */
    .ag-modbar { display: none; }
}

@media (max-width: 720px) {
    .ag-content { padding: 16px 16px 40px; }
    .ag-topbar { padding: 0 14px; gap: 8px; }
    .ag-who-text { display: none; }
    .ag-balance { padding: 5px 10px; }
    .ag-balance-k { display: none; }
    :where(.ag-body h1) { font-size: 1.32rem; }
    .ag-stats { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
    .ag-stat { padding: 13px 14px; }
    .ag-stat-v { font-size: 1.32rem; }
    .ag-card-head, .ag-card-body, .ag-card-foot { padding-inline: 14px; }
    .ag-form-grid > * { grid-column: span 12 !important; }
    .ag-modal { padding: 12px; }
    .ag-page-actions { width: 100%; }
    .ag-page-actions .ag-btn { flex: 1 1 auto; }
}

/* --------------------------------------------------------------------------
   18. Motion & print
   -------------------------------------------------------------------------- */

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

@media print {
    .ag-rail, .ag-topbar, .ag-rail-scrim, .ag-page-actions, .ag-pager { display: none !important; }
    .ag-main { margin-left: 0 !important; }
    .ag-content { max-width: none; padding: 0; }
    .ag-card { border-color: #ccc; box-shadow: none; break-inside: avoid; }
    .ag-body { background: #fff; }
}

/* --- the date pill -----------------------------------------------------------
   A date shown as words with a themed mark, with the real <input type="date">
   lying transparent on top: clicking anywhere still opens the browser's own
   picker and the ISO value still posts, but the agent reads "21 Sep 2026"
   rather than 09/21/2026 in whatever glyph the browser paints.

   Shared by the package panel and the hotel stay panel. It lived in package.css
   until the hotel page used it, where the overlay rule was missing — so the
   pill and the native box both rendered, one under the other.
   -------------------------------------------------------------------------- */

.ag-pk-datepill {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 44px;
    padding: 0 12px;
    border: 1px solid var(--ag-line);
    border-radius: 10px;
    background: var(--ag-surface-2);
    font-size: .88rem;
    font-weight: 600;
    color: var(--ag-ink);
}
.ag-pk-datepill span { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ag-pk-datepill { background: var(--gold-wash); border-color: var(--gold-line); }
.ag-pk-datepill > svg { flex: none; width: 15px; height: 15px; color: var(--gold); stroke: currentColor; stroke-width: 1.9; fill: none; }
.ag-pk-datepill input {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    padding: 0;
    border: 0;
    opacity: 0;
    cursor: pointer;
}
.ag-pk-datepill:focus-within {
    border-color: var(--ag-accent);
    box-shadow: 0 0 0 3px var(--ag-accent-line);
}

/* --- summary rail primitives ------------------------------------------------
   A tick, a row of small facts, and a one-line "included" strip. Shared by the
   package reservation page and the hotel guest-details page, which is why they
   live here: review.php does not load package.css, and its "Your booking"
   panel rendered the tick at its natural SVG size — a black blob half the
   height of the panel — with the facts run together as unstyled text.
   -------------------------------------------------------------------------- */

.ag-rsv-tick {
    display: grid;
    place-items: center;
    flex: none;
    width: 26px; height: 26px;
    border-radius: 50%;
    background: var(--ag-ok);
    color: #fff;
}
.ag-rsv-tick svg { width: 14px; height: 14px; stroke: currentColor; stroke-width: 3; fill: none; }

.ag-rsv-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: 10px;
    margin-bottom: 16px;
}
.ag-rsv-facts > div {
    padding: 10px 13px;
    border: 1px solid var(--gold-line);
    border-radius: 10px;
}
.ag-rsv-facts small {
    display: block;
    margin-bottom: 4px;
    font-size: .62rem;
    font-weight: 700;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--ag-ink-3);
}
.ag-rsv-facts b { font-size: .9rem; color: var(--ag-brand-deep); }

.ag-rsv-meal {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 11px 13px;
    margin-top: 14px;
    border: 1px solid var(--gold-line);
    border-radius: 10px;
    background: var(--gold-wash);
    font-size: .85rem;
}
.ag-rsv-meal .ag-rsv-tick { width: 22px; height: 22px; background: var(--gold); }
.ag-rsv-meal-k {
    font-size: .66rem;
    font-weight: 700;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--ag-ink-3);
}
.ag-rsv-meal b { color: var(--ag-ink); }

/* --- boxed detail grid -------------------------------------------------------
   A label and its value in a card of their own, each marked in its own colour.
   Used where a record has a handful of facts that are read individually rather
   than compared down a column — a hotel's contact details, say — and where one
   long value (an address) must be able to wrap without dragging the others
   down with it, which is exactly what a two-column .ag-kv does.
   -------------------------------------------------------------------------- */

.ag-info-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 10px;
}
.ag-info {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    padding: 12px 14px;
    border: 1px solid var(--ag-line);
    /* Closed by a heavier line in the fact's own colour, so the boxes are told
       apart by their foot as well as by their mark. */
    border-bottom: 2px solid var(--tile, var(--ag-accent));
    border-radius: var(--ag-radius);
    background: var(--ag-surface);
}
/* The address gets the full row: it is the one value that is a sentence. */
.ag-info.is-wide { grid-column: 1 / -1; }
.ag-info > div { min-width: 0; }
.ag-info-ico {
    display: grid;
    place-items: center;
    flex: 0 0 32px;
    width: 32px; height: 32px;
    border-radius: 9px;
    border: 1px solid var(--ag-line);
    border-color: color-mix(in srgb, var(--tile, var(--ag-accent)) 40%, transparent);
    background: var(--ag-accent-wash);
    background: color-mix(in srgb, var(--tile, var(--ag-accent)) 11%, transparent);
    color: var(--tile, var(--ag-accent));
}
.ag-info-ico svg {
    width: 16px; height: 16px;
    stroke: currentColor; stroke-width: 1.9; fill: none;
    stroke-linecap: round; stroke-linejoin: round;
}
.ag-info-k {
    display: block;
    margin-bottom: 3px;
    font-size: .63rem;
    font-weight: 700;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--tile, var(--ag-ink-3));
}
.ag-info strong {
    display: block;
    font-size: .9rem;
    line-height: 1.45;
    color: var(--ag-ink);
    overflow-wrap: break-word;
}

/* --- the rail's animated mark ----------------------------------------------
   /b2b/'s sidebar brand, redrawn for this rail: a gold building (the gradient
   is the <linearGradient> in rail.php) with a glow that breathes, a full turn
   when the head is hovered, and a light sweeping across the head — once on
   hover, and on its own every few seconds so the mark is visibly alive. */
.ag-rail-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.ag-rail-head { position: relative; overflow: hidden; }
.ag-rail-head > :not(.ag-rail-defs) { position: relative; z-index: 1; }
.ag-rail-head::before {
    content: "";
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    pointer-events: none;
    background: linear-gradient(90deg, transparent, rgba(212, 175, 55, .18), transparent);
    animation: ag-rail-sweep 6s ease-in-out 1.5s infinite;
}
.ag-rail-head:hover::before { animation: ag-rail-sweep-now .6s ease-out 1 forwards; }

.ag-rail-logo svg {
    width: 24px;
    height: 24px;
    fill: #d4af37;
    fill: url(#agRailGold);
    stroke: none;
    filter: drop-shadow(0 0 6px rgba(212, 175, 55, .5));
    transition: transform .3s ease-out;
    animation: ag-rail-glow 3.2s ease-in-out infinite;
}
.ag-rail-head:hover .ag-rail-logo svg { transform: rotate(360deg) scale(1.05); }

@keyframes ag-rail-sweep {
    0%, 78% { left: -100%; }
    100%    { left: 100%; }
}
@keyframes ag-rail-sweep-now {
    from { left: -100%; }
    to   { left: 100%; }
}
@keyframes ag-rail-glow {
    0%, 100% { filter: drop-shadow(0 0 4px rgba(212, 175, 55, .38)); }
    50%      { filter: drop-shadow(0 0 10px rgba(212, 175, 55, .75)); }
}
@media (prefers-reduced-motion: reduce) {
    .ag-rail-head::before,
    .ag-rail-head:hover::before,
    .ag-rail-logo svg { animation: none; }
    .ag-rail-head:hover .ag-rail-logo svg { transform: none; }
}

/* --- Make payment, joined to the ledger pill -------------------------------
   One split pill: the balance on the left (to Wallet & Ledger), the action
   on the right. Where the bar is short of room the action keeps only its mark,
   with the words in its title and label: below 1440px, and from 1561px to
   1760px, where the module bar has its labels back (they drop at 1560px) and
   the two met at 1600px. */
.ag-balance-wrap { display: inline-flex; align-items: stretch; flex: none; }
.ag-balance-wrap.has-pay .ag-balance { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.ag-balance-pay {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 14px 6px 11px;
    border: 1px solid var(--ag-accent);
    border-left: 0;
    border-radius: 0 99px 99px 0;
    background: var(--ag-accent);
    font-size: .78rem;
    font-weight: 700;
    color: #fff;
    white-space: nowrap;
    transition: background var(--ag-ease), border-color var(--ag-ease);
}
.ag-body .ag-balance-pay:hover {
    border-color: var(--ag-accent-hover);
    background: var(--ag-accent-hover);
    color: #fff;
    text-decoration: none;
}
.ag-balance-pay svg {
    flex: none;
    width: 15px;
    height: 15px;
    stroke: currentColor;
    stroke-width: 2;
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
}
@media (max-width: 1440px), (min-width: 1561px) and (max-width: 1760px) {
    .ag-balance-pay { padding: 6px 11px 6px 9px; }
    .ag-balance-pay span { display: none; }
}

/* Your own colour, and the "+" that opens the picker, in the swatch rows. */
.ag-theme-swatch[hidden] { display: none; }
.ag-theme-swatch.is-add {
    display: grid;
    place-items: center;
    border: 1px dashed var(--ag-line-strong);
    background: var(--ag-surface-2);
    color: var(--ag-ink-3);
    box-shadow: none;
}
.ag-theme-swatch.is-add svg {
    width: 14px;
    height: 14px;
    stroke: currentColor;
    stroke-width: 2.2;
    fill: none;
    stroke-linecap: round;
}
.ag-body .ag-theme-swatch.is-add:hover {
    border-color: var(--ag-accent);
    color: var(--ag-accent);
    text-decoration: none;
}


/* ==========================================================================
   PHONES AND TABLETS: ICON TABS UNDER THE HEADER, A BAR ALONG THE BOTTOM
   The travels site's mobile chrome, in this panel's own colour: the header
   gains a second row of module tabs (icon over label, each icon in the
   module's colour from --tile), and a fixed bar along the bottom carries
   Dashboard, My Trips, Quotes, Reports and Wallet.

   BOTH BARS ARE WALLS. Same ground as the header (--ag-brand, so an agent's
   chosen panel colour still applies) with the girih tile laid over it, and a
   run of stepped merlons (--ag-crest) on the edge that faces the page:
   pointing down from the tabs, up from the bottom bar. Nothing is drawn
   along those edges - a rule there would show through every merlon gap.

   Desktop is untouched: both are display:none above 1024px.
   ========================================================================== */
.ag-mtabs, .ag-mbot { display: none; }

@media (max-width: 1024px) {
    /* The header wraps so the tabs can take a row of their own. */
    .ag-topbar {
        flex-wrap: wrap;
        height: auto;
        min-height: var(--ag-topbar);
        padding: 10px 14px 0;
        row-gap: 0;
        border-bottom: 0;
        isolation: isolate;
    }
    .ag-topbar::before,
    .ag-mbot::before {
        content: "";
        position: absolute;
        inset: 0;
        z-index: -1;
        pointer-events: none;
        background-color: #fff;
        opacity: .07;
        -webkit-mask-image: var(--ag-pattern);
                mask-image: var(--ag-pattern);
        -webkit-mask-size: 26px 26px;
                mask-size: 26px 26px;
    }

    /* --- the tabs ------------------------------------------------------- */
    .ag-mtabs {
        position: relative;
        order: 99;
        flex: 0 0 calc(100% + 28px);
        display: flex;
        gap: 2px;
        margin: 8px -14px 0;
        padding: 4px 4px 6px;
        border-top: 1px solid rgba(255, 255, 255, .08);
    }
    .ag-mtab {
        flex: 1 1 0;
        min-width: 0;
        display: grid;
        justify-items: center;
        align-content: start;
        gap: 4px;
        padding: 6px 2px;
        border-radius: 10px;
        color: #f1f5f9;
        font-size: .72rem;
        font-weight: 600;
        line-height: 1.15;
        text-align: center;
        text-decoration: none;
        white-space: nowrap;
    }
    .ag-mtab > span:last-child { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
    .ag-mtab:hover, .ag-mtab.is-on { background: rgba(255, 255, 255, .1); color: #fff; text-decoration: none; }
    .ag-mtab.is-on { box-shadow: inset 0 -2px 0 var(--tile, #fff); }
    .ag-mtab-ico { display: grid; place-items: center; height: 1.6rem; color: var(--tile, #fff); }
    .ag-mtab-ico svg { width: 1.4rem; height: 1.4rem; }

    /* --- the bottom bar ------------------------------------------------- */
    .ag-mbot {
        position: fixed;
        left: 0; right: 0; bottom: 0;
        /* Under the rail drawer (60) and its scrim, so an open menu covers it. */
        z-index: 52;
        display: grid;
        grid-template-columns: repeat(var(--n, 5), minmax(0, 1fr));
        padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
        background: var(--ag-brand);
        isolation: isolate;
    }
    .ag-mbot-item {
        display: grid;
        justify-items: center;
        gap: 4px;
        padding: 5px 2px;
        border-radius: 10px;
        color: #e2e8f0;
        font-size: .68rem;
        font-weight: 600;
        line-height: 1.15;
        text-align: center;
        text-decoration: none;
        white-space: nowrap;
    }
    .ag-mbot-item span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
    .ag-mbot-item svg { width: 1.4rem; height: 1.4rem; color: var(--tile, #fff); }
    .ag-mbot-item:hover, .ag-mbot-item.is-on { background: rgba(255, 255, 255, .1); color: #fff; text-decoration: none; }
    .ag-mbot-item.is-on { box-shadow: inset 0 2px 0 var(--tile, #fff); }

    /* --- the merlons ---------------------------------------------------- */
    .ag-mtabs::after,
    .ag-mbot::after {
        content: "";
        position: absolute;
        left: 0; right: 0;
        height: 14px;
        pointer-events: none;
        background: var(--ag-brand);
        -webkit-mask: var(--ag-crest) 0 100% / auto 14px repeat-x;
                mask: var(--ag-crest) 0 100% / auto 14px repeat-x;
    }
    /* Down from the tabs: the same tile turned over. */
    .ag-mtabs::after { top: 100%; margin-top: -1px; transform: scaleY(-1); }
    /* Up from the bottom bar. */
    .ag-mbot::after { bottom: 100%; margin-bottom: -1px; }

    /* The page clears the bar and its merlons. */
    .ag-body { padding-bottom: calc(66px + 14px + env(safe-area-inset-bottom)); }
}

@media (max-width: 400px) {
    .ag-mtab, .ag-mbot-item { font-size: .64rem; letter-spacing: -.01em; }
    .ag-mtab-ico svg, .ag-mbot-item svg { width: 1.25rem; height: 1.25rem; }
}

@media print {
    .ag-mtabs, .ag-mbot { display: none !important; }
}

/* PHONES AND TABLETS: THE HEADER ON ONE LINE.
   The page title is dropped - the icon row under it and the page's own
   heading already say where you are - and the controls keep to the first row:
   menu on the left, balance, colour and account on the right. The account
   button's caret goes; the avatar alone opens the menu. */
@media (max-width: 1024px) {
    .ag-topbar-title { display: none; }
    .ag-topbar { column-gap: 6px; }
    .ag-topbar > .ag-icon-btn:first-child { margin-right: auto; }
    .ag-topbar .ag-who { padding: 2px; gap: 0; }
    .ag-topbar .ag-who > svg { display: none; }
    .ag-topbar .ag-balance-wrap { min-width: 0; }
    .ag-topbar .ag-balance { min-width: 0; }
    .ag-topbar .ag-balance-v { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}
@media (max-width: 380px) {
    .ag-topbar .ag-balance { padding-inline: 8px; }
    .ag-topbar .ag-balance-v { font-size: .82rem; }
}

/* PHONES AND TABLETS: THE PAGE TAKES THE SCREEN, AND NO FOOTER.
   The column was 90% of the window and then padded 16px inside that, so a
   card sat behind two layers of margin - about 34px of empty ground on each
   side of a 360px phone. Here it is the full width with one 12px gutter
   (the hero band and facts strip read the same --ag-col, so they follow).
   !important because a page may set --ag-col inline for desktop.

   The footer line (copyright and support e-mail) goes: the bottom bar is the
   foot of the page on a phone. */
@media (max-width: 1024px) {
    .ag-main { --ag-col: 100% !important; }
    .ag-content { padding-inline: 12px; }
    .ag-pk-hero-in { padding-inline: 12px; }
    .ag-foot { display: none; }
}

/* PHONES AND TABLETS: NO DOUBLED GAPS.
   A card inside a stack was spaced twice - by the stack's gap and again by
   .ag-card + .ag-card's margin - so the dashboard's side cards (account
   manager, Panel colour) sat a double gap apart. And the page's own 40px
   bottom padding stacked on top of the room the body leaves for the bottom
   bar, which left a band of empty ground under the last card. */
@media (max-width: 1024px) {
    .ag-stack > .ag-card + .ag-card { margin-top: 0; }
    main.ag-content { padding-bottom: 14px; }
}

/* PHONES AND TABLETS: THE RECORD TABS ON ONE LINE.
   A hotel's six tabs wrapped to four ragged rows on a phone. One row that
   scrolls sideways instead, as the travels hotel page has it. */
@media (max-width: 1024px) {
    .ag-pk-tabs {
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
        padding: 0;
        -webkit-overflow-scrolling: touch;
    }
    .ag-pk-tabs::-webkit-scrollbar { display: none; }
    .ag-pk-tab { flex: none; white-space: nowrap; padding: 9px 14px 10px; font-size: .84rem; }
}

/* PHONES AND TABLETS: THE PLAN PANEL ON ONE ROW.
   Package, visa and activity pages: Travel date | Adults | Children side by
   side, as on the travels site, instead of stacked one per row. The date takes
   a little more of the width than the two steppers, the labels start at the
   left edge like the category label above them, and the controls are trimmed
   to fit a 360px phone - a date such as "10/15/2026" with its picker icon, and
   each stepper's two buttons either side of "02". */
@media (max-width: 1024px) {
    /* .ag-body: package.css loads after this file and folds the row to one
       column at 720px. */
    .ag-body .ag-pk-plan-row {
        grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr) minmax(0, 1fr);
        gap: 6px;
    }
    .ag-body .ag-pk-plan-row > .ag-pk-field { min-width: 0; }
    .ag-body .ag-pk-plan-row .ag-pk-field label {
        justify-content: flex-start;
        gap: 4px;
        font-size: .58rem;
        letter-spacing: .06em;
        white-space: nowrap;
    }
    .ag-body .ag-pk-plan-row .ag-pk-field.is-date .ag-input {
        height: 44px;
        min-width: 0;
        width: 100%;
        padding: 0 6px;
        font-size: .78rem;
    }
    .ag-body .ag-pk-plan-row .ag-pk-datepill { gap: 4px; padding: 0 7px; font-size: .78rem; }
    .ag-body .ag-pk-plan-row .ag-pk-step { padding: 0 4px; }
    .ag-body .ag-pk-plan-row .ag-pk-step button { width: 24px; height: 24px; flex: none; }
    .ag-body .ag-pk-plan-row .ag-pk-step span { font-size: .92rem; }
}


/* PHONES AND TABLETS: THE PAGER ON ONE ROW.
   "Showing 1-20 of 69 bookings" takes a line of its own, centred, and the
   page buttons sit together on the line under it, a size smaller so seven of
   them (‹ 1 … 4 5 6 … 9 ›) still fit a 360px phone. */
@media (max-width: 1024px) {
    .ag-pager { flex-wrap: wrap; justify-content: center; gap: 10px 4px; }
    .ag-pager-info { flex: 0 0 100%; margin: 0; text-align: center; }
    /* A zero basis with a 34px cap: the buttons share whatever the row has,
       so nine of them (‹ 1 2 3 4 5 … 9 ›) stay on one line even inside a card,
       and are never wider than they are drawn on desktop. */
    .ag-pager-link { flex: 1 1 0; min-width: 0; max-width: 34px; height: 32px; padding: 0; font-size: .8rem; }
}

/* PHONES AND TABLETS: TABLES AS CARDS (.ag-table.is-stack - the wallet).
   A seven-column table scrolled sideways inside its card on a phone, so an
   amount sat a swipe away from the row it belonged to. Each row becomes a
   white card of label | value rows instead, ruled like the booking cards; the
   labels are the column headings, copied onto every cell as data-label by the
   page's script. A cell with no label (the action column) spans the card. */
@media (max-width: 1024px) {
    .ag-table-wrap:has(> .ag-table.is-stack) { overflow: visible; border: 0; }
    .ag-table.is-stack,
    .ag-table.is-stack tbody { display: block; width: 100%; }
    .ag-table.is-stack thead { display: none; }
    .ag-table.is-stack tbody { padding: 10px 12px 2px; }
    .ag-table.is-stack tr {
        display: block;
        margin-bottom: 10px;
        border: 1px solid var(--ag-accent-line);
        border-radius: 12px;
        background: #fff;
        overflow: hidden;
    }
    .ag-table.is-stack tr[hidden] { display: none; }
    /* The label is a column pinned down the cell's left side, and the value
       flows normally to its right - so a cell carrying a date, a <br> and a
       time keeps them together as it does in the table. */
    .ag-table.is-stack td {
        position: relative;
        display: block;
        min-width: 0;
        min-height: 36px;
        padding: 8px 10px 8px calc(6.8rem + 10px);
        border: 0;
        border-bottom: 1px dashed var(--ag-line);
        text-align: left;
        white-space: normal;
        overflow-wrap: anywhere;
    }
    /* tbody tr in the selector: .ag-table tbody tr:last-child td drops the rule
       on the last row of a table, and here every row is a card of its own. */
    .ag-body .ag-table.is-stack tbody tr td { border-bottom: 1px dashed var(--ag-line); border-left: 0; }
    .ag-body .ag-table.is-stack tbody tr td:last-child { border-bottom: 0; }
    .ag-table.is-stack td::before {
        content: attr(data-label);
        position: absolute;
        top: 0; bottom: 0; left: 0;
        width: 6.8rem;
        display: flex;
        align-items: center;
        justify-content: flex-end;
        padding: 0 10px;
        border-right: 1px dashed var(--ag-line);
        font-size: .6rem;
        font-weight: 800;
        letter-spacing: .06em;
        text-transform: uppercase;
        text-align: right;
        color: var(--ag-ink-3);
    }
    .ag-table.is-stack td.ag-num { text-align: left; }
    .ag-table.is-stack .ag-truncate { max-width: none !important; white-space: normal; }

    /* No label - the action buttons, the bank-detail row: across the card. */
    .ag-table.is-stack td:not([data-label]) { display: block; padding: 10px; }
    .ag-table.is-stack td:not([data-label])::before { display: none; }
    .ag-table.is-stack td.is-blank { display: none !important; }
    .ag-table.is-stack td:not([data-label]) > .ag-btn { width: 100%; justify-content: center; }
}

/* ==========================================================================
   PHONES AND TABLETS: A FILTER RAIL BEHIND A FLOATING BUTTON (.ag-fsheet)
   The hotel list's rail (ui/hotel_filters.php), and any rail that takes the
   same four hooks. The Filters pill floats bottom left above the bottom bar;
   it opens the rail as a sheet rising from the bottom over a dimmed page
   (agents.js toggles .is-open). Desktop keeps the rail beside the results.
   ========================================================================== */
.ag-fsheet-btn, .ag-fsheet-scrim, .ag-fsheet-x { display: none; }

@media (max-width: 1024px) {
    .ag-hsplit { grid-template-columns: minmax(0, 1fr); }

    .ag-fsheet-btn {
        position: fixed;
        left: 14px;
        bottom: calc(66px + 14px + 12px + env(safe-area-inset-bottom));
        z-index: 10;
        display: inline-flex;
        align-items: center;
        gap: 7px;
        padding: 10px 16px;
        border: 0;
        border-radius: 999px;
        background: var(--ag-accent);
        font: inherit;
        font-size: .9rem;
        font-weight: 700;
        color: #fff;
        box-shadow: 0 8px 20px -6px rgba(9, 24, 54, .45);
        cursor: pointer;
    }
    .ag-fsheet-btn svg { width: 16px; height: 16px; stroke: currentColor; stroke-width: 2; fill: none; stroke-linejoin: round; }
    .ag-fsheet-btn b {
        display: grid; place-items: center;
        min-width: 20px; height: 20px; padding: 0 5px;
        border-radius: 999px;
        background: #fff;
        font-size: .72rem;
        color: var(--ag-accent);
    }

    .ag-body .ag-fsheet {
        position: fixed;
        left: 0; right: 0; bottom: 0; top: auto;
        z-index: 115;
        width: auto;
        max-height: 82vh;
        overflow-y: auto;
        margin: 0;
        padding: 0 16px calc(18px + env(safe-area-inset-bottom));
        border-radius: 18px 18px 0 0;
        box-shadow: 0 -18px 40px rgba(9, 24, 54, .3);
        transform: translateY(105%);
        visibility: hidden;
        transition: transform .25s ease, visibility .25s;
    }
    .ag-body .ag-fsheet.is-open { transform: none; visibility: visible; }
    /* Its first child is the head: kept in view while the groups scroll. */
    .ag-fsheet > .ag-hfilters-head {
        position: sticky;
        top: 0;
        z-index: 1;
        display: flex;
        align-items: center;
        gap: 10px;
        margin: 0 -16px 6px;
        padding: 14px 16px 12px;
        background: var(--ag-surface);
    }
    .ag-fsheet > .ag-hfilters-head > span { margin-right: auto; }
    .ag-fsheet-x {
        display: grid; place-items: center;
        width: 32px; height: 32px;
        border: 1px solid var(--ag-line);
        border-radius: 50%;
        background: var(--ag-surface-2);
        font-size: 1.3rem; line-height: 1;
        color: var(--ag-ink-2);
        cursor: pointer;
    }

    .ag-fsheet-scrim {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 114;
        background: rgba(9, 24, 54, .45);
    }
    .ag-fsheet-scrim[hidden] { display: none; }
    html.ag-fsheet-locked, html.ag-fsheet-locked body { overflow: hidden; }
}
