/* GlobalTicks Admin — design tokens */
:root {
    --brand: #4f46e5;
    --brand-dark: #4338ca;
    --brand-light: #eef2ff;
    --accent: #0d9488;
    --accent-light: #ccfbf1;
    --amber: #b45309;
    --amber-light: #fef3c7;
    --danger: #dc2626;
    --danger-light: #fee2e2;
    --success: #15803d;
    --success-light: #dcfce7;
    --ink: #0f172a;
    --muted: #64748b;
    --muted-2: #94a3b8;
    --page: #f1f5f9;
    --surface: #ffffff;
    --surface-2: #f8fafc;
    --line: #e2e8f0;
    --sidebar: #0b1220;
    --sidebar-2: #16213a;
    --sidebar-text: #9aa7c2;
    --sidebar-text-active: #ffffff;
    --radius-sm: 7px;
    --radius: 10px;
    --radius-lg: 14px;
    --shadow-sm: 0 1px 2px rgba(15, 23, 42, .05);
    --shadow: 0 8px 20px -10px rgba(15, 23, 42, .18);
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--page);
    color: var(--ink);
    font: 13.5px/1.5 "Segoe UI", system-ui, -apple-system, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
}

/* Scrollbars — slim, floating, rounded thumb on any background */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--muted-2) transparent;
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background-color: var(--muted-2);
    background-clip: padding-box;
    border: 3px solid transparent;
    border-radius: 99px;
}
::-webkit-scrollbar-thumb:hover { background-color: var(--muted); }
::-webkit-scrollbar-corner { background: transparent; }

.sidebar, .nav {
    scrollbar-color: rgba(255, 255, 255, .25) transparent;
}
.sidebar::-webkit-scrollbar-thumb, .nav::-webkit-scrollbar-thumb {
    background-color: rgba(255, 255, 255, .25);
}
.sidebar::-webkit-scrollbar-thumb:hover, .nav::-webkit-scrollbar-thumb:hover {
    background-color: rgba(255, 255, 255, .4);
}

/* Layout */
.layout { display: grid; grid-template-columns: 226px 1fr; min-height: 100vh; }

.sidebar {
    background: linear-gradient(180deg, var(--sidebar), var(--sidebar-2));
    color: var(--sidebar-text);
    padding: 16px 10px;
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
}

