:root,
[data-bs-theme="light"] {
    --fewohbee-blue-dark: #00203b;
    --fewohbee-blue: #012546;
    --fewohbee-blue-light: #082a4d;
    --fewohbee-orange-dark: #f78b00;
    --fewohbee-orange: #fb9005;
    --fewohbee-orange-light: #ffb11a;
    --fewohbee-wordmark-blue: var(--fewohbee-blue);
    --fewohbee-wordmark-orange: var(--fewohbee-orange);
    --feb-surface: #f5f5f5;
    --feb-surface-border: #d3d3d3;
    --feb-border-strong: #666;
    --feb-border-muted: #ddd;
    --feb-reservation-text: #fff;
    --feb-reservation-confirmed-bg: #2d9434;
    --feb-reservation-option-bg: #f6e95c;
    --feb-reservation-option-text: #666;
    --feb-reservation-option-border: #999;
    --feb-weekend-bg: #eee;
    --feb-selection-bg: #f5f5f5;
    --feb-ui-selecting-bg: #feca40;
    --feb-ui-selected-bg: #f39814;
}

[data-bs-theme="dark"] {
    --fewohbee-wordmark-blue: #78bced;
    --fewohbee-wordmark-orange: var(--fewohbee-orange-light);
    --feb-surface: #1f2226;
    --feb-surface-border: #3a3f45;
    --feb-border-strong: #9aa0a6;
    --feb-border-muted: #444a52;
    --feb-reservation-text: #f8f9fa;
    --feb-reservation-confirmed-bg: #2e7d32;
    --feb-reservation-option-bg: #bfa23a;
    --feb-reservation-option-text: #1b1b1b;
    --feb-reservation-option-border: #9f8732;
    --feb-weekend-bg: #3a3f44;
    --feb-selection-bg: #2a2f33;
    --feb-ui-selecting-bg: #b77724;
    --feb-ui-selected-bg: #c06a1b;
    --bs-primary: #1f4b8f;
    --bs-primary-rgb: 31, 75, 143;
}

[data-bs-theme="light"] .navbar.bg-primary {
    --bs-navbar-color: rgba(255, 255, 255, 0.85);
    --bs-navbar-hover-color: rgba(255, 255, 255, 1);
    --bs-navbar-active-color: rgba(255, 255, 255, 1);
    --bs-navbar-brand-color: rgba(255, 255, 255, 1);
    --bs-navbar-brand-hover-color: rgba(255, 255, 255, 1);
    /* Menu button in white like the rest of the bar, without a frame */
    --bs-navbar-toggler-border-color: transparent;
    --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.9%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

/* No thick focus ring around the menu button after a tap; keyboard focus keeps it */
.navbar.bg-primary .navbar-toggler:focus:not(:focus-visible) {
    box-shadow: none;
}

[data-bs-theme="dark"] .navbar.bg-primary {
    --bs-navbar-color: rgba(var(--bs-body-color-rgb), 0.85);
    --bs-navbar-hover-color: rgba(var(--bs-body-color-rgb), 1);
    --bs-navbar-active-color: rgba(var(--bs-body-color-rgb), 1);
    --bs-navbar-brand-color: rgba(var(--bs-body-color-rgb), 1);
    --bs-navbar-brand-hover-color: rgba(var(--bs-body-color-rgb), 1);
    --bs-navbar-toggler-border-color: rgba(var(--bs-body-color-rgb), 0.2);
}

/*
 * Main navigation: below xl the links slide in from the side (offcanvas, base.html.twig) on
 * the page's own colours instead of the blue bar; notifications and the user menu stay in
 * the bar (.navbar-quick), so their dropdowns float instead of opening inline. On touch
 * screens main_nav_controller.js lowers the breakpoint to lg, so a tablet held sideways
 * keeps the full bar. The rules below are tied to the expand class in use.
 */
.main-nav-offcanvas {
    --bs-offcanvas-width: min(20rem, 85vw);
}

.navbar-quick {
    flex-wrap: nowrap;
    flex-shrink: 0;
}

@media (max-width: 1199.98px) {
    .navbar.navbar-expand-xl .main-nav-offcanvas {
        --bs-navbar-color: var(--bs-body-color);
        --bs-navbar-hover-color: var(--bs-primary);
        --bs-navbar-active-color: var(--bs-primary);
        color: var(--bs-body-color);
    }

    .navbar.navbar-expand-xl .main-nav-offcanvas .nav-item.active > .nav-link {
        color: var(--bs-primary);
        font-weight: 500;
    }

    .navbar.navbar-expand-xl .main-nav-offcanvas .dropdown-menu {
        border: 0;
        box-shadow: none;
        padding-top: 0;
        padding-left: 1.75rem;
    }

    /* Brand, quick bar and menu button share one line; a long page title gives way */
    .navbar.navbar-expand-xl > .container-fluid {
        flex-wrap: nowrap;
    }

    .navbar.navbar-expand-xl .navbar-brand {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .navbar.navbar-expand-xl .navbar-quick .nav-item {
        position: relative;
    }

    .navbar.navbar-expand-xl .navbar-quick .dropdown-menu {
        position: absolute;
        right: 0;
        left: auto;
    }
}

@media (max-width: 991.98px) {
    .navbar.navbar-expand-lg .main-nav-offcanvas {
        --bs-navbar-color: var(--bs-body-color);
        --bs-navbar-hover-color: var(--bs-primary);
        --bs-navbar-active-color: var(--bs-primary);
        color: var(--bs-body-color);
    }

    .navbar.navbar-expand-lg .main-nav-offcanvas .nav-item.active > .nav-link {
        color: var(--bs-primary);
        font-weight: 500;
    }

    .navbar.navbar-expand-lg .main-nav-offcanvas .dropdown-menu {
        border: 0;
        box-shadow: none;
        padding-top: 0;
        padding-left: 1.75rem;
    }

    /* Brand, quick bar and menu button share one line; a long page title gives way */
    .navbar.navbar-expand-lg > .container-fluid {
        flex-wrap: nowrap;
    }

    .navbar.navbar-expand-lg .navbar-brand {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .navbar.navbar-expand-lg .navbar-quick .nav-item {
        position: relative;
    }

    .navbar.navbar-expand-lg .navbar-quick .dropdown-menu {
        position: absolute;
        right: 0;
        left: auto;
    }
}

/* Touch screens between lg and xl (a tablet held sideways): full bar; the links wrap
   between page title and quick bar if needed, the side menu's icons and divider stay hidden */
@media (min-width: 992px) and (max-width: 1199.98px) {
    .navbar.navbar-expand-lg .main-nav-offcanvas {
        flex: 1 1 auto;
        min-width: 0;
    }

    .navbar.navbar-expand-lg .offcanvas-body,
    .navbar.navbar-expand-lg .offcanvas-body .navbar-nav {
        flex-wrap: wrap;
    }

    .navbar.navbar-expand-lg .main-nav-offcanvas .d-xl-none {
        display: none !important;
    }
}

[data-bs-theme="dark"] .btn-secondary {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--bs-secondary-bg);
    --bs-btn-border-color: var(--bs-secondary-bg);
    --bs-btn-hover-bg: #2f3338;
    --bs-btn-hover-border-color: #2f3338;
    --bs-btn-active-bg: #3a3f45;
    --bs-btn-active-border-color: #3a3f45;
}

body {
    font-size: 0.9rem
}

.hk-row-form {
    display: contents;
}

.btn {
    font-size: 0.9rem;
}

.dropdown-menu {
    font-size: 0.9rem;
}

.popover-body, .popover-header {
    font-size: 0.9rem;
}

.form-switch > .form-check-input {
    margin-top: .25em;
    margin-right: .75em;
}

.login {
    border-color: var(--feb-surface-border);
    border-width: 1px;
    border-style: solid;
    border-radius: 15px;
    padding: 15px;
    background-color: var(--feb-surface);
}

.fewohbee-wordmark-blue {
    color: var(--fewohbee-wordmark-blue);
}

.fewohbee-wordmark-orange {
    color: var(--fewohbee-wordmark-orange);
}

.button-hidden {
    visibility: hidden;
}

.reservation {
    padding: 4px 2px !important;
    max-width: 0; /* force td to respect colspan width, enables text-overflow on inner */
}

/* Half-day cell model: remove all vertical borders, then re-add at day boundaries */
#reservation-table tbody td {
    border-left: none !important;
    border-right: none !important;
}

#reservation-table tbody td.day-start {
    border-left: 1px solid var(--feb-border-muted) !important;
}

.td-half {
    padding: 0 !important;
}

/* Blocked cell styling */
.td-blocked {
    background: repeating-linear-gradient(
        45deg,
        transparent,
        transparent 4px,
        var(--feb-border-muted) 4px,
        var(--feb-border-muted) 5px
    );
    padding: 0 !important;
}

.blocked-inner {
    width: 100%;
    height: 100%;
    min-height: 1.7rem;
    cursor: pointer;
}

.reservation-inner {
    position: relative;
    --feb-reservation-radius-left: .375rem;
    --feb-reservation-radius-right: .375rem;
    border: 1px solid var(--feb-border-strong);
    border-radius: var(--feb-reservation-radius-left) var(--feb-reservation-radius-right) var(--feb-reservation-radius-right) var(--feb-reservation-radius-left);
    clip-path: inset(0 round var(--feb-reservation-radius-left) var(--feb-reservation-radius-right) var(--feb-reservation-radius-right) var(--feb-reservation-radius-left));
    color: var(--feb-reservation-text);
    padding: 3px;
    white-space: nowrap;
    overflow: hidden;
    overflow: clip;
    overflow-clip-margin: 1px;
    text-overflow: ellipsis;
}

/* Cover the top border; the outline clip ends the accent exactly at the corner arcs. */
.reservation-inner::before {
    content: '';
    position: absolute;
    top: -1px;
    left: -1px;
    right: -1px;
    height: 2px;
    background-color: var(--feb-reservation-origin-color, transparent);
    pointer-events: none;
}

.reservation-inner[draggable="true"] {
    cursor: grab;
}

.reservation-inner.reservation-dragging {
    cursor: grabbing;
    opacity: .55;
}

.reservation-inner.reservation-moving {
    opacity: .55;
    pointer-events: none;
}

#reservation-table .reservation-drop-target {
    background: var(--feb-ui-selecting-bg) !important;
    box-shadow: inset 0 0 0 2px var(--bs-primary);
}

/* A clipped side is not a real start/end of the reservation. */
#reservation-table td.cell-start .reservation-inner {
    --feb-reservation-radius-right: 0;
}

#reservation-table td.cell-end .reservation-inner {
    --feb-reservation-radius-left: 0;
}

#reservation-table td.cell-middle .reservation-inner {
    --feb-reservation-radius-left: 0;
    --feb-reservation-radius-right: 0;
}

.reservation-confirmed {
    background-color: var(--feb-reservation-confirmed-bg);
}

.reservation-option {
    background-color: var(--feb-reservation-option-bg);
    color: var(--feb-reservation-option-text);
    border-color: var(--feb-reservation-option-border);
}

.reservation-table-weekend-single {
    background-color: var(--feb-weekend-bg) !important;
}

.mouse-pointer {
    cursor: pointer;
}

.border-left-thick {
    border-left: 2px solid var(--feb-border-muted);
}

.cell-selected {
    background-color: var(--feb-selection-bg);
}

/* Column widths come from the colgroup, not from the cells: on a table,
   min-width/max-width on cells are undefined per spec and ignored, and width
   is only a suggestion. A table stretched to 100% therefore handed the
   apartment column a share of the leftover space no matter what it was told,
   which is what made it needlessly wide on short periods.

   Laid out fixed so the colgroup actually decides, and given an explicit
   width so that "fixed" doesn't also mean "squeezed": at least the viewport,
   and 46px per day once there are enough days to exceed it - which is when
   the container starts scrolling, as before. Both custom properties are set
   on the table by reservation_table.html.twig. */
#reservation-table {
    table-layout: fixed;
    width: max(
        100%,
        calc(var(--reservation-name-col, 8ch) + 1.5rem + var(--reservation-day-count, 30) * 46px)
    );
}

/* Longest label plus cell padding; the half-day columns are left unsized and
   split whatever is left in equal parts. */
#reservation-table > colgroup > col.reservation-name-col {
    width: calc(var(--reservation-name-col, 8ch) + 1.5rem);
}

/* Week view (initWeekView in reservations_controller.js):
   the table is squeezed to the screen width, so a horizontal swipe never
   competes with scrolling the table sideways. */
body.reservations-week-layout #reservation-table {
    width: 100%;
}

/* Rooms are stretched to fill the screen in the normal and the week view
   (stretchRoomRows), keep the bars level with the room names */
#reservation-table tbody td {
    vertical-align: middle;
}

/* --week-bar-height is set per row by stretchRoomRows; the line height centres
   the text (padding 3px and border 1px on each side) */
#reservation-table tr[style*="--week-bar-height"] .reservation-inner {
    height: var(--week-bar-height);
    line-height: calc(var(--week-bar-height) - 8px);
}

/* Single-row header (compactWeekHeader) replaces the regular header rows
   in the week view; the normal view keeps its header as configured */
#reservation-table thead tr.table-days-compact {
    display: none;
}

body.reservations-week-layout #reservation-table thead tr.table-days-compact {
    display: table-row;
}

body.reservations-week-layout #reservation-table thead tr:not(.table-days-compact) {
    display: none !important;
}

.table-reservation .table-days-compact > th {
    position: relative;
    /* Day columns are about 40px wide on a phone: the date only fits with
       less padding and a smaller font, and must never widen the table */
    /* Room at the top for two rows of calendar accent bars (3px each, see
       getCalendarAccentMarkerStyle) above the centred text */
    padding: 8px 2px 4px;
    font-size: .75rem;
    overflow: hidden;
    white-space: nowrap;
    vertical-align: middle;
}