.brand { display: flex; align-items: center; gap: 9px; margin: 3px 6px 18px; }
.brand .mark {
    width: 29px; height: 29px; border-radius: 8px; flex-shrink: 0;
    background: linear-gradient(135deg, var(--brand), var(--accent));
    display: flex; align-items: center; justify-content: center;
    color: #fff; font-weight: 800; font-size: 14px;
    box-shadow: 0 3px 9px rgba(79, 70, 229, .4);
}
.brand .text { line-height: 1.25; }
.brand strong { display: block; font-size: 14.5px; font-weight: 800; color: #fff; letter-spacing: .01em; }
.brand small { display: block; color: #6b7ba0; font-size: 9.5px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase; }
/* A tenant's own logo replaces the generic "G" mark entirely in the expanded
   sidebar — showing both side by side let the hardcoded mark dominate and
   made the tenant's actual logo (squeezed to the same small height) read as
   too small. The mark still needs to exist in the DOM for the collapsed
   rail view, where it's the only icon-sized brand glyph available. */
.brand.has-logo .mark { display: none; }
.layout.rail .brand.has-logo .mark, html.gt-rail-preload .brand.has-logo .mark { display: flex; }
.brand.has-logo .brand-logo { height: var(--brand-logo-height, 30px); }
.brand-logo { display: block; height: 20px; width: auto; filter: brightness(0) invert(1); margin-bottom: 2px; }

.nav { display: flex; flex-direction: column; flex: 1; overflow-y: auto; }
.nav-label { font-size: 9.5px; letter-spacing: .1em; color: #5f6f93; margin: 0; text-transform: uppercase; font-weight: 700; }
.nav a {
    display: flex; align-items: center; gap: 9px;
    color: var(--sidebar-text); padding: 7px 10px; border-radius: 7px;
    text-decoration: none; margin: 1px 0; font-weight: 600; font-size: 12.5px;
    transition: background .15s ease, color .15s ease;
}
.nav a svg { flex-shrink: 0; opacity: .8; transition: opacity .15s ease; }
.nav a:hover { background: rgba(255, 255, 255, .06); color: #fff; }
.nav a:hover svg { opacity: 1; }
.nav a.active { background: var(--brand); color: #fff; box-shadow: 0 4px 12px -3px rgba(79, 70, 229, .5); }
.nav a.active svg { opacity: 1; }
.nav .nav-footer { margin-top: auto; padding-top: 8px; border-top: 1px solid rgba(255, 255, 255, .08); }

/* Collapsible nav sections (accordion) */
.nav-section-header {
    display: flex; align-items: center; justify-content: space-between; width: 100%;
    background: none; border: 0; padding: 0; margin: 13px 0 5px; cursor: pointer; color: #5f6f93;
}
.nav-section-header:hover { color: #8b9bc4; }
.nav-section-header svg { transition: transform .15s ease; opacity: .8; flex-shrink: 0; }
.nav-section-header[aria-expanded="false"] svg { transform: rotate(-90deg); }
.nav-section-body[hidden] { display: none; }

/* Whole-sidebar rail (icon-only) mode */
.sidebar-toggle {
    background: rgba(255, 255, 255, .06); border: 0; border-radius: 7px; padding: 6px;
    color: var(--sidebar-text); cursor: pointer; margin-left: auto; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center; transition: background .15s ease, color .15s ease;
}
.sidebar-toggle:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.layout.rail, html.gt-rail-preload .layout { grid-template-columns: 64px 1fr; }
.layout.rail .brand, html.gt-rail-preload .brand { justify-content: center; }
.layout.rail .brand .text, html.gt-rail-preload .brand .text,
.layout.rail .nav-section-header .nav-label, html.gt-rail-preload .nav-section-header .nav-label,
.layout.rail .nav-section-header svg, html.gt-rail-preload .nav-section-header svg,
.layout.rail .nav-text, html.gt-rail-preload .nav-text { display: none; }
.layout.rail .sidebar-toggle, html.gt-rail-preload .sidebar-toggle { margin-left: 0; }
.layout.rail .nav a, html.gt-rail-preload .nav a,
.layout.rail .nav-footer a, html.gt-rail-preload .nav-footer a { justify-content: center; }
.layout.rail .nav-section-body[hidden], html.gt-rail-preload .nav-section-body[hidden] { display: block; }

.main { padding: 20px 24px 30px; max-width: 1680px; width: 100%; min-width: 0; }

/* Promo ticker — sits above .topbar, bleeding out to .main's own edges
   (negative margin cancels .main's padding) rather than sitting indented
   like the rest of the page content. Rotates through more than one active
   ticker (see initPromoTicker() in app.js); a message wider than its own
   track auto-scrolls (.is-scrolling), added by the same JS. */
.promo-ticker { display: flex; align-items: stretch; margin: -20px -24px 18px; overflow: hidden; }
.promo-ticker.info { background: var(--brand-light); color: var(--brand-dark); }
.promo-ticker.promo { background: var(--brand); color: #fff; }
.promo-ticker.urgent { background: var(--danger); color: #fff; }
.promo-ticker-item { display: none; align-items: center; gap: 14px; padding: 9px 24px; font-size: 13px; font-weight: 600; flex: 1; min-width: 0; }
.promo-ticker-item.is-active { display: flex; }
.promo-ticker-track { flex: 1; overflow: hidden; white-space: nowrap; min-width: 0; }
.promo-ticker-text { display: inline-block; }
.promo-ticker-text.is-scrolling { padding-left: 100%; animation-name: promo-ticker-scroll; animation-timing-function: linear; animation-iteration-count: infinite; }
@keyframes promo-ticker-scroll { from { transform: translateX(0); } to { transform: translateX(-100%); } }
.promo-ticker-link { color: inherit; text-decoration: underline; flex-shrink: 0; font-weight: 700; white-space: nowrap; }
.promo-ticker-controls { display: flex; align-items: center; gap: 2px; padding: 0 16px; flex-shrink: 0; }
.promo-ticker-btn { border: 0; background: none; color: inherit; opacity: .8; display: flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 6px; cursor: pointer; }
.promo-ticker-btn:hover { opacity: 1; background: rgba(0, 0, 0, .1); }
@media (prefers-reduced-motion: reduce) { .promo-ticker-text.is-scrolling { animation: none; } }

.topbar {
    display: flex; justify-content: space-between; align-items: center;
    margin-bottom: 18px; padding-bottom: 12px; border-bottom: 1px solid var(--line);
}
.topbar h1 { font-size: 19.5px; margin: 0; letter-spacing: -.01em; }
.topbar .subtitle { color: var(--muted); font-size: 12px; margin-top: 2px; }
.user { display: flex; align-items: center; gap: 9px; color: var(--muted); text-decoration: none; border-radius: 10px; padding: 4px 8px 4px 4px; transition: background .15s; }
.user:hover { background: var(--surface-2, rgba(0, 0, 0, .035)); }
.user .avatar {
    width: 30px; height: 30px; border-radius: 50%; background: var(--brand-light); color: var(--brand-dark);
    display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 12px;
}
.user .who strong { display: block; color: var(--ink); font-size: 12.5px; }
.user .who span { font-size: 11px; text-transform: capitalize; }

/* Surfaces */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 15px 17px; box-shadow: var(--shadow-sm); }

.icon-badge { display: flex; align-items: center; justify-content: center; flex-shrink: 0; }

/* Dashboard stats */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 16px; }
.stats-5 { grid-template-columns: repeat(5, 1fr); }
.stats-6 { grid-template-columns: repeat(6, 1fr); }
.stat { display: flex; align-items: center; gap: 11px; }
.stat .icon-badge { width: 36px; height: 36px; border-radius: 9px; }
.stat span { color: var(--muted); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.stat strong { display: block; font-size: 20px; margin-top: 1px; letter-spacing: -.01em; }

.quick-links { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 12px; }
.quick-link {
    display: flex; align-items: center; gap: 10px; padding: 11px 12px; border-radius: var(--radius);
    border: 1px solid var(--line); text-decoration: none; color: var(--ink); background: var(--surface-2);
    transition: border-color .15s ease, transform .15s ease;
}
.quick-link:hover { border-color: var(--brand); transform: translateY(-1px); }
.quick-link .icon-badge { width: 32px; height: 32px; border-radius: 8px; }
.quick-link strong { display: block; font-size: 12.5px; }
.quick-link span { color: var(--muted); font-size: 11px; }

/* Toolbar / filters */
.toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 13px; gap: 10px; flex-wrap: wrap; }
.toolbar h2 { margin: 0; font-size: 15px; }
.filters { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.search-box { position: relative; display: flex; align-items: center; }
.search-box svg { position: absolute; left: 10px; color: var(--muted-2); pointer-events: none; }
.search-box input,
.filters select,
.filters input[type="date"],
.filters input[type="number"] {
    border: 1px solid #d3dae7; border-radius: 7px; padding: 7px 10px; font: inherit; font-size: 12.5px;
    background: #fff; color: var(--ink); height: 34px; transition: border-color .15s ease, box-shadow .15s ease;
}
.search-box input { padding-left: 30px; min-width: 210px; }
.filters select { min-width: 140px; max-width: 200px; cursor: pointer; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; }
.filters input[type="date"] { min-width: 140px; }
.filters input[type="number"] { min-width: 0; }
.search-box input:focus, .filters select:focus, .filters input[type="date"]:focus {
    outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-light);
}

/* Buttons */
.btn {
    background: var(--brand); border: 0; color: #fff; padding: 7px 12px; border-radius: 7px;
    text-decoration: none; cursor: pointer; font-weight: 650; font-size: 12.5px;
    display: inline-flex; align-items: center; gap: 6px; transition: background .15s ease, box-shadow .15s ease;
}
.btn:hover { background: var(--brand-dark); }
.btn.secondary { background: var(--brand-light); color: var(--brand-dark); }
.btn.secondary:hover { background: #e0e4ff; }
.btn.danger { background: var(--danger-light); color: var(--danger); }
.btn.danger:hover { background: #fecdd3; }
.btn.ghost { background: transparent; color: var(--muted); padding: 6px 8px; }
.btn.ghost:hover { background: var(--surface-2); color: var(--ink); }
.btn.small { padding: 5px 9px; font-size: 11.5px; }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.row-actions { display: flex; gap: 6px; }
.review-photo-thumbs { display: flex; flex-wrap: wrap; gap: 4px; }
.review-photo-thumbs img { width: 40px; height: 40px; object-fit: cover; border-radius: 6px; border: 1px solid var(--line); }

/* Tables */
table { width: 100%; border-collapse: collapse; }
th { text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); padding: 8px 10px; border-bottom: 1px solid var(--line); background: var(--surface-2); }
th:first-child { border-top-left-radius: var(--radius-sm); }
th:last-child { border-top-right-radius: var(--radius-sm); }
td { padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
tbody tr:hover { background: var(--surface-2); }
tbody tr:last-child td { border-bottom: 0; }
.cell-primary { font-weight: 650; }
.cell-muted { color: var(--muted); font-size: 12px; }
.cell-checkbox { width: 32px; }

/* Bulk selection + pagination */
.bulk-bar { padding: 8px 2px; margin-bottom: 8px; }
.bulk-bar-info { font-size: 12px; color: var(--muted); font-weight: 650; }
.pagination { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 13px; }
.pagination-summary { font-size: 12px; color: var(--muted); }
.pagination-links { display: flex; align-items: center; gap: 8px; }
.pagination-page { font-size: 12px; color: var(--muted); }
.pagination-links a.disabled { pointer-events: none; opacity: .4; }
.pagination-page-size { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
.pagination-page-size select { padding: 3px 6px; font-size: 12px; }

/* Ajax-paginated order/booking list tables — see the .js-paginated-list click handler in app.js. Reuses the gt-spin keyframes already defined for .js-supplier-import-panel's loading state. */
.js-paginated-list { position: relative; min-height: 60px; transition: opacity .15s ease; }
.js-paginated-list.is-loading { opacity: .45; pointer-events: none; }
.js-paginated-list.is-loading::after {
    content: '';
    position: absolute;
    top: 40px; left: 50%;
    width: 24px; height: 24px;
    margin-left: -12px;
    border: 3px solid var(--line);
    border-top-color: var(--brand);
    border-radius: 50%;
    animation: gt-spin .7s linear infinite;
    z-index: 5;
}

.avatar-circle {
    width: 28px; height: 28px; border-radius: 50%; background: var(--brand-light); color: var(--brand-dark);
    display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 11.5px; flex-shrink: 0;
}
.name-cell { display: flex; align-items: center; gap: 9px; }
.name-cell .meta { line-height: 1.3; }
.name-cell .meta small { display: block; color: var(--muted); font-size: 11.5px; }

/* Badges */
.badge { display: inline-flex; align-items: center; gap: 5px; border-radius: 99px; padding: 3px 9px; font-size: 11px; font-weight: 700; }
.badge::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.badge.active, .badge.success { background: var(--success-light); color: var(--success); }
.badge.draft, .badge.pending, .badge.paused, .badge.inactive { background: var(--amber-light); color: var(--amber); }
.badge.blocked, .badge.rejected, .badge.disabled, .badge.suspended { background: var(--danger-light); color: var(--danger); }
.badge.archived { background: var(--surface-2); color: var(--muted); }
button.badge { border: none; font-family: inherit; cursor: pointer; }

/* Row action menu — a native <details> dropdown, no JS component needed
   beyond closing it on an outside click (see app.js). Used to tuck a row's
   less-common actions (status changes) behind one toggle instead of a wall
   of buttons, keeping only the most-used ones inline. */
.row-menu { position: relative; display: inline-block; }
.row-menu > summary { list-style: none; }
.row-menu > summary::-webkit-details-marker { display: none; }
.row-menu[open] > summary { background: var(--surface-2); }
.row-menu-panel {
    position: absolute; right: 0; top: calc(100% + 4px); z-index: 20;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
    box-shadow: var(--shadow); min-width: 170px; padding: 4px; display: flex; flex-direction: column; gap: 2px;
}
.row-menu-item {
    display: block; width: 100%; text-align: left; padding: 7px 10px; border-radius: 6px;
    border: none; background: none; font-size: 13px; font-weight: 600; cursor: pointer; color: var(--ink);
    font-family: inherit;
}
.row-menu-item:hover { background: var(--surface-2); }
.row-menu-item.danger { color: var(--danger); }

/* Forms */
.grid-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.field.full { grid-column: 1 / -1; }
.field > label { display: block; font-weight: 650; margin-bottom: 4px; font-size: 12.5px; white-space: normal; overflow-wrap: break-word; }
.field .hint { display: block; color: var(--muted-2); font-size: 11px; margin-top: 3px; }
.check-toggle-links { font-weight: 400; margin-left: 6px; }
.btn-link-sm { border: 0; background: none; padding: 0; font: inherit; font-size: 11.5px; color: var(--brand); cursor: pointer; }
.btn-link-sm:hover { text-decoration: underline; }
.field input, .field select, .field textarea {
    width: 100%; border: 1px solid #d3dae7; border-radius: 7px; padding: 7px 9px; font: inherit; background: #fff;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.field input[type="checkbox"], .field input[type="radio"] { width: auto; border: none; padding: 0; background: none; }
.field input:focus, .field select:focus, .field textarea:focus {
    outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-light);
}
.field textarea { min-height: 70px; resize: vertical; }
.field textarea.js-ticket-rows { font-family: ui-monospace, "SF Mono", Consolas, monospace; font-size: 12.5px; line-height: 1.6; }
.field.invalid input, .field.invalid select, .field.invalid textarea {
    border-color: var(--danger); box-shadow: 0 0 0 3px var(--danger-light);
}
.field-error { display: block; color: var(--danger); font-size: 11px; margin-top: 4px; font-weight: 600; }
.field.checkbox-field { display: flex; align-items: center; gap: 8px; margin-top: 20px; }
.field.checkbox-field input { width: auto; }
.color-pair { display: flex; align-items: center; gap: 8px; }
.color-pair input[type="color"] { width: 40px; height: 36px; padding: 2px; flex: none; cursor: pointer; }
.color-pair input[type="text"] { flex: 1; }
.actions { display: flex; gap: 8px; }
.grid-form + .actions { margin-top: 16px; }

/* Repeatable FAQ editor (activity-form.php) — one bordered card per Q&A.
   Shared with the custom-fields editor (activity-variant-form.php,
   activity-manage.php), which reuses this same .faq-row card markup. */
.js-faq-list, .js-custom-field-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 12px; }
.faq-row { position: relative; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-2); padding: 14px; padding-right: 44px; }
.faq-row-remove {
    position: absolute; top: 10px; right: 10px; width: 26px; height: 26px;
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--line); border-radius: 6px; background: #fff; color: var(--muted); cursor: pointer;
}
.faq-row-remove:hover { color: var(--danger); border-color: var(--danger-light); background: var(--danger-light); }

/* Repeatable combo component editor (combo-form.php) — one numbered card per
   activity, auto-numbered via a CSS counter so add/remove never needs JS to
   relabel the remaining cards. */
.js-combo-item-list { display: flex; flex-direction: column; gap: 12px; margin-bottom: 12px; counter-reset: combo-item; }
.combo-item-card { position: relative; border: 1px solid var(--line); border-radius: var(--radius); background: #fff; overflow: hidden; counter-increment: combo-item; }
.combo-item-card-header {
    display: flex; align-items: center; gap: 9px; padding: 10px 44px 10px 14px;
    background: var(--surface-2); border-bottom: 1px solid var(--line);
}
.combo-item-card-index {
    width: 22px; height: 22px; border-radius: 50%; background: var(--brand-light); color: var(--brand-dark);
    display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 11px; flex-shrink: 0;
}
.combo-item-card-index::before { content: counter(combo-item); }
.combo-item-card-title { font-weight: 700; font-size: 12.5px; color: var(--ink); }
.combo-item-card-title::before { content: "Component " counter(combo-item); }
.combo-item-card-body { padding: 14px; }

/* Pricing Rules' "Select individually" repeater (pricing-rule-form.php, add
   AND edit mode) — a plain table, one row per item with its own markup,
   instead of combo-form.php's card-per-item pattern. A table reads better
   here: it's dense, homogeneous, spreadsheet-like entry across up to ~20
   rows, where a card's own border/padding per item (right for combo's 4
   varied fields) is mostly wasted vertical space repeated 20 times. Each
   row becomes one pricing_rule_items row on the rule being saved, not a
   separate pricing_rules row. Row numbering still via CSS counter, same
   idea as .combo-item-card-index above. */
.bulk-margin-table th, .bulk-margin-table td { vertical-align: middle; padding: 6px 10px; }
.bulk-margin-table thead th { padding: 8px 10px; text-align: left; background: var(--surface-2); border-bottom: 1px solid var(--line); }
.bulk-margin-table tbody tr:not(:last-child) td { border-bottom: 1px solid var(--line); }
/* Table cells aren't wrapped in .field (that'd add a <label> per cell), so
   its raw <input>/<select> would otherwise fall back to bare browser
   defaults — no border-radius, no focus ring, mismatched height against the
   select2 box next to it. Same visual treatment as .field input, just
   re-scoped to this table. */
.bulk-margin-table input, .bulk-margin-table select {
    width: 100%; border: 1px solid #d3dae7; border-radius: 7px; padding: 7px 9px; font: inherit; background: #fff;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.bulk-margin-table input:focus, .bulk-margin-table select:focus {
    outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-light);
}
/* :not(.select2-hidden-accessible) matters — once select2 initializes,
   the native <select> stays in the DOM with that class, kept off-screen
   for accessibility via its own width:1px rule. Forcing width:100% onto
   it too (as this rule did before) fights that and made the real select
   stretch to viewport width, overflowing the whole page horizontally —
   only the visible .select2-container replica needs the full-width rule. */
.bulk-margin-table .js-select2:not(.select2-hidden-accessible), .bulk-margin-table .select2-container { width: 100% !important; }
.js-bulk-item-list { counter-reset: bulk-margin-item; }
.bulk-margin-row { counter-increment: bulk-margin-item; }
.bulk-margin-row .bulk-margin-row-index::before { content: counter(bulk-margin-item); }
.bulk-margin-row-remove {
    width: 26px; height: 26px; display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--line); border-radius: 6px; background: #fff; color: var(--muted); cursor: pointer;
}
.bulk-margin-row-remove:hover { color: var(--danger); border-color: var(--danger-light); background: var(--danger-light); }

/* Role permissions matrix — grouped collapsible categories (role-form.php) */
.perm-category { border: 1px solid var(--line); border-radius: var(--radius); margin-bottom: 10px; overflow: hidden; }
.perm-category:last-child { margin-bottom: 0; }
.perm-category-header { display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: var(--surface-2); }
.perm-category-toggle {
    display: flex; align-items: center; gap: 7px; background: none; border: 0; padding: 0; cursor: pointer;
    font-weight: 700; font-size: 12.5px; color: var(--ink); flex: 1; text-align: left;
}
.perm-category-toggle svg { transition: transform .15s ease; opacity: .7; flex-shrink: 0; }
.perm-category-toggle[aria-expanded="false"] svg { transform: rotate(-90deg); }
.perm-count {
    flex-shrink: 0; font-size: 11px; font-weight: 700; color: var(--muted);
    background: var(--surface); border: 1px solid var(--line); border-radius: 99px; padding: 2px 9px;
}
.perm-select-all {
    display: flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600; color: var(--muted);
    cursor: pointer; flex-shrink: 0; white-space: nowrap;
}
.perm-select-all input { width: auto; }
.perm-category-body[hidden] { display: none; }
.perm-table td { padding: 8px 12px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.perm-table tr:last-child td { border-bottom: 0; }
.perm-table td.cell-primary { width: 1%; white-space: nowrap; font-size: 12.5px; padding-right: 20px; }
.perm-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.perm-chip {
    display: flex; align-items: center; gap: 5px; padding: 4px 10px; border-radius: 99px;
    border: 1px solid var(--line); font-size: 11.5px; font-weight: 600; color: var(--muted);
    cursor: pointer; transition: background .12s ease, border-color .12s ease, color .12s ease; user-select: none;
}
.perm-chip input { width: auto; margin: 0; }
.perm-chip:hover { border-color: var(--brand); color: var(--ink); }
.perm-chip:has(input:checked) { background: var(--brand-light); border-color: var(--brand); color: var(--brand-dark); }
#permission-matrix.is-disabled { opacity: .4; pointer-events: none; }

/* Form sections — each one reads as its own card */
.record-form { display: flex; flex-direction: column; gap: 14px; max-width: 920px; }
.record-form.form-wide { max-width: 1180px; }
/* Pricing Rules' form — its Shared settings 2-column grid plus the bulk
   repeater table both benefit from the full page width (.main's own
   1680px ceiling) rather than either capped width above, which left a lot
   of empty space at wide viewports. */
.record-form.form-full { max-width: 100%; }
.form-columns { display: grid; grid-template-columns: 1fr 300px; gap: 14px; align-items: start; }
.form-columns .form-main, .form-columns .form-sidebar { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
/* Same stacked-cards spacing as .form-main/.form-sidebar above, for a single
   column of forms with no side-by-side layout to hang it on (e.g. a tab
   panel holding more than one .record-form — see b2c-content.php). Not
   folded into .js-tab-panel itself since that class is shared by pages
   whose panel content isn't a form stack at all (tables, etc.). */
.form-stack { display: flex; flex-direction: column; gap: 14px; }
/* An explicit display: flex above otherwise beats the browser's own
   [hidden]{display:none} default (author styles always win over UA ones,
   regardless of specificity) — without this, a .js-tab-panel.form-stack
   stays visibly flexed even with the hidden attribute set, so every tab's
   content shows stacked at once instead of just the active one. */
.form-stack[hidden] { display: none; }
.form-section {
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 16px 18px; box-shadow: var(--shadow-sm);
}
.form-section-title {
    display: flex; align-items: center; gap: 9px;
    font-size: 13px; font-weight: 700; color: var(--ink);
    margin: 0 0 14px; padding-bottom: 12px; border-bottom: 1px solid var(--line);
}
.form-section-title .icon-badge { width: 26px; height: 26px; border-radius: 7px; background: var(--brand-light); color: var(--brand-dark); flex-shrink: 0; }

/* Collapsible sections — opt-in per form via .js-collapsible added by
   initFormSectionCollapse() (app.js), not a static markup class, so it
   stays scoped to the forms that ask for it (activities/variants — see
   that function's own comment) without touching every other page that
   happens to reuse .form-section/.form-section-title. Collapsing hides
   every direct child except the title itself, so it works regardless of
   what a given section's body actually contains. */
.form-section-title.js-collapsible { cursor: pointer; user-select: none; }
.form-section-title.js-collapsible::after {
    content: '\25BE'; margin-left: auto; flex-shrink: 0; color: var(--muted-2); font-size: 12px;
    transition: transform .15s ease;
}
.form-section.is-collapsed > .form-section-title.js-collapsible::after { transform: rotate(-90deg); }
.form-section.is-collapsed > *:not(.form-section-title) { display: none; }
.form-section-title .step { color: var(--muted-2); font-weight: 600; font-size: 11.5px; text-transform: none; letter-spacing: 0; margin-left: auto; }

/* Sub-groups within one .form-section (pricing-rule-form.php's "Shared
   settings", which outgrew a single flat .grid-form — 15 same-looking
   fields read as one undifferentiated wall of inputs). Scoped to
   .field-groups only, not .form-section generally — a plain typographic
   label + thin rule between groups, no boxes/pills (nesting a bordered
   card inside a card would be heavier, not clearer), and every individual
   field keeps its normal .field/.grid-form markup untouched. A tighter
   row gap than the default .grid-form's 12px keeps a multi-group card from
   reading taller than the same fields would flat. */
.field-groups { display: flex; flex-direction: column; gap: 16px; }
.field-groups .grid-form { gap: 10px 16px; }
.field-group-title {
    font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
    color: var(--muted-2); margin: 0 0 8px;
}
.field-group:not(:first-child) { padding-top: 14px; border-top: 1px solid var(--line); }

/* .form-compact — a denser variant of .record-form, scoped to whichever
   form opts in (pricing-rule-form.php) rather than changing .field/
   .grid-form/select2 sizing for every other admin form that still wants
   the normal size. Same controls, same structure, just less padding/gap. */
.form-compact .form-section { padding: 14px 16px; }
.form-compact .form-section-title { margin-bottom: 10px; padding-bottom: 9px; }
.form-compact .field-groups { gap: 12px; }
.form-compact .field-group:not(:first-child) { padding-top: 10px; }
.form-compact .field-group-title { margin-bottom: 6px; }
.form-compact .grid-form { gap: 8px 14px; }
/* Shared settings is a plain settings form, not a data table — unlike the
   Items card below it (which genuinely needs the full page width for its
   table of activities/variants), stretching a 2-column field grid across
   the full ~1680px container is what actually made it read as "big": a
   small input floating in a mostly-empty ~800px-wide box. Capping the
   whole CARD (not just its inner content) is what most settings UIs do
   regardless of viewport width — narrower, proportionate fields read as
   deliberately designed; capping only the content and leaving the card's
   own border/background full-width would just relocate the same dead
   space inside the box instead of removing it. */
/* Used both on the Shared settings .form-columns (main 1fr + 14px gap +
   300px sidebar, so ~760px of that is the main column — same per-field
   size as before the sidebar split) and directly on the Items card, so
   every card on this page shares one right edge instead of Items being a
   different width than the main+sidebar pair above it. */
.form-section-narrow { max-width: 1080px; }
.form-compact .field > label { font-size: 11.5px; margin-bottom: 3px; }
.form-compact .field input, .form-compact .field select, .form-compact .field textarea {
    padding: 5px 8px; font-size: 12.5px;
}
.form-compact .field .hint { margin-top: 2px; }
.form-compact .field.checkbox-field { margin-top: 4px; }
.form-compact .select2-container--default .select2-selection--single { height: 28px; }
.form-compact .select2-container--default .select2-selection--single .select2-selection__arrow { height: 26px; }
.form-compact .select2-container--default .select2-selection--multiple { min-height: 28px; }
/* "All items" mode's 2 fields are the only content in an otherwise
   full-width Items card (the card stays full-width for "Select
   individually"'s table) — same fix as .form-section-narrow, just for
   this one panel instead of the whole card. */
.form-compact .js-bulk-mode-single-panel { max-width: 520px; }
.form-compact .pp-viewer-toggle { height: 28px; }
.form-compact .pp-viewer-toggle label { padding: 0 10px; font-size: 12px; }
.form-compact .bulk-margin-table th, .form-compact .bulk-margin-table td { padding: 4px 8px; }
.form-compact .bulk-margin-table input, .form-compact .bulk-margin-table select { padding: 5px 8px; }
.form-compact .bulk-margin-table .select2-container--default .select2-selection--single { height: 28px; }
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 16px; }
.tab-btn {
    display: flex; align-items: center; gap: 7px; background: none; border: none; cursor: pointer;
    font-size: 12.5px; font-weight: 600; color: var(--muted); padding: 10px 4px; margin-bottom: -1px;
    border-bottom: 2px solid transparent;
}
.tab-btn:hover { color: var(--ink); }
.tab-btn.is-active { color: var(--brand-dark); border-bottom-color: var(--brand); }
.tab-btn .tab-count { background: var(--surface-2); color: var(--muted); border-radius: 99px; padding: 1px 8px; font-size: 11px; font-weight: 700; }
.tab-btn.is-active .tab-count { background: var(--brand-light); color: var(--brand-dark); }

/* Vertical side-tab layout (Reports page) — same .js-tab-btn/.js-tab-panel JS as the
   horizontal .tabs component above, just arranged as a left-hand rail instead of a top bar. */
.report-tabs { display: flex; gap: 20px; align-items: flex-start; }
.report-tabs-nav { display: flex; flex-direction: column; gap: 3px; width: 190px; flex-shrink: 0; position: sticky; top: 16px; max-height: calc(100vh - 32px); overflow-y: auto; }
/* Schedule's tab labels are real variant names (often longer than the
   Reports page's fixed short labels) — a wider rail on this page only,
   rather than widening .report-tabs-nav everywhere. */
.schedule-tabs .report-tabs-nav { width: 260px; }
.report-tab-btn {
    display: flex; align-items: center; gap: 8px; background: none; border: none; cursor: pointer;
    font: inherit; font-size: 13px; font-weight: 600; color: var(--muted); text-align: left;
    padding: 10px 12px; border-radius: 8px;
}
.report-tab-btn:hover { background: var(--surface-2); color: var(--ink); }
.report-tab-btn.is-active { background: var(--brand-light); color: var(--brand-dark); }
.report-tab-btn .tab-count { margin-left: auto; }
.report-tabs-content { flex: 1; min-width: 0; }
@media (max-width: 720px) {
    .report-tabs { flex-direction: column; }
    .report-tabs-nav { flex-direction: row; width: 100%; overflow-x: auto; position: static; }
}

.combo-chip { display: inline-flex; align-items: center; gap: 4px; background: var(--surface-2); color: var(--muted); font-size: 10.5px; font-weight: 600; padding: 2px 7px; border-radius: 999px; margin-top: 4px; text-decoration: none; }
.combo-chip:hover { background: var(--brand-light); color: var(--brand-dark); }

/* Order/booking detail line item — deliberately NOT named .activity-card:
   that class already exists below (agency catalog browse grid) with
   unrelated display:flex/overflow:hidden rules that silently clobbered
   this component's grid layout when both shared the name. */
.order-line-card { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; }
.order-line-card + .order-line-card { margin-top: 14px; }
.order-line-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.order-line-title { font-weight: 700; font-size: 13.5px; color: var(--ink); line-height: 1.45; }
.order-line-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; margin-bottom: 14px; }
.order-line-field { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 8px 12px; }
.order-line-field .k { display: block; font-size: 10px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted-2); margin-bottom: 4px; font-weight: 700; }
.order-line-field .v { display: block; font-size: 12.5px; font-weight: 700; color: var(--ink); overflow-wrap: anywhere; }
.order-line-supplier { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px 12px; font-size: 12px; color: var(--muted); }
.order-line-supplier > span:first-child { flex: 1 1 220px; min-width: 0; overflow-wrap: anywhere; }
.order-line-supplier .icon-badge { width: 22px; height: 22px; border-radius: 6px; background: var(--brand-light); color: var(--brand-dark); flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; }
.supplier-status { display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px; font-weight: 700; padding: 4px 10px; border-radius: 999px; white-space: nowrap; }
.supplier-status.placed { background: var(--success-light); color: var(--success); }
.supplier-status.pending { background: var(--amber-light); color: var(--amber); }
.supplier-status.failed { background: var(--danger-light); color: var(--danger); }
.supplier-status.na { background: var(--surface-2); color: var(--muted); }
/* Real loading feedback for a panel swapped in via ajax (e.g. the supplier
   import browse/search/preview panel) — the external supplier API call it's
   waiting on can take a couple of seconds, so a bare unresponsive-looking
   page during that wait reads as broken rather than busy.
   The spinner is `position: fixed` (viewport-centered), not absolute
   relative to the panel — a plain absolute spinner centers on the panel's
   own box, which for a long catalog table can sit well below the visible
   scroll position (or, before the very first search, the panel is only a
   couple lines tall so its "center" is barely below the search bar) —
   either way "centered on the panel" doesn't mean "visible on screen". */
.js-supplier-import-panel { position: relative; min-height: 90px; transition: opacity .15s ease; }
.js-supplier-import-panel.is-loading { opacity: .45; pointer-events: none; }
.js-supplier-import-panel.is-loading::after {
    content: '';
    position: fixed;
    top: 50%; left: 50%;
    width: 28px; height: 28px;
    margin: -14px 0 0 -14px;
    border: 3px solid var(--line);
    border-top-color: var(--brand);
    border-radius: 50%;
    animation: gt-spin .7s linear infinite;
    z-index: 20;
}
@keyframes gt-spin { to { transform: rotate(360deg); } }

/* Pricing Preview's filter bar — a richer variant of .filters: every field
   needs its own visible label (activity/variant/date/viewer/agency), unlike
   a typical 2-field search-and-status bar, so each one gets its own labeled
   column instead of a bare input sitting directly in the flex row. */
.pp-filters { align-items: flex-end; row-gap: 12px; }
/* flex: 1 1 Npx (not just min-width) is what actually matters here — a bare
   min-width on a shrink-to-fit flex child still leaves select2's own
   width:'100%' init measuring an intrinsic (near-zero, pre-content) box,
   which is why these rendered tiny before: .filters is flex with no basis,
   unlike .grid-form's CSS Grid columns which give every .field a real
   pre-computed width for select2 to fill. */
.pp-filter-field { display: flex; flex-direction: column; gap: 4px; flex: 1 1 200px; max-width: 320px; }
.pp-filter-field label { font-size: 10.5px; font-weight: 650; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.pp-filter-field select, .pp-filter-field input[type="date"], .pp-filter-field input[type="number"] { width: 100%; }
.pp-filter-submit { flex: 0 0 auto; }
.pp-filter-submit .btn { height: 34px; }

/* Segmented-control look for the Guest/Agency choice — a plain radio pair
   read poorly wedged into a filter bar; this reads as one control with two
   settled states instead of two independent checkboxes. */
.pp-viewer-toggle { display: inline-flex; border: 1px solid #d3dae7; border-radius: 7px; overflow: hidden; height: 34px; background: #fff; }
.pp-viewer-toggle label { position: relative; display: flex; align-items: center; padding: 0 12px; font-size: 12.5px; font-weight: 600; color: var(--muted); cursor: pointer; white-space: nowrap; transition: background .15s ease, color .15s ease; }
.pp-viewer-toggle label:not(:first-child) { border-left: 1px solid #d3dae7; }
.pp-viewer-toggle input { position: absolute; opacity: 0; pointer-events: none; }
.pp-viewer-toggle label:has(input:checked) { background: var(--brand-light); color: var(--brand-dark); }

/* Same loading treatment as .js-supplier-import-panel — a live supplier
   fetch (Traveldesk especially) can take a couple of seconds, so the panel
   needs to visibly say "working" rather than sit unresponsive. */
.js-pricing-preview-panel { position: relative; min-height: 90px; transition: opacity .15s ease; }
.js-pricing-preview-panel.is-loading { opacity: .45; pointer-events: none; }
.js-pricing-preview-panel.is-loading::after {
    content: '';
    position: fixed;
    top: 50%; left: 50%;
    width: 28px; height: 28px;
    margin: -14px 0 0 -14px;
    border: 3px solid var(--line);
    border-top-color: var(--brand);
    border-radius: 50%;
    animation: gt-spin .7s linear infinite;
    z-index: 20;
}

/* Inline spinner swapped into a button's own label while its click handler
   awaits a request — e.g. "Import as new activity", which calls out to the
   external supplier API and otherwise just sits there `disabled` with no
   other visible sign anything is happening. */
.btn-spinner {
    display: inline-block; width: 13px; height: 13px; margin-right: 2px;
    border: 2px solid rgba(255, 255, 255, .4); border-top-color: #fff;
    border-radius: 50%; vertical-align: -2px;
    animation: gt-spin .7s linear infinite;
}
.btn.secondary .btn-spinner, .btn.ghost .btn-spinner { border-color: rgba(79, 70, 229, .25); border-top-color: var(--brand); }

/* Quill rich text editor. The toolbar Quill generates is a preceding
   SIBLING of the container element passed to `new Quill()` — not a
   descendant — and that same container element is both `.quill-container`
   (our class) and `.ql-container.ql-snow` (Quill's own), never two nested
   elements. Selectors below match that real structure; a prior version
   assumed toolbar/container nesting that doesn't exist, so none of them
   ever matched — leaving Quill's own `.ql-container`/`.ql-editor` at their
   library default `height: 100%`, which (in a CSS Grid row) resolved to a
   fixed height instead of growing with content, so a second editor's real
   content silently overflowed past its own field box and visually covered
   whatever came after it on the page. */
.quill-container { background: #fff; overflow: hidden; }
.ql-toolbar.ql-snow { border: 1px solid #d3dae7 !important; border-bottom: 0 !important; }
.quill-container.ql-container.ql-snow { height: auto; min-height: 140px; border: 1px solid #d3dae7 !important; font: inherit; font-size: 13px; }
.quill-container .ql-editor { height: auto; min-height: 140px; }
/* Hidden by default so the raw textarea never flashes before Quill mounts; the
   fallback class re-reveals it if the Quill script failed to load. */
.js-quill { display: none; }
.js-quill.js-quill-fallback { display: block; }
/* Visually separates a field from a Quill editor immediately above it —
   without this, the plain textarea reads as part of the same box. */
.field-divider { margin-top: 45px; padding-top: 16px; border-top: 1px dashed var(--line); }

.hours-table input[type="time"] { width: auto; }
.hours-table input[type="time"]:disabled { opacity: .4; }

/* Image upload + gallery */
.image-upload { display: flex; flex-direction: column; gap: 8px; }
.image-preview {
    width: 100%; max-width: 220px; aspect-ratio: 16/10; border-radius: var(--radius); overflow: hidden;
    background: var(--surface-2); border: 1px solid var(--line);
    display: flex; align-items: center; justify-content: center;
}
.image-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.image-preview.empty { color: var(--muted-2); }
.image-upload .btn { align-self: flex-start; cursor: pointer; }
.gallery-upload { display: flex; flex-direction: column; gap: 8px; }
.gallery-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.gallery-item, .gallery-add {
    position: relative; width: 72px; height: 72px; border-radius: var(--radius-sm); overflow: hidden;
    border: 1px solid var(--line); flex-shrink: 0;
}
.gallery-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gallery-remove {
    position: absolute; top: 3px; right: 3px; width: 18px; height: 18px; border-radius: 50%; border: 0;
    background: rgba(15, 23, 42, .65); color: #fff; display: flex; align-items: center; justify-content: center;
    cursor: pointer; padding: 0;
}
.gallery-add {
    display: flex; align-items: center; justify-content: center; background: var(--surface-2); color: var(--muted-2);
    cursor: pointer; border-style: dashed;
}
.gallery-add:hover { color: var(--brand); border-color: var(--brand); }

/* Icon picker (Categories form) */
.icon-picker-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(40px, 1fr)); gap: 6px; max-width: 420px; }
.icon-picker-option {
    display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; padding: 0;
    border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--surface-2); color: var(--muted);
    cursor: pointer; transition: border-color .15s ease, color .15s ease;
}
.icon-picker-option:hover { border-color: var(--brand); color: var(--brand); }
.icon-picker-option.active { border-color: var(--brand); color: var(--brand); background: var(--surface); box-shadow: 0 0 0 1px var(--brand); }

/* select2's own JS sets an inline width (initSelect2() passes width:'100%'),
   which inside a bare flex .filters bar resolves against the wrong box and
   blows the control way past the other native selects (see
   feedback_select2_multiselect_gotchas). !important is required here since
   only an inline !important could otherwise out-rank the inline style. */
.filters .select2-container { min-width: 200px !important; max-width: 280px !important; width: auto !important; flex: 0 0 auto; }

/* Select2 overrides to match app inputs */
.select2-container--default .select2-selection--single {
    border: 1px solid #d3dae7; border-radius: 7px; height: 34px; display: flex; align-items: center; padding: 0 6px;
}
.select2-container--default .select2-selection--single .select2-selection__rendered { line-height: 1.3; padding-left: 4px; font-size: 12.5px; }
.select2-container--default .select2-selection--single .select2-selection__arrow { height: 32px; }
.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--open .select2-selection--single {
    border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-light);
}
.select2-dropdown { border-color: #d3dae7; border-radius: 7px; overflow: hidden; }
.select2-container--default .select2-results__option--highlighted[aria-selected] { background: var(--brand); }

/* Multi-select: library defaults are noticeably taller/more padded than the
   compact single-select above (e.g. the Pricing Rules scope_value field) —
   match the same sizing so picking several values doesn't blow up the form. */
.select2-container--default .select2-selection--multiple {
    border: 1px solid #d3dae7; border-radius: 7px; box-sizing: border-box;
    min-height: 34px; max-height: 90px; overflow-y: auto; padding: 3px 4px;
}
.select2-container--default.select2-container--focus .select2-selection--multiple,
.select2-container--default.select2-container--open .select2-selection--multiple {
    border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-light);
}
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
    display: inline-flex; flex-wrap: wrap; align-content: flex-start; align-items: center;
    max-width: 100%; vertical-align: top; gap: 4px; padding: 0; margin: 0;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice {
    background: var(--brand-light); border: none; border-radius: 5px; color: var(--brand-dark);
    font-size: 12px; font-weight: 600; padding: 2px 6px; margin: 0; display: flex; align-items: center; gap: 4px;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
    color: var(--brand-dark); border: none; margin: 0; padding: 0; font-weight: 700; order: 2;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { color: var(--brand); background: transparent; }
.select2-container--default .select2-selection--multiple .select2-search--inline .select2-search__field {
    margin: 2px 0 0; padding: 0; font-size: 12.5px; height: 20px; min-height: 0; max-height: 20px;
    line-height: 20px; overflow: hidden; resize: none; box-sizing: border-box; vertical-align: top;
}

/* SweetAlert2 overrides to match app design tokens */
.swal2-popup { font-family: inherit; border-radius: var(--radius-lg); font-size: 14px; }
.swal2-title { font-size: 18px; }
.swal2-html-container { font-size: 13.5px; color: var(--muted); }
.swal2-confirm.swal2-styled { border-radius: 7px !important; font-weight: 650; padding: 9px 16px !important; box-shadow: none !important; }
.swal2-cancel.swal2-styled { border-radius: 7px !important; font-weight: 650; padding: 9px 16px !important; box-shadow: none !important; }
.swal2-toast { border-radius: var(--radius) !important; box-shadow: var(--shadow) !important; }
.swal2-toast .swal2-title { font-size: 13px; font-weight: 650; }
.swal2-timer-progress-bar { background: rgba(255, 255, 255, .55) !important; }
.swal2-radio { flex-direction: column !important; align-items: stretch !important; width: 100% !important; text-align: left !important; }
.swal2-radio label { display: flex !important; align-items: flex-start !important; gap: 8px !important; padding: 8px 0 !important; border-bottom: 1px solid var(--line); margin: 0 !important; }
.swal2-radio label:last-child { border-bottom: 0; }
.swal2-radio input { margin-top: 3px !important; flex-shrink: 0; }

/* Supplier pricing offer row form */
.offer-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; align-items: end; }

/* Empty state */
.empty { text-align: center; padding: 40px 20px; color: var(--muted); }
.empty svg { opacity: .35; margin-bottom: 10px; }
.empty p { margin: 0; font-size: 12.5px; }

/* Modal dialog — reuses .form-section/.grid-form/.field, just hosted in a panel */
.modal-backdrop {
    position: fixed; inset: 0; background: rgba(15, 23, 42, .5);
    display: flex; align-items: center; justify-content: center; padding: 20px; z-index: 1000;
}
.modal-backdrop[hidden] { display: none; }
.modal-panel {
    background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow);
    max-width: 640px; width: 100%; max-height: 90vh; overflow-y: auto;
}
.modal-header {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 18px; border-bottom: 1px solid var(--line);
}
.modal-header h3 { margin: 0; font-size: 14px; }
.modal-close { background: none; border: 0; padding: 4px; cursor: pointer; color: var(--muted); border-radius: 6px; }
.modal-close:hover { background: var(--surface-2); color: var(--ink); }
.modal-panel .form-section { box-shadow: none; border: 0; padding: 16px 18px 4px; }
.modal-footer { padding: 14px 18px; border-top: 1px solid var(--line); display: flex; gap: 8px; justify-content: flex-end; }

/* Read-only rendering of a Quill-authored body (announcement view modal) */
.announcement-view-body { color: var(--ink); font-size: 13.5px; line-height: 1.7; }
.announcement-view-body p, .announcement-view-body ul, .announcement-view-body ol { margin: 0 0 10px; }
.announcement-view-body > :first-child { margin-top: 0; }
.announcement-view-body > :last-child { margin-bottom: 0; }
.announcement-view-body ul, .announcement-view-body ol { padding-left: 22px; }

/* Topbar announcements bell */
.bell-link { position: relative; display: flex; align-items: center; color: var(--muted); border-radius: 10px; padding: 6px; transition: background .15s, color .15s; }
.bell-link:hover { background: var(--surface-2, rgba(0, 0, 0, .035)); color: var(--ink); }
.bell-badge {
    position: absolute; top: 0; right: 0; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 99px;
    background: var(--danger); color: #fff; font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}

/* Login-time announcement popup — deliberately separate from .modal-backdrop
   (built dynamically in app.js, not server-rendered) so the generic global
   Escape/backdrop-click handlers never touch it; see initAnnouncementPopup(). */
.announcement-modal-backdrop {
    position: fixed; inset: 0; background: rgba(15, 23, 42, .55);
    display: flex; align-items: center; justify-content: center; padding: 20px; z-index: 1100;
}
.announcement-modal-panel {
    background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow);
    max-width: 480px; width: 100%; max-height: 90vh; overflow-y: auto;
}
.announcement-modal-header { padding: 18px 20px 4px; }
.announcement-modal-priority {
    display: inline-block; font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    padding: 3px 9px; border-radius: 99px; background: var(--amber-light); color: var(--amber); margin-bottom: 8px;
}
.announcement-modal-backdrop.important .announcement-modal-priority { background: var(--danger-light); color: var(--danger); }
.announcement-modal-title { margin: 0; font-size: 16px; }
.announcement-modal-body { padding: 8px 20px 18px; color: var(--ink); font-size: 13.5px; line-height: 1.6; }
.announcement-modal-body p, .announcement-modal-body ul, .announcement-modal-body ol { margin: 0 0 10px; }
.announcement-modal-body > :first-child { margin-top: 0; }
.announcement-modal-body > :last-child { margin-bottom: 0; }
.announcement-modal-body ul, .announcement-modal-body ol { padding-left: 22px; }
.announcement-modal-footer { padding: 14px 20px; border-top: 1px solid var(--line); display: flex; justify-content: flex-end; }

/* Activity Preview — customer-facing variant + time-slot picker (read-only mock) */
.preview-desc { color: var(--muted); font-size: 13px; margin: 4px 0 0; max-width: 62ch; }
.section-label {
    display: block; font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
    color: var(--muted-2); margin: 20px 0 10px;
}
.preview-columns { display: grid; grid-template-columns: 1fr 460px; gap: 24px; align-items: start; margin-top: 6px; }
.preview-variants { display: flex; flex-direction: column; gap: 8px; }
.preview-variant-option {
    display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
    padding: 12px 14px; cursor: pointer; transition: border-color .15s ease, background .15s ease;
}
.preview-variant-option:hover { border-color: var(--muted-2); }
.preview-variant-option[aria-pressed="true"] { border-color: var(--brand); background: var(--brand-light); }
.preview-variant-radio {
    width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid var(--muted-2); flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
}
.preview-variant-option[aria-pressed="true"] .preview-variant-radio { border-color: var(--brand); }
.preview-variant-radio::after {
    content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--brand); transform: scale(0);
    transition: transform .12s ease;
}
.preview-variant-option[aria-pressed="true"] .preview-variant-radio::after { transform: scale(1); }
.preview-variant-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.preview-variant-text .pv-name { font-weight: 600; font-size: 13.5px; }
.preview-variant-text .pv-desc { color: var(--muted); font-size: 12px; }
.preview-variant-price { font-weight: 700; color: var(--brand-dark); font-size: 14px; white-space: nowrap; }
.preview-slot-group[hidden] { display: none; }
.preview-date-label { font-size: 12px; color: var(--muted-2); margin: 12px 0 6px; }
.preview-date-label:first-child { margin-top: 0; }
.preview-slot-pills { display: flex; flex-wrap: wrap; gap: 8px; }
.preview-slot-pill {
    background: var(--surface-2); border: 1px solid var(--line); border-radius: 8px; padding: 8px 12px;
    cursor: pointer; display: flex; flex-direction: column; gap: 2px; min-width: 76px;
    transition: border-color .15s ease, background .15s ease;
}
.preview-slot-pill:hover { border-color: var(--muted-2); }
.preview-slot-pill[aria-pressed="true"] { border-color: var(--brand); background: var(--brand-light); }
.preview-slot-pill .ps-time { font-weight: 700; font-size: 13px; }
.preview-slot-pill .ps-cap { font-size: 10.5px; color: var(--muted-2); }
.preview-slot-pill[aria-pressed="true"] .ps-cap { color: var(--brand-dark); }
.empty-slots { color: var(--muted-2); font-size: 12.5px; padding: 6px 0 2px; }
.preview-summary {
    background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 16px; position: sticky; top: 20px;
}
.preview-summary h4 { margin: 0 0 12px; font-size: 11px; letter-spacing: .07em; text-transform: uppercase; color: var(--muted-2); }
/* Label/value row — originally the activity-preview summary widget, now a
   general-purpose pattern reused by the agency portal and agency-manage. */
.summary-row { display: flex; justify-content: space-between; gap: 10px; font-size: 12.5px; padding: 8px 0; border-bottom: 1px solid var(--line); }
/* Default: .k absorbs the wrapping (a long activity name in a price-summary
   line), .v is a short, never-wrapping value (a price, a status). Plain
   proportional flex-shrink (both sides shrinking by the same ratio) isn't
   enough here — a short .k label would still get squeezed well below its
   natural width by the algorithm even though it never needs to, starving
   .v of the room it needs. Pinning .k to flex:0 0 auto in the reverse case
   below is what actually fixes that, not just letting it wrap. */
.summary-row .k { color: var(--muted); flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.summary-row .v { font-weight: 600; text-align: right; flex: 0 0 auto; white-space: nowrap; }
/* A reference string (Stripe session id, ~60 chars) is too long to share a
   row with its label at all — even with all the width flex-shrink can give
   it, a ~300px sidebar column only fits ~20 chars per line, forcing 3+
   cramped lines. Stacking the label above and letting the value use the
   row's FULL width instead of half of it roughly doubles chars-per-line. */
.summary-row.stack { flex-direction: column; align-items: flex-start; gap: 4px; }
.summary-row.stack .k, .summary-row.stack .v { flex: none; }
.summary-row.stack .v { text-align: left; white-space: normal; }
.mono-ref { font-family: monospace; font-size: 11px; word-break: break-all; overflow-wrap: anywhere; }
.summary-row.total { border-bottom: 0; padding-top: 12px; }
.summary-row.total .v { font-size: 17px; color: var(--brand-dark); }
.preview-note { font-size: 11px; color: var(--muted-2); text-align: center; margin: 8px 0 0; }
.preview-note.is-warning { color: var(--danger); font-weight: 600; }
.payment-method-toggle { display: flex; gap: 10px; padding-top: 6px; flex-wrap: wrap; }
.payment-method-option {
    position: relative; flex: 1; min-width: 140px; text-align: center; white-space: nowrap;
    padding: 10px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm);
    font-weight: 600; font-size: 12.5px; cursor: pointer; background: var(--surface);
    transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.payment-method-option:hover { border-color: var(--muted-2); }
.payment-method-option.is-active { border-color: var(--brand); background: var(--brand-light); color: var(--brand-dark); }
.payment-method-option input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }

/* Date-first booking widget (agency activity page) — same 1.Date/2.Option/3.Time
   calendar pattern as the B2C storefront's PDP booking card, restyled onto this
   portal's own indigo tokens rather than the storefront's navy palette. */
.pdp-booking-section { padding: 18px 0; border-bottom: 1px solid var(--line); }
.pdp-booking-section:first-child { padding-top: 0; }
.pdp-booking-section-title { font-size: 11px; letter-spacing: .05em; text-transform: uppercase; color: var(--muted-2); font-weight: 700; margin: 0 0 12px; }
.pdp-booking-section-title.is-loading { opacity: .55; }
.pdp-booking-section-title.is-loading::after { content: '\2026'; }

/* Loading skeleton shown in place of the date/time sections while a
   quantity change is re-resolving the supplier — keeps the section open at
   roughly its real height instead of collapsing it to nothing, since a
   hide/empty/reappear cycle on every qty tick reads as broken. */
.pdp-skel-bar, .pdp-skel-dot, .pdp-skel-cal-grid span, .pdp-skel-pill {
    position: relative; overflow: hidden; background: var(--surface-2); border: 1px solid var(--line); border-radius: 6px;
}
.pdp-skel-bar::after, .pdp-skel-dot::after, .pdp-skel-cal-grid span::after, .pdp-skel-pill::after {
    content: ''; position: absolute; inset: 0; transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .75), transparent);
    animation: pdp-shimmer 1.5s ease-in-out infinite;
}
@keyframes pdp-shimmer { 100% { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
    .pdp-skel-bar::after, .pdp-skel-dot::after, .pdp-skel-cal-grid span::after, .pdp-skel-pill::after { animation: none; }
}
.pdp-skel-bar { height: 14px; margin-bottom: 10px; width: 55%; }
.pdp-skel-cal-card { border: 1.5px solid var(--line); border-radius: var(--radius-sm); padding: 12px 14px 14px; }
.pdp-skel-cal-nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.pdp-skel-cal-nav .pdp-skel-bar { width: 90px; height: 13px; margin: 0; }
.pdp-skel-dot { width: 24px; height: 24px; border-radius: 50%; flex-shrink: 0; }
.pdp-skel-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.pdp-skel-cal-grid span { aspect-ratio: 1; border-radius: 7px; display: block; }
.pdp-skel-times { display: flex; flex-wrap: wrap; gap: 6px; }
.pdp-skel-times[hidden] { display: none; }
.pdp-skel-pill { width: 68px; height: 48px; }

.pdp-date-field {
    width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 10px;
    border: 1.5px solid var(--line); border-radius: var(--radius-sm); padding: 10px 14px; background: var(--surface);
    cursor: pointer; text-align: left; font: inherit; color: var(--ink);
}
.pdp-date-field[hidden] { display: none; }
.pdp-date-field:hover { border-color: var(--brand); }
.pdp-date-field.is-open { border-color: var(--brand); border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.pdp-date-field .df-main { font-weight: 700; font-size: 13.5px; }
.pdp-date-field .df-sub { color: var(--muted); font-size: 11.5px; }
.pdp-date-field .df-chevron { color: var(--muted); transition: transform .15s ease; flex-shrink: 0; }
.pdp-date-field.is-open .df-chevron { transform: rotate(180deg); }

.pdp-cal { border: 1.5px solid var(--brand); border-top: 0; border-radius: 0 0 var(--radius-sm) var(--radius-sm); padding: 12px 14px 14px; }
.pdp-cal[hidden] { display: none; }
.pdp-cal-nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.pdp-cal-month { font-weight: 700; font-size: 13.5px; }
.pdp-cal-arrow {
    width: 24px; height: 24px; border-radius: 50%; border: 1.5px solid var(--line); background: var(--surface); color: var(--ink);
    display: flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0;
}
.pdp-cal-arrow:hover:not(:disabled) { border-color: var(--brand); color: var(--brand); }
.pdp-cal-arrow:disabled { opacity: .3; cursor: not-allowed; }
.pdp-cal-weekdays { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; color: var(--muted-2); font-size: 9.5px; font-weight: 700; text-transform: uppercase; margin-bottom: 4px; }
.pdp-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.pdp-cal-day {
    aspect-ratio: 1; border-radius: 7px; border: 1.5px solid transparent; background: none; cursor: default;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; color: var(--line); font-size: 9px; padding: 2px;
}
.pdp-cal-day .cd-num { font-weight: 700; font-size: 11px; }
.pdp-cal-day.has-slots { color: var(--ink); border-color: var(--line); cursor: pointer; background: var(--surface); }
.pdp-cal-day.has-slots .cd-price { font-size: 8px; font-weight: 700; color: var(--brand); }
.pdp-cal-day.has-slots:hover { border-color: var(--brand); }
.pdp-cal-day.is-selected { background: var(--brand); border-color: var(--brand); }
.pdp-cal-day.is-selected .cd-num, .pdp-cal-day.is-selected .cd-price { color: #fff; }

/* Option list — one fully-expanded accordion row per variant (name,
   description, duration/cancellation/instant-confirmation icons, "View
   details" drawer, price), ported from the storefront's PDP
   (public/store/assets/css/store.css's .pdp-acc-* / .pdp-vd-*) so agency
   staff see the same rich option picker while booking. Unlike the
   storefront, picking "Select" here doesn't build an independent per-option
   widget — agency has no cart, so it just drives the single shared
   Travelers/Date/Time form already below the list (see selectVariant() in
   agency-activity.js). */
.pdp-variant-search {
    width: 100%; margin-bottom: 8px; padding: 8px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm);
    font-size: 12.5px; background: var(--surface); box-sizing: border-box;
}
.pdp-variant-search:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-light); }
/* Caps a long option list (e.g. an activity with 20+ time-of-day variants)
   to roughly 4-5 rows with its own scrollbar, rather than pushing the
   Travelers/Date/Time form and traveler-info fields far down the page —
   see renderVariantList()'s search filter in agency-activity.js for the
   other half of "many options" usability. */
.pdp-variants { border: 1px solid var(--line); border-radius: var(--radius); overflow-y: auto; overflow-x: hidden; max-height: 360px; }
.pdp-variants:empty::before { content: "No bookable options"; color: var(--muted-2); font-size: 13px; padding: 12px; display: block; }
.pdp-acc-item { border-bottom: 1px solid var(--line); background: var(--surface); }
.pdp-acc-item:last-child { border-bottom: none; }
.pdp-acc-item.is-open { background: var(--surface-2); box-shadow: inset 4px 0 0 var(--brand); }
.pdp-acc-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; padding: 12px 14px; }
.pdp-acc-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.pdp-acc-main .pv-name { font-weight: 700; font-size: 13.5px; line-height: 1.35; }
.pdp-acc-main .pv-desc { color: var(--muted); font-size: 11.5px; line-height: 1.5; }
.pdp-acc-info { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 1px; }
.pdp-acc-info span { display: flex; align-items: center; gap: 4px; font-size: 10.5px; color: var(--muted); }
.pdp-acc-info svg { color: var(--amber); flex-shrink: 0; }
.pdp-acc-side { flex-shrink: 0; display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
.pdp-variant-price { font-weight: 800; color: var(--brand-dark); font-size: 13.5px; white-space: nowrap; }
.pdp-acc-select {
    padding: 7px 16px; font-size: 12px; font-weight: 700; border-radius: 8px; border: 1.5px solid var(--brand);
    background: var(--brand); color: #fff; cursor: pointer; white-space: nowrap;
}
.pdp-acc-select:hover { background: var(--brand-dark); border-color: var(--brand-dark); }
.pdp-acc-select.is-selected { background: #fff; color: var(--brand); }
.pdp-acc-select.is-selected:hover { background: var(--brand-light); }
.pdp-pkg-link {
    align-self: flex-start; margin-top: 1px; background: none; border: none; padding: 0; font: inherit; cursor: pointer;
    font-size: 10.5px; font-weight: 600; color: var(--ink); text-decoration: underline;
}
@media (max-width: 420px) {
    .pdp-acc-row { flex-direction: column; align-items: stretch; }
    .pdp-acc-side { flex-direction: row; align-items: center; justify-content: space-between; }
}

/* Variant-details drawer — duration/highlights/inclusions/exclusions/ticket
   info/child-price for whichever option's .js-pdp-pkg-link was clicked. One
   shared overlay, not one per option — see openVariantDetails() in
   agency-activity.js. Slides in from the right; .is-open (added a frame
   after [hidden] is cleared, so the transition actually plays) drives both
   the backdrop fade and the sheet's transform. */
.pdp-vd-overlay {
    position: fixed; inset: 0; background: rgba(15, 23, 42, 0); z-index: 200;
    display: flex; align-items: stretch; justify-content: flex-end;
    transition: background-color .25s ease; pointer-events: none;
}
.pdp-vd-overlay[hidden] { display: none; }
.pdp-vd-overlay.is-open { background: rgba(15, 23, 42, .48); pointer-events: auto; }
.pdp-vd-sheet {
    width: 100%; max-width: 480px; height: 100%; overflow-y: auto; background: #fff;
    box-shadow: var(--shadow); padding: 24px 28px 28px;
    transform: translateX(100%); transition: transform .28s ease;
}
.pdp-vd-overlay.is-open .pdp-vd-sheet { transform: translateX(0); }
.pdp-vd-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.pdp-vd-title { font-size: 15px; font-weight: 800; }
.pdp-vd-close {
    width: 26px; height: 26px; border-radius: 50%; border: 1.5px solid var(--line); background: var(--surface-2);
    color: var(--muted); flex-shrink: 0; cursor: pointer; font-size: 14px; line-height: 1;
}
.pdp-vd-close:hover { border-color: var(--muted); color: var(--ink); }
.pdp-vd-desc { font-size: 12.5px; line-height: 1.6; color: var(--muted); margin: 0 0 14px; }
.pdp-vd-facts { list-style: none; margin: 0 0 16px; padding: 12px 14px; background: var(--surface-2); border-radius: 10px; display: flex; flex-direction: column; gap: 8px; }
.pdp-vd-facts li { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 700; }
.pdp-vd-facts svg { color: var(--amber); flex-shrink: 0; }
.pdp-vd-sub { font-size: 10px; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); font-weight: 700; margin: 14px 0 7px; }
.pdp-vd-sub:first-of-type { margin-top: 0; }
.pdp-vd-list { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.pdp-vd-list li { display: flex; align-items: flex-start; gap: 7px; font-size: 12px; line-height: 1.45; }
.pdp-vd-list svg { color: var(--amber); flex-shrink: 0; margin-top: 2px; }
.pdp-vd-list.excluded svg { color: var(--danger); }
.pdp-vd-list.ticket-info svg { color: var(--brand); }
.pdp-vd-steps { margin: 0 0 14px; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; }
.pdp-vd-steps li { font-size: 12px; line-height: 1.45; padding-left: 2px; }
.pdp-vd-child { font-size: 11.5px; font-weight: 600; color: var(--brand-dark); margin: 0; }

.pdp-slot-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.pdp-slot-pills:empty::before { content: "Select an option above"; color: var(--muted-2); font-size: 13px; }
.pdp-slot-pill {
    border: 1.5px solid var(--line); border-radius: 8px; padding: 7px 12px; background: var(--surface); cursor: pointer;
    display: flex; flex-direction: column; align-items: center; min-width: 68px;
}
.pdp-slot-pill:hover { border-color: var(--muted-2); }
.pdp-slot-pill[aria-pressed="true"] { border-color: var(--brand); background: var(--brand-light); }
.pdp-slot-pill .ps-time { font-weight: 700; font-size: 13px; }
.pdp-slot-pill .ps-price { font-size: 11px; color: var(--brand-dark); font-weight: 600; }
.pdp-slot-pill .ps-cap { font-size: 10px; color: var(--muted-2); }
.pdp-times-loading, .pdp-times-error { color: var(--muted-2); font-size: 13px; margin: 0; }
.pdp-times-error { color: var(--danger); }

/* Combo booking: one time-pill group per component activity — agency
   counterpart of store.css's .pdp-combo-time-group. */
.pdp-combo-time-group { margin-bottom: 14px; }
.pdp-combo-time-group:last-child { margin-bottom: 0; }
.pdp-combo-time-label { font-weight: 700; font-size: 12px; margin-bottom: 6px; }

/* Order timeline — WooCommerce-style event log on the agency order-detail page */
.order-timeline { display: flex; flex-direction: column; }
.timeline-item { display: flex; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.timeline-item:last-child { border-bottom: 0; padding-bottom: 0; }
.timeline-item:first-child { padding-top: 0; }
.timeline-dot {
    width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
    flex-shrink: 0; background: var(--surface-2); color: var(--muted-2);
}
.timeline-dot.success { background: var(--success-light); color: var(--success); }
.timeline-dot.danger { background: var(--danger-light); color: var(--danger); }
.timeline-dot.warn { background: var(--amber-light); color: var(--amber); }
.timeline-body { flex: 1; min-width: 0; padding-top: 3px; }
.timeline-message { font-size: 12.5px; font-weight: 600; }
.timeline-meta { font-size: 11px; color: var(--muted-2); margin-top: 2px; }
@media (max-width: 720px) {
    .preview-columns { grid-template-columns: 1fr; }
    .preview-summary { position: static; }
}

/* Voucher — rendered on body.print-page, a bare page with no sidebar/topbar
   (see app/views/agency/layout/header.php's $printPage branch). */
body.print-page { background: var(--surface-2); }
.voucher { max-width: 720px; margin: 32px auto; padding: 0 16px; }
.voucher-actions { display: flex; justify-content: space-between; margin-bottom: 16px; }
.voucher-sheet {
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
    box-shadow: var(--shadow); padding: 28px 32px;
}
/* Each traveler's ticket is a fully standalone page (own QR/ref bar/terms/support) — these stack
   with a visible gap on screen, and break onto separate printed/PDF pages via .voucher-page-break. */
.voucher-page + .voucher-page { margin-top: 24px; }
@media print {
    .voucher-page-break { break-before: page; page-break-before: always; }
}
.voucher-brand { display: flex; align-items: center; }
.voucher-brand img { display: block; height: 24px; width: auto; }
.voucher-note { margin: -6px 0 20px; padding: 8px 12px; background: var(--amber-light); color: var(--amber); border-radius: var(--radius-sm); font-size: 12.5px; }

.voucher-topbar { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; padding-bottom: 16px; border-bottom: 2px solid var(--ink); margin-bottom: 16px; }
.voucher-eticket { display: flex; align-items: center; gap: 10px; text-align: right; }
.voucher-eticket-qr { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 4px; background: #fff; flex-shrink: 0; }
.voucher-eticket-text { display: flex; flex-direction: column; gap: 2px; }
.voucher-eticket-text strong { font-size: 15px; letter-spacing: .04em; color: var(--brand); }
.voucher-eticket-text span { font-size: 10.5px; color: var(--muted); max-width: 140px; }

.voucher-ref-bar {
    display: flex; justify-content: space-between; align-items: center; gap: 12px;
    background: var(--brand-light); border: 1px solid var(--line); border-radius: var(--radius-sm);
    padding: 10px 14px; margin-bottom: 20px;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.voucher-ref-bar .k { font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); font-weight: 700; }
.voucher-ref-bar .v { font-weight: 700; font-size: 15px; color: var(--brand-dark); font-family: ui-monospace, "SF Mono", Consolas, monospace; }

.voucher-ticket { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; margin-bottom: 18px; break-inside: avoid; }
.voucher-ticket-title {
    display: flex; align-items: center; gap: 8px; background: var(--brand); color: #fff;
    font-weight: 700; font-size: 13px; padding: 9px 14px;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.voucher-ticket-body { display: flex; gap: 20px; padding: 16px; align-items: stretch; }
.voucher-info-grid { flex: 1.2; min-width: 0; display: flex; flex-direction: column; gap: 9px; }
.voucher-info-row { display: flex; align-items: flex-start; gap: 9px; }
.voucher-info-icon {
    flex-shrink: 0; width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
    background: var(--brand-light); color: var(--brand);
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.voucher-info-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.voucher-info-text .k { font-size: 10px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 700; }
.voucher-info-text .v { font-size: 12.5px; font-weight: 600; color: var(--ink); overflow-wrap: anywhere; }
.voucher-hero {
    flex: 1; min-width: 0; border-radius: var(--radius-sm); background: var(--brand-dark) center/cover no-repeat;
    display: flex; align-items: flex-end; padding: 14px; position: relative; overflow: hidden;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.voucher-hero::before {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(0deg, rgba(0,0,0,.65) 0%, rgba(0,0,0,.1) 60%, transparent 100%);
}
.voucher-hero-caption { position: relative; color: #fff; display: flex; flex-direction: column; }
.voucher-hero-caption span { font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; opacity: .9; }
.voucher-hero-caption strong { font-size: 17px; line-height: 1.2; }

.voucher-terms { margin-bottom: 20px; break-inside: avoid; }
.voucher-terms h3 { display: flex; align-items: center; gap: 8px; font-size: 13.5px; margin: 0 0 10px; color: var(--ink); }
.voucher-terms ul { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; }
.voucher-terms li { font-size: 11.5px; color: var(--muted); line-height: 1.5; }

.voucher-support { display: flex; flex-wrap: wrap; gap: 14px; padding-top: 16px; border-top: 1px solid var(--line); margin-bottom: 16px; }
.voucher-support-col { flex: 1 1 150px; display: flex; align-items: flex-start; gap: 9px; }
.voucher-support-icon {
    flex-shrink: 0; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
    background: var(--brand-light); color: var(--brand);
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.voucher-support-col strong { display: block; font-size: 12px; }
.voucher-support-col small { font-size: 11px; color: var(--muted); }

.voucher-footer { margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--line); font-size: 11px; color: var(--muted-2); display: flex; align-items: center; justify-content: center; gap: 8px; }
.voucher-footer-logo { height: 16px; width: auto; }

@media print {
    body.print-page { background: #fff; }
    .no-print { display: none !important; }
    .voucher { margin: 0; max-width: none; padding: 0; }
    .voucher-sheet { border: none; box-shadow: none; border-radius: 0; padding: 0; }
}

@media (max-width: 560px) {
    .voucher-topbar { flex-direction: column; }
    .voucher-eticket { align-self: stretch; justify-content: flex-start; text-align: left; }
    .voucher-ticket-body { flex-direction: column; }
    .voucher-hero { min-height: 130px; }
}

/* Agency activity detail — gallery, head, description/highlights/inclusions/
   FAQ content blocks, ported from the B2C storefront PDP (store.css) so
   agency staff see the same activity information while booking on a
   client's behalf. Reuses the storefront's pdp-* class vocabulary, restyled
   onto this portal's own indigo tokens instead of store.css's navy ones. */
.pdp-head { display: flex; flex-direction: column; gap: 8px; margin: 0 0 16px; }
.pdp-head .chip { display: inline-block; background: var(--brand-light); color: var(--brand-dark); font-size: 10.5px; font-weight: 700; padding: 4px 10px; border-radius: 999px; align-self: flex-start; text-transform: uppercase; letter-spacing: .03em; }
.pdp-head h1 { margin: 0; font-size: 21px; font-weight: 800; letter-spacing: -.01em; }
.pdp-head-meta { display: flex; flex-wrap: wrap; gap: 14px; color: var(--muted); font-size: 12.5px; }
.pdp-head-meta span { display: inline-flex; align-items: center; gap: 5px; }

.pdp-gallery { display: grid; grid-template-columns: 2fr 1fr; gap: 6px; height: 280px; border-radius: var(--radius-sm); overflow: hidden; margin: -15px -17px 16px; }
.pdp-gallery:has(.pdp-gallery-main:only-child) { grid-template-columns: 1fr; height: 240px; }
.pdp-gallery-main { border: 0; padding: 0; margin: 0; cursor: pointer; background: none; display: block; overflow: hidden; min-height: 0; min-width: 0; }
.pdp-gallery-main img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .25s ease; }
.pdp-gallery-main:hover img { transform: scale(1.04); }
.pdp-gallery-thumbs { display: grid; gap: 6px; min-height: 0; }
.pdp-gallery-thumb { position: relative; border: 0; padding: 0; margin: 0; cursor: pointer; overflow: hidden; background: none; display: block; min-height: 0; min-width: 0; }
.pdp-gallery-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .25s ease; }
.pdp-gallery-thumb:hover img { transform: scale(1.06); }
.pdp-gallery-more { position: absolute; inset: 0; background: rgba(15, 23, 42, .55); color: #fff; font-weight: 800; font-size: 16px; display: flex; align-items: center; justify-content: center; }

.pdp-lightbox { position: fixed; inset: 0; background: rgba(5, 10, 25, .94); z-index: 200; display: flex; align-items: center; justify-content: center; }
.pdp-lightbox[hidden] { display: none; }
.pdp-lightbox-img { max-width: 88vw; max-height: 84vh; object-fit: contain; border-radius: 8px; }
.pdp-lightbox-close, .pdp-lightbox-arrow { position: absolute; border: 0; background: rgba(255, 255, 255, .12); color: #fff; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.pdp-lightbox-close:hover, .pdp-lightbox-arrow:hover { background: rgba(255, 255, 255, .24); }
.pdp-lightbox-close { top: 20px; right: 20px; width: 40px; height: 40px; }
.pdp-lightbox-arrow { top: 50%; transform: translateY(-50%); width: 46px; height: 46px; }
.pdp-lightbox-arrow.prev { left: 20px; }
.pdp-lightbox-arrow.next { right: 20px; }
.pdp-lightbox-count { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); color: rgba(255, 255, 255, .8); font-size: 12px; font-weight: 600; }

.preview-main { min-width: 0; }
.pdp-desc-lead { font-size: 14px; font-weight: 650; margin: 0 0 8px; }
.pdp-desc { color: var(--muted); font-size: 13px; line-height: 1.7; margin-bottom: 8px; }

.pdp-info-block { border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px; background: var(--surface); margin-top: 18px; }
.pdp-info-block h3 { margin: 0 0 12px; font-size: 13.5px; font-weight: 700; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pdp-bullet-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.pdp-bullet-list li { display: flex; align-items: flex-start; gap: 9px; font-size: 12.5px; color: var(--ink); line-height: 1.5; }
.pdp-bullet-list.highlights li svg, .pdp-bullet-list.inclusions li svg { color: var(--success); flex-shrink: 0; margin-top: 2px; }
.pdp-bullet-list.exclusions li svg { color: var(--danger); flex-shrink: 0; margin-top: 2px; }
.pdp-inex-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.pdp-inex-title { display: flex; align-items: center; gap: 7px; }
.pdp-inex-title.included svg { color: var(--success); }
.pdp-inex-title.excluded svg { color: var(--danger); }
.pdp-bullet-list.ticket-info li svg { color: var(--brand); flex-shrink: 0; margin-top: 2px; }
.pdp-step-num {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 20px; height: 20px; border-radius: 50%; background: var(--brand-light); color: var(--brand);
    font-size: 11px; font-weight: 700; margin-top: 1px;
}

.pdp-hours-status { font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: 999px; text-transform: uppercase; letter-spacing: .03em; }
.pdp-hours-status.open { background: var(--success-light); color: var(--success); }
.pdp-hours-status.closed { background: var(--danger-light); color: var(--danger); }
.pdp-hours-table { width: 100%; border-collapse: collapse; }
.pdp-hours-table tr { border-bottom: 1px solid var(--line); }
.pdp-hours-table tr:last-child { border-bottom: 0; }
.pdp-hours-table td { padding: 8px 0; font-size: 12.5px; color: var(--muted); }
.pdp-hours-table td:first-child { font-weight: 600; color: var(--ink); width: 40%; }
.pdp-hours-table tr.is-today td { color: var(--brand); font-weight: 700; }

.pdp-map { position: relative; width: 100%; padding-top: 45%; border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-2); }
.pdp-map iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.pdp-map-directions { display: inline-flex; align-items: center; gap: 6px; margin-top: 12px; font-size: 12.5px; font-weight: 600; color: var(--brand); text-decoration: none; }
.pdp-map-directions:hover { text-decoration: underline; }
.pdp-video { position: relative; width: 100%; padding-top: 56.25%; border-radius: var(--radius-sm); overflow: hidden; background: #000; }
.pdp-video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.pdp-cancel-table { width: 100%; border-collapse: collapse; margin-top: 12px; font-size: 12.5px; }
.pdp-cancel-table th, .pdp-cancel-table td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); }
.pdp-cancel-table th { font-size: 11px; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); font-weight: 700; }
.pdp-cancel-table td:last-child, .pdp-cancel-table th:last-child { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pdp-cancel-table tbody tr:last-child td { border-bottom: 0; }

/* Combo booking page "What's included" — one card per component activity
   (agency counterpart of store.css's .pdp-combo-item). */
.pdp-combo-items { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; }
.pdp-combo-item {
    display: flex; align-items: flex-start; gap: 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
    padding: 12px; background: #fff;
}
.pdp-combo-item-index {
    width: 26px; height: 26px; border-radius: 50%; background: var(--brand-light); color: var(--brand-dark);
    display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 12px; flex-shrink: 0;
}
.pdp-combo-item-name { display: block; font-weight: 700; font-size: 12.5px; color: var(--ink); margin-bottom: 2px; }
.pdp-combo-item-variant { display: block; color: var(--muted); font-size: 11.5px; }

.pdp-faq-list { display: flex; flex-direction: column; gap: 8px; }
.pdp-faq-item { border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
.pdp-faq-item summary { list-style: none; cursor: pointer; padding: 11px 14px; font-weight: 600; font-size: 12.5px; display: flex; align-items: center; justify-content: space-between; gap: 10px; color: var(--ink); }
.pdp-faq-item summary::-webkit-details-marker { display: none; }
.pdp-faq-item summary:hover { background: var(--surface-2); }
.pdp-faq-chevron { display: flex; flex-shrink: 0; color: var(--muted); transition: transform .15s ease; }
.pdp-faq-item[open] .pdp-faq-chevron { transform: rotate(180deg); }
.pdp-faq-item[open] summary { border-bottom: 1px solid var(--line); }
.pdp-faq-answer { margin: 0; padding: 10px 14px 14px; color: var(--muted); font-size: 12px; line-height: 1.6; }

@media (max-width: 720px) {
    .pdp-inex-grid { grid-template-columns: 1fr; }
}

/* Agency catalog — browse activities grid */
.activity-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; margin-top: 16px; }
.activity-card {
    display: flex; flex-direction: column; text-decoration: none; color: inherit; padding: 0; overflow: hidden;
    transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.activity-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--brand); }
.activity-card-image { position: relative; width: 100%; aspect-ratio: 4 / 3; background: var(--surface-2); overflow: hidden; }
.activity-card-image img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .3s ease; }
.activity-card:hover .activity-card-image img { transform: scale(1.05); }
.activity-card-image.empty { display: flex; align-items: center; justify-content: center; color: var(--muted-2); }
.activity-card-chip {
    position: absolute; top: 10px; left: 10px; background: rgba(15, 23, 42, .72); color: #fff;
    font-size: 10px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; padding: 4px 9px; border-radius: 99px;
}
.activity-card-body { padding: 13px 14px 14px; display: flex; flex-direction: column; gap: 3px; flex: 1; }
.activity-card-meta { color: var(--muted); font-size: 11.5px; display: flex; align-items: center; gap: 4px; }
.activity-card-body h3 { margin: 2px 0 0; font-size: 14.5px; line-height: 1.32; }
.activity-card-footer { display: flex; align-items: baseline; justify-content: space-between; margin-top: auto; padding-top: 10px; }
.activity-card-price { font-weight: 700; font-size: 15.5px; color: var(--brand-dark); }
.activity-card-price small { font-weight: 400; font-size: 10.5px; color: var(--muted); margin-right: 3px; text-transform: none; letter-spacing: 0; }

/* Notices / toasts */
.notice {
    padding: 10px 13px; border-radius: 8px; background: var(--success-light); color: var(--success);
    margin-bottom: 13px; display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 12.5px;
    border: 1px solid rgba(21, 128, 61, .18);
}
.notice.error { background: var(--danger-light); color: var(--danger); border-color: rgba(220, 38, 38, .2); }
.notice.toast { position: fixed; top: 18px; right: 18px; z-index: 50; min-width: 240px; box-shadow: var(--shadow); animation: toast-in .2s ease; }
@keyframes toast-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } }

/* Auth pages */
.auth { max-width: 380px; margin: 10vh auto; padding: 0 16px; }
.auth .card { padding: 26px 24px; box-shadow: var(--shadow); }
.auth-logo { display: block; height: var(--brand-logo-height, 34px); width: auto; margin-bottom: 16px; }
.auth h1 { margin: 0 0 4px; font-size: 19px; }
.muted { color: var(--muted); }

@media (max-width: 900px) {
    .layout { grid-template-columns: 1fr; }
    .sidebar { display: none; }
    .main { padding: 16px; }
    .stats { grid-template-columns: repeat(2, 1fr); }
    .quick-links { grid-template-columns: 1fr; }
    .grid-form { grid-template-columns: 1fr; }
    .offer-grid { grid-template-columns: 1fr; }
    .form-columns { grid-template-columns: 1fr; }
    table { display: block; overflow: auto; }
}