/* With a mouse there is room for the normal header size; fittingWeeks()
   measures in whatever font this sets */
body.reservations-week-fit .table-reservation .table-days-compact > th {
    font-size: .875rem;
}

/* Weekday above the date (fitCompactHeader shortens it on narrow columns) */
.table-days-compact .reservations-weekday {
    display: block;
}

/* The sticky header drew its top line on the first row only (the month row),
   which the table settings or the week view may hide; the scroll container
   supplies it instead, since the day cells may carry inline accent shadows
   that a cell rule would override. The first row then keeps only its bottom line. */
.table-responsive.js-fit-vh:has(> #reservation-table) {
    border-top: 1px solid var(--bs-border-color);
}

#reservation-table.table-sticky thead tr:first-child td {
    box-shadow: inset 0 -1px 0 var(--bs-border-color);
}

/* Week view: the FewohBee logo as a faint grey watermark behind the rooms.
   A pseudo-element, since a filter cannot reach a background image; it sits
   on the container around the scrolling table so it stays put. The free day
   cells turn transparent so it shows between the bars. */
body.reservations-week-layout #table-ajax {
    position: relative;
}

body.reservations-week-layout #table-ajax::before {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--week-watermark) center / auto 50% no-repeat;
    filter: grayscale(1);
    opacity: .04;
    pointer-events: none;
}

body.reservations-week-layout #table-ajax > * {
    position: relative;
    z-index: 1;
}

body.reservations-week-layout #reservation-table tbody {
    --bs-table-bg: transparent;
}

/* Swiping down on the table brings filter row and navbar back; it must not reach
   the browser's pull-to-refresh */
#table-ajax .js-fit-vh {
    overscroll-behavior-y: contain;
}

/* While switching between normal and week view (startTableSwitch) */
body.reservations-table-switching #table-ajax {
    visibility: hidden;
}

/* Touch, normal view: swiping up hides navbar, then filter row (stepNormalViewChrome) */
body.reservations-hide-filter #table-filter,
body.reservations-hide-nav > nav.navbar,
body.reservations-hide-nav #flash-message-container {
    display: none !important;
}

body.reservations-week-focus > nav.navbar,
body.reservations-week-focus #table-filter,
body.reservations-week-focus #flash-message-container,
body.reservations-week-fit > nav.navbar,
body.reservations-week-fit #table-filter,
body.reservations-week-fit #flash-message-container {
    display: none !important;
}

/* Touch screens: a slimmer filter row above the reservation table, so the rooms get
   more of the screen. Materia's fields are 56px tall; desktop keeps them as they are. */
@media not all and (hover: hover) and (pointer: fine) {
    /* Slimmer navbar (82px with Materia's padding and 24px brand) */
    body > nav.navbar {
        padding-top: .25rem;
        padding-bottom: .25rem;
    }

    body > nav.navbar .navbar-brand {
        font-size: 1.125rem;
        padding-top: 0;
        padding-bottom: 0;
    }

    body > nav.navbar .navbar-toggler {
        padding: .125rem .5rem;
    }

    /* With less padding the bell's badge (translate-middle on the link's corner) would
       stick out above the bar; keep it inside */
    body > nav.navbar [data-notifications-badge] {
        top: .6rem !important;
        font-size: .65em;
    }

    .container-fluid.mt-3:has(> #flash-message-container) {
        margin-top: .5rem !important;
    }

    #table-filter .form-control,
    #table-filter .form-select {
        padding-top: .25rem;
        padding-bottom: .25rem;
        min-height: 0;
        height: auto;
    }

    #table-filter .mb-2 {
        margin-bottom: .25rem !important;
    }

    /* Tighter spacing, so the filter row fits one line on a phone held sideways */
    #table-filter .js-shift-date {
        padding-left: .5rem !important;
        padding-right: .5rem !important;
    }

    #table-filter .vr {
        margin-left: .5rem !important;
        margin-right: .5rem !important;
    }

    #table-filter .me-4 {
        margin-right: .75rem !important;
    }

    /* The column of the inline add button is empty here unless there are conflicts */
    #table-filter > .row > .col-auto:not(:has(> a)) {
        display: none;
    }

    #table-filter + * + .row.mt-2,
    #table-filter ~ .row.mt-2 {
        margin-top: .25rem !important;
    }

    /* Header rows of the normal view: less padding; the weekday and date rows keep
       6px at the top for two rows of calendar accent bars (3px each) */
    /* !important: the month and week cells carry Bootstrap's p-1 */
    #reservation-table thead tr:not(.table-days-compact) > * {
        padding-top: .125rem !important;
        padding-bottom: .125rem !important;
        line-height: 1.2;
    }

    #reservation-table thead tr.table-weekdays > *,
    #reservation-table thead tr.table-days > * {
        padding-top: 6px !important;
    }
}

/* New reservation button on touch screens, phones and tablets alike (Reservations/index.html.twig):
   round, at the bottom right above the table, in place of the button in the filter row, and
   also in the full-screen week view. Same touch test as isDesktopWeekMode(). */
.reservations-fab {
    display: none;
}

@media not all and (hover: hover) and (pointer: fine) {
    .reservations-fab {
        display: inline-block;
    }

    .reservations-add-inline {
        display: none;
    }
}

.reservations-fab {
    position: fixed;
    right: 1rem;
    bottom: calc(1rem + env(safe-area-inset-bottom));
    z-index: 1030;
    width: 3.5rem;
    height: 3.5rem;
    padding: 0;
    /* Glass in the manner of iOS 26: nearly transparent, the content behind it
       blurred, a fine light edge instead of a hard border and a soft shadow. Theme
       colours only, so it follows light and dark mode and a swapped theme. */
    border-radius: 50%;
    border: 1px solid rgba(var(--bs-body-bg-rgb), .6);
    background-color: rgba(var(--bs-body-bg-rgb), .25);
    -webkit-backdrop-filter: blur(12px) saturate(180%);
    backdrop-filter: blur(12px) saturate(180%);
    box-shadow: var(--bs-box-shadow), inset 0 1px 1px rgba(var(--bs-body-bg-rgb), .7);
    color: var(--bs-secondary-color);
    font-size: 1.5rem;
    line-height: 1;
}

.reservations-fab:hover,
.reservations-fab:active {
    border-color: rgba(var(--bs-body-bg-rgb), .6);
    background-color: rgba(var(--bs-body-bg-rgb), .45);
    color: var(--bs-body-color);
}

/* Desktop week view: paging arrows at the screen edges and a close button,
   shown only while the mouse moves (reservations-week-pointer) */
.reservations-week-controls {
    display: none;
}

body.reservations-week-fit .reservations-week-controls {
    display: block;
}

.reservations-week-controls > .btn {
    position: fixed;
    z-index: 1030;
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s;
}

body.reservations-week-pointer .reservations-week-controls > .btn {
    opacity: .85;
    pointer-events: auto;
}

.reservations-week-controls > .btn:hover {
    opacity: 1;
}

.reservations-week-prev,
.reservations-week-next {
    top: 50%;
    transform: translateY(-50%);
}

.reservations-week-prev {
    left: .5rem;
}

.reservations-week-next {
    right: .5rem;
}

.reservations-week-close {
    top: .5rem;
    right: .5rem;
}

/* Right border on the last cell of each row */
#reservation-table tbody tr > :last-child {
    border-right: 1px solid var(--feb-border-muted) !important;
}

/* Long press starts a selection on touch screens (initCellSelection):
   no text selection or iOS callout menu on the free cells */
.table-reservation .td-empty, .table-reservation-year .reservation-yearly-parent {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
}

.table-reservation .ui-selecting, .table-reservation-year .ui-selecting {
    background: var(--feb-ui-selecting-bg) !important;
}

.table-reservation .table-days > th {
    position: relative;
}

/* remove border because of box-shadow for sticky header */
.table.table-sticky,.table-sticky tbody tr:first-child { 
    border-top: 0 !important;
}

/* remove border because of box-shadow for sticky header */
.table-sticky thead tr, .table-sticky thead th { 
    border-top: 0 !important; 
    border-bottom: 0 !important;
}

.table-responsive { position: relative; }

/* With border-collapse the table paints the shared border lines, not the cells,
   so a sticky header cell has nothing to cover them with - the reservation bars
   scrolling underneath stayed visible as a coloured line in every border
   between two day columns.

   The header cells therefore give up their borders entirely, which leaves the
   table nothing to paint there and nothing to shine through. The background
   covers the full cell box; the horizontal lines come from an inset shadow on
   the cell, which sticks with it. */
.table.table-sticky thead th, .table.table-sticky thead td {
  position: sticky;
  z-index: 3;
  border: 0 !important;
  background-color: var(--bs-table-bg, var(--bs-body-bg));
  box-shadow: inset 0 -1px 0 var(--bs-border-color); /* bottom line */
}

.table.table-sticky thead tr:first-child td{
  box-shadow:
    inset 0  1px 0 var(--bs-border-color),  /* top line */
    inset 0 -1px 0 var(--bs-border-color);  /* bottom line */
}

/* The vertical separator sits in a pseudo-element rather than in that shadow:
   header cells can carry a background or shadow of their own (the calendar
   entries' accent bars, partly set inline), which would override a shadow
   declared here. It sits on the inside of the right edge so the neighbouring
   cell's background cannot paint over it. */
.table.table-sticky thead th::after,
.table.table-sticky thead td::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  width: 1px;
  background-color: var(--bs-border-color);
  pointer-events: none;
}

/* The right-edge pseudo-element above supplies the separators between header
   cells. Since their real borders are disabled, the first cell in each row
   also needs an explicit left edge to close the table outline. */
.table.table-sticky thead tr > :first-child::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 1px;
  background-color: var(--bs-border-color);
  pointer-events: none;
}

/* left sticky column in reservation overview*/
.table.table-sticky tbody tr > *:first-child {
  position: sticky;
  left: 0;
  z-index: 2;
  background-color: var(--bs-table-bg, var(--bs-body-bg));
  box-shadow: 
    inset  1px 0 0 var(--bs-border-color), /* linke Linie */
    inset -1px 0 0 var(--bs-border-color); /* rechte Linie */
  background-clip: padding-box;
  border-right: 0;
  border-left: 0;
}

.template-editor-content {
    min-height: 320px;
    padding: 0.75rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.375rem;
    background-color: var(--bs-body-bg);
    font-size: 0.95rem;
}

/* A flex item does not shrink below its content's minimum width by default. A table
   has one even at width: 100% — the sum of its columns' widest unbreakable content —
   so it pushed the editor past the card, and next to the snippet panel the editor slid
   right instead of narrowing. (Bootstrap has no min-w-0 utility.) */
.template-editor-main {
    min-width: 0;
}

/* A table that still cannot fit — too many columns, or columns sized by dragging, which
   Tiptap turns into a pixel width — scrolls inside the editor instead of spilling over. */
.template-editor-content .tableWrapper {
    overflow-x: auto;
}

.template-editor-content:focus {
    outline: none;
}

.simple-html-editor-content .ProseMirror:focus {
    outline: none;
    box-shadow: none;
}

.template-editor-content table {
    border-collapse: collapse;
    width: 100%;
    margin: 0.5rem 0;
}

.template-editor-content table th,
.template-editor-content table td {
    border: 1px solid var(--bs-border-color);
    padding: 0.35rem 0.5rem;
    vertical-align: top;
}

.template-editor-content .header,
.template-editor-content .footer {
    border: 1px var(--bs-border-color) dashed;
    width: 100%;
}

/* Stays in view while a long template scrolls past, so a snippet is always next to
   the spot it goes into. align-self keeps the flex row from stretching the panel to
   the editor's full height, which would leave sticky nothing to do. */
.template-editor-snippet-panel {
    width: 260px;
    min-width: 260px;
    position: sticky;
    top: 0.5rem;
    align-self: flex-start;
    max-height: calc(100vh - 1rem);
    overflow-y: auto;
    padding-right: 0.75rem;
    margin-right: 0.75rem;
    border-right: 1px solid var(--bs-border-color);
}

.template-editor-snippet-panel h6 {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--bs-body-color);
    opacity: 0.65;
}

.template-editor-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}

.template-editor-toolbar .btn {
    line-height: 1;
}

.template-editor-toolbar {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.5rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.5rem;
    background: var(--bs-tertiary-bg);
}

.template-editor-toolbar-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
}

.template-editor-toolbar-row:has(.template-editor-row-controls) {
    flex-direction: column;
    align-items: flex-start;
}

.template-editor-toolbar-row:has(.template-editor-row-controls) > .template-editor-row-controls {
    align-self: stretch;
}

.template-editor-toolbar-row-content {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
    flex: 1 1 auto;
}

.template-editor-toolbar-group {
    display: inline-flex;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.4rem;
    overflow: hidden;
    background: var(--bs-body-bg);
}

.template-editor-btn {
    border: 0;
    border-right: 1px solid var(--bs-border-color);
    border-radius: 0 !important;
    min-width: 2.3rem;
}

.template-editor-toolbar-group .template-editor-btn:last-child {
    border-right: 0;
}

/* Bootstrap turns off pointer events on disabled buttons, which also hides the title
   that explains why the button is unavailable. */
.template-editor-toolbar-group .template-editor-btn:disabled {
    pointer-events: auto;
    cursor: not-allowed;
}

.template-editor-btn.is-active {
    background: var(--bs-primary);
    color: var(--bs-white);
}

.template-editor-mode-btn {
    margin-left: auto;
}

.template-editor-select {
    min-width: 120px;
    border: 0;
    border-right: 1px solid var(--bs-border-color);
    border-radius: 0 !important;
}

.template-editor-toolbar-group .template-editor-select:last-child {
    border-right: 0;
}

.template-editor-snippets {
    min-width: 220px;
}

.template-editor-row-controls {
    border: 1px solid var(--bs-border-color);
    border-radius: 0.4rem;
    padding: 0.5rem;
    background: var(--bs-body-bg);
    min-width: 380px;
}

.template-editor-row-grid {
    display: grid;
    grid-template-columns: auto 1fr 1fr 1fr auto;
    gap: 0.4rem;
    align-items: center;
}

.template-editor-row-grid .form-check-input {
    cursor: pointer;
}

.template-editor-row-grid .form-check-label {
    white-space: nowrap;
}

@media (max-width: 992px) {
    .template-editor-row-controls {
        min-width: 100%;
    }

    .template-editor-row-grid {
        grid-template-columns: 1fr;
    }
}

.snippet-item {
    cursor: grab;
    background: var(--bs-tertiary-bg);
    transition: background-color .15s ease-in-out;
    font-size: 0.82rem;
}

.snippet-item:hover {
    background: var(--bs-secondary-bg);
}

.template-editor-comment-token {
    display: none;
}

.template-editor-style-token {
    display: none;
}

.template-editor-content [data-template-style] {
    display: none !important;
}

/* ── Image resize & alignment ── */

.template-editor-image-wrapper {
    position: relative;
    display: inline-block;
    max-width: 100%;
    line-height: 0;
    cursor: default;
}

.template-editor-image-wrapper img {
    max-width: 100%;
    height: auto;
    display: block;
}

.template-editor-image-wrapper.is-selected {
    outline: 2px solid var(--bs-primary);
    outline-offset: 2px;
}

.template-editor-image-resize-handle {
    position: absolute;
    right: -4px;
    bottom: -4px;
    width: 12px;
    height: 12px;
    background: var(--bs-primary);
    border: 2px solid var(--bs-body-bg);
    border-radius: 2px;
    cursor: se-resize;
    opacity: 0;
    transition: opacity 0.15s;
}

.template-editor-image-wrapper:hover .template-editor-image-resize-handle,
.template-editor-image-wrapper.is-selected .template-editor-image-resize-handle {
    opacity: 1;
}

/* Template include pill (template-in-template) */
.template-include {
    display: inline-flex;
    align-items: center;
    gap: 0.25em;
    background: var(--bs-info-bg-subtle, #cff4fc);
    color: var(--bs-info-text-emphasis, #055160);
    border: 1px solid var(--bs-info-border-subtle, #9eeaf9);
    border-radius: 0.375rem;
    padding: 0.1em 0.5em;
    font-size: 0.85em;
    font-weight: 500;
    white-space: nowrap;
    cursor: default;
    user-select: none;
}

.template-editor-image-toolbar {
    position: absolute;
    top: -36px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 2px;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.375rem;
    padding: 2px;
    box-shadow: var(--bs-box-shadow-sm);
    z-index: 10;
}

.template-editor-image-toolbar .btn {
    padding: 0.15rem 0.4rem;
    font-size: 0.75rem;
    line-height: 1;
}

/* ── Variable picker ── */

.template-editor-variable-picker {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 100;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.375rem;
    box-shadow: var(--bs-box-shadow);
    width: 280px;
    max-height: 360px;
    display: flex;
    flex-direction: column;
}

.template-editor-variable-picker-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.4rem 0.6rem;
    border-bottom: 1px solid var(--bs-border-color);
    font-size: 0.8rem;
    font-weight: 600;
    background: var(--bs-tertiary-bg);
    border-radius: 0.375rem 0.375rem 0 0;
}

.template-editor-variable-picker-header .btn-close {
    transform: scale(0.7);
}

.template-editor-variable-picker-list {
    overflow-y: auto;
    padding: 0.25rem 0;
}

.template-editor-variable-label {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    border: 0;
    background: transparent;
    padding: 0.3rem 0.6rem;
    font-size: 0.8rem;
    text-align: left;
    cursor: pointer;
    color: inherit;
    gap: 0.5rem;
}

.template-editor-variable-label:hover {
    background: var(--bs-primary-bg-subtle, #e8f0fe);
}

.template-editor-variable-name {
    font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 0.78rem;
}

.template-editor-variable-type-hint {
    font-size: 0.7rem;
    color: var(--bs-secondary);
    white-space: nowrap;
}

.template-editor-variable-type-entity > .template-editor-variable-label,
.template-editor-variable-type-collection > .template-editor-variable-label,
.template-editor-variable-type-array > .template-editor-variable-label {
    font-weight: 500;
}

.template-editor-variable-item.is-expanded > .template-editor-variable-label {
    background: var(--bs-tertiary-bg);
}

.template-editor-variable-children {
    padding-left: 0.75rem;
    border-left: 2px solid var(--bs-border-color);
    margin-left: 0.6rem;
}

.template-editor-variable-loop-action {
    color: var(--bs-primary);
    font-style: italic;
}

.template-editor-variable-loop-action:hover {
    background: var(--bs-primary-bg-subtle, #e8f0fe);
}

.table.table-sticky tbody tr > *:nth-child(2) {
  border-left: 0;
}


.reservation-table-weekend {
    background-color: var(--feb-weekend-bg) !important;
}

/* Holiday highlighting must win over the plain weekend background -
   .reservation-table-weekend uses !important, so only an equally !important
   rule further down (or the combined selector, kept here to state the
   precedence outright) can override it.

   The tint is mixed into an opaque color instead of being laid over the cell
   as a translucent one: these are sticky header cells, and a translucent
   background there lets the body rows scrolling underneath show through the
   header. color-mix reproduces what Bootstrap's bg-info bg-opacity-25 painted
   before - 25% info over the cell background - and follows the theme through
   --bs-body-bg. Doing the same with a translucent layer in background-image
   is not an option: calendar-entry accents already set one inline, see
   calendar_accent_marker_style.
   Their accent lines (box-shadow) need no equivalent override - box-shadow
   and background-color are different properties and never fight for
   precedence the way two background-colors do. */
.reservation-table-weekend.holiday-info,
#reservation-table .holiday-info {
    /* The second selector covers holidays on weekdays: there the cell only has
       Bootstrap's translucent bg-info bg-opacity-25, and the bars showed through */
    background-color: color-mix(in srgb, rgb(var(--bs-info-rgb)) 25%, var(--bs-body-bg)) !important;
}


/* remove bottom border of tr for multiple reservations of one apartment (select tr where the next tr has border-top-0 class) */
#reservation-table tr:has( + .border-top-0) {
    border-bottom: 0 !important;
}

/* Calendar-entry accent bars are rendered in both the weekday and the
   date-number row (see reservation_table.html.twig / calendar_accent_marker_style);
   toggleDisplayTableRows() adds .weekday-row-visible once that row is
   shown, so suppress the duplicate bars on the date row - overriding the
   inline box-shadow/background-image needs !important since inline styles
   otherwise win. Restores the plain bottom border (rather than "none") so
   non-entry cells don't lose theirs too, and clears the background-image
   layers (the segmented-row gradients) entirely. */
/* Note that this box-shadow doubles as the bottom line the sticky header
   otherwise draws for itself - the !important overrides it for this one row.
   The two have to match: change the header line (colour, width) where it is
   defined and the date row silently keeps the old one. */
#reservation-table.weekday-row-visible .table-days th {
    box-shadow: inset 0 -1px 0 0 var(--bs-border-color) !important;
    background-image: none !important;
}

#reservation-table .room-info {
    white-space: nowrap;
    vertical-align: middle;
    overflow: hidden;
    text-overflow: ellipsis;
}


/* fix for autocomplete not  shown */
.ui-front { 
    z-index: 9999; 
}

.price-period .badge {
    font-size: 90%;
    margin: 4px;
}

.badge .close {
    margin-left: .25rem;
    color: inherit;
    font-size: medium;
    font-weight: bold;
}

/* yearly reservation overview */
.reservation-yearly-parent { 
    padding: 0 !important; 
    position: relative; 
    overflow:hidden; 
}

.no-pointer-events {
    pointer-events: none;
}

div .reservation-yearly {
    padding: .5rem;
    width: 100%; 
    height: 100%;
    box-shadow: inset 0 2px 0 var(--feb-reservation-origin-color, transparent);
    pointer-events: auto; 
    z-index: 1;
    cursor: pointer;
}

div .reservation-yearly-day {
    width: 100%; 
    height: 100%; 
    position: absolute; 
    left: 0; 
    top: 0; 
    z-index: 2; 
    padding: .5rem;
}

.month-reservationstartend {
    flex: 1 0 100%;
}
.month-reservation-end {
    transform: skewY(-45deg);
    transform-origin: bottom left;
}

.month-reservation-start {
    transform: skewX(-45deg);
    transform-origin: top right;
}
.month-reservation-onlystart {
    transform: skewY(-45deg);
}

.dummy-day {
    position: absolute;
    width: 100%;
    height: 100%;
    transform-origin: unset;
    pointer-events: auto;
    z-index: 1;
}
.month-reservation-start.dummy-day {
    left: 1.4rem;
}

.month-reservation-end.dummy-day {
    left: -1.4rem;
    transform: skewX(-45deg);
}

/*
 * Room block (out of order) in the yearly month view - hatched instead of a solid color.
 * Positioned absolute (filling the day cell) rather than a flex item: on a turnover day
 * a reservation half-cell already claims the flex row, and a second flex item with
 * flex-basis 100% would be pushed out of the cell and clipped away by overflow:hidden.
 * Absolute lets the block overlay its half of the cell independently.
 *
 * The hatch lives on the ::before layer, not on this element directly, because start/end
 * days re-use the reservations' exact skewY(-45deg) transform for a pixel-perfect matching
 * diagonal (corner-to-corner clip-path would be off by a few degrees since the cell isn't
 * square). Skewing the element would tilt the hatch too; the ::before counter-skews by the
 * same angle, cancelling the distortion so the hatch stays parallel to the full-day cells.
 * It is oversized so the counter-skewed layer still covers the whole skewed box.
 */
.month-reservation-blocked {
    position: absolute;
    inset: 0;
    overflow: hidden;
}
/*
 * Sit one layer below the reservations (which are z-index 1). Where a block and a
 * reservation meet on a turnover day, their skewed diagonals share an edge with a
 * sub-pixel overlap - invisible for the reservation's solid fill but noticeable as
 * hatch spilling over. Painting the opaque reservation on top lets it define that
 * edge cleanly and hide any spill. The two-class selector outweighs `div .reservation-yearly`.
 */
.reservation-yearly.month-reservation-blocked {
    z-index: 0;
}
.month-reservation-blocked::before {
    content: "";
    position: absolute;
    inset: -150%;
    background-color: rgba(108, 117, 125, 0.08);
    background-image: repeating-linear-gradient(
        45deg,
        transparent,
        transparent 4px,
        var(--feb-border-muted) 4px,
        var(--feb-border-muted) 5px
    );
}

/* start/end (half) days: mirror the reservation skew exactly for a matching diagonal */
.month-reservation-blocked.month-reservation-start,
.month-reservation-blocked.month-reservation-onlystart {
    transform: skewY(-45deg);
    transform-origin: top right;
}
.month-reservation-blocked.month-reservation-end {
    transform: skewY(-45deg);
    transform-origin: bottom left;
}
/* counter-skew the hatch layer so its lines stay parallel with the full-day cells */
.month-reservation-blocked.month-reservation-start::before,
.month-reservation-blocked.month-reservation-onlystart::before,
.month-reservation-blocked.month-reservation-end::before {
    transform: skewY(45deg);
}

/*
 * Forms
 */
/* reduce default font size of labels in modals */
.modal-body .col-form-label {
    font-size: 14px;
}

/*
 * Dialogs on phones and tablets
 * Below the xl breakpoint a dialog with .modal-fullscreen-xl-down covers the screen like a page
 * (Bootstrap): header and footer stay put, the body scrolls between them. Ajax content wraps
 * .modal-body and .modal-footer in Stimulus roots and forms, which would keep the body from
 * scrolling on its own; display: contents takes those wrappers out of the layout.
 * Class and breakpoint belong together: another fullscreen class needs its own breakpoint here.
 */
@media (max-width: 1199.98px) {
    .modal-fullscreen-xl-down .modal-content :has(.modal-body, .modal-footer):not(.modal-body *, .modal-footer *) {
        display: contents;
    }

    /* Safety net for content nested in other ways: then the dialog itself scrolls, with header
       and footer sticking to its edges, instead of the content spilling past the screen. */
    .modal-fullscreen-xl-down .modal-content {
        overflow-y: auto;
    }

    .modal-fullscreen-xl-down .modal-header,
    .modal-fullscreen-xl-down .modal-footer {
        position: sticky;
        z-index: 3;
        background-color: var(--bs-modal-bg);
    }

    .modal-fullscreen-xl-down .modal-header {
        top: 0;
    }

    .modal-fullscreen-xl-down .modal-footer {
        bottom: 0;
    }

    /* Tabs stay in reach while the body scrolls, flush below the header and across its width */
    .modal-fullscreen-xl-down .modal-tabs {
        position: sticky;
        top: calc(-1 * var(--bs-modal-padding));
        z-index: 2;
        margin-inline: calc(-1 * var(--bs-modal-padding));
        padding-inline: var(--bs-modal-padding);
        background-color: var(--bs-modal-bg);
        /* Swiped sideways; a scrollbar would only cover the underline */
        scrollbar-width: none;
    }

    .modal-fullscreen-xl-down .modal-tabs::-webkit-scrollbar {
        display: none;
    }
}

/* Reservation details: the wrapper around business card and tabs takes no part in the layout, so
   the tabs can stick within the whole body (reservation_form_show_fields.html.twig) */
.reservation-head {
    display: contents;
}

/* add hint to required fields */
#accordionSettings label.required:after {
    content: " *";
}

/*
 * Sortable table headers (generic sortable-table Stimulus controller)
 */
.sort-header {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    font-weight: 600;
    padding: 0;
    text-align: inherit;
    white-space: nowrap;
}
.sort-header:hover,
.sort-header:focus {
    color: var(--bs-primary);
}
.sort-header .sort-icon {
    display: inline-flex;
    justify-content: center;
    min-width: .75rem;
    opacity: .45;
}
th[aria-sort="ascending"] .sort-icon,
th[aria-sort="descending"] .sort-icon {
    opacity: 1;
}

/*
 * Zebra striping that counts only the visible rows, so the pattern stays
 * correct while a filter hides rows (Bootstrap's .table-striped counts hidden
 * rows via nth-of-type and would break). Mirrors .table-striped's mechanism so
 * hover and contextual colours keep working. The `of :not(.d-none)` selector
 * needs a modern browser (Chrome/Edge 111+, Firefox 113+, Safari 9+); older
 * browsers simply show no striping.
 */
.table-visible-striped > tbody > tr:nth-child(even of :not(.d-none)) > * {
    --bs-table-bg-type: var(--bs-table-striped-bg);
}

/* compact e-invoice readiness disclosure: hide the default marker, keep the summary clickable */
details.einvoice-readiness > summary {
    list-style: none;
    cursor: pointer;
}
details.einvoice-readiness > summary::-webkit-details-marker {
    display: none;
}

/* Person cards of the online check-in review: a whole-row summary with its own chevron */
details > summary:has(> .fhb-details-chevron) {
    list-style: none;
    cursor: pointer;
}
details > summary:has(> .fhb-details-chevron)::-webkit-details-marker {
    display: none;
}
details[open] > summary > .fhb-details-chevron {
    transform: rotate(180deg);
}

/* Frontdesk check-in state: one width for every state, so the rows line up. The labels of all
   states share one grid cell; the hidden ones only lend their width. */
.fd-checkin-state {
    text-align: start;
}
.fd-checkin-labels {
    display: inline-grid;
}
.fd-checkin-labels > * {
    grid-area: 1 / 1;
}
.fd-checkin-labels > [aria-hidden="true"] {
    visibility: hidden;
}

/*
 * Rendered release-note markdown. The source is written as a GitHub release
 * body, so it leans on h2/h3 and long bullet lists; without these rules the
 * headings render at page-title size inside a modal and the list spacing is
 * too tight to scan. Colours come from Bootstrap variables so the block
 * follows the light/dark theme.
 */
.release-notes-body > *:first-child {
    margin-top: 0;
}
.release-notes-body > *:last-child {
    margin-bottom: 0;
}
.release-notes-body h1,
.release-notes-body h2 {
    font-size: 1.15rem;
    font-weight: 600;
    margin-top: 1.5rem;
    margin-bottom: 0.5rem;
    padding-bottom: 0.25rem;
    border-bottom: 1px solid var(--bs-border-color);
}
.release-notes-body h3,
.release-notes-body h4 {
    font-size: 1rem;
    font-weight: 600;
    margin-top: 1.25rem;
    margin-bottom: 0.35rem;
}
.release-notes-body ul {
    padding-left: 1.25rem;
}
.release-notes-body li {
    margin-bottom: 0.4rem;
}
.release-notes-body code {
    background-color: var(--bs-secondary-bg);
    padding: 0.1rem 0.3rem;
    border-radius: 0.2rem;
}
.release-notes-body pre {
    background-color: var(--bs-secondary-bg);
    padding: 0.75rem;
    border-radius: 0.375rem;
    overflow-x: auto;
}
.release-notes-body table {
    display: block;
    overflow-x: auto;
    max-width: 100%;
}

/* Notification bell dropdown: wide enough for two-line entries, capped so a
   long list scrolls inside the panel instead of running off the viewport. */
.notification-panel {
    min-width: 22rem;
    max-width: calc(100vw - 1rem);
    max-height: 70vh;
    overflow-y: auto;
}

/* Match the established price-period badge while keeping its close action easy to hit. */
.calendar-import-filter-term {
    font-size: 90%;
}

.calendar-import-filter-remove {
    width: 1em;
    height: 1em;
    margin-left: .25rem;
    padding: .5em;
    opacity: .85;
}

.calendar-import-filter-remove:hover,
.calendar-import-filter-remove:focus {
    opacity: 1;
}

/* ── Booking rule calendar (Settings → Online booking → Booking rules) ───────────── */
.booking-rule-calendar__main {
    position: relative;
    min-width: 0;
    padding: .75rem 0 .875rem;
}
.booking-rule-calendar__scroll {
    overflow-x: auto;
}
/* Days share the card width and only scroll once they would get narrower than 2.25rem. */
.booking-rule-calendar__grid {
    display: grid;
    grid-template-columns: 9.75rem repeat(var(--brc-days, 28), minmax(2.25rem, 1fr));
    width: 100%;
    min-width: calc(9.75rem + var(--brc-days, 28) * 2.25rem);
    font-size: .8125rem;
    border-top: 1px solid var(--bs-border-color);
}
.brc-label {
    position: sticky;
    left: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 2.125rem;
    padding: 0 .75rem;
    background-color: var(--bs-body-bg);
    border-right: 1px solid var(--bs-border-color);
    border-bottom: 1px solid var(--bs-border-color-translucent);
}
.brc-label__main { line-height: 1.2; }
.brc-label__sub { font-size: .6875rem; line-height: 1.2; color: var(--bs-secondary-color); }
.brc-month {
    display: flex;
    align-items: center;
    height: 1.625rem;
    padding-left: .375rem;
    overflow: hidden;
    font-size: .6875rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--bs-secondary-color);
    border-left: 1px solid var(--bs-border-color);
    border-bottom: 1px solid var(--bs-border-color-translucent);
}
.brc-label.brc-month {
    min-height: 1.625rem;
    padding-left: .75rem;
    letter-spacing: .03em;
    color: var(--bs-body-color);
    border-left: 0;
}
.brc-group {
    grid-column: 1 / -1;
    display: flex;
    align-items: flex-end;
    height: 1.625rem;
    padding-bottom: .25rem;
    font-size: .6875rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--bs-secondary-color);
    background-color: var(--bs-body-bg);
    border-bottom: 1px solid var(--bs-border-color-translucent);
}
.brc-group span { position: sticky; left: .75rem; }
.brc-day,
.brc-cell {
    position: relative;
    margin: 0;
    padding: 0;
    color: var(--bs-body-color);
    background-color: transparent;
    border: 0;
    border-right: 1px solid var(--bs-border-color-translucent);
    border-bottom: 1px solid var(--bs-border-color-translucent);
    cursor: default;
    appearance: none;
}
.brc-day {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    height: 2.875rem;
}
.brc-day__weekday { font-size: .6875rem; color: var(--bs-secondary-color); }
.brc-day__date { font: 500 .8125rem/1.1 var(--bs-font-monospace); font-variant-numeric: tabular-nums; }
.brc-cell {
    display: grid;
    place-items: center;
    height: 2.125rem;
    font: 500 .8125rem/1 var(--bs-font-monospace);
    font-variant-numeric: tabular-nums;
}
.brc-day.is-weekend,
.brc-cell.is-weekend { background-color: var(--bs-tertiary-bg); }
.brc-day.is-today .brc-day__date { color: var(--bs-primary-text-emphasis); }
.brc-day.is-today::before {
    content: "";
    position: absolute;
    left: 50%;
    bottom: .3rem;
    width: .25rem;
    height: .25rem;
    margin-left: -.125rem;
    border-radius: 50%;
    background-color: var(--bs-primary);
}
/* Value states come after the weekend tint, so a set value is never hidden by it. */
.brc-cell.brc-cell--general,
.brc-swatch.brc-cell--general { color: var(--bs-primary-text-emphasis); background-color: var(--bs-primary-bg-subtle); }
.brc-cell.brc-cell--period,
.brc-swatch.brc-cell--period { color: var(--bs-warning-text-emphasis); background-color: var(--bs-warning-bg-subtle); box-shadow: inset 0 3px 0 var(--bs-warning); }
.brc-cell.brc-cell--closed,
.brc-swatch.brc-cell--closed { color: var(--bs-danger-text-emphasis); background-color: var(--bs-danger-bg-subtle); }
.brc-cell.brc-cell--closed.is-period { box-shadow: inset 0 3px 0 var(--bs-warning); }
.brc-cell.brc-cell--none,
.brc-cell.brc-cell--open,
.brc-swatch.brc-cell--none { font-weight: 400; color: var(--bs-secondary-color); }
.brc-cell.has-override::after,
.brc-swatch.has-override::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    border-style: solid;
    border-width: 0 .5rem .5rem 0;
    border-color: transparent var(--bs-warning) transparent transparent;
}
.brc-cell.is-source { z-index: 1; outline: 2px solid var(--bs-primary); outline-offset: -2px; }
.brc-cell.is-replaced { z-index: 1; outline: 2px dashed var(--bs-primary); outline-offset: -3px; }
.brc-cell:focus-visible { z-index: 3; outline: 2px solid var(--bs-primary); outline-offset: -2px; }
/* Legend and highlight notes overlap in one cell; the tallest reserves the height, so a note never moves the rules below. */
.brc-legend-slot { display: grid; padding: .75rem 1rem 0; }
.brc-legend-slot > * { grid-area: 1 / 1; }
.brc-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem 1.125rem;
    font-size: .78rem;
    color: var(--bs-secondary-color);
}
.brc-legend > span { display: inline-flex; align-items: center; gap: .45rem; }
.brc-swatch {
    position: relative;
    display: inline-grid;
    place-items: center;
    width: 1rem;
    height: .875rem;
    overflow: hidden;
    font: 500 .625rem/1 var(--bs-font-monospace);
    border: 1px solid var(--bs-border-color);
    border-radius: 3px;
}
.brc-highlight-note { visibility: hidden; margin: 0; font-size: .78rem; color: var(--bs-primary-text-emphasis); }
.brc-legend-slot[data-highlight] > .brc-legend { visibility: hidden; }
.brc-legend-slot[data-highlight="found"] > [data-note="found"],
.brc-legend-slot[data-highlight="none"] > [data-note="none"] { visibility: visible; }
/* A clicked rule stays marked in the list, so it is clear which rule the calendar outlines. */
.booking-rule-item { cursor: pointer; }
.booking-rule-item.is-highlighted { background-color: var(--bs-primary-bg-subtle); box-shadow: inset 3px 0 0 var(--bs-primary); }
.booking-rule-item__mark,
.brc-highlight-clear { padding: 0; font: inherit; color: inherit; text-align: start; background: none; border: 0; }
.brc-highlight-clear { margin-left: .35rem; color: var(--bs-link-color); text-decoration: underline; }
.booking-rule-item__mark:focus-visible,
.brc-highlight-clear:focus-visible { outline: 2px solid var(--bs-primary); outline-offset: 2px; border-radius: 2px; }
.brc-tip {
    position: absolute;
    z-index: 30;
    display: grid;
    gap: .375rem;
    width: max-content;
    max-width: 19rem;
    padding: .625rem .75rem;
    font-size: .78rem;
    line-height: 1.45;
    color: var(--bs-body-bg);
    background-color: var(--bs-emphasis-color);
    border-radius: .5rem;
    box-shadow: 0 .5rem 1.5rem rgba(0, 0, 0, .2);
    pointer-events: none;
}
.brc-tip__title { font-size: .72rem; opacity: .72; }
.brc-tip__value { font-size: .85rem; font-weight: 500; }
.brc-tip__label { display: block; font-size: .65rem; letter-spacing: .07em; text-transform: uppercase; opacity: .72; }
/* Top row: what all rules add up to for an arrival on each day, set apart from the rule rows below. */
.brc-label--effective { min-height: 2.5rem; }
.brc-label--effective .brc-label__main { font-weight: 600; }
.brc-cell.brc-cell--effective { height: 2.5rem; font-size: .875rem; font-weight: 600; }
.brc-group--rules { border-top: 2px solid var(--bs-border-color); }
/* A dot where an arrival needs more than its own rules, a ring where a longer stay fails again. */
.brc-cell.is-raised::after,
.brc-cell.has-gap::before { content: ""; position: absolute; top: 4px; width: 6px; height: 6px; border-radius: 50%; }
.brc-cell.is-raised::after { right: 4px; background-color: var(--bs-danger); }
.brc-cell.has-gap::before { left: 4px; border: 1.5px solid var(--bs-danger); }
.brc-swatch.is-raised::after,
.brc-swatch.has-gap::after { content: ""; width: 6px; height: 6px; border-radius: 50%; }
.brc-swatch.is-raised::after { background-color: var(--bs-danger); }
.brc-swatch.has-gap::after { border: 1.5px solid var(--bs-danger); }

/* Price rules offcanvas: opened from the bottom on phones, tall enough for the whole form. */
.price-rules-offcanvas.offcanvas-bottom {
    height: 85vh;
}

/* Price calendar: the month as a seven-column grid on wider screens. */
.price-calendar-grid {
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: .5rem;
}

.price-calendar-cell {
    min-height: 6.5rem;
}

/* Popovers listing one entry per line (e.g. "payment method → template"); Bootstrap's 276px
   default would break the longer entries. */
.popover-wide {
    --bs-popover-max-width: 420px;
}
